mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
Added the documents table to the app - needs api setup to generate pre-signed urls
This commit is contained in:
parent
b550c47e1a
commit
8147a0d4b7
5 changed files with 191 additions and 8 deletions
|
|
@ -18,3 +18,22 @@ export function TanButton({
|
|||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function BrandBlueButton({
|
||||
label,
|
||||
onClick,
|
||||
}: {
|
||||
label: string;
|
||||
onClick: Dispatch<SetStateAction<any>>;
|
||||
}) {
|
||||
// General tan colored button
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex justify-center rounded-md border border-transparent bg-brandblue px-4 py-2 text-sm font-medium text-white hover:bg-hoverblue focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
||||
onClick={onClick}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,3 +195,11 @@ export const energyAssessmentDocuments = pgTable(
|
|||
|
||||
// Types for the new table
|
||||
export type EnergyAssessment = InferModel<typeof energyAssessment, "select">;
|
||||
export type EnergyAssessmentScenario = InferModel<
|
||||
typeof energyAssessmentScenarios,
|
||||
"select"
|
||||
>;
|
||||
export type EnergyAssessmentDocument = InferModel<
|
||||
typeof energyAssessmentDocuments,
|
||||
"select"
|
||||
>;
|
||||
|
|
|
|||
|
|
@ -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<Props> = ({
|
||||
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 (
|
||||
<Table className="min-w-full divide-y divide-gray-200 shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
|
||||
<TableBody className="bg-white divide-y divide-gray-200">
|
||||
{processedDocuments.map((doc) => (
|
||||
<TableRow key={doc.id.toString()}>
|
||||
<TableCell className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
|
||||
{doc.documentType}
|
||||
</TableCell>
|
||||
<TableCell className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{doc.showDescription ? descriptions[doc.documentType] : ""}
|
||||
</TableCell>
|
||||
<TableCell className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<BrandBlueButton
|
||||
label="Download"
|
||||
onClick={() =>
|
||||
console.log(`Downloading ${doc.documentLocation}`)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
|
|
@ -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 (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<div className="text-center text-gray-500">
|
||||
<div className="text-2xl font-semibold mb-4">
|
||||
This property does not have a Domna energy assessment
|
||||
</div>
|
||||
<p className="text-lg">Please check back later for updates.</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const documents = await getEnergyAssessmentDocuments(ea.id);
|
||||
|
||||
const table1AllowedTypes = [
|
||||
"EPR",
|
||||
"Condition Report",
|
||||
"Evidence Report",
|
||||
"Summary Information",
|
||||
"Floor Plan",
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<div className="text-center text-gray-500">
|
||||
<div className="text-2xl font-semibold mb-4">
|
||||
This property does not have a Domna energy assessement
|
||||
</div>
|
||||
<p className="text-lg">Please check back later for updates.</p>
|
||||
<div>
|
||||
<div className="flex pt-8 text-lg">Core Survey Documents</div>
|
||||
<div className="py-4 max-w-8xl">
|
||||
<DocumentsTable
|
||||
documents={documents}
|
||||
allowedTypes={table1AllowedTypes}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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<EnergyAssessment> {
|
||||
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<EnergyAssessmentDocument[]> {
|
||||
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<Recommendation[]> {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue