Files
004_comission/_resources/_tecky/party-planner/backend/routes/eventsRoutes.ts
louiscklaw 6c60a73f30 update,
2025-01-31 19:15:17 +08:00

247 lines
7.1 KiB
TypeScript

import express, { Request, Response } from 'express';
import { client } from '../app';
import { Events } from '../util/models';
import { onlyNumbers } from '../util/functions/onlyNumbers';
import { logger } from '../util/logger';
import { isLoggedInAPI, isLoggedInInvitation } from '../util/guard';
import { eventDetailsRoutes } from './eventDetailsRoutes';
import { venuePollRoutes } from './venuePollRoutes';
import { datetimePollRoutes } from './datetimePollRoutes';
import crypto from 'crypto';
import { eventInvitationRoutes } from './eventInvitationRoutes';
export const eventsRoutes = express.Router();
eventsRoutes.get('/created', isLoggedInAPI, getCreateEventList);
eventsRoutes.get('/participated', isLoggedInAPI, getParticipateEventList);
eventsRoutes.post('/', isLoggedInAPI, postEvent);
eventsRoutes.delete('/:eventId', isLoggedInAPI, deleteEvent);
eventsRoutes.delete('/participants/:eventId', isLoggedInAPI, deleteParticipants);
eventsRoutes.use('/detail', isLoggedInAPI, eventDetailsRoutes);
eventsRoutes.use('/invitation', isLoggedInInvitation, eventInvitationRoutes);
eventsRoutes.use('/poll/venue', isLoggedInAPI, venuePollRoutes);
eventsRoutes.use('/poll/datetime', isLoggedInAPI, datetimePollRoutes);
// getCreatedEvents
async function getCreateEventList(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const [columnCountObject] = (
await client.query(`SELECT COUNT(*) FROM events WHERE creator_id = $1 `, [req.session.user || 0])
).rows;
const columnCount = parseInt(columnCountObject.count);
let currentPage = req.query.page + '';
let offset: number = onlyNumbers(currentPage) ? (parseInt(currentPage) - 1) * 10 : 0;
if (!columnCount) {
currentPage = '1';
offset = 0;
} else if (Math.ceil(columnCount / 10) < parseInt(currentPage)) {
currentPage = Math.ceil(columnCount / 10).toString();
offset = (Math.ceil(columnCount / 10) - 1) * 10;
}
const result = await client.query(
`
SELECT * FROM events
WHERE creator_id = $1
ORDER BY start_datetime DESC, id DESC
LIMIT 10 OFFSET $2;
`,
[req.session.user || 0, offset]
);
const eventList: Events[] = result.rows;
res.json({
object: eventList, // should be called eventList or events
currentPage: currentPage,
page: columnCount ? Math.ceil(columnCount / 10) : 1
});
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[EVT001]: Failed to get Created Event List'
});
}
}
// getParticipatedEvents
async function getParticipateEventList(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const [columnCountObject] = (
await client.query(
`SELECT COUNT(events.*) FROM events
INNER JOIN participants ON participants.event_id = events.id
INNER JOIN users ON participants.user_id = users.id
WHERE users.id = $1;`,
[req.session.user || 0]
)
).rows;
const columnCount = parseInt(columnCountObject.count);
let currentPage = req.query.page as string;
let offset: number = onlyNumbers(currentPage) ? (parseInt(currentPage) - 1) * 10 : 0;
if (!columnCount) {
currentPage = '1';
offset = 0;
} else if (Math.ceil(columnCount / 10) < parseInt(currentPage)) {
currentPage = Math.ceil(columnCount / 10).toString();
offset = (Math.ceil(columnCount / 10) - 1) * 10;
}
const result = await client.query(
`
SELECT events.* FROM events
INNER JOIN participants ON participants.event_id = events.id
INNER JOIN users ON participants.user_id = users.id
WHERE users.id = $1
ORDER BY events.start_datetime DESC, events.id DESC
LIMIT 10 OFFSET $2;
`,
[req.session.user || 0, offset]
);
const eventList: Events[] = result.rows;
res.json({
object: eventList,
currentPage: currentPage,
page: columnCount ? Math.ceil(columnCount / 10) : 1
});
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[EVT002]: Failed to get Participated Event List'
});
}
}
async function postEvent(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const invitation_token = crypto.randomBytes(64).toString('hex');
await client.query(
`INSERT INTO events
(name, venue, start_datetime, end_datetime,
creator_id, invitation_token, deleted,
date_poll_created,
date_poll_terminated,
venue_poll_created,
venue_poll_terminated,
created_at, updated_at)
VALUES ($1,$2,$3,$4,$5,$6,FALSE,FALSE,FALSE,FALSE,FALSE,
CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)`,
[
req.body.eventName,
req.body.eventVenue,
req.body.startTime,
req.body.endTime,
req.session.user,
invitation_token
]
);
res.json({ msg: 'Posted to DB' });
} catch (e) {
logger.error(e);
res.status(500).json({ msg: '[EVT003]: Failed to post Event' });
}
}
async function deleteParticipants(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const eventId = req.params.eventId ? parseInt(req.params.eventId) : 0;
const [eventDetail] = (
await client.query(
`
SELECT * FROM events
WHERE creator_id = $1
AND id = $2;
`,
[req.session.user, eventId]
)
).rows;
const deletedParticipants: { id: number }[] = req.body.deletedParticipants;
if (eventDetail) {
const participantsWithItemAssigned = await client.query(
`
SELECT user_id FROM items
WHERE user_id = ANY($1::int[])
`,
[deletedParticipants.map((p) => p.id)]
);
console.log(participantsWithItemAssigned);
// Removed all of the ids from participantsWithItemAssigned
// Then run delete
let notDeletable = [];
for (let deletedParticipant of req.body) {
// n + 1 problem
const itemInCharge = (
await client.query(
`
SELECT * FROM items
WHERE user_id = $1 AND event_id = $2 AND purchased = FALSE;
`,
[deletedParticipant.id, eventId]
)
).rows;
if (itemInCharge.length) {
notDeletable.push({
deletedParticipant,
itemInCharge
});
} else {
await client.query(
`
DELETE FROM participants WHERE user_id = $1 and event_id = $2;
`,
[deletedParticipant.id, eventId]
);
}
}
res.json({
status: true,
notDeletable
});
} else {
res.status(500).json({ status: false });
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[EVT004]: Failed to delete Participants'
});
}
}
// Archived
async function deleteEvent(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const eventId = req.params.eventId ? parseInt(req.params.eventId) : 0;
const [eventDetail] = (
await client.query(
`
SELECT * FROM events
WHERE creator_id = $1
AND id = $2;
`,
[req.session.user, eventId]
)
).rows;
if (eventDetail) {
// Marked Delete
await client.query(
`
UPDATE events SET deleted = TRUE
WHERE id = $1;
`,
[eventId]
);
res.json({ status: true });
} else {
res.json({ status: false });
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[EVT005]: Failed to delete Event'
});
}
}