mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +00:00
Update api routes to use authenticated user
This commit is contained in:
77
components/Login/LoginForm.tsx
Normal file
77
components/Login/LoginForm.tsx
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import sendLoginUserRequest from '@/requests/sendLoginUserRequest';
|
||||||
|
import LoginValidationSchema from '@/services/user/schema/LoginValidationSchema';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||||
|
import { z } from 'zod';
|
||||||
|
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 FormTextInput from '../ui/forms/FormTextInput';
|
||||||
|
|
||||||
|
type LoginT = z.infer<typeof LoginValidationSchema>;
|
||||||
|
const LoginForm = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
const { register, handleSubmit, formState } = useForm<LoginT>({
|
||||||
|
resolver: zodResolver(LoginValidationSchema),
|
||||||
|
defaultValues: {
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { errors } = formState;
|
||||||
|
|
||||||
|
const onSubmit: SubmitHandler<LoginT> = async (data) => {
|
||||||
|
try {
|
||||||
|
const response = await sendLoginUserRequest(data);
|
||||||
|
|
||||||
|
router.push(`/users/${response.id}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className="form-control w-9/12 space-y-5" onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<div>
|
||||||
|
<FormInfo>
|
||||||
|
<FormLabel htmlFor="username">username</FormLabel>
|
||||||
|
<FormError>{errors.username?.message}</FormError>
|
||||||
|
</FormInfo>
|
||||||
|
<FormSegment>
|
||||||
|
<FormTextInput
|
||||||
|
id="username"
|
||||||
|
type="text"
|
||||||
|
formValidationSchema={register('username')}
|
||||||
|
error={!!errors.username}
|
||||||
|
placeholder="username"
|
||||||
|
/>
|
||||||
|
</FormSegment>
|
||||||
|
|
||||||
|
<FormInfo>
|
||||||
|
<FormLabel htmlFor="password">password</FormLabel>
|
||||||
|
<FormError>{errors.password?.message}</FormError>
|
||||||
|
</FormInfo>
|
||||||
|
<FormSegment>
|
||||||
|
<FormTextInput
|
||||||
|
id="password"
|
||||||
|
type="password"
|
||||||
|
formValidationSchema={register('password')}
|
||||||
|
error={!!errors.password}
|
||||||
|
placeholder="password"
|
||||||
|
/>
|
||||||
|
</FormSegment>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full">
|
||||||
|
<button type="submit" className="btn-primary btn w-full">
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoginForm;
|
||||||
@@ -3,11 +3,11 @@ import { NextHandler } from 'next-connect';
|
|||||||
import findUserById from '@/services/user/findUserById';
|
import findUserById from '@/services/user/findUserById';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import ServerError from '@/config/util/ServerError';
|
||||||
import { getLoginSession } from '../session';
|
import { getLoginSession } from '../session';
|
||||||
import { ExtendedNextApiRequest } from '../types';
|
import { UserExtendedNextApiRequest } from '../types';
|
||||||
|
|
||||||
/** Get the current user from the session. Adds the user to the request object. */
|
/** Get the current user from the session. Adds the user to the request object. */
|
||||||
const getCurrentUser = async (
|
const getCurrentUser = async (
|
||||||
req: ExtendedNextApiRequest,
|
req: UserExtendedNextApiRequest,
|
||||||
res: NextApiResponse,
|
res: NextApiResponse,
|
||||||
next: NextHandler,
|
next: NextHandler,
|
||||||
) => {
|
) => {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const UserSessionSchema = BasicUserInfoSchema.merge(
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface ExtendedNextApiRequest extends NextApiRequest {
|
export interface UserExtendedNextApiRequest extends NextApiRequest {
|
||||||
user?: z.infer<typeof GetUserSchema>;
|
user?: z.infer<typeof GetUserSchema>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
48
config/zod/middleware/validateRequest.ts
Normal file
48
config/zod/middleware/validateRequest.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import ServerError from '@/config/util/ServerError';
|
||||||
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
import { NextHandler } from 'next-connect';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Middleware to validate the request body and/or query against a zod schema.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const handler = nextConnect(NextConnectConfig).post(
|
||||||
|
* validateRequest({ bodySchema: BeerPostValidationSchema }),
|
||||||
|
* getCurrentUser,
|
||||||
|
* createBeerPost,
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* @param args.bodySchema The body schema to validate against.
|
||||||
|
* @param args.querySchema The query schema to validate against.
|
||||||
|
* @throws ServerError with status code 400 if the request body or query is invalid.
|
||||||
|
*/
|
||||||
|
const validateRequest =
|
||||||
|
({
|
||||||
|
bodySchema,
|
||||||
|
querySchema,
|
||||||
|
}: {
|
||||||
|
bodySchema?: z.ZodSchema<any>;
|
||||||
|
querySchema?: z.ZodSchema<any>;
|
||||||
|
}) =>
|
||||||
|
async (req: NextApiRequest, res: NextApiResponse, next: NextHandler) => {
|
||||||
|
if (bodySchema) {
|
||||||
|
const parsed = bodySchema.safeParse(req.body);
|
||||||
|
if (!parsed.success) {
|
||||||
|
throw new ServerError('Invalid request body.', 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (querySchema) {
|
||||||
|
const parsed = querySchema.safeParse(req.query);
|
||||||
|
if (!parsed.success) {
|
||||||
|
throw new ServerError(parsed.error.message, 400);
|
||||||
|
}
|
||||||
|
req.query = parsed.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default validateRequest;
|
||||||
@@ -1,27 +1,31 @@
|
|||||||
|
import validateRequest from '@/config/zod/middleware/validateRequest';
|
||||||
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
||||||
import ServerError from '@/config/util/ServerError';
|
|
||||||
import createNewBeerComment from '@/services/BeerComment/createNewBeerComment';
|
import createNewBeerComment from '@/services/BeerComment/createNewBeerComment';
|
||||||
import { BeerCommentQueryResultT } from '@/services/BeerComment/schema/BeerCommentQueryResult';
|
import { BeerCommentQueryResultT } from '@/services/BeerComment/schema/BeerCommentQueryResult';
|
||||||
import BeerCommentValidationSchema from '@/services/BeerComment/schema/CreateBeerCommentValidationSchema';
|
import BeerCommentValidationSchema from '@/services/BeerComment/schema/CreateBeerCommentValidationSchema';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
|
||||||
import { NextApiHandler } from 'next';
|
|
||||||
import nextConnect from 'next-connect';
|
import nextConnect from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
||||||
|
import { NextApiResponse } from 'next';
|
||||||
|
|
||||||
const createComment: NextApiHandler<z.infer<typeof APIResponseValidationSchema>> = async (
|
interface CreateCommentRequest extends UserExtendedNextApiRequest {
|
||||||
req,
|
body: z.infer<typeof BeerCommentValidationSchema>;
|
||||||
res,
|
}
|
||||||
|
|
||||||
|
const createComment = async (
|
||||||
|
req: CreateCommentRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
) => {
|
) => {
|
||||||
const cleanedReqBody = BeerCommentValidationSchema.safeParse(req.body);
|
const { content, rating, beerPostId } = req.body;
|
||||||
if (!cleanedReqBody.success) {
|
|
||||||
throw new ServerError('Invalid request body', 400);
|
|
||||||
}
|
|
||||||
const { content, rating, beerPostId } = cleanedReqBody.data;
|
|
||||||
|
|
||||||
const newBeerComment: BeerCommentQueryResultT = await createNewBeerComment({
|
const newBeerComment: BeerCommentQueryResultT = await createNewBeerComment({
|
||||||
content,
|
content,
|
||||||
rating,
|
rating,
|
||||||
beerPostId,
|
beerPostId,
|
||||||
|
userId: req.user!.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(201).json({
|
res.status(201).json({
|
||||||
@@ -32,6 +36,10 @@ const createComment: NextApiHandler<z.infer<typeof APIResponseValidationSchema>>
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handler = nextConnect(NextConnectConfig).post(createComment);
|
const handler = nextConnect(NextConnectConfig).post(
|
||||||
|
validateRequest({ bodySchema: BeerCommentValidationSchema }),
|
||||||
|
getCurrentUser,
|
||||||
|
createComment,
|
||||||
|
);
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
|
import validateRequest from '@/config/zod/middleware/validateRequest';
|
||||||
import nextConnect from 'next-connect';
|
import nextConnect from 'next-connect';
|
||||||
import ServerError from '@/config/util/ServerError';
|
|
||||||
import createNewBeerPost from '@/services/BeerPost/createNewBeerPost';
|
import createNewBeerPost from '@/services/BeerPost/createNewBeerPost';
|
||||||
import BeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema';
|
import BeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiHandler } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
||||||
|
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
||||||
|
|
||||||
const createBeerPost: NextApiHandler<
|
interface CreateBeerPostRequest extends UserExtendedNextApiRequest {
|
||||||
z.infer<typeof APIResponseValidationSchema>
|
body: z.infer<typeof BeerPostValidationSchema>;
|
||||||
> = async (req, res) => {
|
}
|
||||||
const cleanedReqBody = BeerPostValidationSchema.safeParse(req.body);
|
|
||||||
if (!cleanedReqBody.success) {
|
const createBeerPost = async (
|
||||||
throw new ServerError('Invalid request body', 400);
|
req: CreateBeerPostRequest,
|
||||||
}
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
const { name, description, typeId, abv, ibu, breweryId } = req.body;
|
||||||
|
|
||||||
const { name, description, typeId, abv, ibu, breweryId } = cleanedReqBody.data;
|
|
||||||
const newBeerPost = await createNewBeerPost({
|
const newBeerPost = await createNewBeerPost({
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
@@ -23,6 +26,7 @@ const createBeerPost: NextApiHandler<
|
|||||||
ibu,
|
ibu,
|
||||||
typeId,
|
typeId,
|
||||||
breweryId,
|
breweryId,
|
||||||
|
userId: req.user!.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(201).json({
|
res.status(201).json({
|
||||||
@@ -33,6 +37,10 @@ const createBeerPost: NextApiHandler<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handler = nextConnect(NextConnectConfig).post(createBeerPost);
|
const handler = nextConnect(NextConnectConfig).post(
|
||||||
|
validateRequest({ bodySchema: BeerPostValidationSchema }),
|
||||||
|
getCurrentUser,
|
||||||
|
createBeerPost,
|
||||||
|
);
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
||||||
import { ExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
||||||
import nextConnect from 'next-connect';
|
import nextConnect from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
const sendCurrentUser = async (req: ExtendedNextApiRequest, res: NextApiResponse) => {
|
const sendCurrentUser = async (req: UserExtendedNextApiRequest, res: NextApiResponse) => {
|
||||||
const { user } = req;
|
const { user } = req;
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
message: `Currently logged in as ${user!.username}`,
|
message: `Currently logged in as ${user!.username}`,
|
||||||
@@ -17,7 +17,7 @@ const sendCurrentUser = async (req: ExtendedNextApiRequest, res: NextApiResponse
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handler = nextConnect<
|
const handler = nextConnect<
|
||||||
ExtendedNextApiRequest,
|
UserExtendedNextApiRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>(NextConnectConfig).get(getCurrentUser, sendCurrentUser);
|
>(NextConnectConfig).get(getCurrentUser, sendCurrentUser);
|
||||||
|
|
||||||
|
|||||||
@@ -8,20 +8,19 @@ import { NextApiResponse } from 'next';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import ServerError from '@/config/util/ServerError';
|
||||||
import LoginValidationSchema from '@/services/user/schema/LoginValidationSchema';
|
import LoginValidationSchema from '@/services/user/schema/LoginValidationSchema';
|
||||||
import { ExtendedNextApiRequest } from '../../../config/auth/types';
|
import { UserExtendedNextApiRequest } from '../../../config/auth/types';
|
||||||
|
|
||||||
export default nextConnect<
|
export default nextConnect<
|
||||||
ExtendedNextApiRequest,
|
UserExtendedNextApiRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>(NextConnectConfig)
|
>(NextConnectConfig)
|
||||||
.use(passport.initialize())
|
.use(passport.initialize())
|
||||||
.use(async (req, res, next) => {
|
.use(async (req, res, next) => {
|
||||||
passport.use(localStrat);
|
|
||||||
const parsed = LoginValidationSchema.safeParse(req.body);
|
const parsed = LoginValidationSchema.safeParse(req.body);
|
||||||
if (!parsed.success) {
|
if (!parsed.success) {
|
||||||
throw new ServerError('Username and password are required.', 400);
|
throw new ServerError('Username and password are required.', 400);
|
||||||
}
|
}
|
||||||
|
passport.use(localStrat);
|
||||||
passport.authenticate('local', { session: false }, (error, token) => {
|
passport.authenticate('local', { session: false }, (error, token) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
next(error);
|
next(error);
|
||||||
|
|||||||
@@ -1,44 +1,18 @@
|
|||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import ServerError from '@/config/util/ServerError';
|
||||||
import nc, { NextHandler } from 'next-connect';
|
import nc from 'next-connect';
|
||||||
import createNewUser from '@/services/user/createNewUser';
|
import createNewUser from '@/services/user/createNewUser';
|
||||||
import CreateUserValidationSchema from '@/services/user/schema/CreateUserValidationSchema';
|
import CreateUserValidationSchema from '@/services/user/schema/CreateUserValidationSchema';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
||||||
import findUserByUsername from '@/services/user/findUserByUsername';
|
import findUserByUsername from '@/services/user/findUserByUsername';
|
||||||
import findUserByEmail from '@/services/user/findUserByEmail';
|
import findUserByEmail from '@/services/user/findUserByEmail';
|
||||||
|
import validateRequest from '@/config/zod/middleware/validateRequest';
|
||||||
|
|
||||||
interface RegisterUserRequest extends NextApiRequest {
|
interface RegisterUserRequest extends NextApiRequest {
|
||||||
body: z.infer<typeof CreateUserValidationSchema>;
|
body: z.infer<typeof CreateUserValidationSchema>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const validateRequest =
|
|
||||||
({
|
|
||||||
bodySchema,
|
|
||||||
querySchema,
|
|
||||||
}: {
|
|
||||||
bodySchema?: z.ZodSchema<any>;
|
|
||||||
querySchema?: z.ZodSchema<any>;
|
|
||||||
}) =>
|
|
||||||
async (req: NextApiRequest, res: NextApiResponse, next: NextHandler) => {
|
|
||||||
if (bodySchema) {
|
|
||||||
const parsed = bodySchema.safeParse(req.body);
|
|
||||||
if (!parsed.success) {
|
|
||||||
throw new ServerError('Invalid request body.', 400);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (querySchema) {
|
|
||||||
const parsed = querySchema.safeParse(req.query);
|
|
||||||
if (!parsed.success) {
|
|
||||||
throw new ServerError(parsed.error.message, 400);
|
|
||||||
}
|
|
||||||
req.query = parsed.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
};
|
|
||||||
|
|
||||||
const registerUser = async (req: RegisterUserRequest, res: NextApiResponse) => {
|
const registerUser = async (req: RegisterUserRequest, res: NextApiResponse) => {
|
||||||
const [usernameTaken, emailTaken] = await Promise.all([
|
const [usernameTaken, emailTaken] = await Promise.all([
|
||||||
findUserByUsername(req.body.username),
|
findUserByUsername(req.body.username),
|
||||||
|
|||||||
@@ -1,82 +1,9 @@
|
|||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
import { SubmitHandler, useForm } from 'react-hook-form';
|
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { z } from 'zod';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import FormError from '@/components/ui/forms/FormError';
|
|
||||||
import FormInfo from '@/components/ui/forms/FormInfo';
|
|
||||||
import FormLabel from '@/components/ui/forms/FormLabel';
|
|
||||||
import FormSegment from '@/components/ui/forms/FormSegment';
|
|
||||||
import FormTextInput from '@/components/ui/forms/FormTextInput';
|
|
||||||
import Layout from '@/components/ui/Layout';
|
import Layout from '@/components/ui/Layout';
|
||||||
import LoginValidationSchema from '@/services/user/schema/LoginValidationSchema';
|
|
||||||
import sendLoginUserRequest from '@/requests/sendLoginUserRequest';
|
|
||||||
import useUser from '@/hooks/useUser';
|
import useUser from '@/hooks/useUser';
|
||||||
|
import LoginForm from '@/components/Login/LoginForm';
|
||||||
type LoginT = z.infer<typeof LoginValidationSchema>;
|
|
||||||
const LoginForm = () => {
|
|
||||||
const router = useRouter();
|
|
||||||
const { register, handleSubmit, formState } = useForm<LoginT>({
|
|
||||||
resolver: zodResolver(LoginValidationSchema),
|
|
||||||
defaultValues: {
|
|
||||||
username: '',
|
|
||||||
password: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { errors } = formState;
|
|
||||||
|
|
||||||
const onSubmit: SubmitHandler<LoginT> = async (data) => {
|
|
||||||
try {
|
|
||||||
const response = await sendLoginUserRequest(data);
|
|
||||||
|
|
||||||
router.push(`/users/${response.id}`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form className="form-control w-9/12 space-y-5" onSubmit={handleSubmit(onSubmit)}>
|
|
||||||
<div>
|
|
||||||
<FormInfo>
|
|
||||||
<FormLabel htmlFor="username">username</FormLabel>
|
|
||||||
<FormError>{errors.username?.message}</FormError>
|
|
||||||
</FormInfo>
|
|
||||||
<FormSegment>
|
|
||||||
<FormTextInput
|
|
||||||
id="username"
|
|
||||||
type="text"
|
|
||||||
formValidationSchema={register('username')}
|
|
||||||
error={!!errors.username}
|
|
||||||
placeholder="username"
|
|
||||||
/>
|
|
||||||
</FormSegment>
|
|
||||||
|
|
||||||
<FormInfo>
|
|
||||||
<FormLabel htmlFor="password">password</FormLabel>
|
|
||||||
<FormError>{errors.password?.message}</FormError>
|
|
||||||
</FormInfo>
|
|
||||||
<FormSegment>
|
|
||||||
<FormTextInput
|
|
||||||
id="password"
|
|
||||||
type="password"
|
|
||||||
formValidationSchema={register('password')}
|
|
||||||
error={!!errors.password}
|
|
||||||
placeholder="password"
|
|
||||||
/>
|
|
||||||
</FormSegment>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="w-full">
|
|
||||||
<button type="submit" className="btn-primary btn w-full">
|
|
||||||
Login
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const LoginPage: NextPage = () => {
|
const LoginPage: NextPage = () => {
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
@@ -88,7 +15,7 @@ const LoginPage: NextPage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
router.push(`/user/current`);
|
router.push(`/user/current`);
|
||||||
}, [user]);
|
}, [user, router]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
|
|||||||
@@ -2,18 +2,21 @@ import DBClient from '@/prisma/DBClient';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import BeerCommentValidationSchema from './schema/CreateBeerCommentValidationSchema';
|
import BeerCommentValidationSchema from './schema/CreateBeerCommentValidationSchema';
|
||||||
|
|
||||||
|
const CreateBeerCommentWithUserSchema = BeerCommentValidationSchema.extend({
|
||||||
|
userId: z.string().uuid(),
|
||||||
|
});
|
||||||
const createNewBeerComment = async ({
|
const createNewBeerComment = async ({
|
||||||
content,
|
content,
|
||||||
rating,
|
rating,
|
||||||
beerPostId,
|
beerPostId,
|
||||||
}: z.infer<typeof BeerCommentValidationSchema>) => {
|
userId,
|
||||||
const user = await DBClient.instance.user.findFirstOrThrow();
|
}: z.infer<typeof CreateBeerCommentWithUserSchema>) => {
|
||||||
return DBClient.instance.beerComment.create({
|
return DBClient.instance.beerComment.create({
|
||||||
data: {
|
data: {
|
||||||
content,
|
content,
|
||||||
rating,
|
rating,
|
||||||
beerPost: { connect: { id: beerPostId } },
|
beerPost: { connect: { id: beerPostId } },
|
||||||
postedBy: { connect: { id: user.id } },
|
postedBy: { connect: { id: userId } },
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ import DBClient from '@/prisma/DBClient';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import BeerPostValidationSchema from './schema/CreateBeerPostValidationSchema';
|
import BeerPostValidationSchema from './schema/CreateBeerPostValidationSchema';
|
||||||
|
|
||||||
|
const CreateBeerPostWithUserSchema = BeerPostValidationSchema.extend({
|
||||||
|
userId: z.string().uuid(),
|
||||||
|
});
|
||||||
|
|
||||||
const createNewBeerPost = async ({
|
const createNewBeerPost = async ({
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
@@ -9,9 +13,8 @@ const createNewBeerPost = async ({
|
|||||||
ibu,
|
ibu,
|
||||||
typeId,
|
typeId,
|
||||||
breweryId,
|
breweryId,
|
||||||
}: z.infer<typeof BeerPostValidationSchema>) => {
|
userId,
|
||||||
const user = await DBClient.instance.user.findFirstOrThrow();
|
}: z.infer<typeof CreateBeerPostWithUserSchema>) => {
|
||||||
|
|
||||||
const newBeerPost = await DBClient.instance.beerPost.create({
|
const newBeerPost = await DBClient.instance.beerPost.create({
|
||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
@@ -19,7 +22,7 @@ const createNewBeerPost = async ({
|
|||||||
abv,
|
abv,
|
||||||
ibu,
|
ibu,
|
||||||
type: { connect: { id: typeId } },
|
type: { connect: { id: typeId } },
|
||||||
postedBy: { connect: { id: user.id } },
|
postedBy: { connect: { id: userId } },
|
||||||
brewery: { connect: { id: breweryId } },
|
brewery: { connect: { id: breweryId } },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user