From 8e075dd904e3b7f5e04da70e0fd2f3eb80e2b0a5 Mon Sep 17 00:00:00 2001 From: Martin Berka Date: Mon, 8 Jan 2024 23:39:12 +0100 Subject: [PATCH] =?UTF-8?q?Z=C3=A1kladn=C3=AD=20Pizza=20kalkula=C4=8Dka?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/App.tsx | 3 +- client/src/components/Header.tsx | 9 ++ .../modals/PizzaCalculatorModal.tsx | 141 ++++++++++++++++++ 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 client/src/components/modals/PizzaCalculatorModal.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index 88e4c9c..8f492a8 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -360,8 +360,7 @@ function App() { Poslední změny: {dayIndex != null && diff --git a/client/src/components/Header.tsx b/client/src/components/Header.tsx index e941782..166f379 100644 --- a/client/src/components/Header.tsx +++ b/client/src/components/Header.tsx @@ -7,6 +7,7 @@ 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() { @@ -14,6 +15,7 @@ export default function Header() { const bank = useBank(); const [bankModalOpen, setBankModalOpen] = useState(false); const [votingModalOpen, setVotingModalOpen] = useState(false); + const [pizzaModalOpen, setPizzaModalOpen] = useState(false); const [featureVotes, setFeatureVotes] = useState([]); useEffect(() => { @@ -32,6 +34,10 @@ export default function Header() { setVotingModalOpen(false); } + const closePizzaModal = () => { + setPizzaModalOpen(false); + } + const isValidInteger = (str: string) => { str = str.trim(); if (!str) { @@ -108,11 +114,14 @@ export default function Header() { setBankModalOpen(true)}>Nastavit číslo účtu setVotingModalOpen(true)}>Hlasovat o nových funkcích + setPizzaModalOpen(true)}>Pizza kalkulačka + Odhlásit se + } \ No newline at end of file diff --git a/client/src/components/modals/PizzaCalculatorModal.tsx b/client/src/components/modals/PizzaCalculatorModal.tsx new file mode 100644 index 0000000..e66b120 --- /dev/null +++ b/client/src/components/modals/PizzaCalculatorModal.tsx @@ -0,0 +1,141 @@ +import { useRef, useState } from "react"; +import { Modal, Button, Row, Col } from "react-bootstrap" + +type Props = { + isOpen: boolean, + onClose: () => void, +} + +type Result = { + pizza1?: { + diameter?: number, + area?: number, + pricePerM?: number, + }, + pizza2?: { + diameter?: number, + area?: number, + pricePerM?: number, + } + choice?: number, + ratio?: number, + diameterDiff?: number, +} + +/** Modální dialog pro výpočet výhodnosti pizzy. */ +export default function PizzaCalculatorModal({ isOpen, onClose }: Props) { + const diameter1Ref = useRef(null); + const price1Ref = useRef(null); + const diameter2Ref = useRef(null); + const price2Ref = useRef(null); + + const [result, setResult] = useState(null); + + const recalculate = () => { + const r: Result = { ...result } + + // 1. pizza + if (diameter1Ref.current?.value) { + const diameter1 = parseInt(diameter1Ref.current?.value); + if (!r.pizza1) { + r.pizza1 = {}; + } + if (diameter1 && diameter1 > 0) { + r.pizza1.diameter = diameter1; + r.pizza1.area = Math.PI * Math.pow(diameter1 / 2, 2); + if (price1Ref.current?.value) { + const price1 = parseInt(price1Ref.current?.value); + if (price1) { + r.pizza1.pricePerM = price1 / r.pizza1.area; + } else { + r.pizza1.pricePerM = undefined; + } + } + } else { + r.pizza1.area = undefined; + } + } + + // 2. pizza + if (diameter2Ref.current?.value) { + const diameter2 = parseInt(diameter2Ref.current?.value); + if (!r.pizza2) { + r.pizza2 = {}; + } + if (diameter2 && diameter2 > 0) { + r.pizza2.diameter = diameter2; + r.pizza2.area = Math.PI * Math.pow(diameter2 / 2, 2); + if (price2Ref.current?.value) { + const price2 = parseInt(price2Ref.current?.value); + if (price2) { + r.pizza2.pricePerM = price2 / r.pizza2.area; + } else { + r.pizza2.pricePerM = undefined; + } + } + } else { + r.pizza2.area = undefined; + } + } + + // Srovnání + if (r.pizza1?.pricePerM && r.pizza2?.pricePerM && r.pizza1.diameter && r.pizza2.diameter) { + r.choice = r.pizza1.pricePerM < r.pizza2.pricePerM ? 1 : 2; + const bigger = r.pizza1.pricePerM > r.pizza2.pricePerM ? r.pizza1.pricePerM : r.pizza2.pricePerM; + const smaller = r.pizza1.pricePerM < r.pizza2.pricePerM ? r.pizza1.pricePerM : r.pizza2.pricePerM; + r.ratio = (bigger / smaller) - 1; + r.diameterDiff = Math.abs(r.pizza1.diameter - r.pizza2.diameter); + } else { + r.choice = undefined; + r.ratio = undefined; + r.diameterDiff = undefined; + } + setResult(r); + } + + const close = () => { + setResult(null); + onClose(); + } + + return + + Pizza kalkulačka + + +

Zadejte parametry pizzy pro jejich srovnání.

+ + + + + + + + + + + + + + + + + + + {result?.pizza1?.area &&

Plocha: {Math.round(result.pizza1.area * 10) / 10} cm²

} + {result?.pizza1?.pricePerM &&

Cena za m²: {Math.round(result.pizza1.pricePerM * 1000000) / 100}

} + + + {result?.pizza2?.area &&

Plocha: {Math.round(result.pizza2.area * 10) / 10} cm²

} + {result?.pizza2?.pricePerM &&

Cena za m²: {Math.round(result.pizza2.pricePerM * 1000000) / 100}

} + +
+ {result?.choice && result?.ratio && result?.ratio > 0 && result?.diameterDiff != null &&

{result.choice}. pizza je zhruba o {Math.round(result.ratio * 1000) / 10}% výhodnější než {result.choice === 1 ? "2" : "1"}. pizza.

|| ''} +
+ + + +
+} \ No newline at end of file