11import express , { Request , Response } from 'express' ;
2+ import { PrismaClient } from '@prisma/client' ; // Add this import
23import {
34 generateGroupInviteLink ,
45 getGroupInviteDetails ,
56 submitGroupRsvp ,
67 getGroupRsvpStatus ,
78 getUserRsvps ,
9+ getUserRsvpForEvent ,
10+ getUserRsvpByGroup ,
11+ updateUserRsvp ,
812 getEventRsvpSummary ,
913 getEventGuestList ,
1014 bulkCreateInvites
@@ -13,6 +17,7 @@ import { verifyIdToken } from '../middleware/verifyIdToken';
1317import { isEventHostOrCoHost } from '../services/guestService' ;
1418
1519const router = express . Router ( ) ;
20+ const prisma = new PrismaClient ( ) ; // Add this line
1621
1722// Generate invite link for a specific group
1823router . post ( '/generate/:eventId/:groupId' , verifyIdToken , async ( req : Request , res : Response ) => {
@@ -90,6 +95,113 @@ router.post('/bulk/:eventId', verifyIdToken, async (req: Request, res: Response)
9095 }
9196} ) ;
9297
98+ // Get authenticated user's RSVP for a specific event
99+ router . get ( '/rsvp/event/:eventId' , verifyIdToken , async ( req : Request , res : Response ) => {
100+ try {
101+ const { eventId } = req . params ;
102+ const userId = req . userId ;
103+ if ( ! userId ) {
104+ res . status ( 401 ) . json ( { message : 'Unauthorized' } ) ;
105+ return ;
106+ }
107+
108+ const result = await getUserRsvpForEvent ( userId , eventId ) ;
109+
110+ if ( ! result . success ) {
111+ if ( result . error ?. includes ( 'not found' ) ) {
112+ res . status ( 404 ) . json ( { message : result . error } ) ;
113+ } else {
114+ res . status ( 400 ) . json ( { message : result . error } ) ;
115+ }
116+ return ;
117+ }
118+
119+ res . status ( 200 ) . json ( {
120+ rsvp : result . rsvp
121+ } ) ;
122+ } catch ( error ) {
123+ console . error ( error ) ;
124+ res . status ( 500 ) . json ( { message : 'Internal Server Error' } ) ;
125+ }
126+ } ) ;
127+
128+ // Get authenticated user's RSVP by group ID
129+ router . get ( '/rsvp/event/:eventId/group/:groupId' , verifyIdToken , async ( req : Request , res : Response ) => {
130+ try {
131+ const { eventId, groupId } = req . params ;
132+ const userId = req . userId ;
133+ if ( ! userId ) {
134+ res . status ( 401 ) . json ( { message : 'Unauthorized' } ) ;
135+ return ;
136+ }
137+
138+ const result = await getUserRsvpByGroup ( userId , eventId , groupId ) ;
139+
140+ if ( ! result . success ) {
141+ if ( result . error ?. includes ( 'not found' ) ) {
142+ res . status ( 404 ) . json ( { message : result . error } ) ;
143+ } else {
144+ res . status ( 400 ) . json ( { message : result . error } ) ;
145+ }
146+ return ;
147+ }
148+
149+ res . status ( 200 ) . json ( {
150+ rsvp : result . rsvp
151+ } ) ;
152+ } catch ( error ) {
153+ console . error ( error ) ;
154+ res . status ( 500 ) . json ( { message : 'Internal Server Error' } ) ;
155+ }
156+ } ) ;
157+
158+ // Update authenticated user's RSVP for a specific event
159+ router . put ( '/rsvp/event/:eventId' , verifyIdToken , async ( req : Request , res : Response ) => {
160+ try {
161+ const { eventId } = req . params ;
162+ const userId = req . userId ;
163+ if ( ! userId ) {
164+ res . status ( 401 ) . json ( { message : 'Unauthorized' } ) ;
165+ return ;
166+ }
167+ const { rsvp, food, alcohol, accommodation, count } = req . body ;
168+
169+ // Validate RSVP status
170+ const validRsvpStatuses = [ 'accepted' , 'declined' , 'maybe' ] ;
171+ if ( ! rsvp || ! validRsvpStatuses . includes ( rsvp ) ) {
172+ res . status ( 400 ) . json ( { message : 'Valid RSVP status is required (accepted, declined, maybe)' } ) ;
173+ return ;
174+ }
175+
176+ const result = await updateUserRsvp ( userId , eventId , {
177+ rsvp,
178+ food,
179+ alcohol,
180+ accommodation,
181+ count
182+ } ) ;
183+
184+ if ( ! result . success ) {
185+ if ( result . error ?. includes ( 'not found' ) ) {
186+ res . status ( 404 ) . json ( { message : result . error } ) ;
187+ } else if ( result . error ?. includes ( 'already started' ) ) {
188+ res . status ( 400 ) . json ( { message : result . error } ) ;
189+ } else {
190+ res . status ( 400 ) . json ( { message : result . error } ) ;
191+ }
192+ return ;
193+ }
194+
195+ res . status ( 200 ) . json ( {
196+ message : result . message ,
197+ rsvp : result . rsvp
198+ } ) ;
199+ } catch ( error ) {
200+ console . error ( error ) ;
201+ res . status ( 500 ) . json ( { message : 'Internal Server Error' } ) ;
202+ }
203+ } ) ;
204+
93205// Get RSVP summary for an event (host/co-host only)
94206router . get ( '/summary/:eventId' , verifyIdToken , async ( req : Request , res : Response ) => {
95207 try {
@@ -156,7 +268,10 @@ router.get('/guests/:eventId', verifyIdToken, async (req: Request, res: Response
156268 }
157269
158270 res . status ( 200 ) . json ( {
159- guests : result . guests
271+ guests : result . guests ,
272+ linkedGuests : result . linkedGuests ,
273+ unlinkedGuests : result . unlinkedGuests ,
274+ summary : result . summary
160275 } ) ;
161276 } catch ( error ) {
162277 console . error ( error ) ;
@@ -189,6 +304,8 @@ router.get('/my-rsvps', verifyIdToken, async (req: Request, res: Response) => {
189304 }
190305} ) ;
191306
307+ // ===== PUBLIC ROUTES WITH OPTIONAL AUTH =====
308+
192309// Optional authentication middleware for invite routes
193310const optionalAuth = ( req : Request , res : Response , next : any ) => {
194311 const authHeader = req . headers . authorization ;
@@ -203,12 +320,12 @@ const optionalAuth = (req: Request, res: Response, next: any) => {
203320} ;
204321
205322// Get group invite details by group ID (public with optional auth)
206- router . get ( '/:groupId' , optionalAuth , async ( req : Request , res : Response ) => {
323+ router . get ( '/:eventId/: groupId' , optionalAuth , async ( req : Request , res : Response ) => {
207324 try {
208- const { groupId } = req . params ;
325+ const { eventId , groupId } = req . params ;
209326 const userId = req . userId ; // Will be undefined if not authenticated
210327
211- const result = await getGroupInviteDetails ( groupId , userId ) ;
328+ const result = await getGroupInviteDetails ( eventId , groupId , userId ) ;
212329
213330 if ( ! result . success ) {
214331 res . status ( 404 ) . json ( { message : result . error } ) ;
@@ -228,9 +345,9 @@ router.get('/:groupId', optionalAuth, async (req: Request, res: Response) => {
228345} ) ;
229346
230347// Submit RSVP for a group (public with optional auth)
231- router . post ( '/:groupId/rsvp' , optionalAuth , async ( req : Request , res : Response ) => {
348+ router . post ( '/:eventId/: groupId/rsvp' , optionalAuth , async ( req : Request , res : Response ) => {
232349 try {
233- const { groupId } = req . params ;
350+ const { eventId , groupId } = req . params ;
234351 const userId = req . userId ; // Will be undefined if not authenticated
235352 const { name, phone_no, email, rsvp, food, alcohol, accommodation, count } = req . body ;
236353
@@ -254,7 +371,7 @@ router.post('/:groupId/rsvp', optionalAuth, async (req: Request, res: Response)
254371 return ;
255372 }
256373
257- const result = await submitGroupRsvp ( groupId , {
374+ const result = await submitGroupRsvp ( eventId , groupId , {
258375 name,
259376 phone_no,
260377 email,
@@ -285,7 +402,7 @@ router.post('/:groupId/rsvp', optionalAuth, async (req: Request, res: Response)
285402} ) ;
286403
287404// Get RSVP status for a phone number in a group (public)
288- router . get ( '/:groupId/status/:phoneNo' , async ( _req : Request , res : Response ) => {
405+ router . get ( '/:eventId/: groupId/status/:phoneNo' , async ( _req : Request , res : Response ) => {
289406 res . status ( 403 ) . json ( { message : 'RSVP status can be viewed and managed in the app. Please download the app to continue.' } ) ;
290407} ) ;
291408
0 commit comments