Added budget updates

This commit is contained in:
Khalim Conn-Kowlessar 2023-05-31 11:50:36 +01:00
parent 380f9bfe9b
commit 94e1cc5973
4 changed files with 131 additions and 5 deletions

View file

@ -0,0 +1,94 @@
import { Dialog, Transition } from "@headlessui/react";
import { Dispatch, Fragment, SetStateAction, useState } from "react";
import { TanButton } from "../Buttons";
export default function BudgetModal({
isOpen,
setIsOpen,
budget,
setBudget,
}: {
isOpen: boolean;
setIsOpen: Dispatch<SetStateAction<boolean>>;
budget: number | "Not set";
setBudget: Dispatch<SetStateAction<number | "Not set">>;
}) {
const [budgetInput, setBudgetInput] = useState<number | null>(null);
function handleSubmit() {
if (budgetInput !== null) {
setBudget(budgetInput);
}
setIsOpen(false);
}
return (
<>
<Transition appear show={isOpen} as={Fragment}>
<Dialog
as="div"
className="relative z-10"
onClose={() => setIsOpen(false)}
>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-1/2 max-w-screen-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-brandblue mb-3"
>
{"Set a Budget"}
</Dialog.Title>
<div className="flex justify-center">
<input
id="search"
className="w-full appearance-none rounded border-2 border-gray-200 bg-gray-200 px-8 py-2 leading-tight text-gray-700 focus:border-brandmidblue focus:bg-white focus:outline-none"
type="number"
placeholder="Set your budget "
onChange={(e) => setBudgetInput(Number(e.target.value))}
onKeyDown={(e) =>
(e.key === "e" || e.key === "E") && e.preventDefault()
}
/>
</div>
<div className="mt-4 flex justify-end gap-2">
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={() => setIsOpen(false)}
>
Cancel
</button>
<TanButton label={"Save"} onClick={handleSubmit} />
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</>
);
}

View file

@ -19,7 +19,8 @@ export default function PartModal({
setSelectedOption: Dispatch<SetStateAction<string>>;
}) {
function handleModalSubmit() {
// setTargetEpcRating(modalEpcTarget);
// Right now the dropdown is setting the state on the selected option so we might not need
// to do anything here
setIsOpen(false);
}

View file

@ -9,6 +9,8 @@ import { PencilSquareIcon } from "@heroicons/react/24/outline";
import PlanPart from "@/app/components/plan/PlanPart";
import EditEpctargetModal from "@/app/components/property/EditEpcTargetModal";
import Link from "next/link";
import BudgetModal from "@/app/components/plan/BudgetModal";
import { formatNumber } from "@/app/utils";
export default function Plan({
params,
@ -62,10 +64,11 @@ export default function Plan({
const partsTotalCost = partsConfig.reduce((sum, part) => sum + part.cost, 0);
const [budget, setBudget] = useState("Not set");
const [budget, setBudget] = useState<number | "Not set">("Not set");
const [totalCost, setTotalCost] = useState(partsTotalCost);
const [installTime, setInstallTime] = useState(totalWorkHours);
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [isBudgetModalOpen, setIsBudgetModalOpen] = useState(false);
const [targetEpcRating, setTargetEpcRating] = useState<EpcRating | "">(
(searchParams.targetEpcRating as EpcRating) ?? "C"
);
@ -122,10 +125,12 @@ export default function Plan({
<PencilSquareIcon className="h-6 w-6 ml-2" />
</li>
<li
onClick={() => console.log("clicked")}
onClick={() => setIsBudgetModalOpen(true)}
className="px-2 mb-2 flex items-center cursor-pointer hover:bg-brandblue hover:rounded-md transition-colors duration-200"
>
Budget: {budget}
{budget !== "Not set"
? "Budget: £" + formatNumber(budget)
: "Budget: " + budget}
<PencilSquareIcon className="h-6 w-6 ml-2" />
</li>
<Link
@ -137,7 +142,6 @@ export default function Plan({
</li>
</Link>
<li className="px-2 mb-2">Total cost: £{totalCost}</li>
<li className="px-2 mb-2">
Installation Time: {installTime} hours
</li>
@ -153,6 +157,12 @@ export default function Plan({
targetEpcRating={targetEpcRating}
currentEpcRating={propertyData["current-energy-rating"]}
/>
<BudgetModal
isOpen={isBudgetModalOpen}
setIsOpen={setIsBudgetModalOpen}
budget={budget}
setBudget={setBudget}
/>
</section>
);
}

21
src/app/utils.ts Normal file
View file

@ -0,0 +1,21 @@
export function formatNumber(number: number): string {
const suffixes: string[] = ["", "k", "m", "b", "t"];
const suffixIndex: number = Math.floor(Math.log10(Math.abs(number)) / 3);
// Check if the suffix index is within the available suffixes
if (suffixIndex >= suffixes.length) {
return number.toString(); // Return the number as is
}
// Check if the number is smaller and round to 2 decimal places
const roundedNumber: number =
Math.abs(number) < 1000
? Number(number.toFixed(2))
: Number(number.toPrecision(4));
const formattedNumber: string = (
roundedNumber / Math.pow(1000, suffixIndex)
).toString();
return formattedNumber + suffixes[suffixIndex];
}