diff --git a/.gitignore b/.gitignore index 2306282..a87bdfa 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ next-env.d.ts /cloudinary-images +.obsidian \ No newline at end of file diff --git a/src/components/BeerStyleById/BeerStyleCommentForm.tsx b/src/components/BeerStyleById/BeerStyleCommentForm.tsx index 7ab0df9..d6376eb 100644 --- a/src/components/BeerStyleById/BeerStyleCommentForm.tsx +++ b/src/components/BeerStyleById/BeerStyleCommentForm.tsx @@ -10,7 +10,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/sendCreateBeerStyleCommentRequest'; +import { sendCreateBeerStyleCommentRequest } from '@/requests/comments/beer-style-comment'; import CommentForm from '../ui/CommentForm'; interface BeerCommentFormProps { @@ -35,8 +35,7 @@ const BeerStyleCommentForm: FunctionComponent = ({ const loadingToast = toast.loading('Posting a new comment...'); try { await sendCreateBeerStyleCommentRequest({ - content: data.content, - rating: data.rating, + body: { content: data.content, rating: data.rating }, beerStyleId: beerStyle.id, }); reset(); diff --git a/src/components/BeerStyleById/BeerStyleCommentSection.tsx b/src/components/BeerStyleById/BeerStyleCommentSection.tsx index 470ee7e..7d742f9 100644 --- a/src/components/BeerStyleById/BeerStyleCommentSection.tsx +++ b/src/components/BeerStyleById/BeerStyleCommentSection.tsx @@ -10,6 +10,10 @@ import useBeerStyleComments from '@/hooks/data-fetching/beer-style-comments/useB import LoadingComponent from '../BeerById/LoadingComponent'; import CommentsComponent from '../ui/CommentsComponent'; import BeerStyleCommentForm from './BeerStyleCommentForm'; +import { + sendDeleteBeerStyleCommentRequest, + sendEditBeerStyleCommentRequest, +} from '@/requests/comments/beer-style-comment'; interface BeerStyleCommentsSectionProps { beerStyle: z.infer; @@ -28,28 +32,18 @@ const BeerStyleCommentsSection: FC = ({ beerStyle const commentSectionRef: MutableRefObject = useRef(null); const handleDeleteRequest = async (id: string) => { - const response = await fetch(`/api/beers/styles/${beerStyle.id}/comments/${id}`, { - method: 'DELETE', - }); - - if (!response.ok) { - throw new Error('Failed to delete comment.'); - } + await sendDeleteBeerStyleCommentRequest({ beerStyleId: beerStyle.id, commentId: id }); }; const handleEditRequest = async ( id: string, data: z.infer, ) => { - const response = await fetch(`/api/beers/styles/${beerStyle.id}/comments/${id}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ content: data.content, rating: data.rating }), + await sendEditBeerStyleCommentRequest({ + beerStyleId: beerStyle.id, + commentId: id, + body: data, }); - - if (!response.ok) { - throw new Error(response.statusText); - } }; return ( diff --git a/src/components/BreweryById/BreweryCommentsSection.tsx b/src/components/BreweryById/BreweryCommentsSection.tsx index 1ecbcfc..a40da94 100644 --- a/src/components/BreweryById/BreweryCommentsSection.tsx +++ b/src/components/BreweryById/BreweryCommentsSection.tsx @@ -57,7 +57,6 @@ const BreweryCommentsSection: FC = ({ breweryPost }) => if (!response.ok) { throw new Error(response.statusText); } - console.log(await response.json()); }; return ( diff --git a/src/pages/api/breweries/[postId]/like/index.ts b/src/pages/api/breweries/[postId]/like/index.ts index 1bdc931..5073764 100644 --- a/src/pages/api/breweries/[postId]/like/index.ts +++ b/src/pages/api/breweries/[postId]/like/index.ts @@ -1,4 +1,3 @@ -import { UserExtendedNextApiRequest } from '@/config/auth/types'; import NextConnectOptions from '@/config/nextConnect/NextConnectOptions'; import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser'; import validateRequest from '@/config/nextConnect/middleware/validateRequest'; @@ -6,6 +5,7 @@ import { sendBreweryPostLikeRequest, getBreweryPostLikeCount, } from '@/controllers/likes/brewery-post-likes'; +import { LikeRequest } from '@/controllers/likes/types'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiResponse } from 'next'; @@ -13,7 +13,7 @@ import { createRouter } from 'next-connect'; import { z } from 'zod'; const router = createRouter< - UserExtendedNextApiRequest, + LikeRequest, NextApiResponse> >(); diff --git a/src/pages/api/breweries/[postId]/like/is-liked.ts b/src/pages/api/breweries/[postId]/like/is-liked.ts index 16e97bf..c169b1b 100644 --- a/src/pages/api/breweries/[postId]/like/is-liked.ts +++ b/src/pages/api/breweries/[postId]/like/is-liked.ts @@ -1,8 +1,8 @@ -import { UserExtendedNextApiRequest } from '@/config/auth/types'; import NextConnectOptions from '@/config/nextConnect/NextConnectOptions'; import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser'; import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import { getBreweryPostLikeStatus } from '@/controllers/likes/brewery-post-likes'; +import { LikeRequest } from '@/controllers/likes/types'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiResponse } from 'next'; @@ -10,7 +10,7 @@ import { createRouter } from 'next-connect'; import { z } from 'zod'; const router = createRouter< - UserExtendedNextApiRequest, + LikeRequest, NextApiResponse> >(); diff --git a/src/requests/comments/beer-comment/index.ts b/src/requests/comments/beer-comment/index.ts index d922500..dc39c1b 100644 --- a/src/requests/comments/beer-comment/index.ts +++ b/src/requests/comments/beer-comment/index.ts @@ -6,6 +6,16 @@ import { SendEditBeerPostCommentRequest, } from './types'; +/** + * Sends an api request to edit a beer post comment. + * + * @param params - The parameters for the request. + * @param params.body - The body of the request. + * @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. + * @throws An error if the request fails or the response is invalid. + */ export const editBeerPostCommentRequest: SendEditBeerPostCommentRequest = async ({ body, commentId, @@ -22,7 +32,6 @@ export const editBeerPostCommentRequest: SendEditBeerPostCommentRequest = async } const json = await response.json(); - const parsed = APIResponseValidationSchema.safeParse(json); if (!parsed.success) { @@ -32,6 +41,15 @@ export const editBeerPostCommentRequest: SendEditBeerPostCommentRequest = async return parsed.data; }; +/** + * Sends an api request to delete a beer post comment. + * + * @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. + * @throws An error if the request fails or the response is invalid. + */ export const deleteBeerPostCommentRequest: SendDeleteBeerPostCommentRequest = async ({ commentId, beerPostId, @@ -45,7 +63,6 @@ export const deleteBeerPostCommentRequest: SendDeleteBeerPostCommentRequest = as } const json = await response.json(); - const parsed = APIResponseValidationSchema.safeParse(json); if (!parsed.success) { @@ -55,22 +72,32 @@ export const deleteBeerPostCommentRequest: SendDeleteBeerPostCommentRequest = as return parsed.data; }; +/** + * Send an api request to create a comment on a beer post. + * + * @param params - The parameters for the request. + * @param params.beerPostId - The id of the beer post to create the comment on. + * @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. + * @returns The created comment. + * @throws An error if the request fails or the response is invalid. + */ export const sendCreateBeerCommentRequest: SendCreateBeerCommentRequest = async ({ beerPostId, - body, + body: { content, rating }, }) => { - const { content, rating } = body; const response = await fetch(`/api/beers/${beerPostId}/comments`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ beerPostId, content, rating }), }); + if (!response.ok) { throw new Error(response.statusText); } const data = await response.json(); - const parsedResponse = APIResponseValidationSchema.safeParse(data); if (!parsedResponse.success) { diff --git a/src/requests/comments/beer-style-comment/index.ts b/src/requests/comments/beer-style-comment/index.ts new file mode 100644 index 0000000..5c8629c --- /dev/null +++ b/src/requests/comments/beer-style-comment/index.ts @@ -0,0 +1,85 @@ +import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult'; +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; +import { + SendCreateBeerStyleCommentRequest, + SendDeleteBeerStyleCommentRequest, + SendEditBeerStyleCommentRequest, +} from './types'; + +export const sendCreateBeerStyleCommentRequest: SendCreateBeerStyleCommentRequest = + async ({ beerStyleId, body: { content, rating } }) => { + const response = await fetch(`/api/beers/styles/${beerStyleId}/comments`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ beerStyleId, 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; + }; + +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/beer-style-comment/sendCreateBeerStyleCommentRequest.ts b/src/requests/comments/beer-style-comment/sendCreateBeerStyleCommentRequest.ts deleted file mode 100644 index 89a0cd9..0000000 --- a/src/requests/comments/beer-style-comment/sendCreateBeerStyleCommentRequest.ts +++ /dev/null @@ -1,53 +0,0 @@ -import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult'; -import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema'; - -import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; -import { z } from 'zod'; - -const BeerStyleCommentValidationSchemaWithId = CreateCommentValidationSchema.extend({ - beerStyleId: z.string().cuid(), -}); - -/** - * Sends a POST request to the server to create a new beer comment. - * - * @param data The data to be sent to the server. - * @param data.beerPostId The ID of the beer post to comment on. - * @param data.content The content of the comment. - * @param data.rating The rating of the beer. - * @returns A promise that resolves to the created comment. - * @throws An error if the request fails, the API response is invalid, or the API response - * payload is invalid. - */ -const sendCreateBeerStyleCommentRequest = async ({ - beerStyleId, - content, - rating, -}: z.infer) => { - const response = await fetch(`/api/beers/styles/${beerStyleId}/comments`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ beerStyleId, 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; -}; - -export default sendCreateBeerStyleCommentRequest; diff --git a/src/requests/comments/beer-style-comment/types/index.ts b/src/requests/comments/beer-style-comment/types/index.ts new file mode 100644 index 0000000..e9b695a --- /dev/null +++ b/src/requests/comments/beer-style-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 SendEditBeerStyleCommentRequest = (args: { + body: { content: string; rating: number }; + commentId: string; + beerStyleId: string; +}) => Promise>; + +export type SendDeleteBeerStyleCommentRequest = (args: { + commentId: string; + beerStyleId: string; +}) => Promise>; + +export type SendCreateBeerStyleCommentRequest = (args: { + beerStyleId: string; + body: { content: string; rating: number }; +}) => Promise>;