Možnost přidat k objednávce poznámku
This commit is contained in:
parent
26337121de
commit
67242c48df
@ -48,7 +48,7 @@ Aplikace sestává ze tří (čtyř) modulů.
|
||||
- [x] https://qr-platba.cz/pro-vyvojare/restful-api/
|
||||
- [ ] Zobrazovat celkovou cenu objednávky pod tabulkou objednávek
|
||||
- [ ] Zobrazit upozornění před smazáním/zamknutím/odemknutím pizza day
|
||||
- [ ] Umožnit přidat k objednávce poznámku (např. "bez oliv")
|
||||
- [x] Umožnit přidat k objednávce poznámku (např. "bez oliv")
|
||||
- [ ] Negenerovat QR kód pro objednávajícího
|
||||
- [ ] Pizzy se samy budou při naklikání přidávat do košíku
|
||||
- [ ] Nutno nejprve vyřešit předávání PHPSESSIONID cookie na pizzachefie.cz pomocí fetch()
|
||||
|
@ -68,4 +68,8 @@ export const addPizza = async (login: string, pizzaIndex: number, pizzaSizeIndex
|
||||
|
||||
export const removePizza = async (login: string, pizzaOrder: PizzaOrder) => {
|
||||
return await api.post<any, any>('/api/removePizza', JSON.stringify({ login, pizzaOrder }));
|
||||
}
|
||||
|
||||
export const updateNote = async (login: string, note?: string) => {
|
||||
return await api.post<any, any>('/api/updateNote', JSON.stringify({ login, note }));
|
||||
}
|
@ -75,4 +75,8 @@
|
||||
|
||||
.qr-code {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.select-search-container {
|
||||
margin: auto;
|
||||
}
|
@ -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 { addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, getQrUrl, lockPizzaDay, removePizza, unlockPizzaDay, updateChoice } from './Api';
|
||||
import { addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, getQrUrl, lockPizzaDay, removePizza, unlockPizzaDay, updateChoice, updateNote } from './Api';
|
||||
import { useAuth } from './context/auth';
|
||||
import Login from './Login';
|
||||
import { Locations, ClientData, Pizza, PizzaOrder, State, Order } from './Types';
|
||||
@ -29,6 +29,7 @@ function App() {
|
||||
const [myOrder, setMyOrder] = useState<Order>();
|
||||
const socket = useContext(SocketContext);
|
||||
const choiceRef = useRef<HTMLSelectElement>(null);
|
||||
const poznamkaRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
// Prvotní načtení aktuálního stavu
|
||||
useEffect(() => {
|
||||
@ -83,9 +84,7 @@ function App() {
|
||||
useEffect(() => {
|
||||
if (data?.pizzaDay?.orders) {
|
||||
const myOrder = data.pizzaDay.orders.find(o => o.customer === auth?.login);
|
||||
if (myOrder) {
|
||||
setMyOrder(myOrder);
|
||||
}
|
||||
setMyOrder(myOrder);
|
||||
}
|
||||
}, [data?.pizzaDay?.orders])
|
||||
|
||||
@ -131,9 +130,19 @@ function App() {
|
||||
}
|
||||
}
|
||||
|
||||
const handlePizzaDelete = (pizzaOrder: PizzaOrder) => {
|
||||
const handlePizzaDelete = async (pizzaOrder: PizzaOrder) => {
|
||||
if (auth?.login) {
|
||||
removePizza(auth?.login, pizzaOrder);
|
||||
await removePizza(auth?.login, pizzaOrder);
|
||||
}
|
||||
}
|
||||
|
||||
const handlePoznamkaChange = async () => {
|
||||
if (auth?.login) {
|
||||
if (poznamkaRef.current?.value && poznamkaRef.current.value.length > 100) {
|
||||
alert("Poznámka může mít maximálně 100 znaků");
|
||||
return;
|
||||
}
|
||||
updateNote(auth.login, poznamkaRef.current?.value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,6 +207,7 @@ function App() {
|
||||
<ul>
|
||||
<li>Nová žárovka zatím funguje</li>
|
||||
<li>Funkční generování a zobrazení QR kódů pro Pizza day</li>
|
||||
<li>Možnost zadat k Pizza day objednávce poznámku</li>
|
||||
</ul>
|
||||
</Alert>
|
||||
<h1 className='title'>Dnes je {data.date}</h1>
|
||||
@ -260,7 +270,10 @@ function App() {
|
||||
{
|
||||
data.pizzaDay.state === State.CREATED &&
|
||||
<div>
|
||||
<p>Pizza Day je založen a spravován uživatelem {data.pizzaDay.creator}.<br />Můžete upravovat své objednávky.</p>
|
||||
<p>
|
||||
Pizza Day je založen a spravován uživatelem {data.pizzaDay.creator}.<br />
|
||||
Můžete upravovat své objednávky.
|
||||
</p>
|
||||
{
|
||||
data.pizzaDay.creator === auth.login &&
|
||||
<>
|
||||
@ -275,18 +288,22 @@ function App() {
|
||||
</div>
|
||||
}
|
||||
{
|
||||
data.pizzaDay.state === State.LOCKED && data.pizzaDay.creator === auth.login &&
|
||||
data.pizzaDay.state === State.LOCKED &&
|
||||
<div>
|
||||
<p>Objednávky jsou uzamčeny uživatelem {data.pizzaDay.creator}</p>
|
||||
<Button className='danger mb-3' title="Umožní znovu editovat objednávky." onClick={async () => {
|
||||
await unlockPizzaDay(auth.login);
|
||||
}}>Odemknout</Button>
|
||||
{/* <Button className='danger mb-3' style={{ marginLeft: '20px' }} onClick={async () => {
|
||||
{data.pizzaDay.creator === auth.login &&
|
||||
<>
|
||||
<Button className='danger mb-3' title="Umožní znovu editovat objednávky." onClick={async () => {
|
||||
await unlockPizzaDay(auth.login);
|
||||
}}>Odemknout</Button>
|
||||
{/* <Button className='danger mb-3' style={{ marginLeft: '20px' }} onClick={async () => {
|
||||
await addToCart();
|
||||
}}>Přidat vše do košíku</Button> */}
|
||||
<Button className='danger mb-3' style={{ marginLeft: '20px' }} title={noOrders ? "Nelze objednat - neexistuje žádná objednávka" : "Použij po objednání. Objednávky zůstanou zamčeny."} disabled={noOrders} onClick={async () => {
|
||||
await finishOrder(auth.login);
|
||||
}}>Objednáno</Button>
|
||||
<Button className='danger mb-3' style={{ marginLeft: '20px' }} title={noOrders ? "Nelze objednat - neexistuje žádná objednávka" : "Použij po objednání. Objednávky zůstanou zamčeny."} disabled={noOrders} onClick={async () => {
|
||||
await finishOrder(auth.login);
|
||||
}}>Objednáno</Button>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
@ -312,13 +329,27 @@ function App() {
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<SelectSearch
|
||||
search={true}
|
||||
options={pizzaSuggestions}
|
||||
placeholder='Vyhledat pizzu...'
|
||||
onChange={handlePizzaChange}
|
||||
disabled={data.pizzaDay.state !== State.CREATED}
|
||||
/>
|
||||
{data.pizzaDay.state === State.CREATED &&
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<SelectSearch
|
||||
search={true}
|
||||
options={pizzaSuggestions}
|
||||
placeholder='Vyhledat pizzu...'
|
||||
onChange={handlePizzaChange}
|
||||
/>
|
||||
Poznámka: <input ref={poznamkaRef} className='mt-3' type="text" onKeyDown={event => {
|
||||
if (event.key === 'Enter') {
|
||||
handlePoznamkaChange();
|
||||
}
|
||||
}} />
|
||||
<Button
|
||||
style={{ marginLeft: '20px' }}
|
||||
disabled={!myOrder?.pizzaList?.length}
|
||||
onClick={handlePoznamkaChange}>
|
||||
Uložit
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
<PizzaOrderList state={data.pizzaDay.state} orders={data.pizzaDay.orders} onDelete={handlePizzaDelete} />
|
||||
{
|
||||
data.pizzaDay.state === State.DELIVERED && myOrder?.hasQr &&
|
||||
|
@ -29,6 +29,7 @@ export interface Order {
|
||||
pizzaList: PizzaOrder[], // seznam objednaných pizz
|
||||
totalPrice: number, // celková cena všech objednaných pizz a krabic
|
||||
hasQr?: boolean, // zda je pro objednávku vygenerován QR kód pro platbu
|
||||
note?: string, // volitelná poznámka uživatele k objednávce
|
||||
}
|
||||
|
||||
export interface Choices {
|
||||
|
@ -17,6 +17,7 @@ export default function PizzaOrderList({ state, orders, onDelete }: { state: Sta
|
||||
<tr>
|
||||
<th>Jméno</th>
|
||||
<th>Objednávka</th>
|
||||
<th>Poznámka</th>
|
||||
<th>Cena</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -34,6 +35,7 @@ export default function PizzaOrderList({ state, orders, onDelete }: { state: Sta
|
||||
</span>)
|
||||
.reduce((prev, curr, index) => [prev, <br key={`br-${index}`} />, curr])}
|
||||
</td>
|
||||
<td>{order.note || '-'}</td>
|
||||
<td>{order.totalPrice} Kč</td>
|
||||
</tr>)}
|
||||
</tbody>
|
||||
|
@ -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 } from "./service";
|
||||
import { addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, lockPizzaDay, removePizzaOrder, unlockPizzaDay, updateChoice, updateNote } from "./service";
|
||||
import dotenv from 'dotenv';
|
||||
import path from 'path';
|
||||
import { fetchMenus } from "./restaurants";
|
||||
@ -161,6 +161,18 @@ app.get("/api/qr", (req, res) => {
|
||||
res.end(img);
|
||||
});
|
||||
|
||||
app.post("/api/updateNote", (req, res) => {
|
||||
if (!req.body.login) {
|
||||
throw Error("Nebyl předán login");
|
||||
}
|
||||
if (req.body.note && req.body.note.length > 100) {
|
||||
throw Error("Poznámka může mít maximálně 100 znaků");
|
||||
}
|
||||
const data = updateNote(req.body.login, req.body.note);
|
||||
io.emit("message", data);
|
||||
res.status(200).json(data);
|
||||
});
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log(`New client connected: ${socket.id}`);
|
||||
|
||||
|
@ -262,4 +262,22 @@ export function updateChoice(login: string, choice: Locations | null) {
|
||||
}
|
||||
db.set(today, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
export function updateNote(login: string, note?: string) {
|
||||
const today = formatDate(getToday());
|
||||
let clientData: ClientData = db.get(today);
|
||||
if (!clientData.pizzaDay) {
|
||||
throw Error("Pizza day pro dnešní den neexistuje");
|
||||
}
|
||||
if (clientData.pizzaDay.state !== PizzaDayState.CREATED) {
|
||||
throw Error("Pizza day není ve stavu " + PizzaDayState.CREATED);
|
||||
}
|
||||
const myOrder = clientData.pizzaDay.orders.find(o => o.customer === login);
|
||||
if (!myOrder || !myOrder.pizzaList.length) {
|
||||
throw Error("Pizza day neobsahuje žádné objednávky uživatele " + login);
|
||||
}
|
||||
myOrder.note = note;
|
||||
db.set(today, clientData);
|
||||
return clientData;
|
||||
}
|
@ -34,6 +34,7 @@ export interface Order {
|
||||
pizzaList: PizzaOrder[], // seznam objednaných pizz
|
||||
totalPrice: number, // celková cena všech objednaných pizz a krabic
|
||||
hasQr?: boolean, // true, pokud je k objednávce vygenerován QR kód pro platbu
|
||||
note?: string, // volitelná uživatelská poznámka k objednávce
|
||||
}
|
||||
|
||||
/** Stav pizza dne */
|
||||
|
Loading…
x
Reference in New Issue
Block a user