Možnost skrytí polévek

This commit is contained in:
Martin Berka 2024-01-24 18:54:05 +01:00
parent 2633d445cc
commit 72c7bfe80c
5 changed files with 67 additions and 37 deletions

View File

@ -13,7 +13,7 @@ import 'react-select-search/style.css';
import './App.css';
import { SelectSearchOption } from 'react-select-search';
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 Footer from './components/Footer';
import { faChainBroken, faChevronLeft, faChevronRight, faGear, faSatelliteDish, faSearch } from '@fortawesome/free-solid-svg-icons';
@ -26,7 +26,7 @@ const EVENT_CONNECT = "connect"
function App() {
const auth = useAuth();
const bank = useBank();
const settings = useSettings();
const [isConnected, setIsConnected] = useState<boolean>(false);
const [data, setData] = useState<ClientData>();
const [food, setFood] = useState<{ [key in Restaurants]?: DayMenu }>();
@ -302,7 +302,7 @@ function App() {
} else if (menu?.food?.length > 0) {
content = <Table striped bordered hover>
<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}>
<td>{f.amount}</td>
<td>{f.name}</td>
@ -360,7 +360,7 @@ function App() {
<Alert variant={'primary'}>
Poslední změny:
<ul>
<li>Základní pizza kalkulačka (v menu)</li>
<li>Možnost skrytí polévek</li>
</ul>
</Alert>
{dayIndex != null &&
@ -540,7 +540,7 @@ function App() {
await lockPizzaDay();
}}>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(bank?.bankAccount, bank?.holderName);
await finishDelivery(settings?.bankAccount, settings?.holderName);
}}>Doručeno</Button>
</div>
}

View File

