replace file uploading to integrate with the new blob image data through trpc

This commit is contained in:
Brandon Egger 2023-08-24 11:29:05 -05:00
parent 6253668e8a
commit 4a03135f2d
2 changed files with 22 additions and 64 deletions

View File

@ -41,7 +41,6 @@ import Modal from "react-modal";
import { type RouterInputs } from "~/utils/api"; import { type RouterInputs } from "~/utils/api";
import { PlatformLinkButton } from "~/pages/resources/[id]"; import { PlatformLinkButton } from "~/pages/resources/[id]";
import { ResourcePhoto } from "~/components/ResourcePhoto"; import { ResourcePhoto } from "~/components/ResourcePhoto";
import Image from "next/image";
// Required for accessibility // Required for accessibility
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access // 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/ * File needs to be path relative to resource_logos/
*/ */
const SelectImageInput = ({ const SelectImageInput = ({ resource }: { resource?: ResourceUpdateInput }) => {
resource, const { setValue, setError, watch } = useFormContext<ResourceUpdateInput>();
setIconFile, const photo = watch("photo");
}: { const icon = watch("icon");
resource?: ResourceUpdateInput;
setIconFile: (file: File) => void;
}) => {
const [previewImg, setPreviewImg] = useState<string | undefined>(undefined);
const onChange = (event: ChangeEvent<HTMLInputElement>) => { const onChange = (event: ChangeEvent<HTMLInputElement>) => {
if (!event.target.files || !event.target.files[0]) { if (!event.target.files || !event.target.files[0]) {
@ -71,11 +66,17 @@ const SelectImageInput = ({
const file = event.target.files[0]; const file = event.target.files[0];
const reader = new FileReader(); const reader = new FileReader();
reader.onloadend = () => { reader.onloadend = () => {
setPreviewImg(reader.result as string); if (!reader.result || !(reader.result instanceof ArrayBuffer)) {
}; setError("photo.data", { message: "Failed uploading the photo data." });
reader.readAsDataURL(file); return;
}
setIconFile(file); setValue("photo", {
name: file.name,
data: Buffer.from(reader.result),
});
};
reader.readAsArrayBuffer(file);
}; };
return ( return (
@ -84,21 +85,12 @@ const SelectImageInput = ({
htmlFor="resource-image-file" htmlFor="resource-image-file"
className="bg-whit group relative cursor-pointer overflow-hidden rounded-xl border border-neutral-400 drop-shadow-lg" className="bg-whit group relative cursor-pointer overflow-hidden rounded-xl border border-neutral-400 drop-shadow-lg"
> >
{!previewImg ? ( <ResourcePhoto
<ResourcePhoto name={resource?.name ?? "n/a"}
name={resource?.name ?? "n/a"} photo={photo ?? null}
photo={resource?.photo ?? null} src={icon}
src={resource?.icon} />
/>
) : (
<Image
className="w-full"
src={previewImg ?? ""}
alt={`resource logo`}
width={512}
height={512}
/>
)}
<div className="absolute bottom-0 left-0 right-0 top-0 hidden place-items-center group-hover:grid group-hover:bg-white/70"> <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" /> <PencilSquareIcon className="w-16 text-black/50" />
</div> </div>
@ -342,10 +334,8 @@ const PaymentTypeOption = ({
*/ */
function ResourceSummarySubForm({ function ResourceSummarySubForm({
resource, resource,
setIconFile,
}: { }: {
resource?: ResourceUpdateInput; resource?: ResourceUpdateInput;
setIconFile: (file: File) => void;
}) { }) {
const { register } = useFormContext<ResourceUpdateInput>(); const { register } = useFormContext<ResourceUpdateInput>();
@ -353,7 +343,7 @@ function ResourceSummarySubForm({
<div className="space-y-4 px-4"> <div className="space-y-4 px-4">
<div className="flex flex-row space-x-4 sm:mt-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"> <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>
<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]"> <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"> <h2 className="border-b border-neutral-300 px-2 text-center font-semibold">
@ -473,12 +463,10 @@ const ResourceDescriptionSubForm = () => {
}; };
const ResourceForm = ({ const ResourceForm = ({
setIconFile,
methods, methods,
resource, resource,
error, error,
}: { }: {
setIconFile: (file: File) => void;
resource?: ResourceUpdateInput; resource?: ResourceUpdateInput;
methods: UseFormReturn<ResourceUpdateInput>; methods: UseFormReturn<ResourceUpdateInput>;
error?: string; error?: string;
@ -500,10 +488,7 @@ const ResourceForm = ({
General General
</h1> </h1>
<div className="justify-left mx-auto flex max-w-lg flex-col space-y-4 pb-5"> <div className="justify-left mx-auto flex max-w-lg flex-col space-y-4 pb-5">
<ResourceSummarySubForm <ResourceSummarySubForm resource={resource} />
resource={resource}
setIconFile={setIconFile}
/>
<ResourceDescriptionSubForm /> <ResourceDescriptionSubForm />
</div> </div>
</div> </div>

View File

@ -20,7 +20,6 @@ const EditResourcePage = () => {
// TODO: Maybe useWait id before querying // TODO: Maybe useWait id before querying
const { data: resource } = api.auditoryResource.byId.useQuery({ id }); const { data: resource } = api.auditoryResource.byId.useQuery({ id });
const [updateIconFile, setIconFile] = useState<File | undefined>(undefined);
const [serverError, setServerError] = useState<string | undefined>(undefined); const [serverError, setServerError] = useState<string | undefined>(undefined);
const formMethods = useForm<ResourceUpdateInput>({ const formMethods = useForm<ResourceUpdateInput>({
defaultValues: resource as ResourceUpdateInput, defaultValues: resource as ResourceUpdateInput,
@ -34,31 +33,6 @@ const EditResourcePage = () => {
} }
setServerError(undefined); 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}`); await router.push(`/resources/${resource.id}`);
}, },
onError: (error) => setServerError(error.message), onError: (error) => setServerError(error.message),
@ -113,7 +87,6 @@ const EditResourcePage = () => {
> >
<main className="mb-12"> <main className="mb-12">
<ResourceForm <ResourceForm
setIconFile={setIconFile}
methods={formMethods} methods={formMethods}
error={serverError} error={serverError}
resource={resource as ResourceUpdateInput} resource={resource as ResourceUpdateInput}