From fb7adc39986eda590049cb7a34a2386b804463fc Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Mon, 2 Feb 2026 15:26:00 +0000 Subject: [PATCH] move types to dedicated files --- .../condition/components/ElementTable.tsx | 21 +---------- .../condition/components/RenewalsTimeline.tsx | 0 .../[propertyId]/condition/page.tsx | 35 ++++++++++++++----- .../condition/types/aspectCondition.ts | 11 ++++++ .../[propertyId]/condition/types/element.ts | 9 +++++ .../[propertyId]/condition/types/survey.ts | 9 +++++ .../condition/viewModels/renewal.ts | 10 ++++++ 7 files changed, 67 insertions(+), 28 deletions(-) create mode 100644 src/app/portfolio/[slug]/building-passport/[propertyId]/condition/components/RenewalsTimeline.tsx create mode 100644 src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/aspectCondition.ts create mode 100644 src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/element.ts create mode 100644 src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/survey.ts create mode 100644 src/app/portfolio/[slug]/building-passport/[propertyId]/condition/viewModels/renewal.ts diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/components/ElementTable.tsx b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/components/ElementTable.tsx index 98913b92..bfb1db06 100644 --- a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/components/ElementTable.tsx +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/components/ElementTable.tsx @@ -9,29 +9,10 @@ import { TableHead, TableCell, } from "@/app/shadcn_components/ui/table"; +import { Element } from "../types/element"; import { ASPECT_TYPE_LABELS, ELEMENT_TYPE_LABELS } from "../constants"; -export type AspectCondition = { - id: string; - elementId: string; - aspectType: string; - aspectInstance: number; - value: string | null; - quantity: number | null; - installDate: string | null; - renewalYear: number | null; - comments: string | null; -}; - -export type Element = { - id: string; - surveyId: string; - elementType: string; - elementInstance: number; - aspects: AspectCondition[]; -}; - export type ElementGroup = { elementType: string; elementInstance: number; diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/components/RenewalsTimeline.tsx b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/components/RenewalsTimeline.tsx new file mode 100644 index 00000000..e69de29b diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/page.tsx b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/page.tsx index 081ed021..87059775 100644 --- a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/page.tsx +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/page.tsx @@ -1,6 +1,9 @@ import { getPropertyMeta } from "../utils"; import { db } from "@/app/db/db"; -import ElementTable, { ElementGroup, Element } from "./components/ElementTable"; +import { Element } from "./types/element"; +import { Survey } from "./types/survey"; +import { Renewal } from "./viewModels/renewal"; +import ElementTable, { ElementGroup } from "./components/ElementTable"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/app/shadcn_components/ui/tabs"; type ConditionPageProps = { @@ -10,14 +13,11 @@ type ConditionPageProps = { }; }; -type Survey = { - id: string; - uprn: string; - date: string; - source: string; - elements: Element[]; +type RenewalTimelineProps = { + renewals: Renewal[]; }; + function serializeBigInt(obj: unknown): Survey[] { return JSON.parse( JSON.stringify(obj, (_key, value) => (typeof value === "bigint" ? value.toString() : value)) @@ -39,6 +39,23 @@ async function getConditionsByUprn(uprn: number): Promise { return serializeBigInt(surveys); } +function buildRenewals(elements: Element[]): Renewal[] { + return elements.flatMap(element => + element.aspects + .filter(aspect => aspect.renewalYear !== null) + .map(aspect => ({ + id: `${element.id}-${aspect.id}`, + elementId: element.id, + aspectId: aspect.id, + renewalYear: aspect.renewalYear!, + elementType: element.elementType, + aspectType: aspect.aspectType, + label: `${element.elementType} ${element.elementInstance} – ${aspect.aspectType}`, + comments: aspect.comments, + })) + ); +} + export default async function Condition({ params }: ConditionPageProps) { const { propertyId } = params; const propertyMeta = await getPropertyMeta(propertyId); @@ -49,7 +66,7 @@ export default async function Condition({ params }: ConditionPageProps) { return
No survey data found for this property.
; } - const survey = surveys[0]; // assuming one survey per property + const survey = surveys[0]; // TODO: handle more than one survey per property const groupedElements: ElementGroup[] = Object.values( survey.elements.reduce((acc: Record, el: Element) => { @@ -64,6 +81,8 @@ export default async function Condition({ params }: ConditionPageProps) { }, {}) ); + + return (
diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/aspectCondition.ts b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/aspectCondition.ts new file mode 100644 index 00000000..bc886214 --- /dev/null +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/aspectCondition.ts @@ -0,0 +1,11 @@ +export type AspectCondition = { + id: string; + elementId: string; + aspectType: string; + aspectInstance: number; + value: string | null; + quantity: number | null; + installDate: string | null; + renewalYear: number | null; + comments: string | null; +}; diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/element.ts b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/element.ts new file mode 100644 index 00000000..1914d236 --- /dev/null +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/element.ts @@ -0,0 +1,9 @@ +import { AspectCondition } from "./aspectCondition"; + +export type Element = { + id: string; + surveyId: string; + elementType: string; + elementInstance: number; + aspects: AspectCondition[]; +}; \ No newline at end of file diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/survey.ts b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/survey.ts new file mode 100644 index 00000000..d5517f00 --- /dev/null +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/types/survey.ts @@ -0,0 +1,9 @@ +import { Element } from "./element"; + +export type Survey = { + id: string; + uprn: string; + date: string; + source: string; + elements: Element[]; +}; \ No newline at end of file diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/viewModels/renewal.ts b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/viewModels/renewal.ts new file mode 100644 index 00000000..1ea24cfb --- /dev/null +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/viewModels/renewal.ts @@ -0,0 +1,10 @@ + export type Renewal = { + id: string; // unique for timeline + elementId: string; + aspectId: string; + label: string; // what user sees + renewalYear: number; + elementType: string; + aspectType: string; + comments?: string | null; + }; \ No newline at end of file