From e4879ef6397a6b4c6256467f4bff0a9459ba6404 Mon Sep 17 00:00:00 2001 From: zmeyer44 Date: Wed, 18 Oct 2023 09:05:59 -0400 Subject: [PATCH] adding image upload --- .env | 7 +++ app/api/upload/route.ts | 28 +++++++++ bun.lockb | Bin 326301 -> 332809 bytes lib/actions/upload.ts | 19 ++++++ lib/clients/s3.ts | 9 +++ lib/hooks/useImageUpload.tsx | 110 +++++++++++++++++++++++++++++++++++ package.json | 1 + 7 files changed, 174 insertions(+) create mode 100644 .env create mode 100644 app/api/upload/route.ts create mode 100644 lib/actions/upload.ts create mode 100644 lib/clients/s3.ts create mode 100644 lib/hooks/useImageUpload.tsx diff --git a/.env b/.env new file mode 100644 index 0000000..0883d88 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +# S3 data storage +S3_BUCKET_NAME="flockstr" +MY_AWS_ACCESS_KEY="AKIAT2UDOJMC6K25RFFN" +MY_AWS_SECRET_KEY="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" +REGION="us-east-1" +S3_BUCKET_URL="https://flockstr.s3.amazonaws.com" +NEXT_PUBLIC_S3_BUCKET_URL="https://flockstr.s3.amazonaws.com" \ No newline at end of file diff --git a/app/api/upload/route.ts b/app/api/upload/route.ts new file mode 100644 index 0000000..75dd052 --- /dev/null +++ b/app/api/upload/route.ts @@ -0,0 +1,28 @@ +import { nanoid } from "nanoid"; +import { NextResponse } from "next/server"; +import { generateV4UploadSignedUrl } from "@/lib/actions/upload"; +import { z } from "zod"; + +const BodySchema = z.object({ + folderName: z.string().optional(), + fileType: z.string(), +}); + +// export const runtime = "edge"; +async function handler(req: Request) { + // const session = await getSession(); + // if (!session?.user.id) { + // return new Response("Unauthorized", { + // status: 401, + // }); + // } + const rawJson = await req.json(); + const body = BodySchema.parse(rawJson); + const { folderName, fileType } = body; + const filename = (`${folderName}/` ?? "") + nanoid(); + const signedUrl = await generateV4UploadSignedUrl(filename, fileType); + + return NextResponse.json({ ...signedUrl, fileName: filename }); +} + +export { handler as POST }; diff --git a/bun.lockb b/bun.lockb index ed569d707c31c41cfc7634ca17c0c816b6206dfe..bf5558d7a104ab73e9406bb0aa71ddde3c2220bc 100755 GIT binary patch delta 58199 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 delta 54793 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 PRqrhgi;sCH`PBapvCz;x diff --git a/lib/actions/upload.ts b/lib/actions/upload.ts new file mode 100644 index 0000000..b4b3046 --- /dev/null +++ b/lib/actions/upload.ts @@ -0,0 +1,19 @@ +import { s3Client } from "@/lib/clients/s3"; + +export async function generateV4UploadSignedUrl( + fileName: string, + fileType: string, +) { + const preSignedUrl = await s3Client.getSignedUrl("putObject", { + Bucket: process.env.S3_BUCKET_NAME, + Key: fileName, + ContentType: fileType, + Expires: 5 * 60, + }); + + console.log("PresignedUrl", preSignedUrl); + + return { url: preSignedUrl }; +} + +export default generateV4UploadSignedUrl; diff --git a/lib/clients/s3.ts b/lib/clients/s3.ts new file mode 100644 index 0000000..9538639 --- /dev/null +++ b/lib/clients/s3.ts @@ -0,0 +1,9 @@ +import S3 from "aws-sdk/clients/s3"; +const s3Client = new S3({ + signatureVersion: "v4", + region: process.env.REGION, + accessKeyId: process.env.MY_AWS_ACCESS_KEY, + secretAccessKey: process.env.MY_AWS_SECRET_KEY, +}); + +export { s3Client }; diff --git a/lib/hooks/useImageUpload.tsx b/lib/hooks/useImageUpload.tsx new file mode 100644 index 0000000..4da4767 --- /dev/null +++ b/lib/hooks/useImageUpload.tsx @@ -0,0 +1,110 @@ +"use client"; +import { useState, ReactNode, useRef } from "react"; +import { z } from "zod"; +import { createZodFetcher } from "zod-fetch"; + +const fetchWithZod = createZodFetcher(); + +const PresignedPostSchema = z.object({ + url: z.string(), + fileName: z.string(), +}); + +const useImageUpload = (folderName?: string) => { + const [status, setStatus] = useState< + "empty" | "uploading" | "success" | "error" + >("empty"); + const [imageUrl, setImageUrl] = useState(); + const [imagePreview, setImagePreview] = useState(); + + const uploadImage = async (file: File, folderName?: string) => { + if (!file) return; + try { + const presignedPost = await fetchWithZod( + // The schema you want to validate with + PresignedPostSchema, + // Any parameters you would usually pass to fetch + "/api/upload", + { + method: "POST", + body: JSON.stringify({ folderName, fileType: file.type }), + }, + ); + + const { url, fileName } = presignedPost; + + if (!url) return; + + const result = await fetch(url, { + method: "PUT", + body: file, + headers: { + "Content-Type": file.type, + }, + }); + + if (result.ok) { + setStatus("success"); + const imageUrl = `${process.env.NEXT_PUBLIC_S3_BUCKET_URL}/${fileName}`; + setImageUrl(imageUrl); + setImagePreview(imageUrl); + return imageUrl; + } + return; + } catch (err) { + setStatus("error"); + console.log("ERROR", err); + } + }; + + const onImageChange = (e: React.FormEvent) => { + const file = e.currentTarget.files?.[0]; + if (!file) return; + setStatus("uploading"); + uploadImage(file, folderName); + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = async (readerEvent) => { + setImagePreview(readerEvent?.target?.result as string); + }; + }; + + const ImageUploadButton = ({ children }: { children: ReactNode }) => { + const inputFileRef = useRef(null); + function onButtonClick() { + if (inputFileRef.current) { + inputFileRef.current!.click(); + } + } + return ( + <> + + + + ); + }; + + const clear = () => { + setStatus("empty"); + setImageUrl(null); + setImagePreview(null); + }; + + return { + imagePreview, + status, + imageUrl, + ImageUploadButton, + clear, + }; +}; + +export default useImageUpload; diff --git a/package.json b/package.json index 8f32124..5165ca3 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", "@tailwindcss/container-queries": "^0.1.1", + "aws-sdk": "^2.1475.0", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", "cmdk": "^0.2.0",