From 830e9dc8453c5241b322bc26574d69ac8aad3add Mon Sep 17 00:00:00 2001 From: Aaron William Po Date: Sun, 10 Dec 2023 12:47:09 -0500 Subject: [PATCH] Update eslint config, brewery post controllers --- .eslintrc.json | 4 +- src/controllers/images/beerImages/index.ts | 4 +- src/controllers/images/breweryImages/index.ts | 34 ++++ .../images/{beerImages => }/types/index.ts | 2 +- .../likes/breweryPostLikes/index.ts | 94 ++++++++++ src/controllers/posts/beerPosts/index.ts | 4 +- src/controllers/posts/beerStyles/index.ts | 11 +- .../posts/beerStyles/types/index.ts | 4 - src/controllers/posts/breweries/index.ts | 163 +++++++++++++++++- .../posts/breweries/types/index.ts | 13 ++ src/controllers/posts/types/index.ts | 31 +++- src/pages/api/beers/[id]/images/index.ts | 4 +- src/pages/api/breweries/[id]/beers/index.ts | 65 +------ src/pages/api/breweries/[id]/images/index.ts | 42 +---- src/pages/api/breweries/[id]/like/index.ts | 78 +-------- src/pages/api/breweries/[id]/like/is-liked.ts | 27 +-- src/pages/api/breweries/create.ts | 6 +- src/pages/api/breweries/index.ts | 29 +--- src/pages/api/breweries/map/index.ts | 4 +- src/pages/api/users/[id]/posts/beers.ts | 4 +- src/pages/api/users/[id]/posts/breweries.ts | 4 +- 21 files changed, 372 insertions(+), 255 deletions(-) create mode 100644 src/controllers/images/breweryImages/index.ts rename src/controllers/images/{beerImages => }/types/index.ts (79%) create mode 100644 src/controllers/likes/breweryPostLikes/index.ts create mode 100644 src/controllers/posts/breweries/types/index.ts diff --git a/.eslintrc.json b/.eslintrc.json index ea29278..0ad70c2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,7 +2,9 @@ "extends": ["next/core-web-vitals", "airbnb-base", "airbnb-typescript", "prettier"], "rules": { "arrow-body-style": "off", - "import/extensions": "off" + "import/extensions": "warn", + "import/order": "warn", + "import/no-extraneous-dependencies": ["error", { "devDependencies": true }] }, "parserOptions": { "project": ["./tsconfig.json"] diff --git a/src/controllers/images/beerImages/index.ts b/src/controllers/images/beerImages/index.ts index 13835b3..cd996f7 100644 --- a/src/controllers/images/beerImages/index.ts +++ b/src/controllers/images/beerImages/index.ts @@ -3,11 +3,11 @@ import addBeerImageToDB from '@/services/BeerImage/addBeerImageToDB'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiResponse } from 'next'; import { z } from 'zod'; -import { UploadBeerPostImagesRequest } from './types'; +import { UploadImagesRequest } from '../types'; // eslint-disable-next-line import/prefer-default-export export const processBeerImageData = async ( - req: UploadBeerPostImagesRequest, + req: UploadImagesRequest, res: NextApiResponse>, ) => { const { files, user, body } = req; diff --git a/src/controllers/images/breweryImages/index.ts b/src/controllers/images/breweryImages/index.ts new file mode 100644 index 0000000..8f7b33b --- /dev/null +++ b/src/controllers/images/breweryImages/index.ts @@ -0,0 +1,34 @@ +import ServerError from '@/config/util/ServerError'; +import addBreweryImageToDB from '@/services/BreweryImage/addBreweryImageToDB'; +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; +import { NextApiResponse } from 'next'; +import { z } from 'zod'; +import { UploadImagesRequest } from '../types'; + +// eslint-disable-next-line import/prefer-default-export +export const processBreweryImageData = async ( + req: UploadImagesRequest, + res: NextApiResponse>, +) => { + const { files, user, body } = req; + + if (!files || !files.length) { + throw new ServerError('No images uploaded', 400); + } + + const breweryImages = await addBreweryImageToDB({ + alt: body.alt, + caption: body.caption, + breweryPostId: req.query.id, + userId: user!.id, + files, + }); + + res.status(200).json({ + success: true, + message: `Successfully uploaded ${breweryImages.length} image${ + breweryImages.length > 1 ? 's' : '' + }`, + statusCode: 200, + }); +}; diff --git a/src/controllers/images/beerImages/types/index.ts b/src/controllers/images/types/index.ts similarity index 79% rename from src/controllers/images/beerImages/types/index.ts rename to src/controllers/images/types/index.ts index bf8e8dd..f91a095 100644 --- a/src/controllers/images/beerImages/types/index.ts +++ b/src/controllers/images/types/index.ts @@ -2,7 +2,7 @@ import { UserExtendedNextApiRequest } from '@/config/auth/types'; import ImageMetadataValidationSchema from '@/services/schema/ImageSchema/ImageMetadataValidationSchema'; import { z } from 'zod'; -export interface UploadBeerPostImagesRequest extends UserExtendedNextApiRequest { +export interface UploadImagesRequest extends UserExtendedNextApiRequest { files?: Express.Multer.File[]; query: { id: string }; body: z.infer; diff --git a/src/controllers/likes/breweryPostLikes/index.ts b/src/controllers/likes/breweryPostLikes/index.ts new file mode 100644 index 0000000..d09ac56 --- /dev/null +++ b/src/controllers/likes/breweryPostLikes/index.ts @@ -0,0 +1,94 @@ +import { UserExtendedNextApiRequest } from '@/config/auth/types'; +import ServerError from '@/config/util/ServerError'; +import DBClient from '@/prisma/DBClient'; +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; +import { NextApiResponse, NextApiRequest } from 'next'; +import { z } from 'zod'; + +export const sendBreweryPostLikeRequest = async ( + req: UserExtendedNextApiRequest, + res: NextApiResponse>, +) => { + const id = req.query.id! as string; + const user = req.user!; + + const breweryPost = await DBClient.instance.breweryPost.findUnique({ + where: { id }, + }); + + if (!breweryPost) { + throw new ServerError('Could not find a brewery post with that id', 404); + } + + const alreadyLiked = await DBClient.instance.breweryPostLike.findFirst({ + where: { breweryPostId: breweryPost.id, likedById: user.id }, + }); + + const jsonResponse = { + success: true as const, + message: '', + statusCode: 200 as const, + }; + + if (alreadyLiked) { + await DBClient.instance.breweryPostLike.delete({ + where: { id: alreadyLiked.id }, + }); + jsonResponse.message = 'Successfully unliked brewery post'; + } else { + await DBClient.instance.breweryPostLike.create({ + data: { breweryPostId: breweryPost.id, likedById: user.id }, + }); + jsonResponse.message = 'Successfully liked brewery post'; + } + + res.status(200).json(jsonResponse); +}; + +export const getBreweryPostLikeCount = async ( + req: NextApiRequest, + res: NextApiResponse>, +) => { + const id = req.query.id! as string; + + const breweryPost = await DBClient.instance.breweryPost.findUnique({ + where: { id }, + }); + + if (!breweryPost) { + throw new ServerError('Could not find a brewery post with that id', 404); + } + + const likeCount = await DBClient.instance.breweryPostLike.count({ + where: { breweryPostId: breweryPost.id }, + }); + + res.status(200).json({ + success: true, + message: 'Successfully retrieved like count', + statusCode: 200, + payload: { likeCount }, + }); +}; + +export const getBreweryPostLikeStatus = async ( + req: UserExtendedNextApiRequest, + res: NextApiResponse>, +) => { + const user = req.user!; + const id = req.query.id as string; + + const alreadyLiked = await DBClient.instance.breweryPostLike.findFirst({ + where: { + breweryPostId: id, + likedById: user.id, + }, + }); + + res.status(200).json({ + success: true, + message: alreadyLiked ? 'Brewery post is liked.' : 'Brewery post is not liked.', + statusCode: 200, + payload: { isLiked: !!alreadyLiked }, + }); +}; diff --git a/src/controllers/posts/beerPosts/index.ts b/src/controllers/posts/beerPosts/index.ts index 600318b..9daf865 100644 --- a/src/controllers/posts/beerPosts/index.ts +++ b/src/controllers/posts/beerPosts/index.ts @@ -18,7 +18,7 @@ import { GetAllBeerPostsRequest, GetBeerRecommendationsRequest, } from './types'; -import { GetPostsByUserIdRequest } from '../types'; +import { GetAllPostsByConnectedPostId } from '../types'; export const checkIfBeerPostOwner = async ( req: BeerPostRequestType, @@ -145,7 +145,7 @@ export const createBeerPost = async ( }; export const getBeerPostsByUserId = async ( - req: GetPostsByUserIdRequest, + req: GetAllPostsByConnectedPostId, res: NextApiResponse>, ) => { const pageNum = parseInt(req.query.page_num, 10); diff --git a/src/controllers/posts/beerStyles/index.ts b/src/controllers/posts/beerStyles/index.ts index 91eac09..a49ea42 100644 --- a/src/controllers/posts/beerStyles/index.ts +++ b/src/controllers/posts/beerStyles/index.ts @@ -10,13 +10,8 @@ import getBeerPostsByBeerStyleId from '@/services/BeerPost/getBeerPostsByBeerSty import getAllBeerStyles from '@/services/BeerStyles/getAllBeerStyles'; import ServerError from '@/config/util/ServerError'; -import { - CreateBeerStyleRequest, - GetAllBeersByBeerStyleRequest, - GetBeerStyleByIdRequest, -} from './types'; - -import { GetAllPostsRequest } from '../types'; +import { CreateBeerStyleRequest, GetBeerStyleByIdRequest } from './types'; +import { GetAllPostsByConnectedPostId, GetAllPostsRequest } from '../types'; export const getBeerStyle = async ( req: GetBeerStyleByIdRequest, @@ -35,7 +30,7 @@ export const getBeerStyle = async ( }; export const getAllBeersByBeerStyle = async ( - req: GetAllBeersByBeerStyleRequest, + req: GetAllPostsByConnectedPostId, res: NextApiResponse>, ) => { // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/src/controllers/posts/beerStyles/types/index.ts b/src/controllers/posts/beerStyles/types/index.ts index 9ffc675..edb0042 100644 --- a/src/controllers/posts/beerStyles/types/index.ts +++ b/src/controllers/posts/beerStyles/types/index.ts @@ -1,6 +1,5 @@ import { NextApiRequest } from 'next'; -import { GetAllPostsRequest } from '@/controllers/posts/types'; import { UserExtendedNextApiRequest } from '@/config/auth/types'; import { z } from 'zod'; import CreateBeerStyleValidationSchema from '@/services/BeerStyles/schema/CreateBeerStyleValidationSchema'; @@ -9,9 +8,6 @@ export interface GetBeerStyleByIdRequest extends NextApiRequest { query: { id: string }; } -export interface GetAllBeersByBeerStyleRequest extends GetAllPostsRequest { - query: { page_size: string; page_num: string; id: string }; -} export interface CreateBeerStyleRequest extends UserExtendedNextApiRequest { body: z.infer; } diff --git a/src/controllers/posts/breweries/index.ts b/src/controllers/posts/breweries/index.ts index e3b7c0c..05de01b 100644 --- a/src/controllers/posts/breweries/index.ts +++ b/src/controllers/posts/breweries/index.ts @@ -3,11 +3,17 @@ import getAllBreweryPostsByPostedById from '@/services/BreweryPost/getAllBrewery import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiResponse } from 'next'; import { z } from 'zod'; -import { GetPostsByUserIdRequest } from '../types'; +import getAllBreweryPosts from '@/services/BreweryPost/getAllBreweryPosts'; +import createNewBreweryPost from '@/services/BreweryPost/createNewBreweryPost'; +import geocode from '@/config/mapbox/geocoder'; +import ServerError from '@/config/util/ServerError'; +import BreweryPostMapQueryResult from '@/services/BreweryPost/schema/BreweryPostMapQueryResult'; +import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; +import { CreateBreweryPostRequest, GetBreweryPostsRequest } from './types'; +import { GetAllPostsByConnectedPostId } from '../types'; -// eslint-disable-next-line import/prefer-default-export export const getBreweryPostsByUserId = async ( - req: GetPostsByUserIdRequest, + req: GetAllPostsByConnectedPostId, res: NextApiResponse>, ) => { const pageNum = parseInt(req.query.page_num, 10); @@ -34,3 +40,154 @@ export const getBreweryPostsByUserId = async ( success: true, }); }; + +export const getBreweryPosts = async ( + req: GetBreweryPostsRequest, + res: NextApiResponse>, +) => { + const pageNum = parseInt(req.query.page_num, 10); + const pageSize = parseInt(req.query.page_size, 10); + + const breweryPosts = await getAllBreweryPosts({ pageNum, pageSize }); + const breweryPostCount = await DBClient.instance.breweryPost.count(); + + res.setHeader('X-Total-Count', breweryPostCount); + res.status(200).json({ + message: 'Brewery posts retrieved successfully', + statusCode: 200, + payload: breweryPosts, + success: true, + }); +}; + +export const createBreweryPost = async ( + req: CreateBreweryPostRequest, + res: NextApiResponse>, +) => { + const { name, description, dateEstablished, address, city, country, region } = req.body; + const userId = req.user!.id; + + const fullAddress = `${address}, ${city}, ${region}, ${country}`; + + const geocoded = await geocode(fullAddress); + + if (!geocoded) { + throw new ServerError('Address is not valid', 400); + } + + const [latitude, longitude] = geocoded.center; + + const location = await DBClient.instance.breweryLocation.create({ + data: { + address, + city, + country, + stateOrProvince: region, + coordinates: [latitude, longitude], + postedBy: { connect: { id: userId } }, + }, + select: { id: true }, + }); + + const newBreweryPost = await createNewBreweryPost({ + name, + description, + locationId: location.id, + dateEstablished, + userId, + }); + + res.status(201).json({ + message: 'Brewery post created successfully', + statusCode: 201, + payload: newBreweryPost, + success: true, + }); +}; + +export const getMapBreweryPosts = async ( + req: GetBreweryPostsRequest, + res: NextApiResponse>, +) => { + const pageNum = parseInt(req.query.page_num, 10); + const pageSize = parseInt(req.query.page_size, 10); + + const skip = (pageNum - 1) * pageSize; + const take = pageSize; + + const breweryPosts: z.infer[] = + await DBClient.instance.breweryPost.findMany({ + select: { + location: { + select: { coordinates: true, city: true, country: true, stateOrProvince: true }, + }, + id: true, + name: true, + }, + skip, + take, + }); + const breweryPostCount = await DBClient.instance.breweryPost.count(); + + res.setHeader('X-Total-Count', breweryPostCount); + + res.status(200).json({ + message: 'Brewery posts retrieved successfully', + statusCode: 200, + payload: breweryPosts, + success: true, + }); +}; + +export const getAllBeersByBrewery = async ( + req: GetAllPostsByConnectedPostId, + res: NextApiResponse>, +) => { + // eslint-disable-next-line @typescript-eslint/naming-convention + const { page_size, page_num, id } = req.query; + + const pageNum = parseInt(page_num, 10); + const pageSize = parseInt(page_size, 10); + + const beers: z.infer[] = + await DBClient.instance.beerPost.findMany({ + where: { breweryId: id }, + skip: (pageNum - 1) * pageSize, + take: pageSize, + select: { + id: true, + name: true, + ibu: true, + abv: true, + createdAt: true, + updatedAt: true, + description: true, + postedBy: { select: { username: true, id: true } }, + brewery: { select: { name: true, id: true } }, + style: { select: { name: true, id: true, description: true } }, + beerImages: { + select: { + alt: true, + path: true, + caption: true, + id: true, + createdAt: true, + updatedAt: true, + }, + }, + }, + }); + + const count = await DBClient.instance.beerPost.count({ + where: { breweryId: id }, + }); + + res.setHeader('X-Total-Count', count); + + res.status(200).json({ + message: 'Beers fetched successfully', + statusCode: 200, + payload: beers, + success: true, + }); +}; diff --git a/src/controllers/posts/breweries/types/index.ts b/src/controllers/posts/breweries/types/index.ts new file mode 100644 index 0000000..cfed9f8 --- /dev/null +++ b/src/controllers/posts/breweries/types/index.ts @@ -0,0 +1,13 @@ +import { UserExtendedNextApiRequest } from '@/config/auth/types'; +import CreateBreweryPostSchema from '@/services/BreweryPost/schema/CreateBreweryPostSchema'; +import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema'; +import { NextApiRequest } from 'next'; +import { z } from 'zod'; + +export interface GetBreweryPostsRequest extends NextApiRequest { + query: z.infer; +} + +export interface CreateBreweryPostRequest extends UserExtendedNextApiRequest { + body: z.infer; +} diff --git a/src/controllers/posts/types/index.ts b/src/controllers/posts/types/index.ts index e6578ac..e98c03f 100644 --- a/src/controllers/posts/types/index.ts +++ b/src/controllers/posts/types/index.ts @@ -1,9 +1,38 @@ import { NextApiRequest } from 'next'; +/** Represents the request object for getting all posts. */ export interface GetAllPostsRequest extends NextApiRequest { query: { page_size: string; page_num: string }; } -export interface GetPostsByUserIdRequest extends NextApiRequest { +/** + * Represents the request object for getting all posts by a connected post ID. + * + * This may include: + * + * - All beers by a brewery ID + * - All beers by a beer style ID + * - All beer styles by a user ID + * - And more... + * + * @example + * const getAllBeersByBeerStyle = async ( + * req: GetAllPostsByConnectedPostId, + * res: NextApiResponse>, + * ) => { + * const { page_size, page_num, id } = req.query; + * // ... + * }; + * + * @example + * const getAllBeersByUserId = async ( + * req: GetAllPostsByConnectedPostId, + * res: NextApiResponse>, + * ) => { + * const { page_size, page_num, id } = req.query; + * // ... + * }; + */ +export interface GetAllPostsByConnectedPostId extends NextApiRequest { query: { id: string; page_size: string; page_num: string }; } diff --git a/src/pages/api/beers/[id]/images/index.ts b/src/pages/api/beers/[id]/images/index.ts index ba2fb31..10739f2 100644 --- a/src/pages/api/beers/[id]/images/index.ts +++ b/src/pages/api/beers/[id]/images/index.ts @@ -9,11 +9,11 @@ import { z } from 'zod'; import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import ImageMetadataValidationSchema from '@/services/schema/ImageSchema/ImageMetadataValidationSchema'; import { uploadMiddlewareMultiple } from '@/config/multer/uploadMiddleware'; -import { UploadBeerPostImagesRequest } from '@/controllers/images/beerImages/types'; +import { UploadImagesRequest } from '@/controllers/images/types'; import { processBeerImageData } from '@/controllers/images/beerImages'; const router = createRouter< - UploadBeerPostImagesRequest, + UploadImagesRequest, NextApiResponse> >(); diff --git a/src/pages/api/breweries/[id]/beers/index.ts b/src/pages/api/breweries/[id]/beers/index.ts index b2bcb59..c50ebe4 100644 --- a/src/pages/api/breweries/[id]/beers/index.ts +++ b/src/pages/api/breweries/[id]/beers/index.ts @@ -1,71 +1,14 @@ import NextConnectOptions from '@/config/nextConnect/NextConnectOptions'; import validateRequest from '@/config/nextConnect/middleware/validateRequest'; -import DBClient from '@/prisma/DBClient'; -import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; +import { getAllBeersByBrewery } from '@/controllers/posts/breweries'; +import { GetAllPostsByConnectedPostId } from '@/controllers/posts/types'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; -import { NextApiRequest, NextApiResponse } from 'next'; +import { NextApiResponse } from 'next'; import { createRouter } from 'next-connect'; import { z } from 'zod'; -interface GetAllBeersByBreweryRequest extends NextApiRequest { - query: { page_size: string; page_num: string; id: string }; -} - -const getAllBeersByBrewery = async ( - req: GetAllBeersByBreweryRequest, - res: NextApiResponse>, -) => { - // eslint-disable-next-line @typescript-eslint/naming-convention - const { page_size, page_num, id } = req.query; - - const pageNum = parseInt(page_num, 10); - const pageSize = parseInt(page_size, 10); - - const beers: z.infer[] = - await DBClient.instance.beerPost.findMany({ - where: { breweryId: id }, - skip: (pageNum - 1) * pageSize, - take: pageSize, - select: { - id: true, - name: true, - ibu: true, - abv: true, - createdAt: true, - updatedAt: true, - description: true, - postedBy: { select: { username: true, id: true } }, - brewery: { select: { name: true, id: true } }, - style: { select: { name: true, id: true, description: true } }, - beerImages: { - select: { - alt: true, - path: true, - caption: true, - id: true, - createdAt: true, - updatedAt: true, - }, - }, - }, - }); - - const count = await DBClient.instance.beerPost.count({ - where: { breweryId: id }, - }); - - res.setHeader('X-Total-Count', count); - - res.status(200).json({ - message: 'Beers fetched successfully', - statusCode: 200, - payload: beers, - success: true, - }); -}; - const router = createRouter< - GetAllBeersByBreweryRequest, + GetAllPostsByConnectedPostId, NextApiResponse> >(); diff --git a/src/pages/api/breweries/[id]/images/index.ts b/src/pages/api/breweries/[id]/images/index.ts index ad056ef..02f88f0 100644 --- a/src/pages/api/breweries/[id]/images/index.ts +++ b/src/pages/api/breweries/[id]/images/index.ts @@ -1,53 +1,19 @@ import NextConnectOptions from '@/config/nextConnect/NextConnectOptions'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; -import { UserExtendedNextApiRequest } from '@/config/auth/types'; import { createRouter } from 'next-connect'; import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser'; import { NextApiResponse } from 'next'; import { z } from 'zod'; -import ServerError from '@/config/util/ServerError'; import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import ImageMetadataValidationSchema from '@/services/schema/ImageSchema/ImageMetadataValidationSchema'; -import addBreweryImageToDB from '@/services/BreweryImage/addBreweryImageToDB'; import { uploadMiddlewareMultiple } from '@/config/multer/uploadMiddleware'; - -interface UploadBreweryPostImagesRequest extends UserExtendedNextApiRequest { - files?: Express.Multer.File[]; - query: { id: string }; - body: z.infer; -} - -const processImageData = async ( - req: UploadBreweryPostImagesRequest, - res: NextApiResponse>, -) => { - const { files, user, body } = req; - - if (!files || !files.length) { - throw new ServerError('No images uploaded', 400); - } - - const breweryImages = await addBreweryImageToDB({ - alt: body.alt, - caption: body.caption, - breweryPostId: req.query.id, - userId: user!.id, - files, - }); - - res.status(200).json({ - success: true, - message: `Successfully uploaded ${breweryImages.length} image${ - breweryImages.length > 1 ? 's' : '' - }`, - statusCode: 200, - }); -}; +import { UploadImagesRequest } from '@/controllers/images/types'; +import { processBreweryImageData } from '@/controllers/images/breweryImages'; const router = createRouter< - UploadBreweryPostImagesRequest, + UploadImagesRequest, NextApiResponse> >(); @@ -56,7 +22,7 @@ router.post( // @ts-expect-error uploadMiddlewareMultiple, validateRequest({ bodySchema: ImageMetadataValidationSchema }), - processImageData, + processBreweryImageData, ); const handler = router.handler(NextConnectOptions); diff --git a/src/pages/api/breweries/[id]/like/index.ts b/src/pages/api/breweries/[id]/like/index.ts index d567dd6..3ac2890 100644 --- a/src/pages/api/breweries/[id]/like/index.ts +++ b/src/pages/api/breweries/[id]/like/index.ts @@ -2,80 +2,16 @@ 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 ServerError from '@/config/util/ServerError'; -import DBClient from '@/prisma/DBClient'; +import { + sendBreweryPostLikeRequest, + getBreweryPostLikeCount, +} from '@/controllers/likes/breweryPostLikes'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; -import { NextApiRequest, NextApiResponse } from 'next'; +import { NextApiResponse } from 'next'; import { createRouter } from 'next-connect'; import { z } from 'zod'; -const sendLikeRequest = async ( - req: UserExtendedNextApiRequest, - res: NextApiResponse>, -) => { - const id = req.query.id! as string; - const user = req.user!; - - const breweryPost = await DBClient.instance.breweryPost.findUnique({ - where: { id }, - }); - - if (!breweryPost) { - throw new ServerError('Could not find a brewery post with that id', 404); - } - - const alreadyLiked = await DBClient.instance.breweryPostLike.findFirst({ - where: { breweryPostId: breweryPost.id, likedById: user.id }, - }); - - const jsonResponse = { - success: true as const, - message: '', - statusCode: 200 as const, - }; - - if (alreadyLiked) { - await DBClient.instance.breweryPostLike.delete({ - where: { id: alreadyLiked.id }, - }); - jsonResponse.message = 'Successfully unliked brewery post'; - } else { - await DBClient.instance.breweryPostLike.create({ - data: { breweryPostId: breweryPost.id, likedById: user.id }, - }); - jsonResponse.message = 'Successfully liked brewery post'; - } - - res.status(200).json(jsonResponse); -}; - -const getLikeCount = async ( - req: NextApiRequest, - res: NextApiResponse>, -) => { - const id = req.query.id! as string; - - const breweryPost = await DBClient.instance.breweryPost.findUnique({ - where: { id }, - }); - - if (!breweryPost) { - throw new ServerError('Could not find a brewery post with that id', 404); - } - - const likeCount = await DBClient.instance.breweryPostLike.count({ - where: { breweryPostId: breweryPost.id }, - }); - - res.status(200).json({ - success: true, - message: 'Successfully retrieved like count', - statusCode: 200, - payload: { likeCount }, - }); -}; - const router = createRouter< UserExtendedNextApiRequest, NextApiResponse> @@ -84,12 +20,12 @@ const router = createRouter< router.post( getCurrentUser, validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }), - sendLikeRequest, + sendBreweryPostLikeRequest, ); router.get( validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }), - getLikeCount, + getBreweryPostLikeCount, ); const handler = router.handler(NextConnectOptions); diff --git a/src/pages/api/breweries/[id]/like/is-liked.ts b/src/pages/api/breweries/[id]/like/is-liked.ts index 00dc7eb..aa59509 100644 --- a/src/pages/api/breweries/[id]/like/is-liked.ts +++ b/src/pages/api/breweries/[id]/like/is-liked.ts @@ -2,34 +2,13 @@ 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 DBClient from '@/prisma/DBClient'; +import { getBreweryPostLikeStatus } from '@/controllers/likes/breweryPostLikes'; + import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiResponse } from 'next'; import { createRouter } from 'next-connect'; import { z } from 'zod'; -const checkIfLiked = async ( - req: UserExtendedNextApiRequest, - res: NextApiResponse>, -) => { - const user = req.user!; - const id = req.query.id as string; - - const alreadyLiked = await DBClient.instance.breweryPostLike.findFirst({ - where: { - breweryPostId: id, - likedById: user.id, - }, - }); - - res.status(200).json({ - success: true, - message: alreadyLiked ? 'Brewery post is liked.' : 'Brewery post is not liked.', - statusCode: 200, - payload: { isLiked: !!alreadyLiked }, - }); -}; - const router = createRouter< UserExtendedNextApiRequest, NextApiResponse> @@ -42,7 +21,7 @@ router.get( id: z.string().cuid(), }), }), - checkIfLiked, + getBreweryPostLikeStatus, ); const handler = router.handler(NextConnectOptions); diff --git a/src/pages/api/breweries/create.ts b/src/pages/api/breweries/create.ts index 8cf3e04..12edf2d 100644 --- a/src/pages/api/breweries/create.ts +++ b/src/pages/api/breweries/create.ts @@ -1,4 +1,3 @@ -import { UserExtendedNextApiRequest } from '@/config/auth/types'; import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import { createRouter } from 'next-connect'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; @@ -11,10 +10,7 @@ import createNewBreweryPost from '@/services/BreweryPost/createNewBreweryPost'; import geocode from '@/config/mapbox/geocoder'; import ServerError from '@/config/util/ServerError'; import DBClient from '@/prisma/DBClient'; - -interface CreateBreweryPostRequest extends UserExtendedNextApiRequest { - body: z.infer; -} +import { CreateBreweryPostRequest } from '@/controllers/posts/breweries/types'; const createBreweryPost = async ( req: CreateBreweryPostRequest, diff --git a/src/pages/api/breweries/index.ts b/src/pages/api/breweries/index.ts index d8814fa..1bffcd2 100644 --- a/src/pages/api/breweries/index.ts +++ b/src/pages/api/breweries/index.ts @@ -1,36 +1,13 @@ import validateRequest from '@/config/nextConnect/middleware/validateRequest'; -import DBClient from '@/prisma/DBClient'; -import getAllBreweryPosts from '@/services/BreweryPost/getAllBreweryPosts'; +import { getBreweryPosts } from '@/controllers/posts/breweries'; +import { GetBreweryPostsRequest } from '@/controllers/posts/breweries/types'; import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; -import { NextApiRequest, NextApiResponse } from 'next'; +import { NextApiResponse } from 'next'; import { createRouter } from 'next-connect'; import { z } from 'zod'; -interface GetBreweryPostsRequest extends NextApiRequest { - query: z.infer; -} - -const getBreweryPosts = async ( - req: GetBreweryPostsRequest, - res: NextApiResponse>, -) => { - const pageNum = parseInt(req.query.page_num, 10); - const pageSize = parseInt(req.query.page_size, 10); - - const breweryPosts = await getAllBreweryPosts({ pageNum, pageSize }); - const breweryPostCount = await DBClient.instance.breweryPost.count(); - - res.setHeader('X-Total-Count', breweryPostCount); - res.status(200).json({ - message: 'Brewery posts retrieved successfully', - statusCode: 200, - payload: breweryPosts, - success: true, - }); -}; - const router = createRouter< GetBreweryPostsRequest, NextApiResponse> diff --git a/src/pages/api/breweries/map/index.ts b/src/pages/api/breweries/map/index.ts index 1696faf..7c5f6d6 100644 --- a/src/pages/api/breweries/map/index.ts +++ b/src/pages/api/breweries/map/index.ts @@ -12,7 +12,7 @@ interface GetBreweryPostsRequest extends NextApiRequest { query: z.infer; } -const getBreweryPosts = async ( +const getMapBreweryPosts = async ( req: GetBreweryPostsRequest, res: NextApiResponse>, ) => { @@ -53,7 +53,7 @@ const router = createRouter< router.get( validateRequest({ querySchema: PaginatedQueryResponseSchema }), - getBreweryPosts, + getMapBreweryPosts, ); const handler = router.handler(); diff --git a/src/pages/api/users/[id]/posts/beers.ts b/src/pages/api/users/[id]/posts/beers.ts index a710d6b..7bdd47e 100644 --- a/src/pages/api/users/[id]/posts/beers.ts +++ b/src/pages/api/users/[id]/posts/beers.ts @@ -5,11 +5,11 @@ import { z } from 'zod'; import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; -import { GetPostsByUserIdRequest } from '@/controllers/posts/types'; +import { GetAllPostsByConnectedPostId } from '@/controllers/posts/types'; import { getBeerPostsByUserId } from '@/controllers/posts/beerPosts'; const router = createRouter< - GetPostsByUserIdRequest, + GetAllPostsByConnectedPostId, NextApiResponse> >(); diff --git a/src/pages/api/users/[id]/posts/breweries.ts b/src/pages/api/users/[id]/posts/breweries.ts index dcc79b8..5ff73da 100644 --- a/src/pages/api/users/[id]/posts/breweries.ts +++ b/src/pages/api/users/[id]/posts/breweries.ts @@ -6,10 +6,10 @@ import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { getBreweryPostsByUserId } from '@/controllers/posts/breweries'; -import { GetPostsByUserIdRequest } from '@/controllers/posts/types'; +import { GetAllPostsByConnectedPostId } from '@/controllers/posts/types'; const router = createRouter< - GetPostsByUserIdRequest, + GetAllPostsByConnectedPostId, NextApiResponse> >();