@ -1,8 +1,8 @@
import { useEffect, useState } from "react";
import { Navbar, Nav, NavDropdown } from "react-bootstrap";
import { useAuth } from "../context/auth";
import BankAccountModal from "./modals/BankAccountModal";
import { useBank } from "../context/bank";
import SettingsModal from "./modals/SettingsModal";
import { useSettings } from "../context/settings";
import FeaturesVotingModal from "./modals/FeaturesVotingModal";
import { FeatureRequest } from "../types";
import { errorHandler } from "../api/Api";
@ -12,8 +12,8 @@ import PizzaCalculatorModal from "./modals/PizzaCalculatorModal";
export default function Header() {
const auth = useAuth();
const bank = useBank();
const [bankModalOpen, setBankModalOpen] = useState<boolean>(false);
const settings = useSettings();
const [settingsModalOpen, setSettingsModalOpen] = useState<boolean>(false);
const [votingModalOpen, setVotingModalOpen] = useState<boolean>(false);
const [pizzaModalOpen, setPizzaModalOpen] = useState<boolean>(false);
const [featureVotes, setFeatureVotes] = useState<FeatureRequest[]>([]);
@ -26,8 +26,8 @@ export default function Header() {
}
}, [auth?.login]);
const closeBankModal = () => {
setBankModalOpen(false);
const closeSettingsModal = () => {
setSettingsModalOpen(false);
}
const closeVotingModal = () => {
@ -48,7 +48,7 @@ export default function Header() {
return n !== Infinity && String(n) === str && n >= 0;
}
const saveBankAccount = (bankAccountNumber?: string, bankAccountHolderName?: string) => {
const saveSettings = (bankAccountNumber?: string, bankAccountHolderName?: string, hideSoupsOption?: boolean) => {
if (bankAccountNumber) {
try {
// Validace kódu banky
@ -90,9 +90,10 @@ export default function Header() {
return
}
}
bank?.setBankAccountNumber(bankAccountNumber);
bank?.setBankAccountHolderName(bankAccountHolderName);
closeBankModal();
settings?.setBankAccountNumber(bankAccountNumber);
settings?.setBankAccountHolderName(bankAccountHolderName);
settings?.setHideSoupsOption(hideSoupsOption);
closeSettingsModal();
}
const saveFeatureVote = async (option: FeatureRequest, active: boolean) => {
@ -112,7 +113,7 @@ export default function Header() {
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="nav">
<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={() => setPizzaModalOpen(true)}>Pizza kalkulačka</NavDropdown.Item>
<NavDropdown.Divider />
@ -120,7 +121,7 @@ export default function Header() {
</NavDropdown>
</Nav>
</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} />
<PizzaCalculatorModal isOpen={pizzaModalOpen} onClose={closePizzaModal} />
</Navbar>

View File

@ -1,33 +1,40 @@
import { useRef } from "react";
import { Modal, Button } from "react-bootstrap"
import { useBank } from "../../context/bank";
import { useSettings } from "../../context/settings";
type Props = {
isOpen: boolean,
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. */
export default function BankAccountModal({ isOpen, onClose, onSave }: Props) {
const bank = useBank();
/** Modální dialog pro uživatelská nastavení. */
export default function SettingsModal({ isOpen, onClose, onSave }: Props) {
const settings = useSettings();
const bankAccountRef = useRef<HTMLInputElement>(null);
const nameRef = useRef<HTMLInputElement>(null);
const hideSoupsRef = useRef<HTMLInputElement>(null);
return <Modal show={isOpen} onHide={onClose} size="lg">
<Modal.Header closeButton>
<Modal.Title>Bankovní účet</Modal.Title>
<Modal.Title><h2>Nastavení</h2></Modal.Title>
</Modal.Header>
<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>
Číslo účtu: <input className="mb-3" ref={bankAccountRef} type="text" placeholder="123456-1234567890/1234" defaultValue={bank?.bankAccount} /> <br />
Název příjemce (jméno majitele účtu): <input ref={nameRef} type="text" placeholder="Jan Novák" defaultValue={bank?.holderName} />
Čí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={settings?.holderName} />
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={onClose}>
Storno
</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
</Button>
</Modal.Footer>

View File

@ -3,32 +3,36 @@ import { useEffect } from "react"
const BANK_ACCOUNT_NUMBER_KEY = 'bank_account_number';
const BANK_ACCOUNT_HOLDER_KEY = 'bank_account_holder_name';
const HIDE_SOUPS_KEY = 'hide_soups';
export type BankContextProps = {
export type SettingsContextProps = {
bankAccount?: string,
holderName?: string,
hideSoups?: boolean,
setBankAccountNumber: (accountNumber?: string) => void,
setBankAccountHolderName: (holderName?: string) => void,
setHideSoupsOption: (hideSoups?: boolean) => void,
}
type ContextProps = {
children: ReactNode
}
const bankContext = React.createContext<BankContextProps | null>(null);
const settingsContext = React.createContext<SettingsContextProps | null>(null);
export function ProvideBank(props: ContextProps) {
const bank = useProvideBank();
return <bankContext.Provider value={bank}>{props.children}</bankContext.Provider>
export function ProvideSettings(props: ContextProps) {
const settings = useProvideSettings();
return <settingsContext.Provider value={settings}>{props.children}</settingsContext.Provider>
}
export const useBank = () => {
return useContext(bankContext);
export const useSettings = () => {
return useContext(settingsContext);
}
function useProvideBank(): BankContextProps {
function useProvideSettings(): SettingsContextProps {
const [bankAccount, setBankAccount] = useState<string | undefined>();
const [holderName, setHolderName] = useState<string | undefined>();
const [hideSoups, setHideSoups] = useState<boolean | undefined>();
useEffect(() => {
const accountNumber = localStorage.getItem(BANK_ACCOUNT_NUMBER_KEY);
@ -39,6 +43,10 @@ function useProvideBank(): BankContextProps {
if (holderName) {
setHolderName(holderName);
}
const hideSoups = localStorage.getItem(HIDE_SOUPS_KEY);
if (hideSoups !== null) {
setHideSoups(hideSoups === 'true' ? true : false);
}
}, [])
useEffect(() => {
@ -57,6 +65,14 @@ function useProvideBank(): BankContextProps {
}
}, [holderName]);
useEffect(() => {
if (hideSoups) {
localStorage.setItem(HIDE_SOUPS_KEY, hideSoups ? 'true' : 'false');
} else {
localStorage.removeItem(HIDE_SOUPS_KEY);
}
}, [hideSoups]);
function setBankAccountNumber(bankAccount?: string) {
setBankAccount(bankAccount);
}
@ -65,10 +81,16 @@ function useProvideBank(): BankContextProps {
setHolderName(holderName);
}
function setHideSoupsOption(hideSoups?: boolean) {
setHideSoups(hideSoups);
}
return {
bankAccount,
holderName,
hideSoups,
setBankAccountNumber,
setBankAccountHolderName,
setHideSoupsOption,
}
}

View File

@ -4,7 +4,7 @@ import App from './App';
import { SocketContext, socket } from './context/socket';
import { ProvideAuth } from './context/auth';
import { ToastContainer } from 'react-toastify';
import { ProvideBank } from './context/bank';
import { ProvideSettings } from './context/settings';
import 'react-toastify/dist/ReactToastify.css';
import './index.css';
@ -14,12 +14,12 @@ const root = ReactDOM.createRoot(
root.render(
<React.StrictMode>
<ProvideAuth>
<ProvideBank>
<ProvideSettings>
<SocketContext.Provider value={socket}>
<App />
<ToastContainer />
</SocketContext.Provider>
</ProvideBank>
</ProvideSettings>
</ProvideAuth>
</React.StrictMode>
);