247 lines
7.1 KiB
TypeScript
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'
|
|
});
|
|
}
|
|
}
|