From fd7c1578ef428178f854fef49e9d57f6bdb5667f Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 15 Sep 2023 11:53:58 +0100 Subject: [PATCH] set up presigned urls api --- .../api/upload/due-considerations/route.ts | 57 +++++++++++++++++++ .../due-considerations/SelectFolder.tsx | 31 +--------- src/app/due-considerations/page.tsx | 21 ++++--- 3 files changed, 72 insertions(+), 37 deletions(-) create mode 100644 src/app/api/upload/due-considerations/route.ts diff --git a/src/app/api/upload/due-considerations/route.ts b/src/app/api/upload/due-considerations/route.ts new file mode 100644 index 0000000..4efabc5 --- /dev/null +++ b/src/app/api/upload/due-considerations/route.ts @@ -0,0 +1,57 @@ +import S3 from "aws-sdk/clients/s3"; +import { NextRequest, NextResponse } from "next/server"; +import { z } from "zod"; + +const presignedUrlSchema = z.object({ + files: z.array( + z.object({ + fileKey: z.string(), + contentType: z.string(), + }) + ), +}); + +export async function POST(request: NextRequest) { + const body = await request.json(); + let validatedBody; + + try { + validatedBody = presignedUrlSchema.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.PRSIGN_AWS_ACCESS_KEY, + secretAccessKey: process.env.PRESIGN_AWS_SECRET_KEY, + }); + + const { files } = validatedBody; + // generate a presigned URL for each file + const preSignedUrls = await Promise.all( + files.map(async (file: any) => { + return s3.getSignedUrlPromise("putObject", { + Bucket: process.env.RETOFIT_PLAN_INPUT_BUCKET_NAME, + Key: file.fileKey, + ContentType: file.contentType, + Expires: 5 * 60, + }); + }) + ); + + return new NextResponse(JSON.stringify({ url: preSignedUrls }), { + status: 200, + }); + } catch (error) { + console.error(error); + return new NextResponse(JSON.stringify({ msg: "Internal server error" }), { + status: 500, + }); + } +} diff --git a/src/app/components/due-considerations/SelectFolder.tsx b/src/app/components/due-considerations/SelectFolder.tsx index a13c458..57cef91 100644 --- a/src/app/components/due-considerations/SelectFolder.tsx +++ b/src/app/components/due-considerations/SelectFolder.tsx @@ -4,41 +4,14 @@ import { Input } from "@/app/shadcn_components/ui/input"; import { Label } from "@/app/shadcn_components/ui/label"; export function SelectFolder({ - handleButtonDisabled, - setUploadMessage, - setFile, + handleOnChange, }: { - handleButtonDisabled: (file?: File[]) => void; - setUploadMessage: (message: string) => void; - setFile: (file: File[]) => void; + handleOnChange: (e: React.ChangeEvent) => void; }) { - function handleOnChange(e: React.ChangeEvent) { - if (e.target.files && e.target.files.length === 3) { - const files = Array.from(e.target.files); - const extensions = files.map((file) => - file.name.split(".").pop()?.toLowerCase() - ); - - if ( - extensions.includes("xml") && - extensions.includes("pdf") && - extensions.includes("docx") - ) { - setFile(files); // You would need to update setFile to accept an array of files - handleButtonDisabled(files); // Similarly, update handleButtonDisabled to work with multiple files - } else { - setUploadMessage("Please select a .xml, .pdf, and .docx file."); - } - } else { - setUploadMessage("Please select exactly 3 files."); - } - } - return ( ([]); + const [files, setFile] = useState([]); const [buttonDisabled, setButtonDisabled] = useState(true); const [uploadMessage, setUploadMessage] = useState(""); - function handleButtonDisabled(files?: File[]) { - if (files && files.length === 3) { - const extensions = files.map((file) => + function handleOnChange(e: React.ChangeEvent) { + if (e.target.files && e.target.files.length === 3) { + const filesArray = Array.from(e.target.files); + const extensions = filesArray.map((file) => file.name.split(".").pop()?.toLowerCase() ); @@ -20,7 +21,9 @@ export default function DueConsiderationsHome() { extensions.includes("pdf") && extensions.includes("docx") ) { + setFile(files); setButtonDisabled(false); + setUploadMessage(""); } else { setUploadMessage("Please select a .xml, .pdf, and .docx file."); setButtonDisabled(true); @@ -31,6 +34,10 @@ export default function DueConsiderationsHome() { } } + function onUpload() { + // We want to upload the files to s3 via a presigned link + } + return (
@@ -45,10 +52,7 @@ export default function DueConsiderationsHome() {
- +
@@ -56,6 +60,7 @@ export default function DueConsiderationsHome() {