From 4a03135f2d7f6536d56ab7ec3da60342d94fc8f0 Mon Sep 17 00:00:00 2001 From: Brandon Egger <brandonegger64@gmail.com> Date: Thu, 24 Aug 2023 11:29:05 -0500 Subject: [PATCH] replace file uploading to integrate with the new blob image data through trpc --- src/components/admin/resources/form.tsx | 59 +++++++++---------------- src/pages/resources/[id]/edit.tsx | 27 ----------- 2 files changed, 22 insertions(+), 64 deletions(-) diff --git a/src/components/admin/resources/form.tsx b/src/components/admin/resources/form.tsx index 4efd041..760c97d 100644 --- a/src/components/admin/resources/form.tsx +++ b/src/components/admin/resources/form.tsx @@ -41,7 +41,6 @@ import Modal from "react-modal"; import { type RouterInputs } from "~/utils/api"; import { PlatformLinkButton } from "~/pages/resources/[id]"; import { ResourcePhoto } from "~/components/ResourcePhoto"; -import Image from "next/image"; // Required for accessibility // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access @@ -54,14 +53,10 @@ export type ResourceUpdateInput = RouterInputs["auditoryResource"]["update"]; * * File needs to be path relative to resource_logos/ */ -const SelectImageInput = ({ - resource, - setIconFile, -}: { - resource?: ResourceUpdateInput; - setIconFile: (file: File) => void; -}) => { - const [previewImg, setPreviewImg] = useState<string | undefined>(undefined); +const SelectImageInput = ({ resource }: { resource?: ResourceUpdateInput }) => { + const { setValue, setError, watch } = useFormContext<ResourceUpdateInput>(); + const photo = watch("photo"); + const icon = watch("icon"); const onChange = (event: ChangeEvent<HTMLInputElement>) => { if (!event.target.files || !event.target.files[0]) { @@ -71,11 +66,17 @@ const SelectImageInput = ({ const file = event.target.files[0]; const reader = new FileReader(); reader.onloadend = () => { - setPreviewImg(reader.result as string); - }; - reader.readAsDataURL(file); + if (!reader.result || !(reader.result instanceof ArrayBuffer)) { + setError("photo.data", { message: "Failed uploading the photo data." }); + return; + } - setIconFile(file); + setValue("photo", { + name: file.name, + data: Buffer.from(reader.result), + }); + }; + reader.readAsArrayBuffer(file); }; return ( @@ -84,21 +85,12 @@ const SelectImageInput = ({ htmlFor="resource-image-file" className="bg-whit group relative cursor-pointer overflow-hidden rounded-xl border border-neutral-400 drop-shadow-lg" > - {!previewImg ? ( - <ResourcePhoto - name={resource?.name ?? "n/a"} - photo={resource?.photo ?? null} - src={resource?.icon} - /> - ) : ( - <Image - className="w-full" - src={previewImg ?? ""} - alt={`resource logo`} - width={512} - height={512} - /> - )} + <ResourcePhoto + name={resource?.name ?? "n/a"} + photo={photo ?? null} + src={icon} + /> + <div className="absolute bottom-0 left-0 right-0 top-0 hidden place-items-center group-hover:grid group-hover:bg-white/70"> <PencilSquareIcon className="w-16 text-black/50" /> </div> @@ -342,10 +334,8 @@ const PaymentTypeOption = ({ */ function ResourceSummarySubForm({ resource, - setIconFile, }: { resource?: ResourceUpdateInput; - setIconFile: (file: File) => void; }) { const { register } = useFormContext<ResourceUpdateInput>(); @@ -353,7 +343,7 @@ function ResourceSummarySubForm({ <div className="space-y-4 px-4"> <div className="flex flex-row space-x-4 sm:mt-4"> <div className="flex w-20 flex-col justify-center space-y-2 sm:w-28"> - <SelectImageInput resource={resource} setIconFile={setIconFile} /> + <SelectImageInput resource={resource} /> </div> <div className="flex flex-col justify-center overflow-hidden rounded-xl border border-neutral-400 bg-white drop-shadow-lg sm:w-[300px] md:w-[400px]"> <h2 className="border-b border-neutral-300 px-2 text-center font-semibold"> @@ -473,12 +463,10 @@ const ResourceDescriptionSubForm = () => { }; const ResourceForm = ({ - setIconFile, methods, resource, error, }: { - setIconFile: (file: File) => void; resource?: ResourceUpdateInput; methods: UseFormReturn<ResourceUpdateInput>; error?: string; @@ -500,10 +488,7 @@ const ResourceForm = ({ General </h1> <div className="justify-left mx-auto flex max-w-lg flex-col space-y-4 pb-5"> - <ResourceSummarySubForm - resource={resource} - setIconFile={setIconFile} - /> + <ResourceSummarySubForm resource={resource} /> <ResourceDescriptionSubForm /> </div> </div> diff --git a/src/pages/resources/[id]/edit.tsx b/src/pages/resources/[id]/edit.tsx index e5f40f7..9adaf44 100644 --- a/src/pages/resources/[id]/edit.tsx +++ b/src/pages/resources/[id]/edit.tsx @@ -20,7 +20,6 @@ const EditResourcePage = () => { // TODO: Maybe useWait id before querying const { data: resource } = api.auditoryResource.byId.useQuery({ id }); - const [updateIconFile, setIconFile] = useState<File | undefined>(undefined); const [serverError, setServerError] = useState<string | undefined>(undefined); const formMethods = useForm<ResourceUpdateInput>({ defaultValues: resource as ResourceUpdateInput, @@ -34,31 +33,6 @@ const EditResourcePage = () => { } setServerError(undefined); - - if (updateIconFile) { - const data = new FormData(); - data.append("photo", updateIconFile); - - if (!resource?.id) { - throw Error("Resource data missing for photo to upload"); - } - - const uploadResponse = await fetch( - `/api/resources/photo/${resource.id}`, - { - method: "POST", - body: data, - } - ); - - if (uploadResponse.status !== 200) { - setServerError( - "Failed uploading resource icon file. Changes did not save!" - ); - throw new Error(JSON.stringify(uploadResponse)); - } - } - await router.push(`/resources/${resource.id}`); }, onError: (error) => setServerError(error.message), @@ -113,7 +87,6 @@ const EditResourcePage = () => { > <main className="mb-12"> <ResourceForm - setIconFile={setIconFile} methods={formMethods} error={serverError} resource={resource as ResourceUpdateInput}