event rsvp popup
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
import React, { useState } from 'react'
|
||||
import EventInfo from './EventInfo'
|
||||
import EventRsvpTracking from './EventRsvpTracking'
|
||||
import EventToDoList from './EventToDoList'
|
||||
import ToDoList from '../ToDoList'
|
||||
import { fetchEventTodos } from '@/lib/helper/fetchTodos'
|
||||
|
||||
|
||||
97
components/events/EventRsvpModal.tsx
Normal file
97
components/events/EventRsvpModal.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
'use client'
|
||||
import React from 'react'
|
||||
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog'
|
||||
import { toast } from 'sonner'
|
||||
import { Button } from '../ui/button'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'
|
||||
|
||||
interface GuestBookEntry {
|
||||
id: string
|
||||
fName: string
|
||||
lName: string
|
||||
}
|
||||
|
||||
interface EventGuest {
|
||||
id: string
|
||||
rsvp: 'YES' | 'NO' | 'PENDING'
|
||||
eventId: string
|
||||
guestBookEntryId: string
|
||||
guestBookEntry: GuestBookEntry
|
||||
}
|
||||
|
||||
interface Props {
|
||||
eventGuests: EventGuest[]
|
||||
}
|
||||
|
||||
export default function EventRsvpModal({ eventGuests }: Props) {
|
||||
|
||||
const handleRsvpChange = async (
|
||||
guest: EventGuest,
|
||||
rsvp: 'YES' | 'NO' | 'PENDING'
|
||||
) => {
|
||||
try {
|
||||
const res = await fetch(
|
||||
`/api/events/${guest.eventId}/guests/${guest.guestBookEntryId}/rsvp`,
|
||||
{
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ rsvp })
|
||||
}
|
||||
)
|
||||
|
||||
if (!res.ok) throw new Error('Failed to update RSVP')
|
||||
toast.success(`RSVP updated for ${guest.guestBookEntry.fName} ${guest.guestBookEntry.lName}`)
|
||||
} catch (err) {
|
||||
console.error('RSVP update error:', err)
|
||||
toast.error('Failed to update RSVP')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="secondary">Manage Guest RSVPs</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className='max-w-2xl'>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Manage Guest RSVPs</DialogTitle>
|
||||
<DialogDescription>
|
||||
Update RSVP statuses for each guest attending this event.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className='space-y-4 max-h-[400px] overflow-y-auto pr-1'>
|
||||
{eventGuests.length && eventGuests.map(guest => (
|
||||
<div key={guest.id} className="flex justify-between items-center bg-muted p-3 rounded-md">
|
||||
<div>
|
||||
<p className="font-medium">{guest.guestBookEntry.fName + " " + guest.guestBookEntry.lName}</p>
|
||||
</div>
|
||||
<Select
|
||||
defaultValue={guest.rsvp}
|
||||
onValueChange={(value) =>
|
||||
handleRsvpChange(guest, value as 'YES' | 'NO' | 'PENDING')
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-[120px]">
|
||||
<SelectValue placeholder="Select status" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="PENDING">Pending</SelectItem>
|
||||
<SelectItem value="YES">Yes</SelectItem>
|
||||
<SelectItem value="NO">No</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<DialogFooter className="mt-4">
|
||||
<DialogClose asChild>
|
||||
<Button variant="ghost">Close</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
@@ -1,12 +1,30 @@
|
||||
'use client'
|
||||
import React from 'react'
|
||||
import { Card, CardContent } from '../ui/card'
|
||||
import { Button } from '../ui/button'
|
||||
import EventRsvpModal from './EventRsvpModal'
|
||||
|
||||
export default function EventRsvpTracking({ eventGuests }: EventData) {
|
||||
interface GuestBookEntry {
|
||||
id: string
|
||||
fName: string
|
||||
lName: string
|
||||
}
|
||||
|
||||
interface EventGuest {
|
||||
id: string
|
||||
rsvp: 'YES' | 'NO' | 'PENDING'
|
||||
eventId: string
|
||||
guestBookEntryId: string
|
||||
guestBookEntry: GuestBookEntry
|
||||
}
|
||||
|
||||
interface Props {
|
||||
eventGuests: EventGuest[]
|
||||
}
|
||||
|
||||
export default function EventRsvpTracking({ eventGuests }: Props) {
|
||||
const attendingGuests = eventGuests.filter((g) => g.rsvp === 'YES');
|
||||
const notAttendingGuests = eventGuests.filter((g) => g.rsvp === 'NO');
|
||||
const pendingGuests = eventGuests.filter((g) => g.rsvp === 'PENDING');
|
||||
|
||||
return (
|
||||
<Card className='py-0'>
|
||||
<CardContent className='p-4'>
|
||||
@@ -29,7 +47,7 @@ export default function EventRsvpTracking({ eventGuests }: EventData) {
|
||||
<p className='text-2xl font-bold'>{pendingGuests.length}</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button variant="secondary" className="mt-4 hover:cursor-pointer hover:bg-brand-primary-900">Manage Guest List</Button>
|
||||
<EventRsvpModal eventGuests={eventGuests} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user