128 lines
5.1 KiB
TypeScript
128 lines
5.1 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { Navbar, Nav, NavDropdown } from "react-bootstrap";
|
|
import { useAuth } from "../context/auth";
|
|
import SettingsModal from "./modals/SettingsModal";
|
|
import { useSettings } from "../context/settings";
|
|
import FeaturesVotingModal from "./modals/FeaturesVotingModal";
|
|
import { FeatureRequest } from "../../../types";
|
|
import { errorHandler } from "../api/Api";
|
|
import { getFeatureVotes, updateFeatureVote } from "../api/VotingApi";
|
|
import PizzaCalculatorModal from "./modals/PizzaCalculatorModal";
|
|
|
|
|
|
export default function Header() {
|
|
const auth = useAuth();
|
|
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[]>([]);
|
|
|
|
useEffect(() => {
|
|
if (auth?.login) {
|
|
getFeatureVotes().then(votes => {
|
|
setFeatureVotes(votes);
|
|
})
|
|
}
|
|
}, [auth?.login]);
|
|
|
|
const closeSettingsModal = () => {
|
|
setSettingsModalOpen(false);
|
|
}
|
|
|
|
const closeVotingModal = () => {
|
|
setVotingModalOpen(false);
|
|
}
|
|
|
|
const closePizzaModal = () => {
|
|
setPizzaModalOpen(false);
|
|
}
|
|
|
|
const isValidInteger = (str: string) => {
|
|
str = str.trim();
|
|
if (!str) {
|
|
return false;
|
|
}
|
|
str = str.replace(/^0+/, "") || "0";
|
|
const n = Math.floor(Number(str));
|
|
return n !== Infinity && String(n) === str && n >= 0;
|
|
}
|
|
|
|
const saveSettings = (bankAccountNumber?: string, bankAccountHolderName?: string, hideSoupsOption?: boolean) => {
|
|
if (bankAccountNumber) {
|
|
try {
|
|
// Validace kódu banky
|
|
if (bankAccountNumber.indexOf('/') < 0) {
|
|
throw Error("Číslo účtu neobsahuje lomítko/kód banky")
|
|
}
|
|
const split = bankAccountNumber.split("/");
|
|
if (split[1].length !== 4) {
|
|
throw Error("Kód banky musí být 4 číslice")
|
|
}
|
|
if (!isValidInteger(split[1])) {
|
|
throw Error("Kód banky není číslo")
|
|
}
|
|
|
|
// Validace čísla a předčíslí
|
|
let cislo = split[0];
|
|
|
|
if (cislo.indexOf('-') > 0) {
|
|
cislo = cislo.replace('-', '');
|
|
}
|
|
if (!isValidInteger(cislo)) {
|
|
throw Error("Předčíslí nebo číslo účtu neobsahuje pouze číslice")
|
|
}
|
|
if (cislo.length < 16) {
|
|
cislo = cislo.padStart(16, '0');
|
|
}
|
|
let sum = 0;
|
|
for (var i = 0; i < cislo.length; i++) {
|
|
const char = cislo.charAt(i);
|
|
const order = (cislo.length - 1) - i;
|
|
const weight = (2 ** order) % 11;
|
|
sum += Number.parseInt(char) * weight
|
|
}
|
|
if (sum % 11 !== 0) {
|
|
throw Error("Číslo účtu je neplatné")
|
|
}
|
|
} catch (e: any) {
|
|
alert(e.message)
|
|
return
|
|
}
|
|
}
|
|
settings?.setBankAccountNumber(bankAccountNumber);
|
|
settings?.setBankAccountHolderName(bankAccountHolderName);
|
|
settings?.setHideSoupsOption(hideSoupsOption);
|
|
closeSettingsModal();
|
|
}
|
|
|
|
const saveFeatureVote = async (option: FeatureRequest, active: boolean) => {
|
|
await errorHandler(() => updateFeatureVote(option, active));
|
|
const votes = [...featureVotes];
|
|
if (active) {
|
|
votes.push(option);
|
|
} else {
|
|
votes.splice(votes.indexOf(option), 1);
|
|
}
|
|
setFeatureVotes(votes);
|
|
}
|
|
|
|
return <Navbar variant='dark' expand="lg">
|
|
<Navbar.Brand>Luncher</Navbar.Brand>
|
|
<Navbar.Toggle aria-controls="basic-navbar-nav" />
|
|
<Navbar.Collapse id="basic-navbar-nav">
|
|
<Nav className="nav">
|
|
<NavDropdown align="end" title={auth?.login} id="basic-nav-dropdown">
|
|
<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 />
|
|
<NavDropdown.Item onClick={auth?.logout}>Odhlásit se</NavDropdown.Item>
|
|
</NavDropdown>
|
|
</Nav>
|
|
</Navbar.Collapse>
|
|
<SettingsModal isOpen={settingsModalOpen} onClose={closeSettingsModal} onSave={saveSettings} />
|
|
<FeaturesVotingModal isOpen={votingModalOpen} onClose={closeVotingModal} onChange={saveFeatureVote} initialValues={featureVotes} />
|
|
<PizzaCalculatorModal isOpen={pizzaModalOpen} onClose={closePizzaModal} />
|
|
</Navbar>
|
|
} |