mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 20:13:49 +00:00
More work on beer image upload
patFix schema so beer image and brewery image have createdBy column. Rename 'url' to 'path' in schema, add 'caption' column.
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import DBClient from '@/prisma/DBClient';
|
||||
import { BeerImage } from '@prisma/client';
|
||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||
import { NextHandler, createRouter, expressWrapper } from 'next-connect';
|
||||
import { createRouter, expressWrapper } from 'next-connect';
|
||||
|
||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||
import getBeerPostById from '@/services/BeerPost/getBeerPostById';
|
||||
|
||||
import multer from 'multer';
|
||||
|
||||
@@ -12,55 +13,70 @@ import cloudinaryConfig from '@/config/cloudinary';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { z } from 'zod';
|
||||
import ServerError from '@/config/util/ServerError';
|
||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||
|
||||
const { storage } = cloudinaryConfig;
|
||||
|
||||
const fileFilter: multer.Options['fileFilter'] = (req, file, cb) => {
|
||||
if (
|
||||
file.mimetype === 'image/png' ||
|
||||
file.mimetype === 'image/jpg' ||
|
||||
file.mimetype === 'image/jpeg'
|
||||
) {
|
||||
cb(null, true);
|
||||
} else {
|
||||
const { mimetype } = file;
|
||||
|
||||
const isImage = mimetype.startsWith('image/');
|
||||
|
||||
if (!isImage) {
|
||||
cb(null, false);
|
||||
}
|
||||
cb(null, true);
|
||||
};
|
||||
|
||||
const uploadMiddleware = multer({ storage, fileFilter }).array('images');
|
||||
const uploadMiddleware = expressWrapper(
|
||||
multer({ storage, fileFilter, limits: { files: 3 } }).array('images'),
|
||||
);
|
||||
|
||||
const BeerPostImageValidationSchema = z.object({
|
||||
caption: z.string(),
|
||||
alt: z.string(),
|
||||
});
|
||||
|
||||
interface UploadBeerPostImagesRequest extends UserExtendedNextApiRequest {
|
||||
files?:
|
||||
| Express.Multer.File[]
|
||||
| {
|
||||
[fieldname: string]: Express.Multer.File[];
|
||||
};
|
||||
|
||||
query: {
|
||||
id: string;
|
||||
};
|
||||
|
||||
// beerPost?: BeerPostQueryResult;
|
||||
files?: Express.Multer.File[];
|
||||
query: { id: string };
|
||||
body: z.infer<typeof BeerPostImageValidationSchema>;
|
||||
}
|
||||
|
||||
const checkIfBeerPostOwner = async (
|
||||
const processImageData = async (
|
||||
req: UploadBeerPostImagesRequest,
|
||||
res: NextApiResponse,
|
||||
next: NextHandler,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const user = req.user!;
|
||||
const beerPost = await getBeerPostById(id);
|
||||
const { files, user, body } = req;
|
||||
|
||||
if (!beerPost) {
|
||||
throw new ServerError('Beer post not found', 404);
|
||||
if (!files || !files.length) {
|
||||
throw new ServerError('No images uploaded', 400);
|
||||
}
|
||||
const beerImagePromises: Promise<BeerImage>[] = [];
|
||||
|
||||
if (beerPost.postedBy.id !== user.id) {
|
||||
throw new ServerError('You are not authorized to edit this beer post', 403);
|
||||
}
|
||||
files.forEach((file) => {
|
||||
beerImagePromises.push(
|
||||
DBClient.instance.beerImage.create({
|
||||
data: {
|
||||
alt: body.alt,
|
||||
postedBy: { connect: { id: user!.id } },
|
||||
beerPost: { connect: { id: req.query.id } },
|
||||
path: file.path,
|
||||
caption: body.caption,
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
return next();
|
||||
const beerImages = await Promise.all(beerImagePromises);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: `Successfully uploaded ${beerImages.length} image${
|
||||
beerImages.length > 1 ? 's' : ''
|
||||
}`,
|
||||
statusCode: 200,
|
||||
});
|
||||
};
|
||||
|
||||
const router = createRouter<
|
||||
@@ -68,8 +84,13 @@ const router = createRouter<
|
||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
// @ts-expect-error
|
||||
router.post(getCurrentUser, expressWrapper(uploadMiddleware), checkIfBeerPostOwner);
|
||||
router.post(
|
||||
getCurrentUser,
|
||||
// @ts-expect-error
|
||||
uploadMiddleware,
|
||||
validateRequest({ bodySchema: BeerPostImageValidationSchema }),
|
||||
processImageData,
|
||||
);
|
||||
|
||||
const handler = router.handler(NextConnectOptions);
|
||||
export default handler;
|
||||
|
||||
Reference in New Issue
Block a user