diff options
Diffstat (limited to 'backend/src/routes/events.ts')
| -rw-r--r-- | backend/src/routes/events.ts | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/backend/src/routes/events.ts b/backend/src/routes/events.ts new file mode 100644 index 0000000..df65eb5 --- /dev/null +++ b/backend/src/routes/events.ts @@ -0,0 +1,105 @@ +import db from "../db.js"; +import { Router } from "express"; +import { getUser } from "./users.js"; +import { type Event, type Id, type Rsvps, type User } from "../types.js"; + +const router = Router(); + +const joinHost = (event: Event) => { + const host = getUser(event.host_id) as User; + return { ...event, host }; +}; + +const joinRSVPs = (event: Event) => { + const { id } = event; + const getRSVPs = db.prepare("SELECT * FROM rsvps WHERE event_id = @id"); + const rsvps = getRSVPs.all({ id }) as Rsvps[]; + return { ...event, rsvps }; +}; + +const getEvent = (eventId: Id) => { + const byId = db.prepare("SELECT * FROM events WHERE id = @eventId"); + const event = byId.get({ eventId }) as Event; + return joinHost(event); +}; + +router.get("/", (_req, res) => { + const listEvents = db.prepare(`SELECT * FROM events`); + const events = listEvents.all() as Event[]; + res.json(events.map(joinHost).map(joinRSVPs)); +}); + +const insertEvent = db.prepare( + `INSERT INTO events VALUES (@id, @title, @description, @image_url, @date, @host_id)`, +); + +router.post("/new", (req, res) => { + const data = req.body; + const { lastInsertRowid } = insertEvent.run(data); + const id = lastInsertRowid as number; + const event = getEvent(id); + res.status(201).json(event); +}); + +router.get("/:id", (req, res) => { + const id = parseInt(req.params.id); + const event = getEvent(id); + if (!event) { + return res.status(404).json({ error: "Event not found" }); + } + res.json(event); +}); + +router.patch("/:id", (req, res) => { + const eventId = parseInt(req.params.id); + const patch = req.body; + + const updateCol = db.prepare(` + UPDATE events SET @col = @val WHERE id = @eventId + `); + const updateEvent = db.transaction((patch) => { + for (const [col, val] of Object.entries(patch)) { + updateCol.run({ col, val, eventId }); + } + }); + + updateEvent(Object.entries(patch)); + const updated = getEvent(eventId); + res.json(updated); +}); + +router.delete("/:id", (req, res) => { + const deleteEvent = db.prepare(`DELETE FROM events WHERE id = @eventId`); + const eventId = parseInt(req.params.id); + const event = getEvent(eventId); + if (!event) { + return res.status(404).json({ error: "Event not found" }); + } + deleteEvent.run({ eventId }); + res.json(event); +}); + +router.post("/:id/rsvp", (req, res) => { + const eventId = parseInt(req.params.id); + const { name, email } = req.body; + + const getRSVP = db.prepare( + `SELECT * FROM rsvps WHERE (event_id = ${eventId} AND email = '${email}')`, + ); + const insertRSVP = db.prepare( + `INSERT INTO rsvps VALUES (@eventId, @name, @email)`, + ); + + let [rsvp] = getRSVP.all({ eventId, email }); + if (rsvp) { + // This email has already RSVPed + res.status(200).json({ rsvp }); + } else { + // New RSVP + insertRSVP.run({ name, email, eventId }); + rsvp = getRSVP.run({ eventId, email }); + res.status(201).json({ rsvp }); + } +}); + +export default router; |
