import express, { Request } from "express"; import { getLogin } from "../auth"; import { parseToken } from "../utils"; import { getWebsocket } from "../websocket"; import { createGroup, deleteGroup, addGroupMember, removeGroupMember, updateGroupMember, setGroupState, updateGroupTimes, updateGroupFees } from "../groups"; import { GroupState } from "../../../types/gen/types.gen"; const router = express.Router(); function broadcastExtra(data: any) { getWebsocket().emit("message", data); } router.post("/create", async (req: Request, res, next) => { const login = getLogin(parseToken(req)); const { name } = req.body ?? {}; if (!name || typeof name !== 'string') { return res.status(400).json({ error: 'Nebyl předán název skupiny' }); } try { const data = await createGroup(login, name); broadcastExtra(data); res.status(200).json(data); } catch (e: any) { next(e); } }); router.post("/delete", async (req: Request, res, next) => { const login = getLogin(parseToken(req)); const { id } = req.body ?? {}; if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' }); try { const data = await deleteGroup(login, id); broadcastExtra(data); res.status(200).json(data); } catch (e: any) { next(e); } }); router.post("/addMember", async (req: Request, res, next) => { const login = getLogin(parseToken(req)); const { id, login: targetLogin } = req.body ?? {}; if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' }); if (targetLogin !== undefined && (typeof targetLogin !== 'string' || targetLogin.trim() === '')) { return res.status(400).json({ error: 'Neplatný login uživatele' }); } const target = targetLogin ?? login; try { const data = await addGroupMember(login, id, target); broadcastExtra(data); res.status(200).json(data); } catch (e: any) { next(e); } }); router.post("/removeMember", async (req: Request, res, next) => { const login = getLogin(parseToken(req)); const { id, login: targetLogin } = req.body ?? {}; if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' }); if (!targetLogin) return res.status(400).json({ error: 'Nebyl předán login uživatele' }); try { const data = await removeGroupMember(login, id, targetLogin); broadcastExtra(data); res.status(200).json(data); } catch (e: any) { next(e); } }); router.post("/updateMember", async (req: Request, res, next) => { const login = getLogin(parseToken(req)); const { id, login: targetLogin, amount, note, surchargeText, surchargeAmount } = req.body ?? {}; if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' }); if (!targetLogin) return res.status(400).json({ error: 'Nebyl předán login uživatele' }); const patch: Record = {}; if (amount !== undefined) { if (!Number.isInteger(amount) || amount < 0) { return res.status(400).json({ error: 'Neplatná částka' }); } patch.amount = amount; } if (note !== undefined) { if (typeof note !== 'string') return res.status(400).json({ error: 'Neplatná poznámka' }); patch.note = note; } if (surchargeText !== undefined) { if (typeof surchargeText !== 'string') return res.status(400).json({ error: 'Neplatný text příplatku' }); patch.surchargeText = surchargeText; } if (surchargeAmount !== undefined) { if (!Number.isInteger(surchargeAmount) || surchargeAmount < 0) { return res.status(400).json({ error: 'Neplatná výše příplatku' }); } patch.surchargeAmount = surchargeAmount; } try { const data = await updateGroupMember(login, id, targetLogin, patch); broadcastExtra(data); res.status(200).json(data); } catch (e: any) { next(e); } }); router.post("/setState", async (req: Request, res, next) => { const login = getLogin(parseToken(req)); const { id, state } = req.body ?? {}; if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' }); if (!state || !Object.values(GroupState).includes(state)) { return res.status(400).json({ error: 'Neplatný stav skupiny' }); } try { const data = await setGroupState(login, id, state as GroupState); broadcastExtra(data); res.status(200).json(data); } catch (e: any) { next(e); } }); router.post("/updateFees", async (req: Request, res, next) => { const login = getLogin(parseToken(req)); const { id, fees, shipping, tip, discountType, discountValue } = req.body ?? {}; if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' }); if (fees !== undefined && (!Number.isInteger(fees) || fees < 0)) { return res.status(400).json({ error: 'Neplatná výše poplatků' }); } if (shipping !== undefined && (!Number.isInteger(shipping) || shipping < 0)) { return res.status(400).json({ error: 'Neplatná výše dopravy' }); } if (tip !== undefined && (!Number.isInteger(tip) || tip < 0)) { return res.status(400).json({ error: 'Neplatná výše spropitného' }); } if (discountType !== undefined && discountType !== '' && !['percent', 'fixed'].includes(discountType)) { return res.status(400).json({ error: 'Neplatný typ slevy' }); } if (discountValue !== undefined && (!Number.isInteger(discountValue) || discountValue < 0)) { return res.status(400).json({ error: 'Neplatná výše slevy' }); } try { const data = await updateGroupFees(login, id, fees, shipping, tip, discountType, discountValue); broadcastExtra(data); res.status(200).json(data); } catch (e: any) { next(e); } }); router.post("/updateTimes", async (req: Request, res, next) => { const login = getLogin(parseToken(req)); const { id, orderedAt, deliveryAt } = req.body ?? {}; if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' }); const timeRegex = /^([01]\d|2[0-3]):[0-5]\d$/; if (orderedAt !== undefined && orderedAt !== '' && !timeRegex.test(orderedAt)) { return res.status(400).json({ error: 'Neplatný formát času objednání (očekáváno HH:MM)' }); } if (deliveryAt !== undefined && deliveryAt !== '' && !timeRegex.test(deliveryAt)) { return res.status(400).json({ error: 'Neplatný formát času doručení (očekáváno HH:MM)' }); } try { const data = await updateGroupTimes(login, id, orderedAt, deliveryAt); broadcastExtra(data); res.status(200).json(data); } catch (e: any) { next(e); } }); export default router;