diff --git a/client/src/Api.ts b/client/src/Api.ts index 317727d..a3d2c5b 100644 --- a/client/src/Api.ts +++ b/client/src/Api.ts @@ -60,17 +60,16 @@ export const finishDelivery = async (bankAccount?: string, bankAccountHolder?: s return await api.post('/api/finishDelivery', JSON.stringify({ bankAccount, bankAccountHolder })); } -// TODO smazat -// export const updateChoice = async (choice: number | null) => { -// return await api.post('/api/updateChoice', JSON.stringify({ choice })); -// } - -export const addChoice = async (locationIndex: number) => { - return await api.post('/api/addChoice', JSON.stringify({ locationIndex })); +export const addChoice = async (locationIndex: number, foodIndex?: number) => { + return await api.post('/api/addChoice', JSON.stringify({ locationIndex, foodIndex })); } -export const removeChoices = async (location: Location) => { - return await api.post('/api/removeChoices', JSON.stringify({ location })); +export const removeChoices = async (locationIndex: number) => { + return await api.post('/api/removeChoices', JSON.stringify({ locationIndex })); +} + +export const removeChoice = async (locationIndex: number, foodIndex: number) => { + return await api.post('/api/removeChoice', JSON.stringify({ locationIndex, foodIndex })); } export const addPizza = async (pizzaIndex: number, pizzaSizeIndex: number) => { diff --git a/client/src/App.tsx b/client/src/App.tsx index ccf622f..ac9a45a 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,7 +1,7 @@ import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'; import 'bootstrap/dist/css/bootstrap.min.css'; import { EVENT_DISCONNECT, EVENT_MESSAGE, SocketContext } from './context/socket'; -import { addChoice, addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, getQrUrl, lockPizzaDay, removeChoices, removePizza, unlockPizzaDay, updateNote } from './Api'; +import { addChoice, addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, getQrUrl, lockPizzaDay, removeChoice, removeChoices, removePizza, unlockPizzaDay, updateNote } from './Api'; import { useAuth } from './context/auth'; import Login from './Login'; import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap'; @@ -27,8 +27,10 @@ function App() { const [food, setFood] = useState<{ [key in Restaurants]: Food[] }>(); const [pizzy, setPizzy] = useState(); const [myOrder, setMyOrder] = useState(); + const [foodChoiceList, setFoodChoiceList] = useState(); const socket = useContext(SocketContext); const choiceRef = useRef(null); + const foodChoiceRef = useRef(null); const poznamkaRef = useRef(null); // Načtení dat po přihlášení @@ -93,24 +95,64 @@ function App() { } }, [auth?.login, data?.pizzaDay?.orders]) - // TODO přejmenovat na addChoice - const changeChoice = async (event: React.ChangeEvent) => { + useEffect(() => { + if (choiceRef?.current?.value && choiceRef.current.value !== "") { + // TODO: wtf, cos pil, když jsi tohle psal? + const locationIndex = Object.values(Locations).indexOf(choiceRef?.current?.value as unknown as Locations); + const locationsKey = Object.keys(Locations)[locationIndex]; + const restaurantKey = Object.keys(Restaurants).indexOf(locationsKey); + if (restaurantKey > -1 && food) { + const restaurant = Object.values(Restaurants)[restaurantKey]; + setFoodChoiceList(food[restaurant]); + } else { + setFoodChoiceList(undefined); + } + } else { + setFoodChoiceList(undefined); + } + }, [choiceRef.current?.value]) + + const doAddChoice = async (event: React.ChangeEvent) => { const index = Object.values(Locations).indexOf(event.target.value as unknown as Locations); - console.log("Target value", event.target.value) - console.log("Change choices called with index", index); - // TODO implementovat if (auth?.login) { await addChoice(index); + if (foodChoiceRef.current?.value) { + foodChoiceRef.current.value = ""; + } } } - const removeChoice = async (key: string) => { + const doAddFoodChoice = async (event: React.ChangeEvent) => { + if (event.target.value && foodChoiceList?.length && choiceRef.current?.value) { + if (auth?.login) { + const locationIndex = Object.values(Locations).indexOf(choiceRef.current.value as unknown as Locations); + await addChoice(locationIndex, Number(event.target.value)); + } + } + } + + const doRemoveChoices = async (locationKey: string) => { if (auth?.login) { - console.log("Remove choice called with key", key) - // await removeChoices(key); // TODO tohle je určitě blbě + await removeChoices(Number(locationKey)); + // Vyresetujeme výběr, aby bylo jasné pro který případně vybíráme jídlo if (choiceRef?.current?.value) { choiceRef.current.value = ""; } + if (foodChoiceRef?.current?.value) { + foodChoiceRef.current.value = ""; + } + } + } + + const doRemoveFoodChoice = async (locationKey: string, foodIndex: number) => { + if (auth?.login) { + await removeChoice(Number(locationKey), foodIndex); + if (choiceRef?.current?.value) { + choiceRef.current.value = ""; + } + if (foodChoiceRef?.current?.value) { + foodChoiceRef.current.value = ""; + } } } @@ -214,8 +256,9 @@ function App() { Poslední změny:
    -
  • Oprava parsování při neočekávané velikosti písmen v ceně
  • -
  • Přidání nedělitelných mezer k cenám
  • +
  • Bliká mi žárovka v lednici :(
  • +
  • Možnost výběru konkrétních jídel (u podporovaných podniků)
  • +
  • Velmi chatrná, experimentální podpora přihlašování přes Authelia

Dnes je {data.date}

@@ -227,7 +270,7 @@ function App() {

Jak to dnes vidíš s obědem?

- + @@ -237,24 +280,47 @@ function App() { -

- Aktuálně je možné vybrat pouze jednu variantu. -

+ {foodChoiceList && <> +

Na co dobrého? (nepovinné)

+ + + {foodChoiceList.map((food, index) => )} + + } {Object.keys(data.choices).length > 0 ? - {Object.keys(data.choices).map((key: string, index: number) => { - console.log("Rendering for key", key) + {Object.keys(data.choices).map((locationKey: string) => { + const locationName = Object.values(Locations)[Number(locationKey)]; + const locationLoginList = Object.entries(data.choices[Number(locationKey)]); return ( - - + + ) diff --git a/server/src/index.ts b/server/src/index.ts index f874a71..5374c6d 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -204,47 +204,52 @@ app.post("/api/finishDelivery", (req, res) => { io.emit("message", data); res.status(200).json({}); }); -[ + +app.post("/api/addChoice", (req, res) => { + const login = getLogin(parseToken(req)); + if (req.body.locationIndex > -1) { + const data = addChoice(login, req.body.locationIndex, req.body.foodIndex); + io.emit("message", data); + res.status(200).json(data); + } + res.status(400); // TODO přidat popis chyby +}); + +app.post("/api/removeChoices", (req, res) => { + const login = getLogin(parseToken(req)); + const data = removeChoices(login, req.body.locationIndex); + io.emit("message", data); res.status(200).json(data); }); - app.post("/api/removeChoices", (req, res) => { - const login = getLogin(parseToken(req)); - console.log("Remove choices", req.body.location); // TODO smazat - const data = removeChoices(login, req.body.location); - io.emit("message", data); - res.status(200).json(data); +app.post("/api/removeChoice", (req, res) => { + const login = getLogin(parseToken(req)); + const data = removeChoice(login, req.body.locationIndex, req.body.foodIndex); + io.emit("message", data); + res.status(200).json(data); +}); + +app.post("/api/updateNote", (req, res) => { + const login = getLogin(parseToken(req)); + if (req.body.note && req.body.note.length > 100) { + throw Error("Poznámka může mít maximálně 100 znaků"); + } + const data = updateNote(login, req.body.note); + io.emit("message", data); + res.status(200).json(data); +}); + +io.on("connection", (socket) => { + console.log(`New client connected: ${socket.id}`); + + socket.on("message", (message) => { + io.emit("message", message); }); - app.post("/api/removeChoice", (req, res) => { - const login = getLogin(parseToken(req)); - console.log("Remove choice", req.body.location, req.body.foodIndex); // TODO smazat - const data = removeChoice(login, req.body.location, req.body.foodIndex); - io.emit("message", data); - res.status(200).json(data); - }); - - app.post("/api/updateNote", (req, res) => { - const login = getLogin(parseToken(req)); - if (req.body.note && req.body.note.length > 100) { - throw Error("Poznámka může mít maximálně 100 znaků"); - } - const data = updateNote(login, req.body.note); - io.emit("message", data); - res.status(200).json(data); - }); - - io.on("connection", (socket) => { - console.log(`New client connected: ${socket.id}`); - - socket.on("message", (message) => { - io.emit("message", message); - }); - - socket.on("disconnect", () => { - console.log(`Client disconnected: ${socket.id}`); - }); + socket.on("disconnect", () => { + console.log(`Client disconnected: ${socket.id}`); }); +}); const PORT = process.env.PORT || 3001; const HOST = process.env.HOST || '0.0.0.0';
{Object.values(Locations)[Number(key)]}
{locationName}
    - {/* {data.choices[Number(key)].map((p: string, index: number) => -
  • {p} {p === auth.login && { - removeChoice(key); - }} title='Odstranit' className='trash-icon' icon={faTrashCan} />}
  • - )} */} + {locationLoginList.map((entry: [string, number[]], index) => { + const login = entry[0]; + const userChoices = entry[1]; + return
  • {login} {login === auth.login && { + doRemoveChoices(locationKey); + }} title='Odstranit, včetně případných podřízených jídel' className='trash-icon' icon={faTrashCan} />} + {userChoices?.length && food ?
      + {userChoices.map(foodIndex => { + const locationsKey = Object.keys(Locations)[Number(locationKey)] + const restaurantKey = Object.keys(Restaurants).indexOf(locationsKey); + const restaurant = Object.values(Restaurants)[restaurantKey]; + const foodName = food[restaurant][foodIndex].name; + return
    • + {foodName} + {login === auth.login && { + doRemoveFoodChoice(locationKey, foodIndex); + }} title={`Odstranit ${foodName}`} className='trash-icon' icon={faTrashCan} />} +
    • + })} +
    : null} +
  • + } + )}