From 6b12cb72c51a43c77e58fe650a1da6c487fa13a8 Mon Sep 17 00:00:00 2001 From: Aaron William Po Date: Wed, 15 Mar 2023 21:30:26 -0400 Subject: [PATCH] Refactor BeerPostHeader, refactor login and register - Updated BeerPostHeader in /id page to use semantic HTML tags - Removed the getServerSidesProps fn in /login and /register. Moved the redirect logic over to the client, will redirect on the client side. - Added delete BeerPost option on the edit page. --- components/BeerById/BeerInfoHeader.tsx | 38 +++++++++--------- components/EditBeerPostForm.tsx | 21 +++++++++- getServerSideProps/redirectIfLoggedIn.ts | 28 ------------- hooks/useRedirectIfLoggedIn.ts | 17 ++++++++ pages/api/beers/[id]/index.ts | 51 ++++++++++++++++++++---- pages/login/index.tsx | 9 ++--- pages/register/index.tsx | 10 ++--- requests/sendCreateBeerCommentRequest.ts | 1 - 8 files changed, 106 insertions(+), 69 deletions(-) delete mode 100644 getServerSideProps/redirectIfLoggedIn.ts create mode 100644 hooks/useRedirectIfLoggedIn.ts diff --git a/components/BeerById/BeerInfoHeader.tsx b/components/BeerById/BeerInfoHeader.tsx index acb4200..58b6b55 100644 --- a/components/BeerById/BeerInfoHeader.tsx +++ b/components/BeerById/BeerInfoHeader.tsx @@ -39,10 +39,10 @@ const BeerInfoHeader: FC<{ beerPost: BeerPostQueryResult; initialLikeCount: numb }, [beerPost.createdAt]); return ( -
-
+
+
-
+

{beerPost.name}

by{' '} @@ -53,31 +53,29 @@ const BeerInfoHeader: FC<{ beerPost: BeerPostQueryResult; initialLikeCount: numb {beerPost.brewery.name}

-
-
- {isPostOwner && ( -
- - - -
- )} -
+ + {isPostOwner && ( +
+ + + +
+ )}

posted by{' '} - {beerPost.postedBy.username}{' '} + {beerPost.postedBy.username} - {timeDistance} ago + {` ${timeDistance}`} ago

@@ -108,8 +106,8 @@ const BeerInfoHeader: FC<{ beerPost: BeerPostQueryResult; initialLikeCount: numb )}
- - + + ); }; diff --git a/components/EditBeerPostForm.tsx b/components/EditBeerPostForm.tsx index 07163a7..491ae53 100644 --- a/components/EditBeerPostForm.tsx +++ b/components/EditBeerPostForm.tsx @@ -50,6 +50,18 @@ const EditBeerPostForm: FC = ({ previousValues }) => { } }; + const onDelete = async () => { + try { + const response = await fetch(`/api/beers/${previousValues.id}`, { + method: 'DELETE', + }); + if (response.status === 200) { + router.push('/beers'); + } + } catch (e) { + console.error(e); + } + }; return (
@@ -116,10 +128,17 @@ const EditBeerPostForm: FC = ({ previousValues }) => { /> -
+
+
); diff --git a/getServerSideProps/redirectIfLoggedIn.ts b/getServerSideProps/redirectIfLoggedIn.ts deleted file mode 100644 index 5d2b2a7..0000000 --- a/getServerSideProps/redirectIfLoggedIn.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { GetServerSideProps, GetServerSidePropsContext, Redirect } from 'next'; -import { getLoginSession } from '@/config/auth/session'; -import findUserById from '@/services/User/findUserById'; - -const redirectIfLoggedIn = (redirect: Redirect) => { - const fn: GetServerSideProps = async (context: GetServerSidePropsContext) => { - try { - const { req } = context; - const session = await getLoginSession(req); - - const { id } = session; - - const user = await findUserById(id); - - if (!user) { - throw new Error('Could not get user.'); - } - - return { redirect }; - } catch { - return { props: {} }; - } - }; - - return fn; -}; - -export default redirectIfLoggedIn; diff --git a/hooks/useRedirectIfLoggedIn.ts b/hooks/useRedirectIfLoggedIn.ts new file mode 100644 index 0000000..35e5ab0 --- /dev/null +++ b/hooks/useRedirectIfLoggedIn.ts @@ -0,0 +1,17 @@ +import UserContext from '@/contexts/userContext'; +import { useRouter } from 'next/router'; +import { useContext, useEffect } from 'react'; + +const useRedirectWhenLoggedIn = () => { + const { user } = useContext(UserContext); + const router = useRouter(); + + useEffect(() => { + if (!user) { + return; + } + router.push('/'); + }, [user, router]); +}; + +export default useRedirectWhenLoggedIn; diff --git a/pages/api/beers/[id]/index.ts b/pages/api/beers/[id]/index.ts index 001b6b7..a1b24ae 100644 --- a/pages/api/beers/[id]/index.ts +++ b/pages/api/beers/[id]/index.ts @@ -6,20 +6,25 @@ import editBeerPostById from '@/services/BeerPost/editBeerPostById'; import EditBeerPostValidationSchema from '@/services/BeerPost/schema/EditBeerPostValidationSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiResponse } from 'next'; -import { createRouter } from 'next-connect'; +import { createRouter, NextHandler } from 'next-connect'; import { z } from 'zod'; import ServerError from '@/config/util/ServerError'; +import DBClient from '@/prisma/DBClient'; -interface EditBeerPostRequest extends UserExtendedNextApiRequest { +interface BeerPostRequest extends UserExtendedNextApiRequest { query: { id: string }; +} + +interface EditBeerPostRequest extends BeerPostRequest { body: z.infer; } -const editBeerPost = async ( - req: EditBeerPostRequest, - res: NextApiResponse>, +const checkIfBeerPostOwner = async ( + req: BeerPostRequest, + res: NextApiResponse, + next: NextHandler, ) => { - const { body, user, query } = req; + const { user, query } = req; const { id } = query; const beerPost = await getBeerPostById(id); @@ -32,6 +37,18 @@ const editBeerPost = async ( throw new ServerError('You cannot edit that beer post.', 403); } + next(); +}; + +const editBeerPost = async ( + req: EditBeerPostRequest, + res: NextApiResponse>, +) => { + const { + body, + query: { id }, + } = req; + await editBeerPostById(id, body); res.status(200).json({ @@ -41,12 +58,32 @@ const editBeerPost = async ( }); }; +const deleteBeerPost = async (req: BeerPostRequest, res: NextApiResponse) => { + const { + query: { id }, + } = req; + + const deleted = await DBClient.instance.beerPost.delete({ + where: { id }, + }); + + if (!deleted) { + throw new ServerError('Beer post not found', 404); + } + + res.status(200).json({ + message: 'Beer post deleted successfully', + success: true, + statusCode: 200, + }); +}; const router = createRouter< EditBeerPostRequest, NextApiResponse> >(); -router.put(getCurrentUser, editBeerPost); +router.put(getCurrentUser, checkIfBeerPostOwner, editBeerPost); +router.delete(getCurrentUser, checkIfBeerPostOwner, deleteBeerPost); const handler = router.handler(NextConnectOptions); diff --git a/pages/login/index.tsx b/pages/login/index.tsx index 0eb5836..a9a895d 100644 --- a/pages/login/index.tsx +++ b/pages/login/index.tsx @@ -6,9 +6,11 @@ import Image from 'next/image'; import { FaUserCircle } from 'react-icons/fa'; import Head from 'next/head'; import Link from 'next/link'; -import redirectIfLoggedIn from '@/getServerSideProps/redirectIfLoggedIn'; + +import useRedirectWhenLoggedIn from '@/hooks/useRedirectIfLoggedIn'; const LoginPage: NextPage = () => { + useRedirectWhenLoggedIn(); return ( @@ -52,8 +54,3 @@ const LoginPage: NextPage = () => { }; export default LoginPage; - -export const getServerSideProps = redirectIfLoggedIn({ - destination: '/', - permanent: false, -}); diff --git a/pages/register/index.tsx b/pages/register/index.tsx index b34c605..a021de9 100644 --- a/pages/register/index.tsx +++ b/pages/register/index.tsx @@ -1,12 +1,15 @@ import RegisterUserForm from '@/components/RegisterUserForm'; import FormPageLayout from '@/components/ui/forms/FormPageLayout'; import Layout from '@/components/ui/Layout'; -import redirectIfLoggedIn from '@/getServerSideProps/redirectIfLoggedIn'; + +import useRedirectWhenLoggedIn from '@/hooks/useRedirectIfLoggedIn'; import { NextPage } from 'next'; import Head from 'next/head'; import { BiUser } from 'react-icons/bi'; const RegisterUserPage: NextPage = () => { + useRedirectWhenLoggedIn(); + return ( @@ -26,8 +29,3 @@ const RegisterUserPage: NextPage = () => { }; export default RegisterUserPage; - -export const getServerSideProps = redirectIfLoggedIn({ - destination: '/', - permanent: false, -}); diff --git a/requests/sendCreateBeerCommentRequest.ts b/requests/sendCreateBeerCommentRequest.ts index 2d10359..6683728 100644 --- a/requests/sendCreateBeerCommentRequest.ts +++ b/requests/sendCreateBeerCommentRequest.ts @@ -36,7 +36,6 @@ const sendCreateBeerCommentRequest = async ({ throw new Error('Invalid API response'); } - console.log(parsedResponse); const parsedPayload = BeerCommentQueryResult.safeParse(parsedResponse.data.payload); if (!parsedPayload.success) {