mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +00:00
Merge pull request #12 from aaronpo97/dev
Refactor BeerPostHeader, refactor login and register
This commit is contained in:
@@ -39,10 +39,10 @@ const BeerInfoHeader: FC<{ beerPost: BeerPostQueryResult; initialLikeCount: numb
|
||||
}, [beerPost.createdAt]);
|
||||
|
||||
return (
|
||||
<div className="card flex flex-col justify-center bg-base-300">
|
||||
<div className="card-body">
|
||||
<main className="card flex flex-col justify-center bg-base-300">
|
||||
<article className="card-body">
|
||||
<div className="flex justify-between">
|
||||
<div>
|
||||
<header>
|
||||
<h1 className="text-4xl font-bold">{beerPost.name}</h1>
|
||||
<h2 className="text-2xl font-semibold">
|
||||
by{' '}
|
||||
@@ -53,8 +53,7 @@ const BeerInfoHeader: FC<{ beerPost: BeerPostQueryResult; initialLikeCount: numb
|
||||
{beerPost.brewery.name}
|
||||
</Link>
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
</header>
|
||||
{isPostOwner && (
|
||||
<div className="tooltip tooltip-left" data-tip={`Edit '${beerPost.name}'`}>
|
||||
<Link
|
||||
@@ -66,18 +65,17 @@ const BeerInfoHeader: FC<{ beerPost: BeerPostQueryResult; initialLikeCount: numb
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 className="italic">
|
||||
posted by{' '}
|
||||
<Link href={`/users/${beerPost.postedBy.id}`} className="link-hover link">
|
||||
{beerPost.postedBy.username}{' '}
|
||||
{beerPost.postedBy.username}
|
||||
</Link>
|
||||
<span
|
||||
className="tooltip tooltip-bottom"
|
||||
data-tip={format(createdAtDate, 'MM/dd/yyyy')}
|
||||
>
|
||||
{timeDistance} ago
|
||||
{` ${timeDistance}`} ago
|
||||
</span>
|
||||
</h3>
|
||||
|
||||
@@ -108,8 +106,8 @@ const BeerInfoHeader: FC<{ beerPost: BeerPostQueryResult; initialLikeCount: numb
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -50,6 +50,18 @@ const EditBeerPostForm: FC<EditBeerPostFormProps> = ({ 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 (
|
||||
<form className="form-control" onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="mb-5">
|
||||
@@ -116,10 +128,17 @@ const EditBeerPostForm: FC<EditBeerPostFormProps> = ({ previousValues }) => {
|
||||
/>
|
||||
</FormSegment>
|
||||
|
||||
<div className="mt-2">
|
||||
<div className="mt-2 space-y-4">
|
||||
<Button type="submit" isSubmitting={isSubmitting}>
|
||||
{isSubmitting ? 'Submitting...' : 'Submit'}
|
||||
</Button>
|
||||
<button
|
||||
className={`btn-primary btn w-full rounded-xl ${isSubmitting ? 'loading' : ''}`}
|
||||
type="button"
|
||||
onClick={onDelete}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
17
hooks/useRedirectIfLoggedIn.ts
Normal file
17
hooks/useRedirectIfLoggedIn.ts
Normal file
@@ -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;
|
||||
@@ -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<typeof EditBeerPostValidationSchema>;
|
||||
}
|
||||
|
||||
const editBeerPost = async (
|
||||
req: EditBeerPostRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
router.put(getCurrentUser, editBeerPost);
|
||||
router.put(getCurrentUser, checkIfBeerPostOwner, editBeerPost);
|
||||
router.delete(getCurrentUser, checkIfBeerPostOwner, deleteBeerPost);
|
||||
|
||||
const handler = router.handler(NextConnectOptions);
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<Layout>
|
||||
<Head>
|
||||
@@ -52,8 +54,3 @@ const LoginPage: NextPage = () => {
|
||||
};
|
||||
|
||||
export default LoginPage;
|
||||
|
||||
export const getServerSideProps = redirectIfLoggedIn({
|
||||
destination: '/',
|
||||
permanent: false,
|
||||
});
|
||||
|
||||
@@ -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 (
|
||||
<Layout>
|
||||
<Head>
|
||||
@@ -26,8 +29,3 @@ const RegisterUserPage: NextPage = () => {
|
||||
};
|
||||
|
||||
export default RegisterUserPage;
|
||||
|
||||
export const getServerSideProps = redirectIfLoggedIn({
|
||||
destination: '/',
|
||||
permanent: false,
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user