You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
6.5 KiB
TypeScript
204 lines
6.5 KiB
TypeScript
import express, { Router, Request, Response } from "express";
|
|
import Joi from "joi"
|
|
|
|
import { client } from "../../db";
|
|
import { DatabaseError } from "pg";
|
|
import Trainer from "../../interfaces/trainer";
|
|
import { AdminAuth } from "../../middlewares/auth";
|
|
import { trainerExists } from "../../middlewares/trainer";
|
|
import { idSchema } from "../../schemas";
|
|
|
|
const router: Router = express.Router();
|
|
|
|
const trainerFiltersSchema = Joi.object({
|
|
center: Joi.array().single().items(
|
|
idSchema.required()
|
|
)
|
|
});
|
|
|
|
interface TrainerFilters {
|
|
center?: number[]
|
|
}
|
|
|
|
interface TrainerWithHourlyPrice extends Trainer {
|
|
hourly_price: number
|
|
}
|
|
|
|
router.get("/trainer", async (req: Request, res: Response) => {
|
|
try {
|
|
const validation = trainerFiltersSchema.validate(req.query, { abortEarly: false, stripUnknown: true });
|
|
if (validation.error !== undefined) {
|
|
return res.status(400).send(validation.error.details);
|
|
}
|
|
|
|
const trainerFilters: TrainerFilters = validation.value;
|
|
|
|
const databaseResult = await client.query(`
|
|
SELECT trainers.id, first_name, last_name, center_id, centers.name as center_name FROM trainers
|
|
JOIN users ON trainers.user_id = users.id
|
|
JOIN centers on trainers.center_id = centers.id
|
|
WHERE trainers.id = ANY($1) OR $2
|
|
ORDER BY first_name ASC;
|
|
`, [
|
|
trainerFilters.center !== undefined ? trainerFilters.center : [],
|
|
trainerFilters.center === undefined
|
|
]);
|
|
|
|
const trainers: Trainer[] = databaseResult.rows;
|
|
|
|
return res.status(200).send(trainers);
|
|
} catch (error: DatabaseError | Error | any) {
|
|
console.error(error);
|
|
return res.sendStatus(500);
|
|
}
|
|
})
|
|
|
|
router.get("/admin/trainer", AdminAuth, async (req: Request, res: Response) => {
|
|
try {
|
|
const validation = trainerFiltersSchema.validate(req.query, { abortEarly: false, stripUnknown: true });
|
|
if (validation.error !== undefined) {
|
|
return res.status(400).send(validation.error.details);
|
|
}
|
|
|
|
const trainerFilters: TrainerFilters = validation.value;
|
|
|
|
const databaseResult = await client.query(`
|
|
SELECT
|
|
trainers.id,
|
|
first_name,
|
|
last_name,
|
|
center_id,
|
|
centers.name as center_name,
|
|
hourly_price
|
|
FROM trainers
|
|
JOIN users ON trainers.user_id = users.id
|
|
JOIN centers on trainers.center_id = centers.id
|
|
WHERE trainers.id = ANY($1) OR $2
|
|
ORDER BY first_name ASC;
|
|
`, [
|
|
trainerFilters.center !== undefined ? trainerFilters.center : [],
|
|
trainerFilters.center === undefined
|
|
]);
|
|
|
|
const trainers: TrainerWithHourlyPrice[] = databaseResult.rows;
|
|
|
|
return res.status(200).send(trainers);
|
|
} catch (error: DatabaseError | Error | any) {
|
|
console.error(error);
|
|
return res.sendStatus(500);
|
|
}
|
|
})
|
|
|
|
const createTrainerSchema = Joi.object({
|
|
email: Joi.string().email().required(),
|
|
center_id: Joi.number().integer().positive().required(),
|
|
hourly_price: Joi.number().integer().positive().required()
|
|
});
|
|
|
|
router.post("/trainer", AdminAuth, async (req: Request, res: Response) => {
|
|
try {
|
|
const validation = createTrainerSchema.validate(req.body, { abortEarly: false });
|
|
if (validation.error !== undefined) {
|
|
return res.status(400).send(validation.error.details);
|
|
}
|
|
|
|
const trainerLookup = await client.query(`
|
|
SELECT id FROM users
|
|
WHERE email = $1;
|
|
`, [
|
|
validation.value.email
|
|
]);
|
|
|
|
if (trainerLookup.rows.length !== 1)
|
|
return res.status(400).send([{
|
|
message: "\"email\" was not found",
|
|
path: [
|
|
"email"
|
|
],
|
|
type: "email.not_found"
|
|
}]);
|
|
|
|
const user_id = trainerLookup.rows[0].id;
|
|
|
|
await client.query(`
|
|
INSERT INTO trainers (user_id, center_id, hourly_price)
|
|
VALUES ($1, $2, $3);
|
|
`, [
|
|
user_id,
|
|
validation.value.center_id,
|
|
validation.value.hourly_price
|
|
]);
|
|
|
|
return res.sendStatus(204);
|
|
} catch (error: DatabaseError | Error | any) {
|
|
if (error.constraint == "trainers_user_id_key") {
|
|
return res.status(400).send([{
|
|
message: "\"user_id\" is already a trainer",
|
|
path: [
|
|
"user_id"
|
|
],
|
|
type: "user_id.unique"
|
|
}]);
|
|
}
|
|
if (error.constraint == "trainers_center_id_fkey") {
|
|
return res.status(400).send([{
|
|
message: "\"center_id\" is not a valid center",
|
|
path: [
|
|
"center_id"
|
|
],
|
|
type: "center_id.not_found"
|
|
}]);
|
|
}
|
|
console.error(error);
|
|
return res.sendStatus(500);
|
|
}
|
|
})
|
|
|
|
const updateTrainerSchema = Joi.object({
|
|
center_id: Joi.number().integer().positive().required(),
|
|
hourly_price: Joi.number().integer().positive().required()
|
|
});
|
|
|
|
router.put("/trainer/:id", AdminAuth, trainerExists, async (req: Request, res: Response) => {
|
|
try {
|
|
const validation = updateTrainerSchema.validate(req.body, { abortEarly: false });
|
|
if (validation.error !== undefined) {
|
|
return res.status(400).send(validation.error.details);
|
|
}
|
|
|
|
const databaseResult = await client.query(`
|
|
WITH updated AS (
|
|
UPDATE trainers SET
|
|
center_id = $1,
|
|
hourly_price = $2
|
|
WHERE id = $3
|
|
RETURNING *
|
|
)
|
|
SELECT updated.id, user_id, first_name, last_name, center_id, centers.name as center_name from updated
|
|
JOIN users ON updated.user_id = users.id
|
|
JOIN centers on updated.center_id = centers.id;
|
|
`, [
|
|
validation.value.center_id,
|
|
validation.value.hourly_price,
|
|
req.params.id
|
|
]);
|
|
|
|
const trainer: Trainer = databaseResult.rows[0];
|
|
|
|
return res.status(200).send(trainer);
|
|
} catch (error: DatabaseError | Error | any) {
|
|
if (error.constraint == "trainers_center_id_fkey") {
|
|
return res.status(400).send([{
|
|
message: "\"center_id\" is not a valid center",
|
|
path: [
|
|
"center_id"
|
|
],
|
|
type: "center_id.not_found"
|
|
}]);
|
|
}
|
|
console.error(error);
|
|
return res.sendStatus(500);
|
|
}
|
|
})
|
|
|
|
export default router; |