diff --git a/admin/src/pages/MeetingPlannerPage.tsx b/admin/src/pages/MeetingPlannerPage.tsx index f3a85acb..5b0a15c1 100644 --- a/admin/src/pages/MeetingPlannerPage.tsx +++ b/admin/src/pages/MeetingPlannerPage.tsx @@ -233,6 +233,17 @@ export default function MeetingPlannerPage() { } }; + const handleRemoveVoter = async (voterKey: string) => { + if (!selectedPoll) return; + try { + await api.delete(`/meeting-planner/${selectedPoll.id}/voters/${encodeURIComponent(voterKey)}`); + message.success('Voter removed'); + fetchPollDetail(selectedPoll.id); + } catch { + message.error('Failed to remove voter'); + } + }; + const openEditDrawer = async (id: string) => { try { const { data } = await api.get(`/meeting-planner/${id}`); @@ -283,13 +294,23 @@ export default function MeetingPlannerPage() { const handleUpdateOption = async (optionId: string, field: string, value: string) => { if (!editPoll) return; + // Optimistic update: immediately reflect the change in local state + const optimisticDate = field === 'date' ? value + 'T00:00:00.000Z' : undefined; + setEditPoll((prev) => prev ? { + ...prev, + options: prev.options.map((opt: any) => + opt.id === optionId + ? { ...opt, [field]: optimisticDate ?? value } + : opt + ), + } : prev); try { await api.put(`/meeting-planner/${editPoll.id}/options/${optionId}`, { [field]: value }); - // Refresh edit poll data - const { data } = await api.get(`/meeting-planner/${editPoll.id}`); - setEditPoll(data); message.success('Option updated'); } catch { + // Revert on failure by refetching + const { data } = await api.get(`/meeting-planner/${editPoll.id}`); + setEditPoll(data); message.error('Failed to update option'); } }; @@ -399,6 +420,7 @@ export default function MeetingPlannerPage() { Voter + {poll.options.map((opt) => ( {voter.name} + + handleRemoveVoter(voter.voterKey)} + > +