Možnost skrytí polévek
This commit is contained in:
parent
2633d445cc
commit
72c7bfe80c
@ -13,7 +13,7 @@ import 'react-select-search/style.css';
|
|||||||
import './App.css';
|
import './App.css';
|
||||||
import { SelectSearchOption } from 'react-select-search';
|
import { SelectSearchOption } from 'react-select-search';
|
||||||
import { faCircleCheck, faTrashCan } from '@fortawesome/free-regular-svg-icons';
|
import { faCircleCheck, faTrashCan } from '@fortawesome/free-regular-svg-icons';
|
||||||
import { useBank } from './context/bank';
|
import { useSettings } from './context/settings';
|
||||||
import { ClientData, Restaurants, Food, Order, Locations, PizzaOrder, PizzaDayState, FoodChoices, DayMenu, DepartureTime } from './types';
|
import { ClientData, Restaurants, Food, Order, Locations, PizzaOrder, PizzaDayState, FoodChoices, DayMenu, DepartureTime } from './types';
|
||||||
import Footer from './components/Footer';
|
import Footer from './components/Footer';
|
||||||
import { faChainBroken, faChevronLeft, faChevronRight, faGear, faSatelliteDish, faSearch } from '@fortawesome/free-solid-svg-icons';
|
import { faChainBroken, faChevronLeft, faChevronRight, faGear, faSatelliteDish, faSearch } from '@fortawesome/free-solid-svg-icons';
|
||||||
@ -26,7 +26,7 @@ const EVENT_CONNECT = "connect"
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const auth = useAuth();
|
const auth = useAuth();
|
||||||
const bank = useBank();
|
const settings = useSettings();
|
||||||
const [isConnected, setIsConnected] = useState<boolean>(false);
|
const [isConnected, setIsConnected] = useState<boolean>(false);
|
||||||
const [data, setData] = useState<ClientData>();
|
const [data, setData] = useState<ClientData>();
|
||||||
const [food, setFood] = useState<{ [key in Restaurants]?: DayMenu }>();
|
const [food, setFood] = useState<{ [key in Restaurants]?: DayMenu }>();
|
||||||
@ -302,7 +302,7 @@ function App() {
|
|||||||
} else if (menu?.food?.length > 0) {
|
} else if (menu?.food?.length > 0) {
|
||||||
content = <Table striped bordered hover>
|
content = <Table striped bordered hover>
|
||||||
<tbody>
|
<tbody>
|
||||||
{menu.food.map((f: any, index: number) =>
|
{menu.food.filter(f => (settings?.hideSoups ? !f.isSoup : true)).map((f: any, index: number) =>
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{f.amount}</td>
|
<td>{f.amount}</td>
|
||||||
<td>{f.name}</td>
|
<td>{f.name}</td>
|
||||||
@ -360,7 +360,7 @@ function App() {
|
|||||||
<Alert variant={'primary'}>
|
<Alert variant={'primary'}>
|
||||||
Poslední změny:
|
Poslední změny:
|
||||||
<ul>
|
<ul>
|
||||||
<li>Základní pizza kalkulačka (v menu)</li>
|
<li>Možnost skrytí polévek</li>
|
||||||
</ul>
|
</ul>
|
||||||
</Alert>
|
</Alert>
|
||||||
{dayIndex != null &&
|
{dayIndex != null &&
|
||||||
@ -540,7 +540,7 @@ function App() {
|
|||||||
await lockPizzaDay();
|
await lockPizzaDay();
|
||||||
}}>Vrátit do "uzamčeno"</Button>
|
}}>Vrátit do "uzamčeno"</Button>
|
||||||
<Button className='danger mb-3' style={{ marginLeft: '20px' }} title="Nastaví stav na 'Doručeno' - koncový stav." onClick={async () => {
|
<Button className='danger mb-3' style={{ marginLeft: '20px' }} title="Nastaví stav na 'Doručeno' - koncový stav." onClick={async () => {
|
||||||
await finishDelivery(bank?.bankAccount, bank?.holderName);
|
await finishDelivery(settings?.bankAccount, settings?.holderName);
|
||||||
}}>Doručeno</Button>
|
}}>Doručeno</Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Navbar, Nav, NavDropdown } from "react-bootstrap";
|
import { Navbar, Nav, NavDropdown } from "react-bootstrap";
|
||||||
import { useAuth } from "../context/auth";
|
import { useAuth } from "../context/auth";
|
||||||
import BankAccountModal from "./modals/BankAccountModal";
|
import SettingsModal from "./modals/SettingsModal";
|
||||||
import { useBank } from "../context/bank";
|
import { useSettings } from "../context/settings";
|
||||||
import FeaturesVotingModal from "./modals/FeaturesVotingModal";
|
import FeaturesVotingModal from "./modals/FeaturesVotingModal";
|
||||||
import { FeatureRequest } from "../types";
|
import { FeatureRequest } from "../types";
|
||||||
import { errorHandler } from "../api/Api";
|
import { errorHandler } from "../api/Api";
|
||||||
@ -12,8 +12,8 @@ import PizzaCalculatorModal from "./modals/PizzaCalculatorModal";
|
|||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const auth = useAuth();
|
const auth = useAuth();
|
||||||
const bank = useBank();
|
const settings = useSettings();
|
||||||
const [bankModalOpen, setBankModalOpen] = useState<boolean>(false);
|
const [settingsModalOpen, setSettingsModalOpen] = useState<boolean>(false);
|
||||||
const [votingModalOpen, setVotingModalOpen] = useState<boolean>(false);
|
const [votingModalOpen, setVotingModalOpen] = useState<boolean>(false);
|
||||||
const [pizzaModalOpen, setPizzaModalOpen] = useState<boolean>(false);
|
const [pizzaModalOpen, setPizzaModalOpen] = useState<boolean>(false);
|
||||||
const [featureVotes, setFeatureVotes] = useState<FeatureRequest[]>([]);
|
const [featureVotes, setFeatureVotes] = useState<FeatureRequest[]>([]);
|
||||||
@ -26,8 +26,8 @@ export default function Header() {
|
|||||||
}
|
}
|
||||||
}, [auth?.login]);
|
}, [auth?.login]);
|
||||||
|
|
||||||
const closeBankModal = () => {
|
const closeSettingsModal = () => {
|
||||||
setBankModalOpen(false);
|
setSettingsModalOpen(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeVotingModal = () => {
|
const closeVotingModal = () => {
|
||||||
@ -48,7 +48,7 @@ export default function Header() {
|
|||||||
return n !== Infinity && String(n) === str && n >= 0;
|
return n !== Infinity && String(n) === str && n >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveBankAccount = (bankAccountNumber?: string, bankAccountHolderName?: string) => {
|
const saveSettings = (bankAccountNumber?: string, bankAccountHolderName?: string, hideSoupsOption?: boolean) => {
|
||||||
if (bankAccountNumber) {
|
if (bankAccountNumber) {
|
||||||
try {
|
try {
|
||||||
// Validace kódu banky
|
// Validace kódu banky
|
||||||
@ -90,9 +90,10 @@ export default function Header() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bank?.setBankAccountNumber(bankAccountNumber);
|
settings?.setBankAccountNumber(bankAccountNumber);
|
||||||
bank?.setBankAccountHolderName(bankAccountHolderName);
|
settings?.setBankAccountHolderName(bankAccountHolderName);
|
||||||
closeBankModal();
|
settings?.setHideSoupsOption(hideSoupsOption);
|
||||||
|
closeSettingsModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveFeatureVote = async (option: FeatureRequest, active: boolean) => {
|
const saveFeatureVote = async (option: FeatureRequest, active: boolean) => {
|
||||||
@ -112,7 +113,7 @@ export default function Header() {
|
|||||||
<Navbar.Collapse id="basic-navbar-nav">
|
<Navbar.Collapse id="basic-navbar-nav">
|
||||||
<Nav className="nav">
|
<Nav className="nav">
|
||||||
<NavDropdown align="end" title={auth?.login} id="basic-nav-dropdown">
|
<NavDropdown align="end" title={auth?.login} id="basic-nav-dropdown">
|
||||||
<NavDropdown.Item onClick={() => setBankModalOpen(true)}>Nastavit číslo účtu</NavDropdown.Item>
|
<NavDropdown.Item onClick={() => setSettingsModalOpen(true)}>Nastavení</NavDropdown.Item>
|
||||||
<NavDropdown.Item onClick={() => setVotingModalOpen(true)}>Hlasovat o nových funkcích</NavDropdown.Item>
|
<NavDropdown.Item onClick={() => setVotingModalOpen(true)}>Hlasovat o nových funkcích</NavDropdown.Item>
|
||||||
<NavDropdown.Item onClick={() => setPizzaModalOpen(true)}>Pizza kalkulačka</NavDropdown.Item>
|
<NavDropdown.Item onClick={() => setPizzaModalOpen(true)}>Pizza kalkulačka</NavDropdown.Item>
|
||||||
<NavDropdown.Divider />
|
<NavDropdown.Divider />
|
||||||
@ -120,7 +121,7 @@ export default function Header() {
|
|||||||
</NavDropdown>
|
</NavDropdown>
|
||||||
</Nav>
|
</Nav>
|
||||||
</Navbar.Collapse>
|
</Navbar.Collapse>
|
||||||
<BankAccountModal isOpen={bankModalOpen} onClose={closeBankModal} onSave={saveBankAccount} />
|
<SettingsModal isOpen={settingsModalOpen} onClose={closeSettingsModal} onSave={saveSettings} />
|
||||||
<FeaturesVotingModal isOpen={votingModalOpen} onClose={closeVotingModal} onChange={saveFeatureVote} initialValues={featureVotes} />
|
<FeaturesVotingModal isOpen={votingModalOpen} onClose={closeVotingModal} onChange={saveFeatureVote} initialValues={featureVotes} />
|
||||||
<PizzaCalculatorModal isOpen={pizzaModalOpen} onClose={closePizzaModal} />
|
<PizzaCalculatorModal isOpen={pizzaModalOpen} onClose={closePizzaModal} />
|
||||||
</Navbar>
|
</Navbar>
|
||||||
|
@ -1,33 +1,40 @@
|
|||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { Modal, Button } from "react-bootstrap"
|
import { Modal, Button } from "react-bootstrap"
|
||||||
import { useBank } from "../../context/bank";
|
import { useSettings } from "../../context/settings";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean,
|
isOpen: boolean,
|
||||||
onClose: () => void,
|
onClose: () => void,
|
||||||
onSave: (bankAccountNumber?: string, bankAccountHolderName?: string) => void,
|
onSave: (bankAccountNumber?: string, bankAccountHolderName?: string, hideSoupsOption?: boolean) => void,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Modální dialog pro nastavení čísla účtu a jména majitele. */
|
/** Modální dialog pro uživatelská nastavení. */
|
||||||
export default function BankAccountModal({ isOpen, onClose, onSave }: Props) {
|
export default function SettingsModal({ isOpen, onClose, onSave }: Props) {
|
||||||
const bank = useBank();
|
const settings = useSettings();
|
||||||
const bankAccountRef = useRef<HTMLInputElement>(null);
|
const bankAccountRef = useRef<HTMLInputElement>(null);
|
||||||
const nameRef = useRef<HTMLInputElement>(null);
|
const nameRef = useRef<HTMLInputElement>(null);
|
||||||
|
const hideSoupsRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
return <Modal show={isOpen} onHide={onClose} size="lg">
|
return <Modal show={isOpen} onHide={onClose} size="lg">
|
||||||
<Modal.Header closeButton>
|
<Modal.Header closeButton>
|
||||||
<Modal.Title>Bankovní účet</Modal.Title>
|
<Modal.Title><h2>Nastavení</h2></Modal.Title>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
|
<h4>Obecné</h4>
|
||||||
|
<span title="V nabídkách nebudou zobrazovány polévky. Tato funkce je experimentální, a zejména u TechTower bývá často problém polévky spolehlivě rozeznat. V případě využití této funkce průběžně nahlašujte stále se zobrazující polévky." style={{ "cursor": "help" }}>
|
||||||
|
<input ref={hideSoupsRef} type="checkbox" defaultChecked={settings?.hideSoups} /> Skrýt polévky
|
||||||
|
</span>
|
||||||
|
<hr />
|
||||||
|
<h4>Bankovní účet</h4>
|
||||||
<p>Nastavením čísla účtu umožníte automatické generování QR kódů pro úhradu za vámi provedené objednávky v rámci Pizza day.<br />Pokud vaše číslo účtu neobsahuje předčíslí, je možné ho zcela vynechat.<br /><br />Číslo účtu není ukládáno na serveru, posílá se na něj pouze za účelem vygenerování QR kódů.</p>
|
<p>Nastavením čísla účtu umožníte automatické generování QR kódů pro úhradu za vámi provedené objednávky v rámci Pizza day.<br />Pokud vaše číslo účtu neobsahuje předčíslí, je možné ho zcela vynechat.<br /><br />Číslo účtu není ukládáno na serveru, posílá se na něj pouze za účelem vygenerování QR kódů.</p>
|
||||||
Číslo účtu: <input className="mb-3" ref={bankAccountRef} type="text" placeholder="123456-1234567890/1234" defaultValue={bank?.bankAccount} /> <br />
|
Číslo účtu: <input className="mb-3" ref={bankAccountRef} type="text" placeholder="123456-1234567890/1234" defaultValue={settings?.bankAccount} /> <br />
|
||||||
Název příjemce (jméno majitele účtu): <input ref={nameRef} type="text" placeholder="Jan Novák" defaultValue={bank?.holderName} />
|
Název příjemce (jméno majitele účtu): <input ref={nameRef} type="text" placeholder="Jan Novák" defaultValue={settings?.holderName} />
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
<Modal.Footer>
|
<Modal.Footer>
|
||||||
<Button variant="secondary" onClick={onClose}>
|
<Button variant="secondary" onClick={onClose}>
|
||||||
Storno
|
Storno
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="primary" onClick={() => onSave(bankAccountRef.current?.value, nameRef.current?.value)}>
|
<Button variant="primary" onClick={() => onSave(bankAccountRef.current?.value, nameRef.current?.value, hideSoupsRef.current?.checked)}>
|
||||||
Uložit
|
Uložit
|
||||||
</Button>
|
</Button>
|
||||||
</Modal.Footer>
|
</Modal.Footer>
|
@ -3,32 +3,36 @@ import { useEffect } from "react"
|
|||||||
|
|
||||||
const BANK_ACCOUNT_NUMBER_KEY = 'bank_account_number';
|
const BANK_ACCOUNT_NUMBER_KEY = 'bank_account_number';
|
||||||
const BANK_ACCOUNT_HOLDER_KEY = 'bank_account_holder_name';
|
const BANK_ACCOUNT_HOLDER_KEY = 'bank_account_holder_name';
|
||||||
|
const HIDE_SOUPS_KEY = 'hide_soups';
|
||||||
|
|
||||||
export type BankContextProps = {
|
export type SettingsContextProps = {
|
||||||
bankAccount?: string,
|
bankAccount?: string,
|
||||||
holderName?: string,
|
holderName?: string,
|
||||||
|
hideSoups?: boolean,
|
||||||
setBankAccountNumber: (accountNumber?: string) => void,
|
setBankAccountNumber: (accountNumber?: string) => void,
|
||||||
setBankAccountHolderName: (holderName?: string) => void,
|
setBankAccountHolderName: (holderName?: string) => void,
|
||||||
|
setHideSoupsOption: (hideSoups?: boolean) => void,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContextProps = {
|
type ContextProps = {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
const bankContext = React.createContext<BankContextProps | null>(null);
|
const settingsContext = React.createContext<SettingsContextProps | null>(null);
|
||||||
|
|
||||||
export function ProvideBank(props: ContextProps) {
|
export function ProvideSettings(props: ContextProps) {
|
||||||
const bank = useProvideBank();
|
const settings = useProvideSettings();
|
||||||
return <bankContext.Provider value={bank}>{props.children}</bankContext.Provider>
|
return <settingsContext.Provider value={settings}>{props.children}</settingsContext.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useBank = () => {
|
export const useSettings = () => {
|
||||||
return useContext(bankContext);
|
return useContext(settingsContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
function useProvideBank(): BankContextProps {
|
function useProvideSettings(): SettingsContextProps {
|
||||||
const [bankAccount, setBankAccount] = useState<string | undefined>();
|
const [bankAccount, setBankAccount] = useState<string | undefined>();
|
||||||
const [holderName, setHolderName] = useState<string | undefined>();
|
const [holderName, setHolderName] = useState<string | undefined>();
|
||||||
|
const [hideSoups, setHideSoups] = useState<boolean | undefined>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const accountNumber = localStorage.getItem(BANK_ACCOUNT_NUMBER_KEY);
|
const accountNumber = localStorage.getItem(BANK_ACCOUNT_NUMBER_KEY);
|
||||||
@ -39,6 +43,10 @@ function useProvideBank(): BankContextProps {
|
|||||||
if (holderName) {
|
if (holderName) {
|
||||||
setHolderName(holderName);
|
setHolderName(holderName);
|
||||||
}
|
}
|
||||||
|
const hideSoups = localStorage.getItem(HIDE_SOUPS_KEY);
|
||||||
|
if (hideSoups !== null) {
|
||||||
|
setHideSoups(hideSoups === 'true' ? true : false);
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -57,6 +65,14 @@ function useProvideBank(): BankContextProps {
|
|||||||
}
|
}
|
||||||
}, [holderName]);
|
}, [holderName]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (hideSoups) {
|
||||||
|
localStorage.setItem(HIDE_SOUPS_KEY, hideSoups ? 'true' : 'false');
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem(HIDE_SOUPS_KEY);
|
||||||
|
}
|
||||||
|
}, [hideSoups]);
|
||||||
|
|
||||||
function setBankAccountNumber(bankAccount?: string) {
|
function setBankAccountNumber(bankAccount?: string) {
|
||||||
setBankAccount(bankAccount);
|
setBankAccount(bankAccount);
|
||||||
}
|
}
|
||||||
@ -65,10 +81,16 @@ function useProvideBank(): BankContextProps {
|
|||||||
setHolderName(holderName);
|
setHolderName(holderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setHideSoupsOption(hideSoups?: boolean) {
|
||||||
|
setHideSoups(hideSoups);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bankAccount,
|
bankAccount,
|
||||||
holderName,
|
holderName,
|
||||||
|
hideSoups,
|
||||||
setBankAccountNumber,
|
setBankAccountNumber,
|
||||||
setBankAccountHolderName,
|
setBankAccountHolderName,
|
||||||
|
setHideSoupsOption,
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ import App from './App';
|
|||||||
import { SocketContext, socket } from './context/socket';
|
import { SocketContext, socket } from './context/socket';
|
||||||
import { ProvideAuth } from './context/auth';
|
import { ProvideAuth } from './context/auth';
|
||||||
import { ToastContainer } from 'react-toastify';
|
import { ToastContainer } from 'react-toastify';
|
||||||
import { ProvideBank } from './context/bank';
|
import { ProvideSettings } from './context/settings';
|
||||||
import 'react-toastify/dist/ReactToastify.css';
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
@ -14,12 +14,12 @@ const root = ReactDOM.createRoot(
|
|||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<ProvideAuth>
|
<ProvideAuth>
|
||||||
<ProvideBank>
|
<ProvideSettings>
|
||||||
<SocketContext.Provider value={socket}>
|
<SocketContext.Provider value={socket}>
|
||||||
<App />
|
<App />
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
</SocketContext.Provider>
|
</SocketContext.Provider>
|
||||||
</ProvideBank>
|
</ProvideSettings>
|
||||||
</ProvideAuth>
|
</ProvideAuth>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user