mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +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:
@@ -8,7 +8,12 @@ const BeerCard: FC<{ post: BeerPostQueryResult }> = ({ post }) => {
|
|||||||
<div className="card bg-base-300" key={post.id}>
|
<div className="card bg-base-300" key={post.id}>
|
||||||
<figure className="card-image h-96">
|
<figure className="card-image h-96">
|
||||||
{post.beerImages.length > 0 && (
|
{post.beerImages.length > 0 && (
|
||||||
<Image src={post.beerImages[0].url} alt={post.name} width="1029" height="110" />
|
<Image
|
||||||
|
src={post.beerImages[0].path}
|
||||||
|
alt={post.name}
|
||||||
|
width="1029"
|
||||||
|
height="110"
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,32 @@
|
|||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
import type { RequestHandler } from 'next-connect/dist/types/node';
|
||||||
|
import type { HandlerOptions } from 'next-connect/dist/types/types';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import logger from '../pino/logger';
|
||||||
|
|
||||||
import ServerError from '../util/ServerError';
|
import ServerError from '../util/ServerError';
|
||||||
|
|
||||||
const NextConnectOptions = {
|
type NextConnectOptionsT = HandlerOptions<
|
||||||
onNoMatch(req: NextApiRequest, res: NextApiResponse) {
|
RequestHandler<
|
||||||
|
NextApiRequest,
|
||||||
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
|
||||||
|
const NextConnectOptions: NextConnectOptionsT = {
|
||||||
|
onNoMatch(req, res) {
|
||||||
res.status(405).json({
|
res.status(405).json({
|
||||||
message: 'Method not allowed.',
|
message: 'Method not allowed.',
|
||||||
statusCode: 405,
|
statusCode: 405,
|
||||||
success: false,
|
success: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError(error: unknown, req: NextApiRequest, res: NextApiResponse) {
|
onError(error, req, res) {
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
logger.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
const message = error instanceof Error ? error.message : 'Internal server error.';
|
const message = error instanceof Error ? error.message : 'Internal server error.';
|
||||||
const statusCode = error instanceof ServerError ? error.statusCode : 500;
|
const statusCode = error instanceof ServerError ? error.statusCode : 500;
|
||||||
res.status(statusCode).json({
|
res.status(statusCode).json({
|
||||||
|
|||||||
31
config/nextConnect/middleware/checkIfBeerPostOwner.ts
Normal file
31
config/nextConnect/middleware/checkIfBeerPostOwner.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
|
import ServerError from '@/config/util/ServerError';
|
||||||
|
import getBeerPostById from '@/services/BeerPost/getBeerPostById';
|
||||||
|
import { NextApiResponse } from 'next';
|
||||||
|
import { NextHandler } from 'next-connect';
|
||||||
|
|
||||||
|
interface CheckIfBeerPostOwnerRequest extends UserExtendedNextApiRequest {
|
||||||
|
query: { id: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkIfBeerPostOwner = async <RequestType extends CheckIfBeerPostOwnerRequest>(
|
||||||
|
req: RequestType,
|
||||||
|
res: NextApiResponse,
|
||||||
|
next: NextHandler,
|
||||||
|
) => {
|
||||||
|
const { id } = req.query;
|
||||||
|
const user = req.user!;
|
||||||
|
const beerPost = await getBeerPostById(id);
|
||||||
|
|
||||||
|
if (!beerPost) {
|
||||||
|
throw new ServerError('Beer post not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (beerPost.postedBy.id !== user.id) {
|
||||||
|
throw new ServerError('You are not authorized to edit this beer post', 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default checkIfBeerPostOwner;
|
||||||
@@ -28,10 +28,11 @@ const validateRequest =
|
|||||||
}) =>
|
}) =>
|
||||||
async (req: NextApiRequest, res: NextApiResponse, next: NextHandler) => {
|
async (req: NextApiRequest, res: NextApiResponse, next: NextHandler) => {
|
||||||
if (bodySchema) {
|
if (bodySchema) {
|
||||||
const parsed = bodySchema.safeParse(req.body);
|
const parsed = bodySchema.safeParse(JSON.parse(JSON.stringify(req.body)));
|
||||||
if (!parsed.success) {
|
if (!parsed.success) {
|
||||||
throw new ServerError('Invalid request body.', 400);
|
throw new ServerError('Invalid request body.', 400);
|
||||||
}
|
}
|
||||||
|
req.body = parsed.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (querySchema) {
|
if (querySchema) {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
import DBClient from '@/prisma/DBClient';
|
||||||
|
import { BeerImage } from '@prisma/client';
|
||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
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 getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import getBeerPostById from '@/services/BeerPost/getBeerPostById';
|
|
||||||
|
|
||||||
import multer from 'multer';
|
import multer from 'multer';
|
||||||
|
|
||||||
@@ -12,55 +13,70 @@ import cloudinaryConfig from '@/config/cloudinary';
|
|||||||
import { NextApiResponse } from 'next';
|
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 validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
|
|
||||||
const { storage } = cloudinaryConfig;
|
const { storage } = cloudinaryConfig;
|
||||||
|
|
||||||
const fileFilter: multer.Options['fileFilter'] = (req, file, cb) => {
|
const fileFilter: multer.Options['fileFilter'] = (req, file, cb) => {
|
||||||
if (
|
const { mimetype } = file;
|
||||||
file.mimetype === 'image/png' ||
|
|
||||||
file.mimetype === 'image/jpg' ||
|
const isImage = mimetype.startsWith('image/');
|
||||||
file.mimetype === 'image/jpeg'
|
|
||||||
) {
|
if (!isImage) {
|
||||||
cb(null, true);
|
|
||||||
} else {
|
|
||||||
cb(null, false);
|
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 {
|
interface UploadBeerPostImagesRequest extends UserExtendedNextApiRequest {
|
||||||
files?:
|
files?: Express.Multer.File[];
|
||||||
| Express.Multer.File[]
|
query: { id: string };
|
||||||
| {
|
body: z.infer<typeof BeerPostImageValidationSchema>;
|
||||||
[fieldname: string]: Express.Multer.File[];
|
|
||||||
};
|
|
||||||
|
|
||||||
query: {
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
// beerPost?: BeerPostQueryResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkIfBeerPostOwner = async (
|
const processImageData = async (
|
||||||
req: UploadBeerPostImagesRequest,
|
req: UploadBeerPostImagesRequest,
|
||||||
res: NextApiResponse,
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
next: NextHandler,
|
|
||||||
) => {
|
) => {
|
||||||
const { id } = req.query;
|
const { files, user, body } = req;
|
||||||
const user = req.user!;
|
|
||||||
const beerPost = await getBeerPostById(id);
|
|
||||||
|
|
||||||
if (!beerPost) {
|
if (!files || !files.length) {
|
||||||
throw new ServerError('Beer post not found', 404);
|
throw new ServerError('No images uploaded', 400);
|
||||||
}
|
}
|
||||||
|
const beerImagePromises: Promise<BeerImage>[] = [];
|
||||||
|
|
||||||
if (beerPost.postedBy.id !== user.id) {
|
files.forEach((file) => {
|
||||||
throw new ServerError('You are not authorized to edit this beer post', 403);
|
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<
|
const router = createRouter<
|
||||||
@@ -68,8 +84,13 @@ const router = createRouter<
|
|||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
// @ts-expect-error
|
router.post(
|
||||||
router.post(getCurrentUser, expressWrapper(uploadMiddleware), checkIfBeerPostOwner);
|
getCurrentUser,
|
||||||
|
// @ts-expect-error
|
||||||
|
uploadMiddleware,
|
||||||
|
validateRequest({ bodySchema: BeerPostImageValidationSchema }),
|
||||||
|
processImageData,
|
||||||
|
);
|
||||||
|
|
||||||
const handler = router.handler(NextConnectOptions);
|
const handler = router.handler(NextConnectOptions);
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const BeerByIdPage: NextPage<BeerPageProps> = ({
|
|||||||
{beerPost.beerImages[0] && (
|
{beerPost.beerImages[0] && (
|
||||||
<Image
|
<Image
|
||||||
alt={beerPost.beerImages[0].alt}
|
alt={beerPost.beerImages[0].alt}
|
||||||
src={beerPost.beerImages[0].url}
|
src={beerPost.beerImages[0].path}
|
||||||
height={1080}
|
height={1080}
|
||||||
width={1920}
|
width={1920}
|
||||||
className="h-[42rem] w-full object-cover"
|
className="h-[42rem] w-full object-cover"
|
||||||
|
|||||||
30
prisma/migrations/20230211021836_/migration.sql
Normal file
30
prisma/migrations/20230211021836_/migration.sql
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `url` on the `BeerImage` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the column `url` on the `BreweryImage` table. All the data in the column will be lost.
|
||||||
|
- Added the required column `caption` to the `BeerImage` table without a default value. This is not possible if the table is not empty.
|
||||||
|
- Added the required column `path` to the `BeerImage` table without a default value. This is not possible if the table is not empty.
|
||||||
|
- Added the required column `postedById` to the `BeerImage` table without a default value. This is not possible if the table is not empty.
|
||||||
|
- Added the required column `caption` to the `BreweryImage` table without a default value. This is not possible if the table is not empty.
|
||||||
|
- Added the required column `path` to the `BreweryImage` table without a default value. This is not possible if the table is not empty.
|
||||||
|
- Added the required column `postedById` to the `BreweryImage` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "BeerImage" DROP COLUMN "url",
|
||||||
|
ADD COLUMN "caption" TEXT NOT NULL,
|
||||||
|
ADD COLUMN "path" TEXT NOT NULL,
|
||||||
|
ADD COLUMN "postedById" TEXT NOT NULL;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "BreweryImage" DROP COLUMN "url",
|
||||||
|
ADD COLUMN "caption" TEXT NOT NULL,
|
||||||
|
ADD COLUMN "path" TEXT NOT NULL,
|
||||||
|
ADD COLUMN "postedById" TEXT NOT NULL;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BeerImage" ADD CONSTRAINT "BeerImage_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BreweryImage" ADD CONSTRAINT "BreweryImage_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
@@ -26,6 +26,8 @@ model User {
|
|||||||
beerComments BeerComment[]
|
beerComments BeerComment[]
|
||||||
breweryComments BreweryComment[]
|
breweryComments BreweryComment[]
|
||||||
BeerPostLikes BeerPostLike[]
|
BeerPostLikes BeerPostLike[]
|
||||||
|
BeerImage BeerImage[]
|
||||||
|
BreweryImage BreweryImage[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model BeerPost {
|
model BeerPost {
|
||||||
@@ -109,18 +111,24 @@ model BeerImage {
|
|||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
beerPost BeerPost @relation(fields: [beerPostId], references: [id], onDelete: Cascade)
|
beerPost BeerPost @relation(fields: [beerPostId], references: [id], onDelete: Cascade)
|
||||||
beerPostId String
|
beerPostId String
|
||||||
url String
|
path String
|
||||||
alt String
|
alt String
|
||||||
|
caption String
|
||||||
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
||||||
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
||||||
|
postedBy User @relation(fields: [postedById], references: [id], onDelete: Cascade)
|
||||||
|
postedById String
|
||||||
}
|
}
|
||||||
|
|
||||||
model BreweryImage {
|
model BreweryImage {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
breweryPost BreweryPost @relation(fields: [breweryPostId], references: [id], onDelete: Cascade)
|
breweryPost BreweryPost @relation(fields: [breweryPostId], references: [id], onDelete: Cascade)
|
||||||
breweryPostId String
|
breweryPostId String
|
||||||
url String
|
path String
|
||||||
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
||||||
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
||||||
|
caption String
|
||||||
alt String
|
alt String
|
||||||
|
postedBy User @relation(fields: [postedById], references: [id], onDelete: Cascade)
|
||||||
|
postedById String
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ const cleanDatabase = async () => {
|
|||||||
await prisma.$executeRaw`TRUNCATE TABLE "BreweryPost" CASCADE`;
|
await prisma.$executeRaw`TRUNCATE TABLE "BreweryPost" CASCADE`;
|
||||||
await prisma.$executeRaw`TRUNCATE TABLE "BeerComment" CASCADE`;
|
await prisma.$executeRaw`TRUNCATE TABLE "BeerComment" CASCADE`;
|
||||||
await prisma.$executeRaw`TRUNCATE TABLE "BreweryComment" CASCADE`;
|
await prisma.$executeRaw`TRUNCATE TABLE "BreweryComment" CASCADE`;
|
||||||
|
await prisma.$executeRaw`TRUNCATE TABLE "BeerPostLike" CASCADE`;
|
||||||
|
await prisma.$executeRaw`TRUNCATE TABLE "BeerImage" CASCADE`;
|
||||||
|
await prisma.$executeRaw`TRUNCATE TABLE "BreweryImage" CASCADE`;
|
||||||
|
|
||||||
|
await prisma.$disconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
export default cleanDatabase;
|
export default cleanDatabase;
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
import { faker } from '@faker-js/faker';
|
import { faker } from '@faker-js/faker';
|
||||||
import { BeerPost, BeerImage } from '@prisma/client';
|
import { BeerPost, BeerImage, User } from '@prisma/client';
|
||||||
import DBClient from '../../DBClient';
|
import DBClient from '../../DBClient';
|
||||||
|
|
||||||
interface CreateNewBeerImagesArgs {
|
interface CreateNewBeerImagesArgs {
|
||||||
numberOfImages: number;
|
numberOfImages: number;
|
||||||
beerPosts: BeerPost[];
|
|
||||||
|
joinData: {
|
||||||
|
beerPosts: BeerPost[];
|
||||||
|
users: User[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
const createNewBeerImages = async ({
|
const createNewBeerImages = async ({
|
||||||
numberOfImages,
|
numberOfImages,
|
||||||
beerPosts,
|
joinData: { beerPosts, users },
|
||||||
}: CreateNewBeerImagesArgs) => {
|
}: CreateNewBeerImagesArgs) => {
|
||||||
const prisma = DBClient.instance;
|
const prisma = DBClient.instance;
|
||||||
const createdAt = faker.date.past(1);
|
const createdAt = faker.date.past(1);
|
||||||
@@ -18,12 +22,15 @@ const createNewBeerImages = async ({
|
|||||||
// eslint-disable-next-line no-plusplus
|
// eslint-disable-next-line no-plusplus
|
||||||
for (let i = 0; i < numberOfImages; i++) {
|
for (let i = 0; i < numberOfImages; i++) {
|
||||||
const beerPost = beerPosts[Math.floor(Math.random() * beerPosts.length)];
|
const beerPost = beerPosts[Math.floor(Math.random() * beerPosts.length)];
|
||||||
|
const user = users[Math.floor(Math.random() * users.length)];
|
||||||
beerImagesPromises.push(
|
beerImagesPromises.push(
|
||||||
prisma.beerImage.create({
|
prisma.beerImage.create({
|
||||||
data: {
|
data: {
|
||||||
url: 'https://picsum.photos/900/1600',
|
path: 'https://picsum.photos/900/1600',
|
||||||
alt: 'Placeholder beer image.',
|
alt: 'Placeholder beer image.',
|
||||||
|
caption: 'Placeholder beer image caption.',
|
||||||
beerPost: { connect: { id: beerPost.id } },
|
beerPost: { connect: { id: beerPost.id } },
|
||||||
|
postedBy: { connect: { id: user.id } },
|
||||||
createdAt,
|
createdAt,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
import { faker } from '@faker-js/faker';
|
import { faker } from '@faker-js/faker';
|
||||||
import { BreweryPost, BreweryImage } from '@prisma/client';
|
import { BreweryPost, BreweryImage, User } from '@prisma/client';
|
||||||
import DBClient from '../../DBClient';
|
import DBClient from '../../DBClient';
|
||||||
|
|
||||||
interface CreateBreweryImagesArgs {
|
interface CreateBreweryImagesArgs {
|
||||||
numberOfImages: number;
|
numberOfImages: number;
|
||||||
breweryPosts: BreweryPost[];
|
|
||||||
|
joinData: {
|
||||||
|
breweryPosts: BreweryPost[];
|
||||||
|
users: User[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
const createNewBreweryImages = async ({
|
const createNewBreweryImages = async ({
|
||||||
numberOfImages,
|
numberOfImages,
|
||||||
breweryPosts,
|
joinData: { breweryPosts, users },
|
||||||
}: CreateBreweryImagesArgs) => {
|
}: CreateBreweryImagesArgs) => {
|
||||||
const prisma = DBClient.instance;
|
const prisma = DBClient.instance;
|
||||||
const createdAt = faker.date.past(1);
|
const createdAt = faker.date.past(1);
|
||||||
@@ -18,13 +22,16 @@ const createNewBreweryImages = async ({
|
|||||||
// eslint-disable-next-line no-plusplus
|
// eslint-disable-next-line no-plusplus
|
||||||
for (let i = 0; i < numberOfImages; i++) {
|
for (let i = 0; i < numberOfImages; i++) {
|
||||||
const breweryPost = breweryPosts[Math.floor(Math.random() * breweryPosts.length)];
|
const breweryPost = breweryPosts[Math.floor(Math.random() * breweryPosts.length)];
|
||||||
|
const user = users[Math.floor(Math.random() * users.length)];
|
||||||
|
|
||||||
breweryImagesPromises.push(
|
breweryImagesPromises.push(
|
||||||
prisma.breweryImage.create({
|
prisma.breweryImage.create({
|
||||||
data: {
|
data: {
|
||||||
url: 'https://picsum.photos/900/1600',
|
path: 'https://picsum.photos/900/1600',
|
||||||
alt: 'Placeholder brewery image.',
|
alt: 'Placeholder brewery image.',
|
||||||
|
caption: 'Placeholder brewery image caption.',
|
||||||
breweryPost: { connect: { id: breweryPost.id } },
|
breweryPost: { connect: { id: breweryPost.id } },
|
||||||
|
postedBy: { connect: { id: user.id } },
|
||||||
createdAt,
|
createdAt,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ import createNewUsers from './create/createNewUsers';
|
|||||||
}),
|
}),
|
||||||
createNewBeerImages({
|
createNewBeerImages({
|
||||||
numberOfImages: 1000,
|
numberOfImages: 1000,
|
||||||
beerPosts,
|
joinData: { beerPosts, users },
|
||||||
}),
|
}),
|
||||||
createNewBreweryImages({
|
createNewBreweryImages({
|
||||||
numberOfImages: 1000,
|
numberOfImages: 1000,
|
||||||
breweryPosts,
|
joinData: { breweryPosts, users },
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ const getAllBeerPosts = async (pageNum: number, pageSize: number) => {
|
|||||||
},
|
},
|
||||||
beerImages: {
|
beerImages: {
|
||||||
select: {
|
select: {
|
||||||
url: true,
|
path: true,
|
||||||
|
caption: true,
|
||||||
id: true,
|
id: true,
|
||||||
alt: true,
|
alt: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ const getBeerPostById = async (id: string) => {
|
|||||||
beerImages: {
|
beerImages: {
|
||||||
select: {
|
select: {
|
||||||
alt: true,
|
alt: true,
|
||||||
url: true,
|
path: true,
|
||||||
|
caption: true,
|
||||||
id: true,
|
id: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const getBeerRecommendations = async (
|
|||||||
NOT: { id: beerPost.id },
|
NOT: { id: beerPost.id },
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
beerImages: { select: { id: true, url: true, alt: true } },
|
beerImages: { select: { id: true, path: true, caption: true, alt: true } },
|
||||||
brewery: { select: { id: true, name: true } },
|
brewery: { select: { id: true, name: true } },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export default interface BeerPostQueryResult {
|
|||||||
};
|
};
|
||||||
description: string;
|
description: string;
|
||||||
beerImages: {
|
beerImages: {
|
||||||
url: string;
|
path: string;
|
||||||
|
caption: string;
|
||||||
id: string;
|
id: string;
|
||||||
alt: string;
|
alt: string;
|
||||||
}[];
|
}[];
|
||||||
|
|||||||
Reference in New Issue
Block a user