From 2b90bb2e5df4cc0dd93411fa07ae039be7a56d72 Mon Sep 17 00:00:00 2001 From: Aaron William Po Date: Mon, 25 Dec 2023 21:04:15 -0500 Subject: [PATCH] Refactor: update comment components --- src/components/BeerById/BeerCommentForm.tsx | 2 +- .../BeerById/BeerPostCommentsSection.tsx | 38 +++-- .../BeerStyleById/BeerStyleCommentForm.tsx | 2 +- .../BeerStyleById/BeerStyleCommentSection.tsx | 39 +++--- .../BreweryById/BreweryCommentForm.tsx | 2 +- .../BreweryById/BreweryCommentsSection.tsx | 55 +++----- .../CommentCardBody.tsx | 18 ++- .../CommentCardDropdown.tsx | 0 .../CommentContentBody.tsx | 0 .../{ui => Comments}/CommentForm.tsx | 12 +- .../CommentLoadingCardBody.tsx | 0 .../CommentLoadingComponent.tsx} | 8 +- .../{ui => Comments}/CommentsComponent.tsx | 36 ++--- .../EditCommentBody.tsx | 30 ++-- .../{BeerById => Comments}/NoCommentsCard.tsx | 0 src/components/Comments/types/index.ts | 12 ++ src/requests/comments/beer-comment/index.ts | 6 +- .../comments/beer-style-comment/index.ts | 132 +++++++++++------- .../comments/brewery-comment/index.ts | 109 +++++++++++++++ .../comments/brewery-comment/types/index.ts | 19 +++ 20 files changed, 331 insertions(+), 189 deletions(-) rename src/components/{BeerBreweryComments => Comments}/CommentCardBody.tsx (76%) rename src/components/{BeerBreweryComments => Comments}/CommentCardDropdown.tsx (100%) rename src/components/{BeerBreweryComments => Comments}/CommentContentBody.tsx (100%) rename src/components/{ui => Comments}/CommentForm.tsx (88%) rename src/components/{BeerBreweryComments => Comments}/CommentLoadingCardBody.tsx (100%) rename src/components/{BeerById/LoadingComponent.tsx => Comments/CommentLoadingComponent.tsx} (56%) rename src/components/{ui => Comments}/CommentsComponent.tsx (82%) rename src/components/{BeerBreweryComments => Comments}/EditCommentBody.tsx (87%) rename src/components/{BeerById => Comments}/NoCommentsCard.tsx (100%) create mode 100644 src/components/Comments/types/index.ts create mode 100644 src/requests/comments/brewery-comment/index.ts create mode 100644 src/requests/comments/brewery-comment/types/index.ts diff --git a/src/components/BeerById/BeerCommentForm.tsx b/src/components/BeerById/BeerCommentForm.tsx index cbd4a64..a1bf202 100644 --- a/src/components/BeerById/BeerCommentForm.tsx +++ b/src/components/BeerById/BeerCommentForm.tsx @@ -10,7 +10,7 @@ import CreateCommentValidationSchema from '@/services/schema/CommentSchema/Creat import toast from 'react-hot-toast'; import createErrorToast from '@/util/createErrorToast'; import { sendCreateBeerCommentRequest } from '@/requests/comments/beer-comment'; -import CommentForm from '../ui/CommentForm'; +import CommentForm from '../Comments/CommentForm'; interface BeerCommentFormProps { beerPost: z.infer; diff --git a/src/components/BeerById/BeerPostCommentsSection.tsx b/src/components/BeerById/BeerPostCommentsSection.tsx index f8f6738..d2cee4a 100644 --- a/src/components/BeerById/BeerPostCommentsSection.tsx +++ b/src/components/BeerById/BeerPostCommentsSection.tsx @@ -6,15 +6,15 @@ import { FC, MutableRefObject, useContext, useRef } from 'react'; import { z } from 'zod'; import useBeerPostComments from '@/hooks/data-fetching/beer-comments/useBeerPostComments'; import { useRouter } from 'next/router'; -import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema'; + import { deleteBeerPostCommentRequest, editBeerPostCommentRequest, } from '@/requests/comments/beer-comment'; import BeerCommentForm from './BeerCommentForm'; -import LoadingComponent from './LoadingComponent'; -import CommentsComponent from '../ui/CommentsComponent'; +import CommentLoadingComponent from '../Comments/CommentLoadingComponent'; +import CommentsComponent from '../Comments/CommentsComponent'; interface BeerPostCommentsSectionProps { beerPost: z.infer; @@ -32,21 +32,6 @@ const BeerPostCommentsSection: FC = ({ beerPost }) const commentSectionRef: MutableRefObject = useRef(null); - const handleDeleteRequest = async (id: string) => { - await deleteBeerPostCommentRequest({ commentId: id, beerPostId: beerPost.id }); - }; - - const handleEditRequest = async ( - id: string, - data: z.infer, - ) => { - await editBeerPostCommentRequest({ - body: data, - commentId: id, - beerPostId: beerPost.id, - }); - }; - return (
@@ -68,7 +53,7 @@ const BeerPostCommentsSection: FC = ({ beerPost }) */ isLoading ? (
- +
) : ( = ({ beerPost }) setSize={setSize} size={size} mutate={mutate} - handleDeleteRequest={handleDeleteRequest} - handleEditRequest={handleEditRequest} + handleDeleteCommentRequest={(id) => { + return deleteBeerPostCommentRequest({ + commentId: id, + beerPostId: beerPost.id, + }); + }} + handleEditCommentRequest={(id, data) => { + return editBeerPostCommentRequest({ + body: data, + commentId: id, + beerPostId: beerPost.id, + }); + }} /> ) } diff --git a/src/components/BeerStyleById/BeerStyleCommentForm.tsx b/src/components/BeerStyleById/BeerStyleCommentForm.tsx index d6376eb..829ee33 100644 --- a/src/components/BeerStyleById/BeerStyleCommentForm.tsx +++ b/src/components/BeerStyleById/BeerStyleCommentForm.tsx @@ -11,7 +11,7 @@ import createErrorToast from '@/util/createErrorToast'; import BeerStyleQueryResult from '@/services/posts/beer-style-post/schema/BeerStyleQueryResult'; import useBeerStyleComments from '@/hooks/data-fetching/beer-style-comments/useBeerStyleComments'; import { sendCreateBeerStyleCommentRequest } from '@/requests/comments/beer-style-comment'; -import CommentForm from '../ui/CommentForm'; +import CommentForm from '../Comments/CommentForm'; interface BeerCommentFormProps { beerStyle: z.infer; diff --git a/src/components/BeerStyleById/BeerStyleCommentSection.tsx b/src/components/BeerStyleById/BeerStyleCommentSection.tsx index 7d742f9..aa597c9 100644 --- a/src/components/BeerStyleById/BeerStyleCommentSection.tsx +++ b/src/components/BeerStyleById/BeerStyleCommentSection.tsx @@ -3,17 +3,16 @@ import UserContext from '@/contexts/UserContext'; import { FC, MutableRefObject, useContext, useRef } from 'react'; import { z } from 'zod'; import { useRouter } from 'next/router'; -import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema'; import BeerStyleQueryResult from '@/services/posts/beer-style-post/schema/BeerStyleQueryResult'; import useBeerStyleComments from '@/hooks/data-fetching/beer-style-comments/useBeerStyleComments'; -import LoadingComponent from '../BeerById/LoadingComponent'; -import CommentsComponent from '../ui/CommentsComponent'; -import BeerStyleCommentForm from './BeerStyleCommentForm'; import { sendDeleteBeerStyleCommentRequest, sendEditBeerStyleCommentRequest, } from '@/requests/comments/beer-style-comment'; +import CommentLoadingComponent from '../Comments/CommentLoadingComponent'; +import CommentsComponent from '../Comments/CommentsComponent'; +import BeerStyleCommentForm from './BeerStyleCommentForm'; interface BeerStyleCommentsSectionProps { beerStyle: z.infer; @@ -31,21 +30,6 @@ const BeerStyleCommentsSection: FC = ({ beerStyle const commentSectionRef: MutableRefObject = useRef(null); - const handleDeleteRequest = async (id: string) => { - await sendDeleteBeerStyleCommentRequest({ beerStyleId: beerStyle.id, commentId: id }); - }; - - const handleEditRequest = async ( - id: string, - data: z.infer, - ) => { - await sendEditBeerStyleCommentRequest({ - beerStyleId: beerStyle.id, - commentId: id, - body: data, - }); - }; - return (
@@ -67,7 +51,7 @@ const BeerStyleCommentsSection: FC = ({ beerStyle */ isLoading ? (
- +
) : ( = ({ beerStyle setSize={setSize} size={size} mutate={mutate} - handleDeleteRequest={handleDeleteRequest} - handleEditRequest={handleEditRequest} + handleDeleteCommentRequest={(id) => { + return sendDeleteBeerStyleCommentRequest({ + beerStyleId: beerStyle.id, + commentId: id, + }); + }} + handleEditCommentRequest={(id, data) => { + return sendEditBeerStyleCommentRequest({ + beerStyleId: beerStyle.id, + commentId: id, + body: data, + }); + }} /> ) } diff --git a/src/components/BreweryById/BreweryCommentForm.tsx b/src/components/BreweryById/BreweryCommentForm.tsx index a42ada7..1ef4cbc 100644 --- a/src/components/BreweryById/BreweryCommentForm.tsx +++ b/src/components/BreweryById/BreweryCommentForm.tsx @@ -8,7 +8,7 @@ import toast from 'react-hot-toast'; import { z } from 'zod'; import sendCreateBreweryCommentRequest from '@/requests/comments/brewery-comment/sendCreateBreweryCommentRequest'; import createErrorToast from '@/util/createErrorToast'; -import CommentForm from '../ui/CommentForm'; +import CommentForm from '../Comments/CommentForm'; interface BreweryCommentFormProps { breweryPost: z.infer; diff --git a/src/components/BreweryById/BreweryCommentsSection.tsx b/src/components/BreweryById/BreweryCommentsSection.tsx index a40da94..7da4df5 100644 --- a/src/components/BreweryById/BreweryCommentsSection.tsx +++ b/src/components/BreweryById/BreweryCommentsSection.tsx @@ -2,11 +2,14 @@ import UserContext from '@/contexts/UserContext'; import BreweryPostQueryResult from '@/services/posts/brewery-post/schema/BreweryPostQueryResult'; import { FC, MutableRefObject, useContext, useRef } from 'react'; import { z } from 'zod'; -import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema'; import useBreweryPostComments from '@/hooks/data-fetching/brewery-comments/useBreweryPostComments'; -import LoadingComponent from '../BeerById/LoadingComponent'; -import CommentsComponent from '../ui/CommentsComponent'; +import { + sendDeleteBreweryPostCommentRequest, + sendEditBreweryPostCommentRequest, +} from '@/requests/comments/brewery-comment'; +import CommentLoadingComponent from '../Comments/CommentLoadingComponent'; +import CommentsComponent from '../Comments/CommentsComponent'; import BreweryCommentForm from './BreweryCommentForm'; interface BreweryBeerSectionProps { @@ -30,35 +33,6 @@ const BreweryCommentsSection: FC = ({ breweryPost }) => const commentSectionRef: MutableRefObject = useRef(null); - const handleDeleteRequest = async (commentId: string) => { - const response = await fetch( - `/api/breweries/${breweryPost.id}/comments/${commentId}`, - { method: 'DELETE' }, - ); - - if (!response.ok) { - throw new Error(response.statusText); - } - }; - - const handleEditRequest = async ( - commentId: string, - data: z.infer, - ) => { - const response = await fetch( - `/api/breweries/${breweryPost.id}/comments/${commentId}`, - { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ content: data.content, rating: data.rating }), - }, - ); - - if (!response.ok) { - throw new Error(response.statusText); - } - }; - return (
@@ -79,7 +53,7 @@ const BreweryCommentsSection: FC = ({ breweryPost }) => */ isLoading ? (
- +
) : ( = ({ breweryPost }) => size={size} commentSectionRef={commentSectionRef} mutate={mutate} - handleDeleteRequest={handleDeleteRequest} - handleEditRequest={handleEditRequest} + handleDeleteCommentRequest={(id) => { + return sendDeleteBreweryPostCommentRequest({ + breweryPostId: breweryPost.id, + commentId: id, + }); + }} + handleEditCommentRequest={(commentId, data) => { + return sendEditBreweryPostCommentRequest({ + breweryPostId: breweryPost.id, + commentId, + body: { content: data.content, rating: data.rating }, + }); + }} /> ) } diff --git a/src/components/BeerBreweryComments/CommentCardBody.tsx b/src/components/Comments/CommentCardBody.tsx similarity index 76% rename from src/components/BeerBreweryComments/CommentCardBody.tsx rename to src/components/Comments/CommentCardBody.tsx index 2c57d4d..74c0e0a 100644 --- a/src/components/BeerBreweryComments/CommentCardBody.tsx +++ b/src/components/Comments/CommentCardBody.tsx @@ -3,28 +3,26 @@ import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResu import { FC, useState } from 'react'; import { useInView } from 'react-intersection-observer'; import { z } from 'zod'; -import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema'; + import CommentContentBody from './CommentContentBody'; import EditCommentBody from './EditCommentBody'; import UserAvatar from '../Account/UserAvatar'; +import { HandleDeleteCommentRequest, HandleEditCommentRequest } from './types'; interface CommentCardProps { comment: z.infer; mutate: ReturnType['mutate']; ref?: ReturnType['ref']; - handleDeleteRequest: (id: string) => Promise; - handleEditRequest: ( - id: string, - data: z.infer, - ) => Promise; + handleDeleteCommentRequest: HandleDeleteCommentRequest; + handleEditCommentRequest: HandleEditCommentRequest; } const CommentCardBody: FC = ({ comment, mutate, ref, - handleDeleteRequest, - handleEditRequest, + handleDeleteCommentRequest, + handleEditCommentRequest, }) => { const [inEditMode, setInEditMode] = useState(false); @@ -44,8 +42,8 @@ const CommentCardBody: FC = ({ comment={comment} mutate={mutate} setInEditMode={setInEditMode} - handleDeleteRequest={handleDeleteRequest} - handleEditRequest={handleEditRequest} + handleDeleteCommentRequest={handleDeleteCommentRequest} + handleEditCommentRequest={handleEditCommentRequest} /> )}
diff --git a/src/components/BeerBreweryComments/CommentCardDropdown.tsx b/src/components/Comments/CommentCardDropdown.tsx similarity index 100% rename from src/components/BeerBreweryComments/CommentCardDropdown.tsx rename to src/components/Comments/CommentCardDropdown.tsx diff --git a/src/components/BeerBreweryComments/CommentContentBody.tsx b/src/components/Comments/CommentContentBody.tsx similarity index 100% rename from src/components/BeerBreweryComments/CommentContentBody.tsx rename to src/components/Comments/CommentContentBody.tsx diff --git a/src/components/ui/CommentForm.tsx b/src/components/Comments/CommentForm.tsx similarity index 88% rename from src/components/ui/CommentForm.tsx rename to src/components/Comments/CommentForm.tsx index f091cd6..62102f0 100644 --- a/src/components/ui/CommentForm.tsx +++ b/src/components/Comments/CommentForm.tsx @@ -8,12 +8,12 @@ import type { UseFormSetValue, UseFormWatch, } from 'react-hook-form'; -import FormError from './forms/FormError'; -import FormInfo from './forms/FormInfo'; -import FormLabel from './forms/FormLabel'; -import FormSegment from './forms/FormSegment'; -import FormTextArea from './forms/FormTextArea'; -import Button from './forms/Button'; +import FormError from '../ui/forms/FormError'; +import FormInfo from '../ui/forms/FormInfo'; +import FormLabel from '../ui/forms/FormLabel'; +import FormSegment from '../ui/forms/FormSegment'; +import FormTextArea from '../ui/forms/FormTextArea'; +import Button from '../ui/forms/Button'; interface Comment { content: string; diff --git a/src/components/BeerBreweryComments/CommentLoadingCardBody.tsx b/src/components/Comments/CommentLoadingCardBody.tsx similarity index 100% rename from src/components/BeerBreweryComments/CommentLoadingCardBody.tsx rename to src/components/Comments/CommentLoadingCardBody.tsx diff --git a/src/components/BeerById/LoadingComponent.tsx b/src/components/Comments/CommentLoadingComponent.tsx similarity index 56% rename from src/components/BeerById/LoadingComponent.tsx rename to src/components/Comments/CommentLoadingComponent.tsx index fc2dca4..4d55920 100644 --- a/src/components/BeerById/LoadingComponent.tsx +++ b/src/components/Comments/CommentLoadingComponent.tsx @@ -1,12 +1,12 @@ import { FC } from 'react'; import Spinner from '../ui/Spinner'; -import CommentLoadingCardBody from '../BeerBreweryComments/CommentLoadingCardBody'; +import CommentLoadingCardBody from './CommentLoadingCardBody'; -interface LoadingComponentProps { +interface CommentLoadingComponentProps { length: number; } -const LoadingComponent: FC = ({ length }) => { +const CommentLoadingComponent: FC = ({ length }) => { return ( <> {Array.from({ length }).map((_, i) => ( @@ -19,4 +19,4 @@ const LoadingComponent: FC = ({ length }) => { ); }; -export default LoadingComponent; +export default CommentLoadingComponent; diff --git a/src/components/ui/CommentsComponent.tsx b/src/components/Comments/CommentsComponent.tsx similarity index 82% rename from src/components/ui/CommentsComponent.tsx rename to src/components/Comments/CommentsComponent.tsx index 64c1d10..18a0d4d 100644 --- a/src/components/ui/CommentsComponent.tsx +++ b/src/components/Comments/CommentsComponent.tsx @@ -7,39 +7,33 @@ import useBeerPostComments from '@/hooks/data-fetching/beer-comments/useBeerPost import useBreweryPostComments from '@/hooks/data-fetching/brewery-comments/useBreweryPostComments'; import useBeerStyleComments from '@/hooks/data-fetching/beer-style-comments/useBeerStyleComments'; -import NoCommentsCard from '../BeerById/NoCommentsCard'; -import LoadingComponent from '../BeerById/LoadingComponent'; -import CommentCardBody from '../BeerBreweryComments/CommentCardBody'; +import NoCommentsCard from './NoCommentsCard'; +import CommentLoadingComponent from './CommentLoadingComponent'; +import CommentCardBody from './CommentCardBody'; +import { HandleDeleteCommentRequest, HandleEditCommentRequest } from './types'; type HookReturnType = ReturnType< typeof useBeerPostComments | typeof useBreweryPostComments | typeof useBeerStyleComments >; -type HandleDeleteRequest = (id: string) => Promise; - -type HandleEditRequest = ( - id: string, - data: { content: string; rating: number }, -) => Promise; - interface CommentsComponentProps { comments: HookReturnType['comments']; - commentSectionRef: MutableRefObject; - handleDeleteRequest: HandleDeleteRequest; - handleEditRequest: HandleEditRequest; isAtEnd: HookReturnType['isAtEnd']; isLoadingMore: HookReturnType['isLoadingMore']; mutate: HookReturnType['mutate']; - pageSize: number; setSize: HookReturnType['setSize']; size: HookReturnType['size']; + commentSectionRef: MutableRefObject; + handleDeleteCommentRequest: HandleDeleteCommentRequest; + handleEditCommentRequest: HandleEditCommentRequest; + pageSize: number; } const CommentsComponent: FC = ({ comments, commentSectionRef, - handleDeleteRequest, - handleEditRequest, + handleDeleteCommentRequest, + handleEditCommentRequest, isAtEnd, isLoadingMore, mutate, @@ -50,8 +44,8 @@ const CommentsComponent: FC = ({ const { ref: penultimateCommentRef } = useInView({ threshold: 0.1, /** - * When the last comment comes into view, call setSize from useBeerPostComments to - * load more comments. + * When the last comment comes into view, call setSize from the comment fetching hook + * to load more comments. */ onChange: (visible) => { if (!visible || isAtEnd) return; @@ -78,8 +72,8 @@ const CommentsComponent: FC = ({
); @@ -90,7 +84,7 @@ const CommentsComponent: FC = ({ * If there are more comments to load, show a loading component with a * skeleton loader and a loading spinner. */ - !!isLoadingMore && + !!isLoadingMore && } { diff --git a/src/components/BeerBreweryComments/EditCommentBody.tsx b/src/components/Comments/EditCommentBody.tsx similarity index 87% rename from src/components/BeerBreweryComments/EditCommentBody.tsx rename to src/components/Comments/EditCommentBody.tsx index e638baf..cb5d985 100644 --- a/src/components/BeerBreweryComments/EditCommentBody.tsx +++ b/src/components/Comments/EditCommentBody.tsx @@ -14,6 +14,7 @@ import FormInfo from '../ui/forms/FormInfo'; import FormLabel from '../ui/forms/FormLabel'; import FormSegment from '../ui/forms/FormSegment'; import FormTextArea from '../ui/forms/FormTextArea'; +import { HandleDeleteCommentRequest, HandleEditCommentRequest } from './types'; interface EditCommentBodyProps { comment: z.infer; @@ -22,19 +23,16 @@ interface EditCommentBodyProps { mutate: ReturnType< typeof useBeerPostComments | typeof useBreweryPostComments >['mutate']; - handleDeleteRequest: (id: string) => Promise; - handleEditRequest: ( - id: string, - data: z.infer, - ) => Promise; + handleDeleteCommentRequest: HandleDeleteCommentRequest; + handleEditCommentRequest: HandleEditCommentRequest; } const EditCommentBody: FC = ({ comment, setInEditMode, mutate, - handleDeleteRequest, - handleEditRequest, + handleDeleteCommentRequest, + handleEditCommentRequest, }) => { const { register, handleSubmit, formState, setValue, watch } = useForm< z.infer @@ -51,7 +49,7 @@ const EditCommentBody: FC = ({ const loadingToast = toast.loading('Deleting comment...'); setIsDeleting(true); try { - await handleDeleteRequest(comment.id); + await handleDeleteCommentRequest(comment.id); await mutate(); toast.remove(loadingToast); toast.success('Deleted comment.'); @@ -68,7 +66,7 @@ const EditCommentBody: FC = ({ try { setInEditMode(true); - await handleEditRequest(comment.id, data); + await handleEditCommentRequest(comment.id, data); await mutate(); toast.remove(loadingToast); toast.success('Comment edits submitted successfully.'); @@ -80,6 +78,8 @@ const EditCommentBody: FC = ({ } }; + const disableForm = isSubmitting || isDeleting; + return (
@@ -95,7 +95,7 @@ const EditCommentBody: FC = ({ placeholder="Comment" rows={2} error={!!errors.content?.message} - disabled={isSubmitting || isDeleting} + disabled={disableForm} />
@@ -114,8 +114,8 @@ const EditCommentBody: FC = ({ ))} @@ -125,7 +125,7 @@ const EditCommentBody: FC = ({ diff --git a/src/components/BeerById/NoCommentsCard.tsx b/src/components/Comments/NoCommentsCard.tsx similarity index 100% rename from src/components/BeerById/NoCommentsCard.tsx rename to src/components/Comments/NoCommentsCard.tsx diff --git a/src/components/Comments/types/index.ts b/src/components/Comments/types/index.ts new file mode 100644 index 0000000..597d37d --- /dev/null +++ b/src/components/Comments/types/index.ts @@ -0,0 +1,12 @@ +import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema'; +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; +import { z } from 'zod'; + +type APIResponse = z.infer; + +export type HandleEditCommentRequest = ( + id: string, + data: z.infer, +) => Promise; + +export type HandleDeleteCommentRequest = (id: string) => Promise; diff --git a/src/requests/comments/beer-comment/index.ts b/src/requests/comments/beer-comment/index.ts index dc39c1b..cc6863c 100644 --- a/src/requests/comments/beer-comment/index.ts +++ b/src/requests/comments/beer-comment/index.ts @@ -11,9 +11,11 @@ import { * * @param params - The parameters for the request. * @param params.body - The body of the request. + * @param params.body.content - The content of the comment. + * @param params.body.rating - The rating of the beer. * @param params.commentId - The id of the comment to edit. * @param params.beerPostId - The id of the beer post the comment belongs to. - * @returns The edited comment. + * @returns The JSON response from the server. * @throws An error if the request fails or the response is invalid. */ export const editBeerPostCommentRequest: SendEditBeerPostCommentRequest = async ({ @@ -47,7 +49,7 @@ export const editBeerPostCommentRequest: SendEditBeerPostCommentRequest = async * @param params - The parameters for the request. * @param params.commentId - The id of the comment to delete. * @param params.beerPostId - The id of the beer post the comment belongs to. - * @returns The deleted comment. + * @returns The JSON response from the server. * @throws An error if the request fails or the response is invalid. */ export const deleteBeerPostCommentRequest: SendDeleteBeerPostCommentRequest = async ({ diff --git a/src/requests/comments/beer-style-comment/index.ts b/src/requests/comments/beer-style-comment/index.ts index 5c8629c..1beded3 100644 --- a/src/requests/comments/beer-style-comment/index.ts +++ b/src/requests/comments/beer-style-comment/index.ts @@ -6,6 +6,88 @@ import { SendEditBeerStyleCommentRequest, } from './types'; +/** + * Sends an api request to edit a beer style comment. + * + * @param params - The parameters for the request. + * @param params.body - The body of the request. + * @param params.body.content - The content of the comment. + * @param params.body.rating - The rating of the beer. + * @param params.beerStyleId - The id of the beer style the comment belongs to. + * @param params.commentId - The id of the comment to edit. + * @returns The JSON response from the server. + * @throws An error if the request fails or the response is invalid. + */ +export const sendEditBeerStyleCommentRequest: SendEditBeerStyleCommentRequest = async ({ + commentId, + body: { content, rating }, + beerStyleId, +}) => { + const response = await fetch(`/api/beers/styles/${beerStyleId}/comments/${commentId}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ content, rating }), + }); + + if (!response.ok) { + throw new Error(response.statusText); + } + + const json = await response.json(); + + const parsed = APIResponseValidationSchema.safeParse(json); + + if (!parsed.success) { + throw new Error('Invalid API response'); + } + + return parsed.data; +}; + +/** + * Sends an api request to delete a beer style comment. + * + * @param params - The parameters for the request. + * @param params.beerStyleId - The id of the beer style the comment belongs to. + * @param params.commentId - The id of the comment to delete. + * @returns The json response from the server. + * @throws An error if the request fails or the response is invalid. + */ +export const sendDeleteBeerStyleCommentRequest: SendDeleteBeerStyleCommentRequest = + async ({ beerStyleId, commentId }) => { + const response = await fetch( + `/api/beers/styles/${beerStyleId}/comments/${commentId}`, + { + method: 'DELETE', + }, + ); + + if (!response.ok) { + throw new Error(response.statusText); + } + + const json = await response.json(); + + const parsed = APIResponseValidationSchema.safeParse(json); + + if (!parsed.success) { + throw new Error('Invalid API response'); + } + + return parsed.data; + }; + +/** + * Sends an api request to create a beer style comment. + * + * @param params - The parameters for the request. + * @param params.body - The body of the request. + * @param params.body.content - The content of the comment. + * @param params.body.rating - The rating of the beer. + * @param params.beerStyleId - The id of the beer style the comment belongs to. + * @returns The created comment. + * @throws An error if the request fails or the response is invalid. + */ export const sendCreateBeerStyleCommentRequest: SendCreateBeerStyleCommentRequest = async ({ beerStyleId, body: { content, rating } }) => { const response = await fetch(`/api/beers/styles/${beerStyleId}/comments`, { @@ -33,53 +115,3 @@ export const sendCreateBeerStyleCommentRequest: SendCreateBeerStyleCommentReques return parsedPayload.data; }; - -export const sendEditBeerStyleCommentRequest: SendEditBeerStyleCommentRequest = async ({ - commentId, - body: { content, rating }, - beerStyleId, -}) => { - const response = await fetch(`/api/beers/styles/${beerStyleId}/comments/${commentId}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ content, rating }), - }); - - if (!response.ok) { - throw new Error(response.statusText); - } - - const json = await response.json(); - - const parsed = APIResponseValidationSchema.safeParse(json); - - if (!parsed.success) { - throw new Error('Invalid API response'); - } - - return parsed.data; -}; - -export const sendDeleteBeerStyleCommentRequest: SendDeleteBeerStyleCommentRequest = - async ({ beerStyleId, commentId }) => { - const response = await fetch( - `/api/beers/styles/${beerStyleId}/comments/${commentId}`, - { - method: 'DELETE', - }, - ); - - if (!response.ok) { - throw new Error(response.statusText); - } - - const json = await response.json(); - - const parsed = APIResponseValidationSchema.safeParse(json); - - if (!parsed.success) { - throw new Error('Invalid API response'); - } - - return parsed.data; - }; diff --git a/src/requests/comments/brewery-comment/index.ts b/src/requests/comments/brewery-comment/index.ts new file mode 100644 index 0000000..cd3b794 --- /dev/null +++ b/src/requests/comments/brewery-comment/index.ts @@ -0,0 +1,109 @@ +import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult'; +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; +import { + SendCreateBreweryPostCommentRequest, + SendDeleteBreweryPostCommentRequest, + SendEditBreweryPostCommentRequest, +} from './types'; +/** + * Sends an api request to edit a brewery comment. + * + * @param params - The parameters for the request. + * @param params.breweryId - The id of the brewery the comment belongs to. + * @param params.commentId - The id of the comment to edit. + * @param params.body - The body of the request. + * @param params.body.content - The content of the comment. + * @param params.body.rating - The rating of the beer. + */ +export const sendEditBreweryPostCommentRequest: SendEditBreweryPostCommentRequest = + async ({ body: { content, rating }, breweryPostId, commentId }) => { + const response = await fetch( + `/api/breweries/${breweryPostId}/comments/${commentId}`, + { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ content, rating }), + }, + ); + + if (!response.ok) { + throw new Error(response.statusText); + } + + const json = await response.json(); + const parsed = APIResponseValidationSchema.safeParse(json); + + if (!parsed.success) { + throw new Error(parsed.error.message); + } + + return parsed.data; + }; + +/** + * Sends an api request to delete a brewery comment. + * + * @param params - The parameters for the request. + * @param params.breweryId - The id of the brewery the comment belongs to. + * @param params.commentId - The id of the comment to delete. + * @returns The JSON response from the server. + * @throws An error if the request fails or the response is invalid. + */ +export const sendDeleteBreweryPostCommentRequest: SendDeleteBreweryPostCommentRequest = + async ({ breweryPostId, commentId }) => { + const response = await fetch( + `/api/breweries/${breweryPostId}/comments/${commentId}`, + { + method: 'DELETE', + }, + ); + + if (!response.ok) { + throw new Error(response.statusText); + } + + const json = await response.json(); + const parsed = APIResponseValidationSchema.safeParse(json); + + if (!parsed.success) { + throw new Error(parsed.error.message); + } + + return parsed.data; + }; +/** + * Sends an api request to create a brewery comment. + * + * @param params - The parameters for the request. + * @param params.body - The body of the request. + * @param params.body.content - The content of the comment. + * @param params.body.rating - The rating of the beer. + * @param params.breweryId - The id of the brewery the comment belongs to. + * @returns The created comment. + * @throws An error if the request fails or the response is invalid. + */ +export const sendCreateBreweryCommentRequest: SendCreateBreweryPostCommentRequest = + async ({ body: { content, rating }, breweryPostId }) => { + const response = await fetch(`/api/breweries/${breweryPostId}/comments`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ content, rating }), + }); + + if (!response.ok) { + throw new Error(response.statusText); + } + + const data = await response.json(); + const parsedResponse = APIResponseValidationSchema.safeParse(data); + if (!parsedResponse.success) { + throw new Error('Invalid API response'); + } + + const parsedPayload = CommentQueryResult.safeParse(parsedResponse.data.payload); + if (!parsedPayload.success) { + throw new Error('Invalid API response payload'); + } + + return parsedPayload.data; + }; diff --git a/src/requests/comments/brewery-comment/types/index.ts b/src/requests/comments/brewery-comment/types/index.ts new file mode 100644 index 0000000..be3eac6 --- /dev/null +++ b/src/requests/comments/brewery-comment/types/index.ts @@ -0,0 +1,19 @@ +import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult'; +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; +import { z } from 'zod'; + +export type SendEditBreweryPostCommentRequest = (args: { + body: { content: string; rating: number }; + commentId: string; + breweryPostId: string; +}) => Promise>; + +export type SendDeleteBreweryPostCommentRequest = (args: { + commentId: string; + breweryPostId: string; +}) => Promise>; + +export type SendCreateBreweryPostCommentRequest = (args: { + breweryPostId: string; + body: { content: string; rating: number }; +}) => Promise>;