From 8147a0d4b738dee655ee115de4b7de467c3b53fb Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 9 Sep 2024 12:15:55 +0100 Subject: [PATCH] Added the documents table to the app - needs api setup to generate pre-signed urls --- src/app/components/Buttons.tsx | 19 +++++ src/app/db/schema/energy_assessments.ts | 8 ++ .../energy-assessment/DocumentsTable.tsx | 85 +++++++++++++++++++ .../[propertyId]/energy-assessment/page.tsx | 48 +++++++++-- .../building-passport/[propertyId]/utils.ts | 39 ++++++++- 5 files changed, 191 insertions(+), 8 deletions(-) create mode 100644 src/app/portfolio/[slug]/building-passport/[propertyId]/energy-assessment/DocumentsTable.tsx diff --git a/src/app/components/Buttons.tsx b/src/app/components/Buttons.tsx index 7da4ab2..a568800 100644 --- a/src/app/components/Buttons.tsx +++ b/src/app/components/Buttons.tsx @@ -18,3 +18,22 @@ export function TanButton({ ); } + +export function BrandBlueButton({ + label, + onClick, +}: { + label: string; + onClick: Dispatch>; +}) { + // General tan colored button + return ( + + ); +} diff --git a/src/app/db/schema/energy_assessments.ts b/src/app/db/schema/energy_assessments.ts index 44736f7..6f2a133 100644 --- a/src/app/db/schema/energy_assessments.ts +++ b/src/app/db/schema/energy_assessments.ts @@ -195,3 +195,11 @@ export const energyAssessmentDocuments = pgTable( // Types for the new table export type EnergyAssessment = InferModel; +export type EnergyAssessmentScenario = InferModel< + typeof energyAssessmentScenarios, + "select" +>; +export type EnergyAssessmentDocument = InferModel< + typeof energyAssessmentDocuments, + "select" +>; diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/energy-assessment/DocumentsTable.tsx b/src/app/portfolio/[slug]/building-passport/[propertyId]/energy-assessment/DocumentsTable.tsx new file mode 100644 index 0000000..49fae6e --- /dev/null +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/energy-assessment/DocumentsTable.tsx @@ -0,0 +1,85 @@ +"use client"; + +import React from "react"; +import { + Table, + TableBody, + TableCell, + TableRow, +} from "@/app/shadcn_components/ui/table"; +import { BrandBlueButton } from "@/app/components/Buttons"; +import { DocumentType } from "@/app/db/schema/energy_assessments"; + +// Use the type directly from the array +type Document = { + id: bigint; + documentType: (typeof DocumentType)[number]; // Create a union type from the array + documentLocation: string; + uploadedAt: Date; +}; + +type Props = { + documents: Document[]; + allowedTypes: (typeof DocumentType)[number][]; // Use the union type for allowedTypes as well +}; + +// Descriptions based on the document types +const descriptions: { [key in (typeof DocumentType)[number]]: string } = { + EPR: "Contains current energy performance of your home, and recommendations for improvement", + "Condition Report": + "Detailed report on property condition, including photographs", + "Evidence Report": "Additional photographic evidence from the survey", + "Summary Information": "Summarized survey outputs and site notes", + "Floor Plan": "Layout of the property and room/window dimensions", + "Scenario Draft EPC": "Draft EPC based on a given scenario", + "Scenario Site Notes": "Site notes from the scenario analysis", +}; + +export const DocumentsTable: React.FC = ({ + documents, + allowedTypes, +}) => { + const relevantDocuments = documents.filter((doc) => + allowedTypes.includes(doc.documentType) + ); + + // Track displayed descriptions + const displayedDescriptions: Record<(typeof DocumentType)[number], boolean> = + allowedTypes.reduce((acc, type) => { + acc[type] = false; + return acc; + }, {} as Record<(typeof DocumentType)[number], boolean>); + + const processedDocuments = relevantDocuments.map((doc) => { + const showDescription = !displayedDescriptions[doc.documentType]; + if (showDescription) { + displayedDescriptions[doc.documentType] = true; + } + return { ...doc, showDescription }; + }); + + return ( + + + {processedDocuments.map((doc) => ( + + + {doc.documentType} + + + {doc.showDescription ? descriptions[doc.documentType] : ""} + + + + console.log(`Downloading ${doc.documentLocation}`) + } + /> + + + ))} + +
+ ); +}; diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/energy-assessment/page.tsx b/src/app/portfolio/[slug]/building-passport/[propertyId]/energy-assessment/page.tsx index 925a9e2..936f80b 100644 --- a/src/app/portfolio/[slug]/building-passport/[propertyId]/energy-assessment/page.tsx +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/energy-assessment/page.tsx @@ -1,17 +1,51 @@ +import { + getEnergyAssessment, + getEnergyAssessmentDocuments, + getPropertyMeta, +} from "../utils"; + +// EnergyAssessmentsPage.tsx +import { DocumentsTable } from "./DocumentsTable"; + export default async function EnergyAssessmentsPage({ params, }: { params: { slug: string; propertyId: string }; }) { - // If there's no solar data, we cannot display the page + const propertyMeta = await getPropertyMeta(params.propertyId); + const ea = await getEnergyAssessment(propertyMeta.uprn); + + if (!ea) { + return ( +
+
+
+ This property does not have a Domna energy assessment +
+

Please check back later for updates.

+
+
+ ); + } + + const documents = await getEnergyAssessmentDocuments(ea.id); + + const table1AllowedTypes = [ + "EPR", + "Condition Report", + "Evidence Report", + "Summary Information", + "Floor Plan", + ]; return ( -
-
-
- This property does not have a Domna energy assessement -
-

Please check back later for updates.

+
+
Core Survey Documents
+
+
); diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/utils.ts b/src/app/portfolio/[slug]/building-passport/[propertyId]/utils.ts index d33e968..4e0f136 100644 --- a/src/app/portfolio/[slug]/building-passport/[propertyId]/utils.ts +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/utils.ts @@ -1,4 +1,3 @@ -import { recommendation } from "../../../../db/schema/recommendations"; import { Recommendation, planRecommendations, @@ -18,11 +17,49 @@ import { import { plan, Plan } from "@/app/db/schema/recommendations"; import { getRating } from "@/app/utils"; import { eq, desc } from "drizzle-orm"; +import { + energyAssessment, + EnergyAssessment, + energyAssessmentDocuments, + EnergyAssessmentDocument, +} from "@/app/db/schema/energy_assessments"; type RecommendationList = { recommendation: Recommendation; }[]; +export async function getEnergyAssessment( + uprn: number +): Promise { + const data = await db.query.energyAssessment.findFirst({ + where: eq(energyAssessment.uprn, BigInt(uprn)), + }); + + if (!data) { + // If there's no data, we return an empty array. This signififies that no energy assessment has been conducted + return {} as EnergyAssessment; + } + + return data; +} + +export async function getEnergyAssessmentDocuments( + energyAssessmentId: bigint +): Promise { + const data = await db.query.energyAssessmentDocuments.findMany({ + where: eq( + energyAssessmentDocuments.energyAssessmentId, + BigInt(energyAssessmentId) + ), + }); + + if (!data) { + throw new Error("Network response was not ok"); + } + + return data; +} + export async function getRecommendations( planId: string ): Promise {