Možnost zadání preferovaného času odchodu

This commit is contained in:
Martin Berka 2023-08-06 18:13:54 +02:00
parent 37542499a9
commit 3f303ea5ea
5 changed files with 72 additions and 11 deletions

View File

@ -87,3 +87,7 @@ export const updateNote = async (note?: string) => {
export const login = async (login: string) => {
return await api.post<any, any>('/api/login', JSON.stringify({ login }));
}
export const changeDepartureTime = async (login: string, time: string) => {
return await api.post<any, any>('/api/changeDepartureTime', JSON.stringify({ login, time }));
}

View File

@ -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, removeChoice, removeChoices, removePizza, unlockPizzaDay, updateNote } from './Api';
import { addChoice, addPizza, changeDepartureTime, 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';
@ -17,9 +17,25 @@ import { useBank } from './context/bank';
import { ClientData, Restaurants, Food, Pizza, Order, Locations, PizzaOrder, PizzaDayState, FoodChoices } from './types';
import Footer from './components/Footer';
const EVENT_CONNECT = "connect"
// TODO tohle má být kvůli bezpečnosti na serveru
const DEPARTURE_TIMES = [
"10:00",
"10:15",
"10:30",
"10:45",
"11:00",
"11:15",
"11:30",
"11:45",
"12:00",
"12:15",
"12:30",
"12:45",
"13:00",
]
function App() {
const auth = useAuth();
const bank = useBank();
@ -222,6 +238,14 @@ function App() {
// }
// }
const handleChangeDepartureTime = async (event: React.ChangeEvent<HTMLSelectElement>) => {
if (foodChoiceList?.length && choiceRef.current?.value) {
if (auth?.login) {
await changeDepartureTime(auth.login, event.target.value);
}
}
}
const renderFoodTable = (name: string, food: Food[]) => {
return <Col md={12} lg={4}>
<h3>{name}</h3>
@ -257,13 +281,8 @@ function App() {
<Alert variant={'primary'}>
Poslední změny:
<ul>
<li>(Trochu) přehlednější zobrazení tabulky
<ul>
<li>Je to pořád ošklivý :(</li>
</ul>
</li>
<li>(Opět) možnost vybrat jen jednu variantu</li>
<li>"Blue checkmark" pro uživatele přihlášené přes AD</li>
<li>Podpora <a href="https://redis.io">Redis</a></li>
<li>Možnost výběru preferovaného času odchodu</li>
</ul>
</Alert>
<h1 className='title'>Dnes je {data.date}</h1>
@ -293,6 +312,13 @@ function App() {
{foodChoiceList.map((food, index) => <option key={index} value={index}>{food.name}</option>)}
</Form.Select>
</>}
{foodChoiceList && <>
<p style={{ marginTop: "10px" }}>V kolik hodin preferuješ odchod?</p>
<Form.Select ref={foodChoiceRef} onChange={handleChangeDepartureTime}>
<option></option>
{DEPARTURE_TIMES.map(time => <option key={time} value={time}>{time}</option>)}
</Form.Select>
</>}
{Object.keys(data.choices).length > 0 ?
<Table bordered className='mt-5'>
<tbody>
@ -316,6 +342,7 @@ function App() {
<FontAwesomeIcon title='Uživatel ověřený doménovým přihlášením' icon={faCircleCheck} style={{ cursor: "help" }} />
</span>}
{login}
{userPayload.departureTime && <small> ({userPayload.departureTime})</small>}
{login === auth.login && <FontAwesomeIcon onClick={() => {
doRemoveChoices(locationKey);
}} title={`Odstranit volbu ${locationName}, včetně případných zvolených jídel`} className='trash-icon' icon={faTrashCan} />}

View File

@ -3,7 +3,7 @@ import { Server } from "socket.io";
import bodyParser from "body-parser";
import { fetchPizzy } from "./chefie";
import cors from 'cors';
import { addChoice, addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, lockPizzaDay, removeChoice, removeChoices, removePizzaOrder, unlockPizzaDay, updateNote } from "./service";
import { addChoice, addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, lockPizzaDay, removeChoice, removeChoices, removePizzaOrder, unlockPizzaDay, updateDepartureTime, updateNote } from "./service";
import dotenv from 'dotenv';
import path from 'path';
import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
@ -238,6 +238,13 @@ app.post("/api/updateNote", async (req, res) => {
res.status(200).json(data);
});
app.post("/api/changeDepartureTime", async (req, res) => {
const login = getLogin(parseToken(req));
const data = await updateDepartureTime(login, req.body?.time);
io.emit("message", data);
res.status(200).json(data);
});
io.on("connection", (socket) => {
console.log(`New client connected: ${socket.id}`);

View File

@ -372,4 +372,26 @@ export async function updateNote(login: string, note?: string) {
myOrder.note = note;
await storage.setData(today, clientData);
return clientData;
}
/**
* Aktualizuje preferovaný čas odchodu strávníka.
*
* @param login login uživatele
* @param time preferovaný čas odchodu
*/
export async function updateDepartureTime(login: string, time?: string) {
const today = formatDate(getToday());
let clientData: ClientData = await storage.getData(today);
const found = Object.values(clientData.choices).find(location => login in location);
// TODO validace, že se jedná o restauraci
if (found) {
if (!time?.length) {
delete found[login].departureTime;
} else {
found[login].departureTime = time;
}
await storage.setData(today, clientData);
}
return clientData;
}

View File

@ -7,7 +7,8 @@ export enum Restaurants {
export interface FoodChoices {
trusted: boolean,
options: number[]
options: number[],
departureTime?: string,
}
export interface Choices {