mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 20:13:49 +00:00
feat: client app can now upload images for beer posts
Updated seed to incorporate cloudinary images, downgraded multer to recent LTS, update tsconfig to allow spread operator usage on FileList.
This commit is contained in:
@@ -39,6 +39,7 @@ const CommentCardDropdown: FC<CommentCardDropdownProps> = ({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert('This feature is not yet implemented.');
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import sendCreateBeerPostRequest from '@/requests/sendCreateBeerPostRequest';
|
||||
import CreateBeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { BeerType } from '@prisma/client';
|
||||
import router from 'next/router';
|
||||
import { FunctionComponent, useState } from 'react';
|
||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||
import { useForm, SubmitHandler, FieldError } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult';
|
||||
import CreateBeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema';
|
||||
import sendCreateBeerPostRequest from '@/requests/sendCreateBeerPostRequest';
|
||||
import UploadImageValidationSchema from '@/services/types/ImageSchema/UploadImageValidationSchema';
|
||||
import sendUploadBeerImagesRequest from '@/requests/sendUploadBeerImageRequest';
|
||||
import ErrorAlert from './ui/alerts/ErrorAlert';
|
||||
import Button from './ui/forms/Button';
|
||||
import FormError from './ui/forms/FormError';
|
||||
@@ -17,32 +19,52 @@ import FormSelect from './ui/forms/FormSelect';
|
||||
import FormTextArea from './ui/forms/FormTextArea';
|
||||
import FormTextInput from './ui/forms/FormTextInput';
|
||||
|
||||
type CreateBeerPostSchema = z.infer<typeof CreateBeerPostValidationSchema>;
|
||||
|
||||
interface BeerFormProps {
|
||||
breweries: z.infer<typeof BreweryPostQueryResult>[];
|
||||
types: BeerType[];
|
||||
}
|
||||
|
||||
const CreateBeerPostWithImagesValidationSchema = CreateBeerPostValidationSchema.merge(
|
||||
UploadImageValidationSchema,
|
||||
);
|
||||
|
||||
const CreateBeerPostForm: FunctionComponent<BeerFormProps> = ({
|
||||
breweries = [],
|
||||
types = [],
|
||||
}) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<CreateBeerPostSchema>({
|
||||
resolver: zodResolver(CreateBeerPostValidationSchema),
|
||||
const { register, handleSubmit, formState } = useForm<
|
||||
z.infer<typeof CreateBeerPostWithImagesValidationSchema>
|
||||
>({
|
||||
resolver: zodResolver(CreateBeerPostWithImagesValidationSchema),
|
||||
});
|
||||
|
||||
const { errors, isSubmitting } = formState;
|
||||
const [error, setError] = useState('');
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const onSubmit: SubmitHandler<CreateBeerPostSchema> = async (data) => {
|
||||
const onSubmit: SubmitHandler<
|
||||
z.infer<typeof CreateBeerPostWithImagesValidationSchema>
|
||||
> = async (data) => {
|
||||
if (!(data.images instanceof FileList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { breweryId, typeId, name, abv, ibu, description } = data;
|
||||
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
const response = await sendCreateBeerPostRequest(data);
|
||||
const response = await sendCreateBeerPostRequest({
|
||||
breweryId,
|
||||
typeId,
|
||||
name,
|
||||
abv,
|
||||
ibu,
|
||||
description,
|
||||
});
|
||||
|
||||
await sendUploadBeerImagesRequest({
|
||||
beerPost: response,
|
||||
images: data.images,
|
||||
});
|
||||
|
||||
router.push(`/beers/${response.id}`);
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error)) {
|
||||
@@ -160,6 +182,19 @@ const CreateBeerPostForm: FunctionComponent<BeerFormProps> = ({
|
||||
/>
|
||||
</FormSegment>
|
||||
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="images">Images</FormLabel>
|
||||
<FormError>{(errors.images as FieldError | undefined)?.message}</FormError>
|
||||
</FormInfo>
|
||||
<FormSegment>
|
||||
<input
|
||||
type="file"
|
||||
{...register('images')}
|
||||
multiple
|
||||
className="file-input-bordered file-input w-full"
|
||||
/>
|
||||
</FormSegment>
|
||||
|
||||
<div className="mt-6">
|
||||
<Button type="submit" isSubmitting={isSubmitting}>
|
||||
{isSubmitting ? 'Submitting...' : 'Submit'}
|
||||
|
||||
@@ -59,7 +59,11 @@ const EditBeerPostForm: FC<EditBeerPostFormProps> = ({ previousValues }) => {
|
||||
router.push('/beers');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (!(e instanceof Error)) {
|
||||
setError('Something went wrong');
|
||||
return;
|
||||
}
|
||||
setError(e.message);
|
||||
}
|
||||
};
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user