mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 02:39:03 +00:00
Update eslint config, brewery post controllers
This commit is contained in:
@@ -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"]
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const { files, user, body } = req;
|
||||
|
||||
34
src/controllers/images/breweryImages/index.ts
Normal file
34
src/controllers/images/breweryImages/index.ts
Normal file
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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,
|
||||
});
|
||||
};
|
||||
@@ -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<typeof ImageMetadataValidationSchema>;
|
||||
94
src/controllers/likes/breweryPostLikes/index.ts
Normal file
94
src/controllers/likes/breweryPostLikes/index.ts
Normal file
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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 },
|
||||
});
|
||||
};
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
GetAllBeerPostsRequest,
|
||||
GetBeerRecommendationsRequest,
|
||||
} from './types';
|
||||
import { GetPostsByUserIdRequest } from '../types';
|
||||
import { GetAllPostsByConnectedPostId } from '../types';
|
||||
|
||||
export const checkIfBeerPostOwner = async <BeerPostRequestType extends BeerPostRequest>(
|
||||
req: BeerPostRequestType,
|
||||
@@ -145,7 +145,7 @@ export const createBeerPost = async (
|
||||
};
|
||||
|
||||
export const getBeerPostsByUserId = async (
|
||||
req: GetPostsByUserIdRequest,
|
||||
req: GetAllPostsByConnectedPostId,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const pageNum = parseInt(req.query.page_num, 10);
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
|
||||
@@ -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<typeof CreateBeerStyleValidationSchema>;
|
||||
}
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<typeof BreweryPostMapQueryResult>[] =
|
||||
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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
// 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<typeof BeerPostQueryResult>[] =
|
||||
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,
|
||||
});
|
||||
};
|
||||
|
||||
13
src/controllers/posts/breweries/types/index.ts
Normal file
13
src/controllers/posts/breweries/types/index.ts
Normal file
@@ -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<typeof PaginatedQueryResponseSchema>;
|
||||
}
|
||||
|
||||
export interface CreateBreweryPostRequest extends UserExtendedNextApiRequest {
|
||||
body: z.infer<typeof CreateBreweryPostSchema>;
|
||||
}
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
* ) => {
|
||||
* const { page_size, page_num, id } = req.query;
|
||||
* // ...
|
||||
* };
|
||||
*
|
||||
* @example
|
||||
* const getAllBeersByUserId = async (
|
||||
* req: GetAllPostsByConnectedPostId,
|
||||
* res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
* ) => {
|
||||
* const { page_size, page_num, id } = req.query;
|
||||
* // ...
|
||||
* };
|
||||
*/
|
||||
export interface GetAllPostsByConnectedPostId extends NextApiRequest {
|
||||
query: { id: string; page_size: string; page_num: string };
|
||||
}
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
// 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<typeof BeerPostQueryResult>[] =
|
||||
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<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
|
||||
@@ -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<typeof ImageMetadataValidationSchema>;
|
||||
}
|
||||
|
||||
const processImageData = async (
|
||||
req: UploadBreweryPostImagesRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
@@ -56,7 +22,7 @@ router.post(
|
||||
// @ts-expect-error
|
||||
uploadMiddlewareMultiple,
|
||||
validateRequest({ bodySchema: ImageMetadataValidationSchema }),
|
||||
processImageData,
|
||||
processBreweryImageData,
|
||||
);
|
||||
|
||||
const handler = router.handler(NextConnectOptions);
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>
|
||||
@@ -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);
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>
|
||||
@@ -42,7 +21,7 @@ router.get(
|
||||
id: z.string().cuid(),
|
||||
}),
|
||||
}),
|
||||
checkIfLiked,
|
||||
getBreweryPostLikeStatus,
|
||||
);
|
||||
|
||||
const handler = router.handler(NextConnectOptions);
|
||||
|
||||
@@ -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<typeof CreateBreweryPostSchema>;
|
||||
}
|
||||
import { CreateBreweryPostRequest } from '@/controllers/posts/breweries/types';
|
||||
|
||||
const createBreweryPost = async (
|
||||
req: CreateBreweryPostRequest,
|
||||
|
||||
@@ -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<typeof PaginatedQueryResponseSchema>;
|
||||
}
|
||||
|
||||
const getBreweryPosts = async (
|
||||
req: GetBreweryPostsRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
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<z.infer<typeof APIResponseValidationSchema>>
|
||||
|
||||
@@ -12,7 +12,7 @@ interface GetBreweryPostsRequest extends NextApiRequest {
|
||||
query: z.infer<typeof PaginatedQueryResponseSchema>;
|
||||
}
|
||||
|
||||
const getBreweryPosts = async (
|
||||
const getMapBreweryPosts = async (
|
||||
req: GetBreweryPostsRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
@@ -53,7 +53,7 @@ const router = createRouter<
|
||||
|
||||
router.get(
|
||||
validateRequest({ querySchema: PaginatedQueryResponseSchema }),
|
||||
getBreweryPosts,
|
||||
getMapBreweryPosts,
|
||||
);
|
||||
|
||||
const handler = router.handler();
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
|
||||
@@ -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<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user