From 4cd2ab476f74ff1f951495648f518db829abc975 Mon Sep 17 00:00:00 2001 From: Aaron William Po Date: Mon, 20 Feb 2023 09:09:45 -0500 Subject: [PATCH] Formatting changes --- components/BeerById/BeerCommentForm.tsx | 11 +++-- components/BeerById/BeerInfoHeader.tsx | 4 +- components/BeerById/BeerPostLikeButton.tsx | 2 +- components/BeerForm.tsx | 13 +++-- config/auth/withPageAuthRequired.ts | 1 + pages/api/beers/[id]/comments/index.ts | 10 +++- pages/beers/create.tsx | 5 +- requests/sendCreateBeerCommentRequest.ts | 8 ++-- requests/sendCreateBeerPostRequest.ts | 12 ++--- services/BeerComment/createNewBeerComment.ts | 5 +- services/BeerComment/getAllBeerComments.ts | 20 ++------ .../CreateBeerCommentValidationSchema.ts | 1 - services/BeerPost/getAllBeerPosts.ts | 30 ++---------- services/BeerPost/getBeerPostById.ts | 48 ++----------------- 14 files changed, 61 insertions(+), 109 deletions(-) diff --git a/components/BeerById/BeerCommentForm.tsx b/components/BeerById/BeerCommentForm.tsx index e9a27f6..25314ef 100644 --- a/components/BeerById/BeerCommentForm.tsx +++ b/components/BeerById/BeerCommentForm.tsx @@ -26,7 +26,6 @@ const BeerCommentForm: FunctionComponent = ({ beerPost }) z.infer >({ defaultValues: { - beerPostId: beerPost.id, rating: 0, }, resolver: zodResolver(BeerCommentValidationSchema), @@ -35,8 +34,8 @@ const BeerCommentForm: FunctionComponent = ({ beerPost }) const [rating, setRating] = useState(0); useEffect(() => { setRating(0); - reset({ beerPostId: beerPost.id, rating: 0, content: '' }); - }, [beerPost.id, reset]); + reset({ rating: 0, content: '' }); + }, [reset]); const router = useRouter(); const onSubmit: SubmitHandler> = async ( @@ -44,7 +43,11 @@ const BeerCommentForm: FunctionComponent = ({ beerPost }) ) => { setValue('rating', 0); setRating(0); - await sendCreateBeerCommentRequest(data); + await sendCreateBeerCommentRequest({ + content: data.content, + rating: data.rating, + beerPostId: beerPost.id, + }); reset(); router.replace(router.asPath, undefined, { scroll: false }); }; diff --git a/components/BeerById/BeerInfoHeader.tsx b/components/BeerById/BeerInfoHeader.tsx index eac4c49..b89e61a 100644 --- a/components/BeerById/BeerInfoHeader.tsx +++ b/components/BeerById/BeerInfoHeader.tsx @@ -68,7 +68,9 @@ const BeerInfoHeader: FC<{ beerPost: BeerPostQueryResult; initialLikeCount: numb {beerPost.ibu} IBU
- Liked by {likeCount} users + + Liked by {likeCount} user{likeCount !== 1 && 's'} +
diff --git a/components/BeerById/BeerPostLikeButton.tsx b/components/BeerById/BeerPostLikeButton.tsx index ed7c2e6..84b6ae9 100644 --- a/components/BeerById/BeerPostLikeButton.tsx +++ b/components/BeerById/BeerPostLikeButton.tsx @@ -1,8 +1,8 @@ import UserContext from '@/contexts/userContext'; -import sendCheckIfUserLikesBeerPostRequest from '@/requests/sendCheckIfUserLikesBeerPostRequest'; import sendLikeRequest from '@/requests/sendLikeRequest'; import { Dispatch, FC, SetStateAction, useContext, useEffect, useState } from 'react'; import { FaThumbsUp, FaRegThumbsUp } from 'react-icons/fa'; +import sendCheckIfUserLikesBeerPostRequest from '@/requests/sendCheckIfUserLikesBeerPostRequest'; const BeerPostLikeButton: FC<{ beerPostId: string; diff --git a/components/BeerForm.tsx b/components/BeerForm.tsx index fd57e3c..5620e20 100644 --- a/components/BeerForm.tsx +++ b/components/BeerForm.tsx @@ -4,9 +4,10 @@ import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQuer import { zodResolver } from '@hookform/resolvers/zod'; import { BeerType } from '@prisma/client'; import router from 'next/router'; -import { FunctionComponent } from 'react'; +import { FunctionComponent, useState } from 'react'; import { useForm, SubmitHandler } from 'react-hook-form'; import { z } from 'zod'; +import ErrorAlert from './ui/alerts/ErrorAlert'; import Button from './ui/forms/Button'; import FormError from './ui/forms/FormError'; import FormInfo from './ui/forms/FormInfo'; @@ -46,6 +47,8 @@ const BeerForm: FunctionComponent = ({ }, }); + const [error, setError] = useState(''); + const onSubmit: SubmitHandler = async (data) => { switch (formType) { case 'create': { @@ -54,8 +57,9 @@ const BeerForm: FunctionComponent = ({ router.push(`/beers/${response.id}`); break; } catch (e) { - // eslint-disable-next-line no-console - console.error(e); + if (e instanceof Error) { + setError(e.message); + } break; } } @@ -68,6 +72,9 @@ const BeerForm: FunctionComponent = ({ return (
+
+ {error && } +
Name {errors.name?.message} diff --git a/config/auth/withPageAuthRequired.ts b/config/auth/withPageAuthRequired.ts index f54fe90..8f84bf3 100644 --- a/config/auth/withPageAuthRequired.ts +++ b/config/auth/withPageAuthRequired.ts @@ -12,6 +12,7 @@ const withPageAuthRequired = } return await fn(context); } catch (error) { + console.log(error); return { redirect: { destination: '/login', diff --git a/pages/api/beers/[id]/comments/index.ts b/pages/api/beers/[id]/comments/index.ts index 0e0f4dc..71ed17a 100644 --- a/pages/api/beers/[id]/comments/index.ts +++ b/pages/api/beers/[id]/comments/index.ts @@ -13,13 +13,16 @@ import { NextApiResponse } from 'next'; interface CreateCommentRequest extends UserExtendedNextApiRequest { body: z.infer; + query: { id: string }; } const createComment = async ( req: CreateCommentRequest, res: NextApiResponse>, ) => { - const { content, rating, beerPostId } = req.body; + const { content, rating } = req.body; + + const beerPostId = req.query.id; const newBeerComment: BeerCommentQueryResultT = await createNewBeerComment({ content, @@ -42,7 +45,10 @@ const router = createRouter< >(); router.post( - validateRequest({ bodySchema: BeerCommentValidationSchema }), + validateRequest({ + bodySchema: BeerCommentValidationSchema, + querySchema: z.object({ id: z.string().uuid() }), + }), getCurrentUser, createComment, ); diff --git a/pages/beers/create.tsx b/pages/beers/create.tsx index bf2a8c2..af35db6 100644 --- a/pages/beers/create.tsx +++ b/pages/beers/create.tsx @@ -1,5 +1,6 @@ import BeerForm from '@/components/BeerForm'; import Layout from '@/components/ui/Layout'; +import withPageAuthRequired from '@/config/auth/withPageAuthRequired'; import DBClient from '@/prisma/DBClient'; import getAllBreweryPosts from '@/services/BreweryPost/getAllBreweryPosts'; @@ -30,7 +31,7 @@ const Create: NextPage = ({ breweries, types }) => { ); }; -export const getServerSideProps = async () => { +export const getServerSideProps = withPageAuthRequired(async () => { const breweryPosts = await getAllBreweryPosts(); const beerTypes = await DBClient.instance.beerType.findMany(); @@ -40,6 +41,6 @@ export const getServerSideProps = async () => { types: JSON.parse(JSON.stringify(beerTypes)), }, }; -}; +}); export default Create; diff --git a/requests/sendCreateBeerCommentRequest.ts b/requests/sendCreateBeerCommentRequest.ts index d4692e6..2d10359 100644 --- a/requests/sendCreateBeerCommentRequest.ts +++ b/requests/sendCreateBeerCommentRequest.ts @@ -3,11 +3,15 @@ import BeerCommentValidationSchema from '@/services/BeerComment/schema/CreateBee import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { z } from 'zod'; +const BeerCommentValidationSchemaWithId = BeerCommentValidationSchema.extend({ + beerPostId: z.string().uuid(), +}); + const sendCreateBeerCommentRequest = async ({ beerPostId, content, rating, -}: z.infer) => { +}: z.infer) => { const response = await fetch(`/api/beers/${beerPostId}/comments`, { method: 'POST', headers: { @@ -29,7 +33,6 @@ const sendCreateBeerCommentRequest = async ({ const parsedResponse = APIResponseValidationSchema.safeParse(data); if (!parsedResponse.success) { - console.log(parsedResponse.error); throw new Error('Invalid API response'); } @@ -37,7 +40,6 @@ const sendCreateBeerCommentRequest = async ({ const parsedPayload = BeerCommentQueryResult.safeParse(parsedResponse.data.payload); if (!parsedPayload.success) { - console.log(parsedPayload.error); throw new Error('Invalid API response payload'); } diff --git a/requests/sendCreateBeerPostRequest.ts b/requests/sendCreateBeerPostRequest.ts index 7e5c8e8..b40200e 100644 --- a/requests/sendCreateBeerPostRequest.ts +++ b/requests/sendCreateBeerPostRequest.ts @@ -7,21 +7,21 @@ const sendCreateBeerPostRequest = async ( ) => { const response = await fetch('/api/beers/create', { method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); - const json = await response.json(); - const parsed = APIResponseValidationSchema.safeParse(json); if (!parsed.success) { throw new Error('Invalid API response'); } - const { payload } = parsed.data; + const { payload, success, message } = parsed.data; + + if (!success) { + throw new Error(message); + } if ( !( diff --git a/services/BeerComment/createNewBeerComment.ts b/services/BeerComment/createNewBeerComment.ts index eaca82f..1231a1a 100644 --- a/services/BeerComment/createNewBeerComment.ts +++ b/services/BeerComment/createNewBeerComment.ts @@ -2,8 +2,9 @@ import DBClient from '@/prisma/DBClient'; import { z } from 'zod'; import BeerCommentValidationSchema from './schema/CreateBeerCommentValidationSchema'; -const CreateBeerCommentWithUserSchema = BeerCommentValidationSchema.extend({ +const CreateNewBeerCommentServiceSchema = BeerCommentValidationSchema.extend({ userId: z.string().uuid(), + beerPostId: z.string().uuid(), }); const createNewBeerComment = async ({ @@ -11,7 +12,7 @@ const createNewBeerComment = async ({ rating, beerPostId, userId, -}: z.infer) => { +}: z.infer) => { return DBClient.instance.beerComment.create({ data: { content, diff --git a/services/BeerComment/getAllBeerComments.ts b/services/BeerComment/getAllBeerComments.ts index 7410348..f293eb3 100644 --- a/services/BeerComment/getAllBeerComments.ts +++ b/services/BeerComment/getAllBeerComments.ts @@ -9,27 +9,17 @@ const getAllBeerComments = async ( const skip = (pageNum - 1) * pageSize; const beerComments: BeerCommentQueryResultArrayT = await DBClient.instance.beerComment.findMany({ - where: { - beerPostId: id, - }, + skip, + take: pageSize, + where: { beerPostId: id }, select: { id: true, content: true, rating: true, createdAt: true, - postedBy: { - select: { - id: true, - username: true, - createdAt: true, - }, - }, + postedBy: { select: { id: true, username: true, createdAt: true } }, }, - orderBy: { - createdAt: 'desc', - }, - skip, - take: pageSize, + orderBy: { createdAt: 'desc' }, }); return beerComments; }; diff --git a/services/BeerComment/schema/CreateBeerCommentValidationSchema.ts b/services/BeerComment/schema/CreateBeerCommentValidationSchema.ts index 5d02670..174b061 100644 --- a/services/BeerComment/schema/CreateBeerCommentValidationSchema.ts +++ b/services/BeerComment/schema/CreateBeerCommentValidationSchema.ts @@ -10,7 +10,6 @@ const BeerCommentValidationSchema = z.object({ .int() .min(1, { message: 'Rating must be greater than 1.' }) .max(5, { message: 'Rating must be less than 5.' }), - beerPostId: z.string().uuid({ message: 'Beer post ID must be a valid UUID.' }), }); export default BeerCommentValidationSchema; diff --git a/services/BeerPost/getAllBeerPosts.ts b/services/BeerPost/getAllBeerPosts.ts index 25d7d6c..23fc233 100644 --- a/services/BeerPost/getAllBeerPosts.ts +++ b/services/BeerPost/getAllBeerPosts.ts @@ -10,36 +10,14 @@ const getAllBeerPosts = async (pageNum: number, pageSize: number) => { select: { id: true, name: true, - type: { - select: { - name: true, - id: true, - }, - }, ibu: true, abv: true, - brewery: { - select: { - name: true, - id: true, - }, - }, description: true, createdAt: true, - postedBy: { - select: { - id: true, - username: true, - }, - }, - beerImages: { - select: { - path: true, - caption: true, - id: true, - alt: true, - }, - }, + type: { select: { name: true, id: true } }, + brewery: { select: { name: true, id: true } }, + postedBy: { select: { id: true, username: true } }, + beerImages: { select: { path: true, caption: true, id: true, alt: true } }, }, take: pageSize, skip, diff --git a/services/BeerPost/getBeerPostById.ts b/services/BeerPost/getBeerPostById.ts index 1410d29..ba64cb3 100644 --- a/services/BeerPost/getBeerPostById.ts +++ b/services/BeerPost/getBeerPostById.ts @@ -6,56 +6,18 @@ const prisma = DBClient.instance; const getBeerPostById = async (id: string) => { const beerPost: BeerPostQueryResult | null = await prisma.beerPost.findFirst({ select: { - beerComments: { - select: { - id: true, - content: true, - createdAt: true, - postedBy: { - select: { - username: true, - id: true, - }, - }, - rating: true, - }, - }, id: true, name: true, - brewery: { - select: { - name: true, - id: true, - }, - }, ibu: true, abv: true, - type: { - select: { - name: true, - id: true, - }, - }, - beerImages: { - select: { - alt: true, - path: true, - caption: true, - id: true, - }, - }, createdAt: true, description: true, - postedBy: { - select: { - username: true, - id: true, - }, - }, - }, - where: { - id, + postedBy: { select: { username: true, id: true } }, + brewery: { select: { name: true, id: true } }, + type: { select: { name: true, id: true } }, + beerImages: { select: { alt: true, path: true, caption: true, id: true } }, }, + where: { id }, }); return beerPost;