Přechody mezi stavy Pizza Day
This commit is contained in:
@@ -38,6 +38,22 @@ export const deletePizzaDay = async (login) => {
|
||||
return await api.post<any, any>('/api/deletePizzaDay', JSON.stringify({ login }));
|
||||
}
|
||||
|
||||
export const lockPizzaDay = async (login) => {
|
||||
return await api.post<any, any>('/api/lockPizzaDay', JSON.stringify({ login }));
|
||||
}
|
||||
|
||||
export const unlockPizzaDay = async (login) => {
|
||||
return await api.post<any, any>('/api/unlockPizzaDay', JSON.stringify({ login }));
|
||||
}
|
||||
|
||||
export const finishOrder = async (login) => {
|
||||
return await api.post<any, any>('/api/finishOrder', JSON.stringify({ login }));
|
||||
}
|
||||
|
||||
export const finishDelivery = async (login) => {
|
||||
return await api.post<any, any>('/api/finishDelivery', JSON.stringify({ login }));
|
||||
}
|
||||
|
||||
export const updateChoice = async (name: string, choice: number | null) => {
|
||||
return await api.post<any, any>('/api/updateChoice', JSON.stringify({ name, choice }));
|
||||
}
|
||||
|
||||
@@ -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, getData, getFood, getPizzy, removePizza, updateChoice } from './Api';
|
||||
import { addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, lockPizzaDay, removePizza, unlockPizzaDay, updateChoice } from './Api';
|
||||
import { useAuth } from './context/auth';
|
||||
import Login from './Login';
|
||||
import { Locations, ClientData, Pizza, PizzaOrder } from './Types';
|
||||
import { Locations, ClientData, Pizza, PizzaOrder, State } from './Types';
|
||||
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
||||
import Header from './components/Header';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
@@ -125,6 +125,30 @@ function App() {
|
||||
}
|
||||
}
|
||||
|
||||
const addToCart = async () => {
|
||||
// TODO aktuálně nefunkční - nedokážeme poslat PHPSESSIONID cookie
|
||||
// if (data?.pizzaDay?.orders) {
|
||||
// for (const order of data?.pizzaDay?.orders) {
|
||||
// for (const pizzaOrder of order.pizzaList) {
|
||||
// const url = 'https://www.pizzachefie.cz/pridat.html';
|
||||
// const payload = new URLSearchParams();
|
||||
// payload.append('varId', pizzaOrder.varId.toString());
|
||||
// await fetch(url, {
|
||||
// method: "POST",
|
||||
// mode: "no-cors",
|
||||
// cache: "no-cache",
|
||||
// credentials: "same-origin",
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded',
|
||||
// },
|
||||
// body: payload,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// // TODO otevřít košík v nové záložce
|
||||
// }
|
||||
}
|
||||
|
||||
const renderFoodTable = (name, food) => {
|
||||
return <Col md={12} lg={4}>
|
||||
<h3>{name}</h3>
|
||||
@@ -150,6 +174,8 @@ function App() {
|
||||
return <div>Načítám data...</div>
|
||||
}
|
||||
|
||||
const noOrders = data?.pizzaDay?.orders?.length == 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
@@ -158,10 +184,7 @@ function App() {
|
||||
<Alert variant={'primary'}>
|
||||
Poslední změny:
|
||||
<ul>
|
||||
<li>Možnost odhlášení pomocí menu</li>
|
||||
<li>Přihlásit se lze i stiskem Enter</li>
|
||||
<li>Základ pro pizza day - našeptávač pizz z Pizza Chefie, možnost naklikat si objednávku</li>
|
||||
<li>Možnost uložit si číslo účtu pro budoucí generování QR kódů</li>
|
||||
<li>Přechody mezi stavy Pizza Day: Vytvořeno -> Uzamčeno -> Objednáno -> Doručeno</li>
|
||||
</ul>
|
||||
</Alert>
|
||||
<h1 className='title'>Dnes je {data.date}</h1>
|
||||
@@ -220,11 +243,54 @@ function App() {
|
||||
{data.pizzaDay &&
|
||||
<div>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<p>Pizza Day je založen uživatelem {data.pizzaDay.creator}</p>
|
||||
{
|
||||
data.pizzaDay.creator === auth.login && <Button className='danger mb-3' onClick={async () => {
|
||||
await deletePizzaDay(auth.login);
|
||||
}}>Smazat Pizza day</Button>
|
||||
data.pizzaDay.state === State.CREATED && data.pizzaDay.creator === auth.login &&
|
||||
<div>
|
||||
<p>Pizza Day je založen a spravován uživatelem {data.pizzaDay.creator}.<br />Můžete upravovat své objednávky.</p>
|
||||
<Button className='danger mb-3' title="Smaže kompletně pizza day, včetně dosud zadaných objednávek." onClick={async () => {
|
||||
await deletePizzaDay(auth.login);
|
||||
}}>Smazat Pizza day</Button>
|
||||
<Button className='mb-3' style={{ marginLeft: '20px' }} title={noOrders ? "Nelze uzamknout - neexistuje žádná objednávka" : "Zamezí přidávat/odebírat objednávky. Použij před samotným objednáním, aby již nemohlo docházet ke změnám."} disabled={noOrders} onClick={async () => {
|
||||
await lockPizzaDay(auth.login);
|
||||
}}>Uzamknout</Button>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
data.pizzaDay.state === State.LOCKED && data.pizzaDay.creator === auth.login &&
|
||||
<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 () => {
|
||||
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>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
data.pizzaDay.state === State.ORDERED &&
|
||||
<div>
|
||||
<p>Pizzy byly objednány uživatelem {data.pizzaDay.creator}</p>
|
||||
{data.pizzaDay.creator === auth.login &&
|
||||
<div>
|
||||
<Button className='danger mb-3' title="Vrátí stav do předchozího kroku (před objednáním)." onClick={async () => {
|
||||
await lockPizzaDay(auth.login);
|
||||
}}>Vrátit do "uzamčeno"</Button>
|
||||
<Button className='danger mb-3' style={{ marginLeft: '20px' }} title="Nastaví stav na 'Doručeno' - koncový stav." onClick={async () => {
|
||||
await finishDelivery(auth.login);
|
||||
}}>Doručeno</Button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
data.pizzaDay.state === State.DELIVERED &&
|
||||
<div>
|
||||
<p>Pizzy byly doručeny.</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<SelectSearch
|
||||
@@ -232,8 +298,9 @@ function App() {
|
||||
options={pizzaSuggestions}
|
||||
placeholder='Vyhledat pizzu...'
|
||||
onChange={handlePizzaChange}
|
||||
disabled={data.pizzaDay.state !== State.CREATED}
|
||||
/>
|
||||
<PizzaOrderList orders={data.pizzaDay.orders} onDelete={handlePizzaDelete} />
|
||||
<PizzaOrderList state={data.pizzaDay.state} orders={data.pizzaDay.orders} onDelete={handlePizzaDelete} />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// TODO všechno v tomto souboru jsou duplicity se serverem, ale aktuálně nevím jaký je nejlepší způsob jejich sdílení
|
||||
|
||||
export interface PizzaSize {
|
||||
varId: number, // unikátní ID varianty pizzy
|
||||
size: string, // velikost pizzy, např. "30cm"
|
||||
pizzaPrice: number, // cena samotné pizzy
|
||||
boxPrice: number, // cena krabice
|
||||
@@ -16,6 +17,7 @@ export interface Pizza {
|
||||
|
||||
/** Objednávka jedné konkrétní pizzy */
|
||||
export interface PizzaOrder {
|
||||
varId: number, // unikátní ID varianty pizzy
|
||||
name: string, // název pizzy
|
||||
size: string, // velikost pizzy jako string (30cm)
|
||||
price: number, // cena pizzy v Kč, včetně krabice
|
||||
@@ -59,5 +61,7 @@ export enum Locations {
|
||||
export enum State {
|
||||
NOT_CREATED, // Pizza day nebyl založen
|
||||
CREATED, // Pizza day je založen
|
||||
LOCKED // Objednávky uzamčeny
|
||||
LOCKED, // Objednávky uzamčeny
|
||||
ORDERED, // Objednáno
|
||||
DELIVERED, // Doručeno
|
||||
}
|
||||
@@ -1,19 +1,23 @@
|
||||
import React from "react";
|
||||
import { Table } from "react-bootstrap";
|
||||
import { Order, PizzaOrder } from "../Types";
|
||||
import { Order, PizzaOrder, State } from "../Types";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faTrashCan } from "@fortawesome/free-regular-svg-icons";
|
||||
import { useAuth } from "../context/auth";
|
||||
|
||||
export default function PizzaOrderList({ orders, onDelete }: { orders: Order[], onDelete: (pizzaOrder: PizzaOrder) => void }) {
|
||||
export default function PizzaOrderList({ state, orders, onDelete }: { state: State, orders: Order[], onDelete: (pizzaOrder: PizzaOrder) => void }) {
|
||||
const auth = useAuth();
|
||||
|
||||
if (!orders?.length) {
|
||||
return <p><i>Zatím žádné objednávky...</i></p>
|
||||
}
|
||||
|
||||
return <Table className="mt-3" striped bordered hover>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Jméno</th>
|
||||
<th>Objednávka</th>
|
||||
<th>Celkem</th>
|
||||
<th>Cena</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -22,13 +26,13 @@ export default function PizzaOrderList({ orders, onDelete }: { orders: Order[],
|
||||
<td>{order.pizzaList.map<React.ReactNode>((pizzaOrder, index) =>
|
||||
<span key={index}>
|
||||
{`${pizzaOrder.name}, ${pizzaOrder.size} (${pizzaOrder.price} Kč)`}
|
||||
{auth?.login === order.customer &&
|
||||
{auth?.login === order.customer && state === State.CREATED &&
|
||||
<FontAwesomeIcon onClick={() => {
|
||||
onDelete(pizzaOrder);
|
||||
}} title='Odstranit' className='trash-icon' icon={faTrashCan} />
|
||||
}
|
||||
</span>)
|
||||
.reduce((prev, curr) => [prev, <br />, curr])}
|
||||
.reduce((prev, curr, index) => [prev, <br key={`br-${index}`} />, curr])}
|
||||
</td>
|
||||
<td>{order.totalPrice} Kč</td>
|
||||
</tr>)}
|
||||
|
||||
Reference in New Issue
Block a user