mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-30 12:55:02 +00:00
presign api working but want to use temp aws credentials|
This commit is contained in:
parent
8147a0d4b7
commit
07be8eaf84
2 changed files with 84 additions and 19 deletions
49
src/app/api/energy-assessment-documents/route.ts
Normal file
49
src/app/api/energy-assessment-documents/route.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
// pages/api/get-presigned-url.ts
|
||||
import S3 from "aws-sdk/clients/s3";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
|
||||
const PresignedUrlBodySchema = z.object({
|
||||
fileKey: z.string(),
|
||||
});
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const body = await request.json();
|
||||
let validatedBody;
|
||||
|
||||
try {
|
||||
validatedBody = PresignedUrlBodySchema.parse(body);
|
||||
} catch (error) {
|
||||
console.error("Invalid input: ", error);
|
||||
return new NextResponse(JSON.stringify({ msg: "Invalid input" }), {
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const s3 = new S3({
|
||||
signatureVersion: "v4",
|
||||
region: process.env.PRESIGN_AWS_REGION,
|
||||
accessKeyId: process.env.RETROFIT_ENERGY_ASSESSMENTS_AWS_ACCESS_KEY,
|
||||
secretAccessKey: process.env.ENERGY_ASSESSMENTS_AWS_SECRET,
|
||||
});
|
||||
|
||||
const { fileKey } = validatedBody;
|
||||
|
||||
// Presigned URL is valid for 5 minutes
|
||||
const preSignedUrl = await s3.getSignedUrl("getObject", {
|
||||
Bucket: process.env.RETROFIT_ENERGY_ASSESSMENTS_BUCKET,
|
||||
Key: fileKey,
|
||||
Expires: 5 * 60,
|
||||
});
|
||||
|
||||
return new NextResponse(JSON.stringify({ url: preSignedUrl }), {
|
||||
status: 200,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return new NextResponse(JSON.stringify({ msg: "Internal server error" }), {
|
||||
status: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -8,13 +8,14 @@ import {
|
|||
TableRow,
|
||||
} from "@/app/shadcn_components/ui/table";
|
||||
import { BrandBlueButton } from "@/app/components/Buttons";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
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;
|
||||
documentLocation: string; // S3 file key
|
||||
uploadedAt: Date;
|
||||
};
|
||||
|
||||
|
|
@ -35,6 +36,21 @@ const descriptions: { [key in (typeof DocumentType)[number]]: string } = {
|
|||
"Scenario Site Notes": "Site notes from the scenario analysis",
|
||||
};
|
||||
|
||||
// Fetch the presigned URL from the API
|
||||
async function generatePresignedUrl(fileKey: string) {
|
||||
const response = await fetch("/api/energy-assessment-documents", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ fileKey }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to generate presigned URL");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data.url;
|
||||
}
|
||||
|
||||
export const DocumentsTable: React.FC<Props> = ({
|
||||
documents,
|
||||
allowedTypes,
|
||||
|
|
@ -43,38 +59,38 @@ export const DocumentsTable: React.FC<Props> = ({
|
|||
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;
|
||||
// Mutation to handle the presigned URL generation
|
||||
const { mutate: fetchPresignedUrl } = useMutation(
|
||||
async (fileKey: string) => await generatePresignedUrl(fileKey),
|
||||
{
|
||||
onSuccess: (url) => {
|
||||
window.open(url, "_blank"); // Open the file in a new tab
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error("Error generating presigned URL:", error);
|
||||
},
|
||||
}
|
||||
return { ...doc, showDescription };
|
||||
});
|
||||
);
|
||||
|
||||
const handleDownload = (documentLocation: string) => {
|
||||
fetchPresignedUrl(documentLocation); // Generate URL and open in new tab
|
||||
};
|
||||
|
||||
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) => (
|
||||
{relevantDocuments.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] : ""}
|
||||
{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}`)
|
||||
}
|
||||
onClick={() => handleDownload(doc.documentLocation)} // Call the download handler
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue