NOMERGE: Přenos změn
This commit is contained in:
parent
bc6035862a
commit
b1138bc104
@ -60,8 +60,17 @@ export const finishDelivery = async (bankAccount?: string, bankAccountHolder?: s
|
|||||||
return await api.post<any, any>('/api/finishDelivery', JSON.stringify({ bankAccount, bankAccountHolder }));
|
return await api.post<any, any>('/api/finishDelivery', JSON.stringify({ bankAccount, bankAccountHolder }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateChoice = async (choice: number | null) => {
|
// TODO smazat
|
||||||
return await api.post<any, any>('/api/updateChoice', JSON.stringify({ choice }));
|
// export const updateChoice = async (choice: number | null) => {
|
||||||
|
// return await api.post<any, any>('/api/updateChoice', JSON.stringify({ choice }));
|
||||||
|
// }
|
||||||
|
|
||||||
|
export const addChoice = async (locationIndex: number) => {
|
||||||
|
return await api.post<any, any>('/api/addChoice', JSON.stringify({ locationIndex }));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const removeChoices = async (location: Location) => {
|
||||||
|
return await api.post<any, any>('/api/removeChoices', JSON.stringify({ location }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addPizza = async (pizzaIndex: number, pizzaSizeIndex: number) => {
|
export const addPizza = async (pizzaIndex: number, pizzaSizeIndex: number) => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import { EVENT_DISCONNECT, EVENT_MESSAGE, SocketContext } from './context/socket';
|
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 { addChoice, addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, getQrUrl, lockPizzaDay, removeChoices, removePizza, unlockPizzaDay, updateNote } from './Api';
|
||||||
import { useAuth } from './context/auth';
|
import { useAuth } from './context/auth';
|
||||||
import Login from './Login';
|
import Login from './Login';
|
||||||
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
||||||
@ -74,14 +74,15 @@ function App() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO tohle občas náhodně nezafunguje, nutno přepsat, viz https://medium.com/@teh_builder/ref-objects-inside-useeffect-hooks-eb7c15198780
|
// 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) {
|
// TODO nutno opravit
|
||||||
for (let entry of Object.entries(data.choices)) {
|
// if (data?.choices && choiceRef.current) {
|
||||||
if (entry[1].includes(auth.login)) {
|
// for (let entry of Object.entries(data.choices)) {
|
||||||
const value = entry[0] as any as number; // TODO tohle je absurdní
|
// if (entry[1].includes(auth.login)) {
|
||||||
choiceRef.current.value = Object.values(Locations)[value];
|
// const value = entry[0] as any as number; // TODO tohle je absurdní
|
||||||
}
|
// choiceRef.current.value = Object.values(Locations)[value];
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}, [auth, auth?.login, data?.choices])
|
}, [auth, auth?.login, data?.choices])
|
||||||
|
|
||||||
// Reference na mojí objednávku
|
// Reference na mojí objednávku
|
||||||
@ -92,16 +93,21 @@ function App() {
|
|||||||
}
|
}
|
||||||
}, [auth?.login, data?.pizzaDay?.orders])
|
}, [auth?.login, data?.pizzaDay?.orders])
|
||||||
|
|
||||||
|
// TODO přejmenovat na addChoice
|
||||||
const changeChoice = async (event: React.ChangeEvent<HTMLSelectElement>) => {
|
const changeChoice = async (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
const index = Object.values(Locations).indexOf(event.target.value as unknown as Locations);
|
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) {
|
if (auth?.login) {
|
||||||
await updateChoice(index > -1 ? index : null);
|
await addChoice(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeChoice = async (key: string) => {
|
const removeChoice = async (key: string) => {
|
||||||
if (auth?.login) {
|
if (auth?.login) {
|
||||||
await updateChoice(null);
|
console.log("Remove choice called with key", key)
|
||||||
|
// await removeChoices(key); // TODO tohle je určitě blbě
|
||||||
if (choiceRef?.current?.value) {
|
if (choiceRef?.current?.value) {
|
||||||
choiceRef.current.value = "";
|
choiceRef.current.value = "";
|
||||||
}
|
}
|
||||||
@ -237,19 +243,22 @@ function App() {
|
|||||||
{Object.keys(data.choices).length > 0 ?
|
{Object.keys(data.choices).length > 0 ?
|
||||||
<Table striped bordered hover className='results-table mt-5'>
|
<Table striped bordered hover className='results-table mt-5'>
|
||||||
<tbody>
|
<tbody>
|
||||||
{Object.keys(data.choices).map((key: string, index: number) =>
|
{Object.keys(data.choices).map((key: string, index: number) => {
|
||||||
<tr key={index}>
|
console.log("Rendering for key", key)
|
||||||
<td>{Object.values(Locations)[Number(key)]}</td>
|
return (
|
||||||
<td>
|
<tr key={index}>
|
||||||
<ul>
|
<td>{Object.values(Locations)[Number(key)]}</td>
|
||||||
{data.choices[Number(key)].map((p: string, index: number) =>
|
<td>
|
||||||
<li key={index}>{p} {p === auth.login && <FontAwesomeIcon onClick={() => {
|
<ul>
|
||||||
removeChoice(key);
|
{/* {data.choices[Number(key)].map((p: string, index: number) =>
|
||||||
}} title='Odstranit' className='trash-icon' icon={faTrashCan} />}</li>
|
<li key={index}>{p} {p === auth.login && <FontAwesomeIcon onClick={() => {
|
||||||
)}
|
removeChoice(key);
|
||||||
</ul>
|
}} title='Odstranit' className='trash-icon' icon={faTrashCan} />}</li>
|
||||||
</td>
|
)} */}
|
||||||
</tr>
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>)
|
||||||
|
}
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
@ -3,13 +3,13 @@ import { Server } from "socket.io";
|
|||||||
import bodyParser from "body-parser";
|
import bodyParser from "body-parser";
|
||||||
import { fetchPizzy } from "./chefie";
|
import { fetchPizzy } from "./chefie";
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, lockPizzaDay, removePizzaOrder, unlockPizzaDay, updateChoice, updateNote } from "./service";
|
import { addChoice, addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, lockPizzaDay, removeChoice, removeChoices, removePizzaOrder, unlockPizzaDay, updateNote } from "./service";
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
|
import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
|
||||||
import { getQr } from "./qr";
|
import { getQr } from "./qr";
|
||||||
import { generateToken, getLogin, verify } from "./auth";
|
import { generateToken, getLogin, verify } from "./auth";
|
||||||
import { Restaurants } from "../../types";
|
import { Locations, Restaurants } from "../../types";
|
||||||
|
|
||||||
const ENVIRONMENT = process.env.NODE_ENV || 'production';
|
const ENVIRONMENT = process.env.NODE_ENV || 'production';
|
||||||
dotenv.config({ path: path.resolve(__dirname, `./.env.${ENVIRONMENT}`) });
|
dotenv.config({ path: path.resolve(__dirname, `./.env.${ENVIRONMENT}`) });
|
||||||
@ -35,6 +35,15 @@ app.use(cors({
|
|||||||
origin: '*'
|
origin: '*'
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// app.use((req, res, next) => {
|
||||||
|
// console.log("--- Request ---")
|
||||||
|
// console.log(req.url);
|
||||||
|
// console.log(req.baseUrl);
|
||||||
|
// console.log(req.originalUrl);
|
||||||
|
// console.log(req.path);
|
||||||
|
// next();
|
||||||
|
// });
|
||||||
|
|
||||||
app.use(express.static('public'))
|
app.use(express.static('public'))
|
||||||
|
|
||||||
const parseToken = (req: any) => {
|
const parseToken = (req: any) => {
|
||||||
@ -195,35 +204,47 @@ app.post("/api/finishDelivery", (req, res) => {
|
|||||||
io.emit("message", data);
|
io.emit("message", data);
|
||||||
res.status(200).json({});
|
res.status(200).json({});
|
||||||
});
|
});
|
||||||
|
[
|
||||||
app.post("/api/updateChoice", (req, res) => {
|
|
||||||
const login = getLogin(parseToken(req));
|
|
||||||
const data = updateChoice(login, req.body.choice);
|
|
||||||
io.emit("message", data);
|
|
||||||
res.status(200).json(data);
|
res.status(200).json(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/api/updateNote", (req, res) => {
|
app.post("/api/removeChoices", (req, res) => {
|
||||||
const login = getLogin(parseToken(req));
|
const login = getLogin(parseToken(req));
|
||||||
if (req.body.note && req.body.note.length > 100) {
|
console.log("Remove choices", req.body.location); // TODO smazat
|
||||||
throw Error("Poznámka může mít maximálně 100 znaků");
|
const data = removeChoices(login, req.body.location);
|
||||||
}
|
io.emit("message", data);
|
||||||
const data = updateNote(login, req.body.note);
|
res.status(200).json(data);
|
||||||
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", () => {
|
app.post("/api/removeChoice", (req, res) => {
|
||||||
console.log(`Client disconnected: ${socket.id}`);
|
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}`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const PORT = process.env.PORT || 3001;
|
const PORT = process.env.PORT || 3001;
|
||||||
const HOST = process.env.HOST || '0.0.0.0';
|
const HOST = process.env.HOST || '0.0.0.0';
|
||||||
|
@ -239,34 +239,75 @@ export function initIfNeeded() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeChoice(login: string, data: ClientData) {
|
/**
|
||||||
for (let key of Object.keys(data.choices)) {
|
* Odstraní kompletně volbu uživatele (včetně případných podřízených jídel).
|
||||||
if (data.choices[key] && data.choices[key].includes(login)) {
|
*
|
||||||
const index = data.choices[key].indexOf(login);
|
* @param login login uživatele
|
||||||
data.choices[key].splice(index, 1);
|
* @param location vybrané "umístění"
|
||||||
if (data.choices[key].length == 0) {
|
* @returns
|
||||||
delete data.choices[key];
|
*/
|
||||||
|
export function removeChoices(login: string, location: Locations) {
|
||||||
|
const today = formatDate(getToday());
|
||||||
|
let data: ClientData = db.get(today);
|
||||||
|
if (location in data.choices) {
|
||||||
|
if (login in data.choices[location]) {
|
||||||
|
delete data.choices[location][login]
|
||||||
|
if (Object.keys(data.choices[location]).length === 0) {
|
||||||
|
delete data.choices[location]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateChoice(login: string, choice: Locations | null) {
|
/**
|
||||||
|
* Odstraní konkrétní volbu jídla uživatele.
|
||||||
|
* Neodstraňuje volbu samotnou, k tomu slouží {@link removeChoices}.
|
||||||
|
*
|
||||||
|
* @param login login uživatele
|
||||||
|
* @param location vybrané "umístění"
|
||||||
|
* @param foodIndex index jídla v jídelním lístku daného umístění, pokud existuje
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function removeChoice(login: string, location: Locations, foodIndex: number) {
|
||||||
|
const today = formatDate(getToday());
|
||||||
|
let data: ClientData = db.get(today);
|
||||||
|
if (location in data.choices) {
|
||||||
|
if (login in data.choices[location]) {
|
||||||
|
if (data.choices[location][login].includes(foodIndex)) {
|
||||||
|
data.choices[location][login].splice(foodIndex, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Přidá volbu uživatele.
|
||||||
|
*
|
||||||
|
* @param login login uživatele
|
||||||
|
* @param location vybrané "umístění"
|
||||||
|
* @param foodIndex volitelný index jídla v daném umístění
|
||||||
|
* @returns aktuální data
|
||||||
|
*/
|
||||||
|
export function addChoice(login: string, location: Locations, foodIndex?: number) {
|
||||||
initIfNeeded();
|
initIfNeeded();
|
||||||
const today = formatDate(getToday());
|
const today = formatDate(getToday());
|
||||||
let data: ClientData = db.get(today);
|
let data: ClientData = db.get(today);
|
||||||
data = removeChoice(login, data);
|
if (!(location in data.choices)) {
|
||||||
if (choice !== null) {
|
data.choices[location] = {};
|
||||||
if (!data.choices?.[choice]) {
|
}
|
||||||
data.choices[choice] = [];
|
if (!(login in data.choices[location])) {
|
||||||
}
|
data.choices[location][login] = [];
|
||||||
data.choices[choice].push(login);
|
}
|
||||||
|
if (foodIndex != null && !data.choices[location][login].includes(foodIndex)) {
|
||||||
|
data.choices[location][login].push(foodIndex);
|
||||||
}
|
}
|
||||||
db.set(today, data);
|
db.set(today, data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO přejmenovat, ať je jasné že to patří k pizza day
|
||||||
export function updateNote(login: string, note?: string) {
|
export function updateNote(login: string, note?: string) {
|
||||||
const today = formatDate(getToday());
|
const today = formatDate(getToday());
|
||||||
let clientData: ClientData = db.get(today);
|
let clientData: ClientData = db.get(today);
|
||||||
|
@ -6,7 +6,9 @@ export enum Restaurants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Choices {
|
export interface Choices {
|
||||||
[location: string]: string[],
|
[location: string]: {
|
||||||
|
[login: string]: number[]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Velikost konkrétní pizzy */
|
/** Velikost konkrétní pizzy */
|
||||||
@ -74,6 +76,7 @@ export interface Food {
|
|||||||
isSoup: boolean, // příznak, zda se jedná o polévku
|
isSoup: boolean, // příznak, zda se jedná o polévku
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO tohle je dost špatné pojmenování, vzhledem k tomu co to obsahuje
|
||||||
export enum Locations {
|
export enum Locations {
|
||||||
SLADOVNICKA = 'Sladovnická',
|
SLADOVNICKA = 'Sladovnická',
|
||||||
UMOTLIKU = 'U Motlíků',
|
UMOTLIKU = 'U Motlíků',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user