diff --git a/client/src/App.tsx b/client/src/App.tsx index ca27ea4..80aa80d 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -13,12 +13,12 @@ import './App.scss'; import { faCircleCheck, faNoteSticky, faTrashCan, faComment } from '@fortawesome/free-regular-svg-icons'; import { useSettings } from './context/settings'; import Footer from './components/Footer'; -import { faChainBroken, faChevronLeft, faChevronRight, faGear, faSatelliteDish, faSearch } from '@fortawesome/free-solid-svg-icons'; +import { faBasketShopping, faChainBroken, faChevronLeft, faChevronRight, faGear, faSatelliteDish, faSearch } from '@fortawesome/free-solid-svg-icons'; import Loader from './components/Loader'; import { getHumanDateTime, isInTheFuture } from './Utils'; import NoteModal from './components/modals/NoteModal'; import { useEasterEgg } from './context/eggs'; -import { ClientData, Food, PizzaOrder, DepartureTime, PizzaDayState, Restaurant, RestaurantDayMenu, RestaurantDayMenuMap, LunchChoice, UserLunchChoice, PizzaVariant, getData, getEasterEggImage, addPizza, removePizza, updatePizzaDayNote, createPizzaDay, deletePizzaDay, lockPizzaDay, unlockPizzaDay, finishOrder, finishDelivery, addChoice, jdemeObed, removeChoices, removeChoice, updateNote, changeDepartureTime } from '../../types'; +import { ClientData, Food, PizzaOrder, DepartureTime, PizzaDayState, Restaurant, RestaurantDayMenu, RestaurantDayMenuMap, LunchChoice, UserLunchChoice, PizzaVariant, getData, getEasterEggImage, addPizza, removePizza, updatePizzaDayNote, createPizzaDay, deletePizzaDay, lockPizzaDay, unlockPizzaDay, finishOrder, finishDelivery, addChoice, jdemeObed, removeChoices, removeChoice, updateNote, changeDepartureTime, setBuyer } from '../../types'; import { getLunchChoiceName } from './enums'; // import FallingLeaves, { LEAF_PRESETS, LEAF_COLOR_THEMES } from './FallingLeaves'; // import './FallingLeaves.scss'; @@ -284,6 +284,12 @@ function App() { } } + const markAsBuyer = async () => { + if (auth?.login) { + await setBuyer(); + } + } + const pizzaSuggestions = useMemo(() => { if (!data?.pizzaList) { return []; @@ -454,9 +460,9 @@ function App() { Poslední změny: {dayIndex != null && @@ -534,6 +540,7 @@ function App() { const userPayload = entry[1]; const userChoices = userPayload?.selectedFoods; const trusted = userPayload?.trusted || false; + const isBuyer = userPayload?.isBuyer || false; return {trusted && @@ -542,6 +549,17 @@ function App() { {login} {userPayload.departureTime && ({userPayload.departureTime})} {userPayload.note && ({userPayload.note})} + {/* TODO narovnat styly pomocí class */} + {login === auth.login && canChangeChoice && locationKey === LunchChoice.OBJEDNAVAM && + { + markAsBuyer(); + }} icon={faBasketShopping} color={isBuyer ? '#dbba00' : 'rgb(0, 89, 255)'} style={{marginLeft: '10px', padding: 0, cursor: 'pointer'}} /> + } + {login !== auth.login && locationKey === LunchChoice.OBJEDNAVAM && isBuyer && + { + copyNote(userPayload.note!); + }} icon={faBasketShopping} color='#dbba00' style={{marginLeft: '10px', padding: 0}} /> + } {login !== auth.login && canChangeChoice && userPayload?.note?.length && { copyNote(userPayload.note!); diff --git a/server/src/routes/foodRoutes.ts b/server/src/routes/foodRoutes.ts index 8817ded..ba4bdd4 100644 --- a/server/src/routes/foodRoutes.ts +++ b/server/src/routes/foodRoutes.ts @@ -1,6 +1,6 @@ import express, { Request, Response } from "express"; import { getLogin, getTrusted } from "../auth"; -import { addChoice, getDateForWeekIndex, getToday, removeChoice, removeChoices, updateDepartureTime, updateNote, fetchRestaurantWeekMenuData, saveRestaurantWeekMenu } from "../service"; +import { addChoice, getDateForWeekIndex, getToday, removeChoice, removeChoices, updateDepartureTime, updateNote, fetchRestaurantWeekMenuData, saveRestaurantWeekMenu, updateBuyer } from "../service"; import { getDayOfWeekIndex, parseToken, getFirstWorkDayOfWeek } from "../utils"; import { getWebsocket } from "../websocket"; import { callNotifikace } from "../notifikace"; @@ -182,6 +182,15 @@ router.post("/jdemeObed", async (req, res, next) => { } catch (e: any) { next(e) } }); +router.post("/updateBuyer", async (req, res, next) => { + const login = getLogin(parseToken(req)); + try { + const data = await updateBuyer(login); + getWebsocket().emit("message", data); + res.status(200).json({}); + } catch (e: any) { next(e) } +}); + // /api/food/refresh?type=week&heslo=docasnyheslo export const refreshMetoda = async (req: Request, res: Response) => { const { type, heslo } = req.query as { type?: string; heslo?: string }; diff --git a/server/src/service.ts b/server/src/service.ts index f084932..00d24d9 100644 --- a/server/src/service.ts +++ b/server/src/service.ts @@ -477,6 +477,24 @@ export async function updateDepartureTime(login: string, time?: string, date?: D return clientData; } +/** + * Nastaví/odnastaví uživatele jako objednatele pro dnešní den. + * Objednatelů může být více. + * + * @param login přihlašovací jméno uživatele + */ +export async function updateBuyer(login: string) { + const usedDate = getToday(); + let clientData = await getClientData(usedDate); + const userEntry = clientData.choices?.['OBJEDNAVAM']?.[login]; + if (!userEntry) { + throw new Error("Nelze nastavit objednatele pro uživatele s jinou volbou než \"Budu objednávat\""); + } + userEntry.isBuyer = !(userEntry.isBuyer || false); + await storage.setData(formatDate(usedDate), clientData); + return clientData; +} + /** * Vrátí data pro klienta pro předaný nebo aktuální den. * diff --git a/types/api.yml b/types/api.yml index 8311627..114d26e 100644 --- a/types/api.yml +++ b/types/api.yml @@ -26,6 +26,8 @@ paths: $ref: "./paths/food/changeDepartureTime.yml" /food/jdemeObed: $ref: "./paths/food/jdemeObed.yml" + /food/updateBuyer: + $ref: "./paths/food/updateBuyer.yml" # Pizza day (/api/pizzaDay) /pizzaDay/create: diff --git a/types/paths/food/updateBuyer.yml b/types/paths/food/updateBuyer.yml new file mode 100644 index 0000000..f03e3df --- /dev/null +++ b/types/paths/food/updateBuyer.yml @@ -0,0 +1,6 @@ +post: + operationId: setBuyer + summary: Nastavení/odnastavení aktuálně přihlášeného uživatele jako objednatele pro stav "Budu objednávat" pro aktuální den. + responses: + "200": + description: Stav byl úspěšně změněn. diff --git a/types/schemas/_index.yml b/types/schemas/_index.yml index b4be218..8bef9d5 100644 --- a/types/schemas/_index.yml +++ b/types/schemas/_index.yml @@ -74,6 +74,9 @@ UserLunchChoice: note: description: Volitelná, veřejně viditelná uživatelská poznámka k vybrané volbě type: string + isBuyer: + description: Příznak, zda je tento uživatel objednatelem pro stav "Budu objednávat" + type: boolean LocationLunchChoicesMap: description: Objekt, kde klíčem je možnost stravování ((#LunchChoice)) a hodnotou množina uživatelů s touto volbou ((#LunchChoices)). type: object