118 lines
4.5 KiB
TypeScript
118 lines
4.5 KiB
TypeScript
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 FeaturesVotingModal from "./modals/FeaturesVotingModal";
|
|
import { FeatureRequest } from "../types";
|
|
import { errorHandler } from "../api/Api";
|
|
import { getFeatureVotes, updateFeatureVote } from "../api/VotingApi";
|
|
|
|
|
|
export default function Header() {
|
|
const auth = useAuth();
|
|
const bank = useBank();
|
|
const [bankModalOpen, setBankModalOpen] = useState<boolean>(false);
|
|
const [votingModalOpen, setVotingModalOpen] = useState<boolean>(false);
|
|
const [featureVotes, setFeatureVotes] = useState<FeatureRequest[]>([]);
|
|
|
|
useEffect(() => {
|
|
if (auth?.login) {
|
|
getFeatureVotes().then(votes => {
|
|
setFeatureVotes(votes);
|
|
})
|
|
}
|
|
}, [auth?.login]);
|
|
|
|
const closeBankModal = () => {
|
|
setBankModalOpen(false);
|
|
}
|
|
|
|
const closeVotingModal = () => {
|
|
setVotingModalOpen(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 saveBankAccount = (bankAccountNumber?: string, bankAccountHolderName?: string) => {
|
|
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
|
|
}
|
|
}
|
|
bank?.setBankAccountNumber(bankAccountNumber);
|
|
bank?.setBankAccountHolderName(bankAccountHolderName);
|
|
closeBankModal();
|
|
}
|
|
|
|
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={() => setBankModalOpen(true)}>Nastavit číslo účtu</NavDropdown.Item>
|
|
<NavDropdown.Item onClick={() => setVotingModalOpen(true)}>Hlasovat o nových funkcích</NavDropdown.Item>
|
|
<NavDropdown.Item onClick={auth?.logout}>Odhlásit se</NavDropdown.Item>
|
|
</NavDropdown>
|
|
</Nav>
|
|
</Navbar.Collapse>
|
|
<BankAccountModal isOpen={bankModalOpen} onClose={closeBankModal} onSave={saveBankAccount} />
|
|
<FeaturesVotingModal isOpen={votingModalOpen} onClose={closeVotingModal} onChange={saveFeatureVote} initialValues={featureVotes} />
|
|
</Navbar>
|
|
} |