Skip to content

Commit 9f676a7

Browse files
committed
feat: added update rsvp and get rsvp
1 parent 2edff88 commit 9f676a7

File tree

2 files changed

+416
-32
lines changed

2 files changed

+416
-32
lines changed

src/routes/inviteRoutes.ts

Lines changed: 125 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import express, { Request, Response } from 'express';
2+
import { PrismaClient } from '@prisma/client'; // Add this import
23
import {
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';
1317
import { isEventHostOrCoHost } from '../services/guestService';
1418

1519
const router = express.Router();
20+
const prisma = new PrismaClient(); // Add this line
1621

1722
// Generate invite link for a specific group
1823
router.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)
94206
router.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
193310
const 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

Comments
 (0)