diff --git a/src/app/api/upload/retrofit-energy-assessments/route.ts b/src/app/api/upload/retrofit-energy-assessments/route.ts index a1e4b59f..89ce16b7 100644 --- a/src/app/api/upload/retrofit-energy-assessments/route.ts +++ b/src/app/api/upload/retrofit-energy-assessments/route.ts @@ -1,6 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; -import { createS3Client, presignGetUrl } from "@/app/utils/s3"; +import { createS3Client, presignPutUrl } from "@/app/utils/s3"; const Schema = z.object({ path: z.string(), @@ -29,7 +29,7 @@ export async function POST(request: NextRequest) { - const url = await presignGetUrl(s3, { + const url = await presignPutUrl(s3, { bucket, key: path, expiresInSeconds, @@ -45,4 +45,3 @@ export async function POST(request: NextRequest) { } } - 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 a971dde3..05d956f3 100644 --- a/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/page.tsx +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/condition/page.tsx @@ -1,19 +1,57 @@ +import { getPropertyMeta } from "../utils"; +import { getDocuments } from "../documents/page"; +import ConditionReport from "./ConditionReport"; export default async function ConditionPage( - props: { - params: Promise<{ slug: string; propertyId: string }>; - } + props: { params: Promise<{ slug: string; propertyId: string }> } ) { + const params = await props.params; + const propertyId = params.propertyId; + + if (!propertyId || propertyId === "0") { + throw Error("Invalid propertyId"); + } + + const propertyMeta = await getPropertyMeta(propertyId); + const uploadedFiles = await getDocuments(propertyMeta.uprn); + + // keep only ECO condition reports + const conditionReports = + uploadedFiles?.filter((doc: any) => doc.docType === "ECO_CONDITION_REPORT") ?? []; + + // pick latest + const latestReport = + conditionReports.sort( + (a: any, b: any) => + new Date(b.s3FileUploadTimestamp).getTime() - + new Date(a.s3FileUploadTimestamp).getTime() + )[0]; + + console.log(latestReport); + return ( - <> -
-
- This will be here the condition of each room will be +
+ {latestReport ? ( +
+
+ Latest Condition Report +
+ + {/* Pass latestReport down to the client component */} +
-
- Under construction, please contact domna's tech team + ) : ( +
+ Please upload osmosis condition report
-
- + )} +
); } diff --git a/src/app/portfolio/[slug]/building-passport/[propertyId]/documents/page.tsx b/src/app/portfolio/[slug]/building-passport/[propertyId]/documents/page.tsx index f860078b..fee62197 100644 --- a/src/app/portfolio/[slug]/building-passport/[propertyId]/documents/page.tsx +++ b/src/app/portfolio/[slug]/building-passport/[propertyId]/documents/page.tsx @@ -7,7 +7,7 @@ import { type getUploadedFiles } from "@/app/db/surveyDB/schema/surveyDB"; import { EmptyObject } from "react-hook-form"; -async function getDocuments( +export async function getDocuments( uprn: number ): Promise< getUploadedFiles> { const result = surveyDB.query.uploaded_files.findMany({ diff --git a/src/app/utils/s3.ts b/src/app/utils/s3.ts index ebb56308..a75110f7 100644 --- a/src/app/utils/s3.ts +++ b/src/app/utils/s3.ts @@ -22,7 +22,7 @@ export function createS3Client(config?: S3Config) { // Get presigned url from s3 -export type PresignGetOptions = { +export type PresignPutOptions = { bucket: string; key: string; expiresInSeconds?: number; // default 300 @@ -30,9 +30,9 @@ export type PresignGetOptions = { }; /** Presign a GET URL using an existing S3 instance (aws-sdk v2). */ -export async function presignGetUrl( +export async function presignPutUrl( s3: S3, - { bucket, key, expiresInSeconds = 300, ContentType}: PresignGetOptions + { bucket, key, expiresInSeconds = 300, ContentType}: PresignPutOptions ): Promise { return (s3 as any).getSignedUrlPromise("putObject", { Bucket: bucket, @@ -69,4 +69,47 @@ export async function uploadFileToS3({ console.log("File uploaded successfully"); return { success: true }; +} + +export type PresignGetOptions = { + bucket: string; + key: string; + expiresInSeconds?: number; // default 300 + responseContentType?: string; // e.g. application/pdf + responseContentDisposition?: string; // e.g. "inline" or 'attachment; filename="file.pdf"' +}; + +export async function presignGetUrl( + s3: S3, + { bucket, key, expiresInSeconds = 300, responseContentType, responseContentDisposition }: PresignGetOptions +): Promise { + const params: S3.GetObjectRequest & { Expires?: number } = { + Bucket: bucket, + Key: key, + }; + if (responseContentType) { + (params as any).ResponseContentType = responseContentType; + } + if (responseContentDisposition) { + (params as any).ResponseContentDisposition = responseContentDisposition; + } + return (s3 as any).getSignedUrlPromise("getObject", { + ...params, + Expires: expiresInSeconds, + }); +} + +export function parseS3Url(url: string): { bucket: string; key: string } { + if (url.startsWith("s3://")) { + const [, rest] = url.split("s3://"); + const idx = rest.indexOf("/"); + if (idx === -1) throw new Error("Invalid s3 URI"); + return { bucket: rest.slice(0, idx), key: rest.slice(idx + 1) }; + } + const u = new URL(url); + // e.g. retrofit-energy-assessments-dev.s3.eu-west-2.amazonaws.com + const bucket = u.hostname.split(".")[0]; + const key = decodeURIComponent(u.pathname.replace(/^\/+/, "")); + if (!bucket || !key) throw new Error("Cannot parse bucket/key from URL"); + return { bucket, key }; } \ No newline at end of file