Added reactivity for total cost

This commit is contained in:
Khalim Conn-Kowlessar 2023-07-28 16:54:37 +01:00
parent 2b3e8c7211
commit bc8e9f1ebe
3 changed files with 38 additions and 84 deletions

View file

@ -6,6 +6,8 @@ import { Dialog, Transition } from "@headlessui/react";
import RecommendationTable from "@/app/components/building-passport/RecommendationTable";
import { ColumnDef } from "@tanstack/react-table";
import { Checkbox } from "@/app/shadcn_components/ui/checkbox";
import { CostMap } from "@/types/recommendations";
import { sumCostMap } from "@/app/portfolio/[slug]/building-passport/[propertyId]/recommendations/utils";
export const uvalueColumns: ColumnDef<ComponentRecommendation>[] = [
{
@ -49,12 +51,20 @@ export function RecommendationModal({
setIsOpen,
recommendationData,
setCardComponent,
setCostMap,
costMap,
totalEstimatedCost,
setTotalEstimatedCost,
}: {
title: string;
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
recommendationData: ComponentRecommendation[];
setCardComponent: Dispatch<SetStateAction<ComponentRecommendation>>;
setCostMap: Dispatch<SetStateAction<CostMap>>;
costMap: CostMap;
totalEstimatedCost: number;
setTotalEstimatedCost: Dispatch<SetStateAction<number>>;
}) {
const [saveButtonDisabled, setSaveButtonDisabled] = useState(true);
@ -85,6 +95,14 @@ export function RecommendationModal({
setCardComponent(recommendationData[newIndex]);
// Set the default index
setDefaultRowIndex(newIndex);
// Update the cost map
const newCostMap = {
...costMap,
[title]: recommendationData[newIndex].estimatedCost,
};
setCostMap(newCostMap);
// update the cost sum
setTotalEstimatedCost(sumCostMap(newCostMap));
}
return (
@ -174,9 +192,17 @@ const noSelectionStyling =
export default function RecommendationCard({
componentType,
recommendationData,
setCostMap,
costMap,
totalEstimatedCost,
setTotalEstimatedCost,
}: {
componentType: string;
recommendationData: ComponentRecommendation[];
setCostMap: Dispatch<SetStateAction<CostMap>>;
costMap: CostMap;
totalEstimatedCost: number;
setTotalEstimatedCost: Dispatch<SetStateAction<number>>;
}) {
const defaultComponent = recommendationData.find(
(rec: ComponentRecommendation) => rec.default
@ -240,6 +266,10 @@ export default function RecommendationCard({
setIsOpen={setModalIsOpen}
recommendationData={recommendationData}
setCardComponent={setCardComponent}
setCostMap={setCostMap}
costMap={costMap}
totalEstimatedCost={totalEstimatedCost}
setTotalEstimatedCost={setTotalEstimatedCost}
/>
</div>
);

View file

@ -9,22 +9,19 @@ export default function RecommendationCostSummaryCard({
totalEstimatedCost: number;
totalSapPoints: number;
}) {
const [totalCost, setTotalcost] = useState(totalEstimatedCost);
const [totalSap, setTotalSap] = useState(totalSapPoints);
return (
<table className="text-left bg-green-700 rounded-md text-gray-100">
<tbody>
<tr>
<td className="font-medium pl-4 py-2">Total Cost:</td>
<td className="pr-2">{"£" + formatNumber(totalCost)}</td>
<td className="pr-2">{"£" + formatNumber(totalEstimatedCost)}</td>
</tr>
<tr>
<td className="font-medium pl-4 py-2">
Total SAP Points Improvement:
</td>
<td className="pr-2">{totalSap}</td>
<td className="pr-2">{totalSapPoints}</td>
</tr>
</tbody>
</table>

View file

@ -1,12 +1,6 @@
import {
ComponentRecommendation,
Recommendation,
} from "@/app/db/schema/recommendations";
import RecommendationCard from "@/app/components/building-passport/RecommendationCard";
import { formatNumber, sapToEpc } from "@/app/utils";
import { Recommendation } from "@/app/db/schema/recommendations";
import { PropertyMeta } from "@/app/db/schema/property";
import RecommendationCostSummaryCard from "@/app/components/building-passport/RecommendationCostSummaryCard";
import { Separator } from "@/app/shadcn_components/ui/separator";
import RecommendationContainer from "@/app/components/building-passport/RecommendationContainer";
export default async function Recommendations() {
const propertyMeta: PropertyMeta = {
@ -90,80 +84,13 @@ export default async function Recommendations() {
],
};
const defaultWallsRecommendations = recommendations.Walls?.find(
(rec: ComponentRecommendation) => rec.default
) || { estimatedCost: 0, sapPoints: 0 };
const defaultFloorRecommendations = recommendations.Floor?.find(
(rec: ComponentRecommendation) => rec.default
) || { estimatedCost: 0, sapPoints: 0 };
const defaultVentiliationRecommendations = recommendations.Ventilation?.find(
(rec: ComponentRecommendation) => rec.default
) || { estimatedCost: 0, sapPoints: 0 };
const totalEstimatedCost =
(defaultWallsRecommendations.estimatedCost || 0) +
(defaultFloorRecommendations.estimatedCost || 0) +
(defaultVentiliationRecommendations.estimatedCost || 0);
const costMap = {
Walls: defaultWallsRecommendations.estimatedCost,
Floor: defaultFloorRecommendations.estimatedCost,
Ventilation: defaultVentiliationRecommendations.estimatedCost,
};
const totalSapPoints =
(defaultWallsRecommendations.sapPoints || 0) +
(defaultFloorRecommendations.sapPoints || 0) +
(defaultVentiliationRecommendations.sapPoints || 0);
const currentEpcRating = propertyMeta.currentEpcRating;
const currentSapPoints = propertyMeta.currentSapPoints;
const expectedSapPoints = currentSapPoints + totalSapPoints;
const expectedEpcRating = sapToEpc(expectedSapPoints);
return (
<div className="leading-loose tracking-wider">
<div className="flex py-8 text-lg">Recommendations</div>
<div className="mb-4 flex flex-col grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 items-stretch">
<RecommendationCostSummaryCard
totalEstimatedCost={totalEstimatedCost}
totalSapPoints={totalSapPoints}
/>
<table className="text-left bg-green-700 rounded-md text-gray-100">
<tbody>
<tr>
<td className="font-medium pl-4 py-2">Current EPC Rating:</td>
<td className="font-bold pr-2">{currentEpcRating}</td>
</tr>
<tr>
<td className="font-medium pl-4 py-2">Expected EPC Rating:</td>
<td className="font-bold pr-2">{expectedEpcRating}</td>
</tr>
</tbody>
</table>
</div>
<Separator className="mb-4" />
<div className="flex flex-col grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 items-stretch">
{Object.entries(recommendations).map(
([componentType, recommendationData], idx) => {
return (
<RecommendationCard
key={idx}
componentType={componentType}
recommendationData={recommendationData}
/>
);
}
)}
</div>
<RecommendationContainer
recommendations={recommendations}
propertyMeta={propertyMeta}
/>
</div>
);
}