This commit is contained in:
Jun-te kim 2025-08-22 18:35:12 +00:00
parent dc675a02c9
commit c802931b5b
4 changed files with 98 additions and 18 deletions

View file

@ -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) {
}
}

View file

@ -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 (
<>
<div className="mt-6">
<div className="flex items-center justify-between py-4 px-6 bg-brandblue text-white font-semibold text-lg rounded-md">
This will be here the condition of each room will be
<div className="mt-6">
{latestReport ? (
<div className="space-y-4">
<div className="flex items-center justify-between py-4 px-6 bg-brandblue text-white font-semibold text-lg rounded-md">
Latest Condition Report
</div>
{/* Pass latestReport down to the client component */}
<ConditionReport
latestReport={{
id: latestReport.id,
s3FileUri: latestReport.s3FileUri,
s3JsonUri: latestReport.s3JsonUri,
s3FileUploadTimestamp: latestReport.s3FileUploadTimestamp,
}}
/>
</div>
<div className="py-4">
Under construction, please contact domna's tech team
) : (
<div className="flex items-center justify-center py-8 px-6 bg-red-100 text-red-700 font-medium rounded-md">
Please upload osmosis condition report
</div>
</div>
</>
)}
</div>
);
}

View file

@ -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({

View file

@ -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<string> {
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<string> {
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 };
}