diff --git a/backend/src/index.ts b/backend/src/index.ts index ea4a700..a89fa00 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -131,6 +131,31 @@ app.delete('/api/events/:slug/rsvps/:id', async (req: Request, res: Response) => } }); +// Update RSVP +app.put('/api/events/:slug/rsvps/:id', async (req: Request, res: Response) => { + try { + const { slug, id } = req.params; + const { name, attending, bringing_guests, guest_count, guest_names, items_bringing } = req.body; + + // Verify the RSVP belongs to the correct event + const eventRows = await db.all('SELECT id FROM events WHERE slug = ?', [slug]); + + if (eventRows.length === 0) { + return res.status(404).json({ error: 'Event not found' }); + } + + const eventId = eventRows[0].id; + await db.run( + 'UPDATE rsvps SET name = ?, attending = ?, bringing_guests = ?, guest_count = ?, guest_names = ?, items_bringing = ? WHERE id = ? AND event_id = ?', + [name, attending, bringing_guests, guest_count, guest_names, items_bringing, id, eventId] + ); + res.status(200).json({ message: 'RSVP updated successfully' }); + } catch (error) { + console.error('Error updating RSVP:', error); + res.status(500).json({ error: 'Internal server error' }); + } +}); + // Initialize database tables async function initializeDatabase() { try { diff --git a/frontend/src/components/EventAdmin.tsx b/frontend/src/components/EventAdmin.tsx index be3ca7c..0679101 100644 --- a/frontend/src/components/EventAdmin.tsx +++ b/frontend/src/components/EventAdmin.tsx @@ -17,6 +17,13 @@ import { DialogTitle, DialogContent, DialogActions, + TextField, + FormControl, + InputLabel, + Select, + MenuItem, + FormControlLabel, + Switch, } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; @@ -50,6 +57,16 @@ const EventAdmin: React.FC = () => { const [error, setError] = useState(null); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [rsvpToDelete, setRsvpToDelete] = useState(null); + const [editDialogOpen, setEditDialogOpen] = useState(false); + const [rsvpToEdit, setRsvpToEdit] = useState(null); + const [editForm, setEditForm] = useState({ + name: '', + attending: 'yes', + bringing_guests: 'no', + guest_count: 0, + guest_names: '', + items_bringing: '', + }); useEffect(() => { fetchEventAndRsvps(); @@ -88,6 +105,40 @@ const EventAdmin: React.FC = () => { } }; + const handleEditRsvp = (rsvp: RSVP) => { + setRsvpToEdit(rsvp); + setEditForm({ + name: rsvp.name, + attending: rsvp.attending, + bringing_guests: rsvp.bringing_guests, + guest_count: rsvp.guest_count, + guest_names: rsvp.guest_names, + items_bringing: rsvp.items_bringing, + }); + setEditDialogOpen(true); + }; + + const handleEditFormChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setEditForm(prev => ({ + ...prev, + [name as string]: value, + })); + }; + + const handleEditSubmit = async () => { + if (!rsvpToEdit) return; + + try { + await axios.put(`/api/events/${slug}/rsvps/${rsvpToEdit.id}`, editForm); + setRsvps(rsvps.map(r => r.id === rsvpToEdit.id ? { ...r, ...editForm } : r)); + setEditDialogOpen(false); + setRsvpToEdit(null); + } catch (error) { + setError('Failed to update RSVP'); + } + }; + if (loading) { return ( @@ -148,6 +199,13 @@ const EventAdmin: React.FC = () => { {rsvp.items_bringing} + handleEditRsvp(rsvp)} + sx={{ mr: 1 }} + > + + handleDeleteRsvp(rsvp)} @@ -177,6 +235,85 @@ const EventAdmin: React.FC = () => { + + setEditDialogOpen(false)} + maxWidth="sm" + fullWidth + > + Edit RSVP + + + + + Attending + + + + Bringing Guests + + + {editForm.bringing_guests === 'yes' && ( + <> + + + + )} + + + + + + + + ); };