mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-30 12:55:02 +00:00
Adding functionality to recommendations page
This commit is contained in:
parent
057978f50c
commit
ac6ecf3299
7 changed files with 122 additions and 1 deletions
|
|
@ -199,6 +199,12 @@ export default function RecommendationCard({
|
|||
<td>{cardComponent.newUValue}</td>
|
||||
</tr>
|
||||
)}
|
||||
{cardComponent.sapPoints && (
|
||||
<tr>
|
||||
<td className="font-medium">SAP Points:</td>
|
||||
<td>{cardComponent.sapPoints}</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
<RecommendationModal
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export interface PropertyMeta {
|
|||
yearBuilt: number;
|
||||
tenure: string;
|
||||
currentEpcRating: string;
|
||||
currentSapPoints: number;
|
||||
}
|
||||
|
||||
export type Rating = "Very good" | "Good" | "Poor" | "Very poor" | "N/A";
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ export interface ComponentRecommendation {
|
|||
estimatedCost: number;
|
||||
default: boolean;
|
||||
newUValue?: number;
|
||||
sapPoints: number;
|
||||
}
|
||||
|
||||
export interface Recommendation {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export default function DashboardLayout({
|
|||
yearBuilt: 1990,
|
||||
tenure: "Rented (social)",
|
||||
currentEpcRating: "C",
|
||||
currentSapPoints: 78,
|
||||
};
|
||||
if (!propertyId && propertyId !== 0) {
|
||||
throw Error("Invalid propertyId");
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ export default function BuildingPassportHome() {
|
|||
yearBuilt: 1990,
|
||||
tenure: "Rented (social)",
|
||||
currentEpcRating: "C",
|
||||
currentSapPoints: 78,
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,7 +1,30 @@
|
|||
import { Recommendation } from "@/app/db/schema/recommendations";
|
||||
import {
|
||||
ComponentRecommendation,
|
||||
Recommendation,
|
||||
} from "@/app/db/schema/recommendations";
|
||||
import RecommendationCard from "@/app/components/building-passport/RecommendationCard";
|
||||
import { formatNumber, sapToEpc } from "@/app/utils";
|
||||
import { PropertyMeta } from "@/app/db/schema/property";
|
||||
|
||||
export default function Recommendations() {
|
||||
const propertyMeta: PropertyMeta = {
|
||||
id: 1,
|
||||
address: "123 Fake Street",
|
||||
postcode: "AB1 2CD",
|
||||
hasPreConditionReport: true,
|
||||
hasRecommendations: true,
|
||||
createdAt: "2023-07-12 11:51:31.000 +0100",
|
||||
propertyType: "House",
|
||||
builtForm: "Detached",
|
||||
localAuthority: "Birmingham",
|
||||
constituency: "Birmingham",
|
||||
numberOfRooms: 5,
|
||||
yearBuilt: 1990,
|
||||
tenure: "Rented (social)",
|
||||
currentEpcRating: "C",
|
||||
currentSapPoints: 78,
|
||||
};
|
||||
|
||||
const recommendations: Recommendation = {
|
||||
Walls: [
|
||||
{
|
||||
|
|
@ -11,6 +34,7 @@ export default function Recommendations() {
|
|||
estimatedCost: 9_450,
|
||||
default: true,
|
||||
newUValue: 0.29,
|
||||
sapPoints: 11,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
|
|
@ -19,6 +43,7 @@ export default function Recommendations() {
|
|||
estimatedCost: 10_135,
|
||||
default: false,
|
||||
newUValue: 0.28,
|
||||
sapPoints: 12,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
|
|
@ -28,6 +53,7 @@ export default function Recommendations() {
|
|||
estimatedCost: 13_450,
|
||||
default: false,
|
||||
newUValue: 0.25,
|
||||
sapPoints: 14,
|
||||
},
|
||||
],
|
||||
Ventilation: [
|
||||
|
|
@ -37,6 +63,7 @@ export default function Recommendations() {
|
|||
description: "Two decentralised mechanical ventilation units",
|
||||
estimatedCost: 750,
|
||||
default: true,
|
||||
sapPoints: -2,
|
||||
},
|
||||
],
|
||||
Floor: [
|
||||
|
|
@ -47,6 +74,7 @@ export default function Recommendations() {
|
|||
estimatedCost: 3_450,
|
||||
default: true,
|
||||
newUValue: 0.24,
|
||||
sapPoints: 7,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
|
|
@ -55,13 +83,74 @@ export default function Recommendations() {
|
|||
estimatedCost: 4_120,
|
||||
default: true,
|
||||
newUValue: 0.24,
|
||||
sapPoints: 7,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
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 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">
|
||||
<table className="text-left bg-gray-600 rounded-md text-gray-100">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="font-medium pl-4 py-2">Total Cost:</td>
|
||||
<td>{"£" + formatNumber(totalEstimatedCost)}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td className="font-medium pl-4 py-2">
|
||||
Total SAP Points Improvement:
|
||||
</td>
|
||||
<td>{totalSapPoints}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table className="text-left bg-gray-600 rounded-md text-gray-100">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="font-medium pl-4 py-2">Current EPC Rating:</td>
|
||||
<td className="font-bold">{currentEpcRating}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td className="font-medium pl-4 py-2">Expected EPC Rating:</td>
|
||||
<td className="font-bold">{expectedEpcRating}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<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) => {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
export function sapToEpc(sapPoints: number): string {
|
||||
if (sapPoints <= 0 || sapPoints > 100) {
|
||||
throw new Error("SAP points should be between 1 and 100.");
|
||||
}
|
||||
|
||||
if (sapPoints > 91) {
|
||||
return "A";
|
||||
} else if (sapPoints > 80) {
|
||||
return "B";
|
||||
} else if (sapPoints > 69) {
|
||||
return "C";
|
||||
} else if (sapPoints > 55) {
|
||||
return "D";
|
||||
} else if (sapPoints > 39) {
|
||||
return "E";
|
||||
} else if (sapPoints > 21) {
|
||||
return "F";
|
||||
} else {
|
||||
return "G";
|
||||
}
|
||||
}
|
||||
|
||||
export function formatDateTime(dateTimeString: string): string {
|
||||
// Create a new Date object
|
||||
const dateTime = new Date(dateTimeString);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue