Přenos změn
This commit is contained in:
parent
47fbe4173d
commit
e8d7e3fd9e
@ -1,4 +1,4 @@
|
||||
import { PizzaOrder } from "./Types";
|
||||
import { Locations, PizzaOrder } from "./Types";
|
||||
import { getBaseUrl } from "./Utils";
|
||||
|
||||
async function request<TResponse>(
|
||||
@ -58,7 +58,7 @@ export const finishDelivery = async (login, bankAccount, bankAccountHolder) => {
|
||||
return await api.post<any, any>('/api/finishDelivery', JSON.stringify({ login, bankAccount, bankAccountHolder }));
|
||||
}
|
||||
|
||||
export const updateChoice = async (name: string, choice: number | null) => {
|
||||
export const updateChoice = async (name: string, choice?: Locations | null) => {
|
||||
return await api.post<any, any>('/api/updateChoice', JSON.stringify({ name, choice }));
|
||||
}
|
||||
|
||||
@ -72,4 +72,8 @@ export const removePizza = async (login: string, pizzaOrder: PizzaOrder) => {
|
||||
|
||||
export const updateNote = async (login: string, note?: string) => {
|
||||
return await api.post<any, any>('/api/updateNote', JSON.stringify({ login, note }));
|
||||
}
|
||||
|
||||
export const updateFoodChoice = async (login: string, choice: Locations, foodName?: string) => {
|
||||
return await api.post<any, any>('/api/updateFoodChoice', JSON.stringify({ login, choice, foodName }));
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
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 { addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, getQrUrl, lockPizzaDay, removePizza, unlockPizzaDay, updateChoice, updateNote } from './Api';
|
||||
import { addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, getQrUrl, lockPizzaDay, removePizza, unlockPizzaDay, updateChoice, updateFoodChoice, updateNote } from './Api';
|
||||
import { useAuth } from './context/auth';
|
||||
import Login from './Login';
|
||||
import { Locations, ClientData, Pizza, PizzaOrder, State, Order, Food, Restaurants } from './Types';
|
||||
import { Locations, ClientData, Pizza, PizzaOrder, State, Order, Food, Restaurants, FoodChoice } from './Types';
|
||||
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
||||
import Header from './components/Header';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
@ -30,6 +30,8 @@ function App() {
|
||||
const socket = useContext(SocketContext);
|
||||
const choiceRef = useRef<HTMLSelectElement>(null);
|
||||
const poznamkaRef = useRef<HTMLInputElement>(null);
|
||||
const [foodSelection, setFoodSelection] = useState<Food[]>();
|
||||
const foodChoiceRef = useRef<HTMLSelectElement>(null);
|
||||
|
||||
// Prvotní načtení aktuálního stavu
|
||||
useEffect(() => {
|
||||
@ -73,8 +75,8 @@ function App() {
|
||||
// TODO tohle občas náhodně nezafunguje, nutno přepsat, viz https://medium.com/@teh_builder/ref-objects-inside-useeffect-hooks-eb7c15198780
|
||||
if (data?.choices && choiceRef.current) {
|
||||
for (let entry of Object.entries(data.choices)) {
|
||||
if (entry[1].includes(auth.login)) {
|
||||
choiceRef.current.value = Object.values(Locations)[entry[0]]
|
||||
if (entry[1].find(ch => ch.login === auth.login)) {
|
||||
choiceRef.current.value = entry[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,10 +90,64 @@ function App() {
|
||||
}
|
||||
}, [auth?.login, data?.pizzaDay?.orders])
|
||||
|
||||
const locationToRestaurant = (location: Locations): Restaurants | undefined => {
|
||||
switch (location) {
|
||||
case Locations.SLADOVNICKA:
|
||||
return Restaurants.SLADOVNICKA;
|
||||
case Locations.UMOTLIKU:
|
||||
return Restaurants.UMOTLIKU;
|
||||
case Locations.TECHTOWER:
|
||||
return Restaurants.TECHTOWER;
|
||||
}
|
||||
}
|
||||
|
||||
const renderLocation = (location: Locations) => {
|
||||
switch (location) {
|
||||
case Locations.SLADOVNICKA:
|
||||
return 'Sladovnická';
|
||||
case Locations.UMOTLIKU:
|
||||
return 'U Motlíků';
|
||||
case Locations.TECHTOWER:
|
||||
return 'TechTower';
|
||||
case Locations.SPSE:
|
||||
return 'SPŠE';
|
||||
case Locations.PIZZA:
|
||||
return 'Pizza day';
|
||||
case Locations.OBJEDNAVAM:
|
||||
return 'Objednávám (mimo pizza day)';
|
||||
case Locations.NEOBEDVAM:
|
||||
return 'Vlastní/Home office/Neobědvám';
|
||||
}
|
||||
}
|
||||
|
||||
const restaurantToLocation = (restaurant: Restaurants): Locations | undefined => {
|
||||
switch (restaurant) {
|
||||
case Restaurants.SLADOVNICKA:
|
||||
return Locations.SLADOVNICKA;
|
||||
case Restaurants.UMOTLIKU:
|
||||
return Locations.UMOTLIKU;
|
||||
case Restaurants.TECHTOWER:
|
||||
return Locations.TECHTOWER;
|
||||
}
|
||||
}
|
||||
|
||||
const changeChoice = async (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const index = Object.values(Locations).indexOf(event.target.value as unknown as Locations);
|
||||
const choice: Locations | undefined = Locations[event.target.value];
|
||||
console.log("Vybráno", choice); // TODO smazat
|
||||
if (auth?.login) {
|
||||
await updateChoice(auth.login, index > -1 ? index : null);
|
||||
await updateChoice(auth.login, choice);
|
||||
// if (index >= 0) {
|
||||
// const choice = Object.values(Locations)[index];
|
||||
// if ([Locations.SLADOVNICKA, Locations.UMOTLIKU, Locations.TECHTOWER].includes(choice)) {
|
||||
// const restaurant = locationToRestaurant(choice);
|
||||
// if (restaurant) {
|
||||
// const selection = food?.[restaurant];
|
||||
// console.log("Choice and restaurant", choice, restaurant);
|
||||
// setFoodSelection(selection);
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
setFoodSelection(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +160,19 @@ function App() {
|
||||
}
|
||||
}
|
||||
|
||||
const changeFoodChoice = async (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
console.log("Přidání jídla", choiceRef.current?.value, event.target.value);
|
||||
let key: string | undefined = undefined;
|
||||
// TODO pokračovat
|
||||
// if (choiceRef.current?.value) {
|
||||
// const location = choiceRef.current.value as Locations;
|
||||
// key = Object.keys(Locations)[Object.values(Locations).indexOf(location)];
|
||||
// }
|
||||
// if (auth?.login) {
|
||||
// await updateFoodChoice(auth.login, key, event.target.value);
|
||||
// }
|
||||
}
|
||||
|
||||
const pizzaSuggestions = useMemo(() => {
|
||||
if (!pizzy) {
|
||||
return [];
|
||||
@ -222,27 +291,32 @@ function App() {
|
||||
<p>Jak to dnes vidíš s obědem?</p>
|
||||
<Form.Select ref={choiceRef} onChange={changeChoice}>
|
||||
<option></option>
|
||||
<option value={Locations.SLADOVNICKA}>Sladovnická</option>
|
||||
<option value={Locations.UMOTLIKU}>U Motlíků</option>
|
||||
<option value={Locations.TECHTOWER}>TechTower</option>
|
||||
<option value={Locations.SPSE}>SPŠE</option>
|
||||
<option value={Locations.PIZZA}>Pizza day</option>
|
||||
<option value={Locations.OBJEDNAVAM}>Budu objednávat (mimo pizzu)</option>
|
||||
<option value={Locations.NEOBEDVAM}>Mám vlastní/neobědvám</option>
|
||||
{Object.values(Locations).map(key => <option key={key} value={key}>{renderLocation(key)}</option>)}
|
||||
</Form.Select>
|
||||
<p style={{ fontSize: "12px", marginTop: "5px" }}>
|
||||
Aktuálně je možné vybrat pouze jednu variantu.
|
||||
</p>
|
||||
{foodSelection &&
|
||||
<>
|
||||
<p>Na jaké hlavní jídlo?</p>
|
||||
<Form.Select ref={foodChoiceRef} onChange={changeFoodChoice}>
|
||||
<option></option>
|
||||
{foodSelection?.filter(food => !food.isSoup).map(food =>
|
||||
<option key={food.name} value={food.name}>{food.name}</option>
|
||||
)}
|
||||
</Form.Select>
|
||||
</>
|
||||
}
|
||||
{Object.keys(data.choices).length > 0 ?
|
||||
<Table striped bordered hover className='results-table mt-5'>
|
||||
<tbody>
|
||||
{Object.keys(data.choices).map((key: string, index: number) =>
|
||||
<tr key={index}>
|
||||
<td>{Object.values(Locations)[Number(key)]}</td>
|
||||
<td>{renderLocation(Locations[key])}</td>
|
||||
<td>
|
||||
<ul>
|
||||
{data.choices[Number(key)].map((p: string, index: number) =>
|
||||
<li key={index}>{p} {p === auth.login && <FontAwesomeIcon onClick={() => {
|
||||
{data.choices[key].map((p: FoodChoice, index: number) =>
|
||||
<li key={index}>{p.login} {p.login === auth.login && <FontAwesomeIcon onClick={() => {
|
||||
removeChoice(key);
|
||||
}} title='Odstranit' className='trash-icon' icon={faTrashCan} />}</li>
|
||||
)}
|
||||
|
@ -32,8 +32,13 @@ export interface Order {
|
||||
note?: string, // volitelná poznámka uživatele k objednávce
|
||||
}
|
||||
|
||||
export interface FoodChoice {
|
||||
login: string, // jméno uživatele
|
||||
foodName?: string, // název vybraného jídla
|
||||
}
|
||||
|
||||
export interface Choices {
|
||||
[location: string]: string[],
|
||||
[location: string]: FoodChoice[],
|
||||
}
|
||||
|
||||
/** Údaje o Pizza day. */
|
||||
@ -51,13 +56,13 @@ export interface ClientData {
|
||||
}
|
||||
|
||||
export enum Locations {
|
||||
SLADOVNICKA = 'Sladovnická',
|
||||
UMOTLIKU = 'U Motlíků',
|
||||
TECHTOWER = 'TechTower',
|
||||
SPSE = 'SPŠE',
|
||||
PIZZA = 'Pizza day',
|
||||
OBJEDNAVAM = 'Budu objednávat',
|
||||
NEOBEDVAM = 'Mám vlastní/neobědvám',
|
||||
SLADOVNICKA = 'SLADOVNICKA',
|
||||
UMOTLIKU = 'UMOTLIKU',
|
||||
TECHTOWER = 'TECHTOWER',
|
||||
SPSE = 'SPSE',
|
||||
PIZZA = 'PIZZA',
|
||||
OBJEDNAVAM = 'OBJEDNAVAM',
|
||||
NEOBEDVAM = 'NEOBEDVAM',
|
||||
}
|
||||
|
||||
/** Jídlo z obědového menu restaurace. */
|
||||
|
@ -3,7 +3,7 @@ import { Server } from "socket.io";
|
||||
import bodyParser from "body-parser";
|
||||
import { fetchPizzy } from "./chefie";
|
||||
import cors from 'cors';
|
||||
import { addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, lockPizzaDay, removePizzaOrder, unlockPizzaDay, updateChoice, updateNote } from "./service";
|
||||
import { addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, lockPizzaDay, removePizzaOrder, unlockPizzaDay, updateChoice, updateFoodChoice, updateNote } from "./service";
|
||||
import dotenv from 'dotenv';
|
||||
import path from 'path';
|
||||
import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
|
||||
@ -179,6 +179,18 @@ app.post("/api/updateNote", (req, res) => {
|
||||
res.status(200).json(data);
|
||||
});
|
||||
|
||||
app.post("/api/updateFoodChoice", (req, res) => {
|
||||
if (!req.body.login) {
|
||||
throw Error("Nebyl předán login");
|
||||
}
|
||||
if (!req.body.choice) {
|
||||
throw Error("Nebyla předána vybraná restaurace");
|
||||
}
|
||||
const data = updateFoodChoice(req.body.login, req.body.choice, req.body.food);
|
||||
io.emit("message", data);
|
||||
res.status(200).json(data);
|
||||
});
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log(`New client connected: ${socket.id}`);
|
||||
|
||||
|
@ -240,11 +240,13 @@ export function initIfNeeded() {
|
||||
|
||||
export function removeChoice(login: string, data: ClientData) {
|
||||
for (let key of Object.keys(data.choices)) {
|
||||
if (data.choices[key] && data.choices[key].includes(login)) {
|
||||
const index = data.choices[key].indexOf(login);
|
||||
data.choices[key].splice(index, 1);
|
||||
if (data.choices[key].length == 0) {
|
||||
delete data.choices[key];
|
||||
if (data.choices[key]) {
|
||||
const index = data.choices[key].findIndex(choice => choice.login === login);
|
||||
if (index >= 0) {
|
||||
data.choices[key].splice(index, 1);
|
||||
if (data.choices[key].length == 0) {
|
||||
delete data.choices[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,11 +258,11 @@ export function updateChoice(login: string, choice: Locations | null) {
|
||||
const today = formatDate(getToday());
|
||||
let data: ClientData = db.get(today);
|
||||
data = removeChoice(login, data);
|
||||
if (choice !== null) {
|
||||
if (choice) {
|
||||
if (!data.choices?.[choice]) {
|
||||
data.choices[choice] = [];
|
||||
}
|
||||
data.choices[choice].push(login);
|
||||
data.choices[choice].push({ login });
|
||||
}
|
||||
db.set(today, data);
|
||||
return data;
|
||||
@ -282,4 +284,24 @@ export function updateNote(login: string, note?: string) {
|
||||
myOrder.note = note;
|
||||
db.set(today, clientData);
|
||||
return clientData;
|
||||
}
|
||||
|
||||
export function updateFoodChoice(login: string, location: Locations, foodName?: string) {
|
||||
const today = formatDate(getToday());
|
||||
let clientData: ClientData = db.get(today);
|
||||
|
||||
// TODO smazat
|
||||
console.log("Location", location);
|
||||
console.log("Choices", clientData.choices);
|
||||
const myChoice = clientData.choices[location].find(o => o.login === login);
|
||||
if (!myChoice) {
|
||||
throw Error("V datech nebyla nalezena volba pro uživatele " + login);
|
||||
}
|
||||
if (foodName) {
|
||||
myChoice.foodName = foodName;
|
||||
} else {
|
||||
delete myChoice.foodName;
|
||||
}
|
||||
db.set(today, clientData);
|
||||
return clientData;
|
||||
}
|
@ -1,7 +1,13 @@
|
||||
import exp from "constants";
|
||||
|
||||
/** Výběr jídla z restaurace jednoho uživatele. */
|
||||
export interface FoodChoice {
|
||||
login: string, // jméno uživatele
|
||||
foodName?: string, // název vybraného jídla
|
||||
}
|
||||
|
||||
export interface Choices {
|
||||
[location: string]: string[],
|
||||
[location: string]: FoodChoice[],
|
||||
}
|
||||
|
||||
/** Velikost konkrétní pizzy */
|
||||
@ -77,13 +83,13 @@ export enum Restaurants {
|
||||
}
|
||||
|
||||
export enum Locations {
|
||||
SLADOVNICKA = 'Sladovnická',
|
||||
UMOTLIKU = 'U Motlíků',
|
||||
TECHTOWER = 'TechTower',
|
||||
SPSE = 'SPŠE',
|
||||
PIZZA = 'Pizza day',
|
||||
OBJEDNAVAM = 'Budu objednávat',
|
||||
NEOBEDVAM = 'Mám vlastní/neobědvám',
|
||||
SLADOVNICKA = 'SLADOVNICKA',
|
||||
UMOTLIKU = 'UMOTLIKU',
|
||||
TECHTOWER = 'TECHTOWER',
|
||||
SPSE = 'SPSE',
|
||||
PIZZA = 'PIZZA',
|
||||
OBJEDNAVAM = 'OBJEDNAVAM',
|
||||
NEOBEDVAM = 'NEOBEDVAM',
|
||||
}
|
||||
|
||||
export enum UdalostEnum {
|
||||
|
Loading…
x
Reference in New Issue
Block a user