Compare commits
2 Commits
5e94009898
...
e8ceb02194
Author | SHA1 | Date | |
---|---|---|---|
e8ceb02194 | |||
8525bc5c12 |
@ -19,8 +19,10 @@
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.7.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-modal": "^3.16.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-select-search": "^4.1.6",
|
||||
"react-toastify": "^9.1.3",
|
||||
"socket.io-client": "^4.6.1",
|
||||
"typescript": "^4.9.5",
|
||||
"web-vitals": "^2.1.4"
|
||||
|
@ -115,7 +115,6 @@ function App() {
|
||||
const s = value.split('|');
|
||||
const pizzaIndex = Number.parseInt(s[0]);
|
||||
const pizzaSizeIndex = Number.parseInt(s[1]);
|
||||
const pizza = pizzy[pizzaIndex];
|
||||
await addPizza(auth.login, pizzaIndex, pizzaSizeIndex);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ export default function Login() {
|
||||
if (length) {
|
||||
auth?.setLogin(loginRef.current.value);
|
||||
}
|
||||
}, []);
|
||||
}, [auth]);
|
||||
|
||||
if (!auth || !auth.login) {
|
||||
return <div className='login'>
|
||||
|
@ -1,9 +1,30 @@
|
||||
import React from "react";
|
||||
import { Navbar, Nav, NavDropdown } from "react-bootstrap";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { Navbar, Nav, NavDropdown, Modal, Button } from "react-bootstrap";
|
||||
import { useAuth } from "../context/auth";
|
||||
import { useBank } from "../context/bank";
|
||||
|
||||
|
||||
export default function Header() {
|
||||
const auth = useAuth();
|
||||
const bank = useBank();
|
||||
const [modalOpen, setModalOpen] = useState<boolean>(false);
|
||||
const bankAccountRef = useRef<HTMLInputElement>(null);
|
||||
const nameRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const openBankSettings = () => {
|
||||
setModalOpen(true);
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
setModalOpen(false);
|
||||
}
|
||||
|
||||
const save = () => {
|
||||
// TODO validace na modulo 11
|
||||
bank?.setBankAccountNumber(bankAccountRef.current?.value);
|
||||
bank?.setBankAccountHolderName(nameRef.current?.value);
|
||||
closeModal();
|
||||
}
|
||||
|
||||
return <Navbar variant='dark' expand="lg">
|
||||
<Navbar.Brand>Luncher</Navbar.Brand>
|
||||
@ -11,9 +32,28 @@ 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={openBankSettings}>Nastavit číslo účtu</NavDropdown.Item>
|
||||
<NavDropdown.Item onClick={auth?.clearLogin}>Odhlásit se</NavDropdown.Item>
|
||||
</NavDropdown>
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
<Modal show={modalOpen} onHide={closeModal}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>Bankovní účet</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<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 />Poznámka: Číslo účtu není aktuálně nijak validováno. Ověřte si jeho správnost.</p>
|
||||
Číslo účtu: <input ref={bankAccountRef} type="text" placeholder="123456-1234567890/1234" /> <br />
|
||||
Název příjemce (nepovinné): <input ref={nameRef} type="text" placeholder="Jan Novák" />
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant="secondary" onClick={closeModal}>
|
||||
Storno
|
||||
</Button>
|
||||
<Button variant="primary" onClick={save}>
|
||||
Uložit
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</Navbar>
|
||||
}
|
74
client/src/context/bank.tsx
Normal file
74
client/src/context/bank.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
import React, { ReactNode, useContext, useState } from "react"
|
||||
import { useEffect } from "react"
|
||||
|
||||
const BANK_ACCOUNT_NUMBER_KEY = 'bank_account_number';
|
||||
const BANK_ACCOUNT_HOLDER_KEY = 'bank_account_holder_name';
|
||||
|
||||
export type BankContextProps = {
|
||||
bankAccount?: string,
|
||||
holderName?: string,
|
||||
setBankAccountNumber: (accountNumber?: string) => void,
|
||||
setBankAccountHolderName: (holderName?: string) => void,
|
||||
}
|
||||
|
||||
type ContextProps = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const bankContext = React.createContext<BankContextProps | null>(null);
|
||||
|
||||
export function ProvideBank(props: ContextProps) {
|
||||
const bank = useProvideBank();
|
||||
return <bankContext.Provider value={bank}>{props.children}</bankContext.Provider>
|
||||
}
|
||||
|
||||
export const useBank = () => {
|
||||
return useContext(bankContext);
|
||||
}
|
||||
|
||||
function useProvideBank(): BankContextProps {
|
||||
const [bankAccount, setBankAccount] = useState<string | undefined>();
|
||||
const [holderName, setHolderName] = useState<string | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
const accountNumber = localStorage.getItem(BANK_ACCOUNT_NUMBER_KEY);
|
||||
if (accountNumber) {
|
||||
setBankAccount(accountNumber);
|
||||
}
|
||||
const holderName = localStorage.getItem(BANK_ACCOUNT_HOLDER_KEY);
|
||||
if (holderName) {
|
||||
setHolderName(holderName);
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (bankAccount) {
|
||||
localStorage.setItem(BANK_ACCOUNT_NUMBER_KEY, bankAccount)
|
||||
} else {
|
||||
localStorage.removeItem(BANK_ACCOUNT_NUMBER_KEY);
|
||||
}
|
||||
}, [bankAccount]);
|
||||
|
||||
useEffect(() => {
|
||||
if (holderName) {
|
||||
localStorage.setItem(BANK_ACCOUNT_HOLDER_KEY, holderName);
|
||||
} else {
|
||||
localStorage.removeItem(BANK_ACCOUNT_HOLDER_KEY);
|
||||
}
|
||||
}, [holderName]);
|
||||
|
||||
function setBankAccountNumber(bankAccount?: string) {
|
||||
setBankAccount(bankAccount);
|
||||
}
|
||||
|
||||
function setBankAccountHolderName(holderName?: string) {
|
||||
setHolderName(holderName);
|
||||
}
|
||||
|
||||
return {
|
||||
bankAccount,
|
||||
holderName,
|
||||
setBankAccountNumber,
|
||||
setBankAccountHolderName,
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@ import ReactDOM from 'react-dom/client';
|
||||
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 'react-toastify/dist/ReactToastify.css';
|
||||
import './index.css';
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
@ -11,9 +14,12 @@ const root = ReactDOM.createRoot(
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<ProvideAuth>
|
||||
<SocketContext.Provider value={socket}>
|
||||
<App />
|
||||
</SocketContext.Provider>
|
||||
<ProvideBank>
|
||||
<SocketContext.Provider value={socket}>
|
||||
<App />
|
||||
<ToastContainer />
|
||||
</SocketContext.Provider>
|
||||
</ProvideBank>
|
||||
</ProvideAuth>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
@ -3296,6 +3296,11 @@ cliui@^7.0.2:
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
clsx@^1.1.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
|
||||
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
@ -4506,6 +4511,11 @@ execa@^5.0.0:
|
||||
signal-exit "^3.0.3"
|
||||
strip-final-newline "^2.0.0"
|
||||
|
||||
exenv@^1.2.0:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||
integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==
|
||||
|
||||
exit@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
||||
@ -7628,7 +7638,7 @@ prop-types-extra@^1.1.0:
|
||||
react-is "^16.3.2"
|
||||
warning "^4.0.0"
|
||||
|
||||
prop-types@^15.6.2, prop-types@^15.8.1:
|
||||
prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@ -7794,11 +7804,21 @@ react-is@^18.0.0:
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||
|
||||
react-lifecycles-compat@^3.0.4:
|
||||
react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-modal@^3.16.1:
|
||||
version "3.16.1"
|
||||
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.1.tgz#34018528fc206561b1a5467fc3beeaddafb39b2b"
|
||||
integrity sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==
|
||||
dependencies:
|
||||
exenv "^1.2.0"
|
||||
prop-types "^15.7.2"
|
||||
react-lifecycles-compat "^3.0.0"
|
||||
warning "^4.0.3"
|
||||
|
||||
react-refresh@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046"
|
||||
@ -7864,6 +7884,13 @@ react-select-search@^4.1.6:
|
||||
resolved "https://registry.yarnpkg.com/react-select-search/-/react-select-search-4.1.6.tgz#4c3165e02007518726e004267fd1168e0076061d"
|
||||
integrity sha512-BJMf11Ux0hqn6Z3BqRwceXdwjdF+dnpDsYGGehDPB/nZv+Dse7wdPUMqLSCVDyrH5y3xFu7r6IlZ6dj78291vA==
|
||||
|
||||
react-toastify@^9.1.3:
|
||||
version "9.1.3"
|
||||
resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.3.tgz#1e798d260d606f50e0fab5ee31daaae1d628c5ff"
|
||||
integrity sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==
|
||||
dependencies:
|
||||
clsx "^1.1.1"
|
||||
|
||||
react-transition-group@^4.4.5:
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
|
||||
|
Loading…
x
Reference in New Issue
Block a user