From f8ca195b835854f7c2a5a35d28fe782326e32f4d Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 10 Apr 2026 22:35:32 +0000 Subject: [PATCH] trying to get the skeleton working --- .../RecommendationContainer.tsx | 3 + .../[propertyId]/plans/[planId]/page.tsx | 117 ++++++++++++------ tsconfig.json | 7 +- 3 files changed, 83 insertions(+), 44 deletions(-) diff --git a/src/app/components/building-passport/RecommendationContainer.tsx b/src/app/components/building-passport/RecommendationContainer.tsx index 4e5ada7..b524e65 100644 --- a/src/app/components/building-passport/RecommendationContainer.tsx +++ b/src/app/components/building-passport/RecommendationContainer.tsx @@ -1,6 +1,7 @@ "use client"; import { useState, useTransition, useMemo } from "react"; +import { useRouter } from "next/navigation"; import { Recommendation, RecommendationType, @@ -97,6 +98,7 @@ export default function RecommendationContainer({ Record >({}); + const router = useRouter(); const [isPending, startTransition] = useTransition(); // Sort: included first, then not-included, then already-installed @@ -160,6 +162,7 @@ export default function RecommendationContainer({ }), ); await updatePlanMetrics(planId, currentSapPoints, slug, propertyId); + router.refresh(); }); } diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/plans/[planId]/page.tsx b/src/app/portfolio/[slug]/building-passport/[propertyId]/plans/[planId]/page.tsx index b5068bc..eb4d51d 100644 --- a/src/app/portfolio/[slug]/building-passport/[propertyId]/plans/[planId]/page.tsx +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/plans/[planId]/page.tsx @@ -17,14 +17,22 @@ import { function getEpcHex(letter: string | null | undefined): string { switch (letter?.toUpperCase()) { - case "A": return "#117d58"; - case "B": return "#2da55c"; - case "C": return "#8dbd40"; - case "D": return "#f7cd14"; - case "E": return "#f3a96a"; - case "F": return "#ef8026"; - case "G": return "#e41e3b"; - default: return "#9ca3af"; + case "A": + return "#117d58"; + case "B": + return "#2da55c"; + case "C": + return "#8dbd40"; + case "D": + return "#f7cd14"; + case "E": + return "#f3a96a"; + case "F": + return "#ef8026"; + case "G": + return "#e41e3b"; + default: + return "#9ca3af"; } } @@ -34,7 +42,15 @@ const EPC_LETTERS = ["G", "F", "E", "D", "C", "B", "A"]; // Returns the horizontal centre position (%) of each EPC band in the 7-segment bar function epcToBandCenter(letter: string | null | undefined): number { if (!letter) return 0; - const map: Record = { G: 0, F: 1, E: 2, D: 3, C: 4, B: 5, A: 6 }; + const map: Record = { + G: 0, + F: 1, + E: 2, + D: 3, + C: 4, + B: 5, + A: 6, + }; const idx = map[letter.toUpperCase()] ?? 0; return ((idx + 0.5) / 7) * 100; } @@ -44,12 +60,13 @@ export default async function PlanDetail(props: { }) { const params = await props.params; const propertyMeta = await getPropertyMeta(params.propertyId); - const [recommendations, planMeta, installedMeasures, scenarioData] = await Promise.all([ - getRecommendations(params.planId), - getPlanMeta(params.planId), - getInstalledMeasuresByUprn(propertyMeta.uprn), - getScenario(params.planId), - ]); + const [recommendations, planMeta, installedMeasures, scenarioData] = + await Promise.all([ + getRecommendations(params.planId), + getPlanMeta(params.planId), + getInstalledMeasuresByUprn(propertyMeta.uprn), + getScenario(params.planId), + ]); const currentEpc = propertyMeta.currentEpcRating; const targetEpc = @@ -59,7 +76,10 @@ export default async function PlanDetail(props: { const valuationLabel = (() => { if (planMeta.valuationIncreaseAverage) return `+${planMeta.valuationIncreaseAverage.toFixed(1)}%`; - if (planMeta.valuationIncreaseLowerBound && planMeta.valuationIncreaseUpperBound) + if ( + planMeta.valuationIncreaseLowerBound && + planMeta.valuationIncreaseUpperBound + ) return `+${planMeta.valuationIncreaseLowerBound.toFixed(0)}–${planMeta.valuationIncreaseUpperBound.toFixed(0)}%`; if (planMeta.valuationIncrease) return `+${planMeta.valuationIncrease.toFixed(1)}%`; @@ -68,21 +88,15 @@ export default async function PlanDetail(props: { return (
- {/* ── Header ─────────────────────────────────────────────────── */}
-

+

Plan Details: {planMeta.name ?? "Retrofit Plan"}

-

- A comprehensive transformation strategy designed to improve energy - efficiency, reduce running costs, and maximise property value. -

{/* ── Executive Summary Bento ──────────────────────────────────── */}
- {/* EPC Rating card — redesigned with SAP IMPROVEMENT label */}
@@ -92,7 +106,9 @@ export default async function PlanDetail(props: { {/* Current → Target letter badges */}
- Current + + Current + - +
- Target + + Target + -

@@ -221,13 +246,11 @@ export default async function PlanDetail(props: { Valuation Boost

-
{/* ── Financial + Recommendations ──────────────────────────────── */}
- {/* Left: Financial Overview — sticky so it stays visible while scrolling recs */}

@@ -251,7 +274,8 @@ export default async function PlanDetail(props: { Contingency

- {planMeta.contingencyCost != null && planMeta.contingencyCost > 0 + {planMeta.contingencyCost != null && + planMeta.contingencyCost > 0 ? `£${formatNumber(planMeta.contingencyCost)}` : "—"}

@@ -261,7 +285,9 @@ export default async function PlanDetail(props: {

- A contingency buffer is added on top of estimated costs to account for unexpected variations in materials or labour. Rates vary per measure type. + A contingency buffer is added on top of estimated costs to + account for unexpected variations in materials or labour. + Rates vary per measure type.

@@ -286,15 +312,18 @@ export default async function PlanDetail(props: {
  • · - Costs modelled using current market rates and SAP 10.2 methodology. + Costs modelled using current market rates and SAP 10.2 + methodology.
  • · - Annual savings are projected based on typical occupancy patterns. + Annual savings are projected based on typical occupancy + patterns.
  • · - Final quotes confirmed after a technical survey of the property. + Final quotes confirmed after a technical survey of the + property.
@@ -310,17 +339,23 @@ export default async function PlanDetail(props: { {scenarioData.name && (
Scenario - {scenarioData.name} + + {scenarioData.name} +
)}
Housing type - {scenarioData.housingType} + + {scenarioData.housingType} +
{scenarioData.budget != null && (
Budget - £{formatNumber(scenarioData.budget)} + + £{formatNumber(scenarioData.budget)} +
)} {scenarioData.goal && ( @@ -328,7 +363,9 @@ export default async function PlanDetail(props: { Goal {scenarioData.goal} - {scenarioData.goalValue ? ` → ${scenarioData.goalValue}` : ""} + {scenarioData.goalValue + ? ` → ${scenarioData.goalValue}` + : ""}

)} diff --git a/tsconfig.json b/tsconfig.json index 6468155..590486f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,7 @@ { "compilerOptions": { "allowSyntheticDefaultImports": true, - "target": "es5", - // "target": "ESNext", + "target": "ESNext", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, @@ -10,8 +9,8 @@ "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", + "module": "preserve", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve",