mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +00:00
Feat: create user page, add user bio and avatar
This commit is contained in:
@@ -5,7 +5,7 @@ import { Dispatch, FC, SetStateAction, useContext } from 'react';
|
|||||||
import { Rating } from 'react-daisyui';
|
import { Rating } from 'react-daisyui';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||||
|
import Image from 'next/image';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import CommentCardDropdown from './CommentCardDropdown';
|
import CommentCardDropdown from './CommentCardDropdown';
|
||||||
|
|
||||||
@@ -20,41 +20,64 @@ const CommentContentBody: FC<CommentContentBodyProps> = ({ comment, setInEditMod
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card-body animate-in fade-in-10">
|
<div className="card-body animate-in fade-in-10">
|
||||||
<div className="flex flex-row justify-between">
|
<div className="flex space-x-5">
|
||||||
<div>
|
<div className="w-2/12 avatar display flex items-center justify-center">
|
||||||
<p className="font-semibold sm:text-2xl">
|
<div className="w-28 h-28 rounded-full ring ring-primary">
|
||||||
<Link href={`/users/${comment.postedBy.id}`} className="link-hover link">
|
{comment.postedBy.userAvatar ? (
|
||||||
{comment.postedBy.username}
|
<Image
|
||||||
</Link>
|
src={comment.postedBy.userAvatar.path}
|
||||||
</p>
|
alt={comment.postedBy.userAvatar.alt}
|
||||||
<span className="italic">
|
width={200}
|
||||||
posted{' '}
|
height={200}
|
||||||
<time
|
/>
|
||||||
className="tooltip tooltip-bottom"
|
) : (
|
||||||
data-tip={format(new Date(comment.createdAt), 'MM/dd/yyyy')}
|
<div className="flex items-center justify-center w-full h-full text-2xl font-bold text-white bg-primary rounded-full">
|
||||||
>
|
{comment.postedBy.username[0]}
|
||||||
{timeDistance}
|
</div>
|
||||||
</time>{' '}
|
)}
|
||||||
ago
|
</div>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="w-10/12 space-y-2">
|
||||||
|
<div className="flex flex-row justify-between">
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold sm:text-2xl">
|
||||||
|
<Link href={`/users/${comment.postedBy.id}`} className="link-hover link">
|
||||||
|
{comment.postedBy.username}
|
||||||
|
</Link>
|
||||||
|
</p>
|
||||||
|
<span className="italic">
|
||||||
|
posted{' '}
|
||||||
|
<time
|
||||||
|
className="tooltip tooltip-bottom"
|
||||||
|
data-tip={format(new Date(comment.createdAt), 'MM/dd/yyyy')}
|
||||||
|
>
|
||||||
|
{timeDistance}
|
||||||
|
</time>{' '}
|
||||||
|
ago
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
{user && <CommentCardDropdown comment={comment} setInEditMode={setInEditMode} />}
|
{user && (
|
||||||
</div>
|
<CommentCardDropdown comment={comment} setInEditMode={setInEditMode} />
|
||||||
|
)}
|
||||||
<div className="space-y-1">
|
</div>
|
||||||
<Rating value={comment.rating}>
|
<div className="space-y-1">
|
||||||
{Array.from({ length: 5 }).map((val, index) => (
|
<Rating value={comment.rating}>
|
||||||
<Rating.Item
|
{Array.from({ length: 5 }).map((val, index) => (
|
||||||
name="rating-1"
|
<Rating.Item
|
||||||
className="mask mask-star cursor-default"
|
name="rating-1"
|
||||||
disabled
|
className="mask mask-star cursor-default"
|
||||||
aria-disabled
|
disabled
|
||||||
key={index}
|
aria-disabled
|
||||||
/>
|
key={index}
|
||||||
))}
|
/>
|
||||||
</Rating>
|
))}
|
||||||
<p>{comment.content}</p>
|
</Rating>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>{comment.content}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const getBeerPosts = async (
|
|||||||
const pageSize = parseInt(req.query.page_size, 10);
|
const pageSize = parseInt(req.query.page_size, 10);
|
||||||
|
|
||||||
const beerPosts = await getAllBeerPosts({ pageNum, pageSize });
|
const beerPosts = await getAllBeerPosts({ pageNum, pageSize });
|
||||||
|
|
||||||
const beerPostCount = await DBClient.instance.beerPost.count();
|
const beerPostCount = await DBClient.instance.beerPost.count();
|
||||||
|
|
||||||
res.setHeader('X-Total-Count', beerPostCount);
|
res.setHeader('X-Total-Count', beerPostCount);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const createBreweryPost = async (
|
|||||||
|
|
||||||
const [latitude, longitude] = geocoded.center;
|
const [latitude, longitude] = geocoded.center;
|
||||||
|
|
||||||
const location = await DBClient.instance.location.create({
|
const location = await DBClient.instance.breweryLocation.create({
|
||||||
data: {
|
data: {
|
||||||
address,
|
address,
|
||||||
city,
|
city,
|
||||||
|
|||||||
@@ -1,33 +1,69 @@
|
|||||||
|
import useMediaQuery from '@/hooks/utilities/useMediaQuery';
|
||||||
import useTimeDistance from '@/hooks/utilities/useTimeDistance';
|
import useTimeDistance from '@/hooks/utilities/useTimeDistance';
|
||||||
import findUserById from '@/services/User/findUserById';
|
import findUserById from '@/services/User/findUserById';
|
||||||
import GetUserSchema from '@/services/User/schema/GetUserSchema';
|
import GetUserSchema from '@/services/User/schema/GetUserSchema';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { GetServerSideProps } from 'next';
|
import { GetServerSideProps } from 'next';
|
||||||
|
import Head from 'next/head';
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
interface UserInfoPageProps {
|
interface UserInfoPageProps {
|
||||||
user: z.infer<typeof GetUserSchema>;
|
user: z.infer<typeof GetUserSchema>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserInfoPage: FC<UserInfoPageProps> = ({ user }) => {
|
const UserHeader: FC<{ user: z.infer<typeof GetUserSchema> }> = ({ user }) => {
|
||||||
const timeDistance = useTimeDistance(new Date(user.createdAt));
|
const timeDistance = useTimeDistance(new Date(user.createdAt));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<article className="card flex flex-col justify-center bg-base-300">
|
||||||
<h1>
|
<div className="card-body">
|
||||||
{user.firstName} {user.lastName}
|
<header className="flex justify-between">
|
||||||
</h1>
|
<div className="space-y-2">
|
||||||
<h2 className="italic">
|
<div>
|
||||||
joined{' '}
|
<h1 className="text-2xl font-bold lg:text-4xl">
|
||||||
<time
|
{user.firstName} {user.lastName}
|
||||||
className="tooltip tooltip-bottom"
|
</h1>
|
||||||
data-tip={format(new Date(user.createdAt), 'MM/dd/yyyy')}
|
|
||||||
>
|
<h3 className="italic">
|
||||||
{timeDistance}
|
joined{' '}
|
||||||
</time>{' '}
|
{timeDistance && (
|
||||||
ago
|
<span
|
||||||
</h2>
|
className="tooltip tooltip-bottom"
|
||||||
</div>
|
data-tip={format(new Date(user.createdAt), 'MM/dd/yyyy')}
|
||||||
|
>
|
||||||
|
{`${timeDistance} ago`}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UserInfoPage: FC<UserInfoPageProps> = ({ user }) => {
|
||||||
|
const isDesktop = useMediaQuery('(min-width: 1024px)');
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>{user ? `${user.firstName} ${user.lastName}` : 'User Info'}</title>
|
||||||
|
<meta name="description" content="User information" />
|
||||||
|
</Head>
|
||||||
|
<>
|
||||||
|
<main className="mb-12 mt-10 flex w-full items-center justify-center">
|
||||||
|
<Image src={user.userAvatar!.path} alt="avatar" width={200} height={200} />
|
||||||
|
<div className="w-11/12 space-y-3 xl:w-9/12 2xl:w-8/12">
|
||||||
|
<UserHeader user={user} />
|
||||||
|
|
||||||
|
{isDesktop ? <></> : <> </>}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
57
src/prisma/migrations/20231106024511_/migration.sql
Normal file
57
src/prisma/migrations/20231106024511_/migration.sql
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the `Location` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "BreweryPost" DROP CONSTRAINT "BreweryPost_locationId_fkey";
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "Location" DROP CONSTRAINT "Location_postedById_fkey";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" ADD COLUMN "bio" TEXT;
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "Location";
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "UserAvatar" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"path" TEXT NOT NULL,
|
||||||
|
"alt" TEXT NOT NULL,
|
||||||
|
"caption" TEXT NOT NULL,
|
||||||
|
"userId" TEXT NOT NULL,
|
||||||
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
|
|
||||||
|
CONSTRAINT "UserAvatar_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "BreweryLocation" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"city" TEXT NOT NULL,
|
||||||
|
"stateOrProvince" TEXT,
|
||||||
|
"country" TEXT,
|
||||||
|
"coordinates" DOUBLE PRECISION[],
|
||||||
|
"address" TEXT NOT NULL,
|
||||||
|
"postedById" TEXT NOT NULL,
|
||||||
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
|
|
||||||
|
CONSTRAINT "BreweryLocation_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "UserAvatar_userId_key" ON "UserAvatar"("userId");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "UserAvatar" ADD CONSTRAINT "UserAvatar_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BreweryLocation" ADD CONSTRAINT "BreweryLocation_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BreweryPost" ADD CONSTRAINT "BreweryPost_locationId_fkey" FOREIGN KEY ("locationId") REFERENCES "BreweryLocation"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@@ -29,19 +29,32 @@ model User {
|
|||||||
accountIsVerified Boolean @default(false)
|
accountIsVerified Boolean @default(false)
|
||||||
dateOfBirth DateTime
|
dateOfBirth DateTime
|
||||||
role Role @default(USER)
|
role Role @default(USER)
|
||||||
|
bio String?
|
||||||
beerPosts BeerPost[]
|
beerPosts BeerPost[]
|
||||||
beerStyles BeerStyle[]
|
beerStyles BeerStyle[]
|
||||||
breweryPosts BreweryPost[]
|
breweryPosts BreweryPost[]
|
||||||
beerComments BeerComment[]
|
beerComments BeerComment[]
|
||||||
breweryComments BreweryComment[]
|
breweryComments BreweryComment[]
|
||||||
BeerPostLikes BeerPostLike[]
|
beerPostLikes BeerPostLike[]
|
||||||
BeerImage BeerImage[]
|
beerImages BeerImage[]
|
||||||
BreweryImage BreweryImage[]
|
breweryImages BreweryImage[]
|
||||||
BreweryPostLike BreweryPostLike[]
|
breweryPostLikes BreweryPostLike[]
|
||||||
Location Location[]
|
locations BreweryLocation[]
|
||||||
Glassware Glassware[]
|
glasswares Glassware[]
|
||||||
BeerStyleLike BeerStyleLike[]
|
beerStyleLikes BeerStyleLike[]
|
||||||
BeerStyleComment BeerStyleComment[]
|
beerStyleComments BeerStyleComment[]
|
||||||
|
userAvatar UserAvatar?
|
||||||
|
}
|
||||||
|
|
||||||
|
model UserAvatar {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
path String
|
||||||
|
alt String
|
||||||
|
caption String
|
||||||
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
userId String @unique
|
||||||
|
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
||||||
|
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
model BeerPost {
|
model BeerPost {
|
||||||
@@ -60,7 +73,7 @@ model BeerPost {
|
|||||||
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
||||||
beerComments BeerComment[]
|
beerComments BeerComment[]
|
||||||
beerImages BeerImage[]
|
beerImages BeerImage[]
|
||||||
BeerPostLikes BeerPostLike[]
|
beerPostLikes BeerPostLike[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model BeerPostLike {
|
model BeerPostLike {
|
||||||
@@ -108,8 +121,8 @@ model BeerStyle {
|
|||||||
abvRange Float[]
|
abvRange Float[]
|
||||||
ibuRange Float[]
|
ibuRange Float[]
|
||||||
beerPosts BeerPost[]
|
beerPosts BeerPost[]
|
||||||
BeerStyleLike BeerStyleLike[]
|
beerStyleLike BeerStyleLike[]
|
||||||
BeerStyleComment BeerStyleComment[]
|
beerStyleComment BeerStyleComment[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model BeerStyleLike {
|
model BeerStyleLike {
|
||||||
@@ -142,10 +155,10 @@ model Glassware {
|
|||||||
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
updatedAt DateTime? @updatedAt @db.Timestamptz(3)
|
||||||
postedBy User @relation(fields: [postedById], references: [id], onDelete: Cascade)
|
postedBy User @relation(fields: [postedById], references: [id], onDelete: Cascade)
|
||||||
postedById String
|
postedById String
|
||||||
BeerStyle BeerStyle[]
|
beerStyle BeerStyle[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model Location {
|
model BreweryLocation {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
city String
|
city String
|
||||||
stateOrProvince String?
|
stateOrProvince String?
|
||||||
@@ -154,7 +167,7 @@ model Location {
|
|||||||
address String
|
address String
|
||||||
postedBy User @relation(fields: [postedById], references: [id], onDelete: Cascade)
|
postedBy User @relation(fields: [postedById], references: [id], onDelete: Cascade)
|
||||||
postedById String
|
postedById String
|
||||||
BreweryPost BreweryPost?
|
breweryPost BreweryPost?
|
||||||
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)
|
||||||
}
|
}
|
||||||
@@ -162,7 +175,7 @@ model Location {
|
|||||||
model BreweryPost {
|
model BreweryPost {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
name String
|
name String
|
||||||
location Location @relation(fields: [locationId], references: [id])
|
location BreweryLocation @relation(fields: [locationId], references: [id])
|
||||||
locationId String @unique
|
locationId String @unique
|
||||||
beers BeerPost[]
|
beers BeerPost[]
|
||||||
description String
|
description String
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { z } from 'zod';
|
|||||||
import { hashPassword } from '../../../config/auth/passwordFns';
|
import { hashPassword } from '../../../config/auth/passwordFns';
|
||||||
import DBClient from '../../DBClient';
|
import DBClient from '../../DBClient';
|
||||||
import GetUserSchema from '../../../services/User/schema/GetUserSchema';
|
import GetUserSchema from '../../../services/User/schema/GetUserSchema';
|
||||||
|
import imageUrls from '../util/imageUrls';
|
||||||
|
|
||||||
const createAdminUser = async () => {
|
const createAdminUser = async () => {
|
||||||
const hash = await hashPassword('Pas!3word');
|
const hash = await hashPassword('Pas!3word');
|
||||||
@@ -15,6 +16,14 @@ const createAdminUser = async () => {
|
|||||||
dateOfBirth: new Date('1990-01-01'),
|
dateOfBirth: new Date('1990-01-01'),
|
||||||
role: 'ADMIN',
|
role: 'ADMIN',
|
||||||
hash,
|
hash,
|
||||||
|
userAvatar: {
|
||||||
|
create: {
|
||||||
|
path: imageUrls[Math.floor(Math.random() * imageUrls.length)],
|
||||||
|
alt: 'Admin User',
|
||||||
|
caption: 'Admin User',
|
||||||
|
createdAt: new Date(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -27,6 +36,8 @@ const createAdminUser = async () => {
|
|||||||
accountIsVerified: true,
|
accountIsVerified: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
role: true,
|
role: true,
|
||||||
|
bio: true,
|
||||||
|
userAvatar: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
// 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 { Location, User } from '@prisma/client';
|
import { BreweryLocation, User } from '@prisma/client';
|
||||||
import DBClient from '../../DBClient';
|
import DBClient from '../../DBClient';
|
||||||
|
|
||||||
interface CreateNewBreweryPostsArgs {
|
interface CreateNewBreweryPostsArgs {
|
||||||
numberOfPosts: number;
|
numberOfPosts: number;
|
||||||
joinData: {
|
joinData: {
|
||||||
users: User[];
|
users: User[];
|
||||||
locations: Location[];
|
locations: BreweryLocation[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ const createNewLocations = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.location.createMany({ data: locationData, skipDuplicates: true });
|
await prisma.breweryLocation.createMany({ data: locationData, skipDuplicates: true });
|
||||||
|
|
||||||
return prisma.location.findMany();
|
return prisma.breweryLocation.findMany();
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createNewLocations;
|
export default createNewLocations;
|
||||||
|
|||||||
38
src/prisma/seed/create/createNewUserAvatars.ts
Normal file
38
src/prisma/seed/create/createNewUserAvatars.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { User } from '@prisma/client';
|
||||||
|
import DBClient from '../../DBClient';
|
||||||
|
import imageUrls from '../util/imageUrls';
|
||||||
|
|
||||||
|
interface CreateNewUserAvatarsArgs {
|
||||||
|
joinData: { users: User[] };
|
||||||
|
}
|
||||||
|
interface UserAvatarData {
|
||||||
|
path: string;
|
||||||
|
alt: string;
|
||||||
|
caption: string;
|
||||||
|
userId: string;
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createNewUserAvatars = async ({
|
||||||
|
joinData: { users },
|
||||||
|
}: CreateNewUserAvatarsArgs) => {
|
||||||
|
const userAvatars: UserAvatarData[] = [];
|
||||||
|
|
||||||
|
const path = imageUrls[Math.floor(Math.random() * imageUrls.length)];
|
||||||
|
users.forEach((user) => {
|
||||||
|
userAvatars.push({
|
||||||
|
path,
|
||||||
|
alt: `${user.firstName} ${user.lastName}`,
|
||||||
|
caption: `${user.firstName} ${user.lastName}`,
|
||||||
|
userId: user.id,
|
||||||
|
createdAt: new Date(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await DBClient.instance.userAvatar.createMany({ data: userAvatars });
|
||||||
|
return DBClient.instance.userAvatar.findMany({
|
||||||
|
where: { user: { role: { not: 'ADMIN' } } },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createNewUserAvatars;
|
||||||
@@ -71,7 +71,9 @@ const createNewUsers = async ({ numberOfUsers }: CreateNewUsersArgs) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await prisma.user.createMany({ data, skipDuplicates: true });
|
await prisma.user.createMany({ data, skipDuplicates: true });
|
||||||
return prisma.user.findMany();
|
return prisma.user.findMany({
|
||||||
|
where: { role: { not: 'ADMIN' } },
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createNewUsers;
|
export default createNewUsers;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import logger from '../../config/pino/logger';
|
|||||||
import createAdminUser from './create/createAdminUser';
|
import createAdminUser from './create/createAdminUser';
|
||||||
import createNewBeerStyleComments from './create/createNewBeerStyleComments';
|
import createNewBeerStyleComments from './create/createNewBeerStyleComments';
|
||||||
import createNewBeerStyleLikes from './create/createNewBeerStyleLikes';
|
import createNewBeerStyleLikes from './create/createNewBeerStyleLikes';
|
||||||
|
import createNewUserAvatars from './create/createNewUserAvatars';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -33,6 +34,9 @@ import createNewBeerStyleLikes from './create/createNewBeerStyleLikes';
|
|||||||
const users = await createNewUsers({ numberOfUsers: 10000 });
|
const users = await createNewUsers({ numberOfUsers: 10000 });
|
||||||
logger.info('Users created successfully.');
|
logger.info('Users created successfully.');
|
||||||
|
|
||||||
|
const userAvatars = await createNewUserAvatars({ joinData: { users } });
|
||||||
|
logger.info('User avatars created successfully.');
|
||||||
|
|
||||||
const locations = await createNewLocations({
|
const locations = await createNewLocations({
|
||||||
numberOfLocations: 500,
|
numberOfLocations: 500,
|
||||||
joinData: { users },
|
joinData: { users },
|
||||||
@@ -103,6 +107,7 @@ import createNewBeerStyleLikes from './create/createNewBeerStyleLikes';
|
|||||||
logger.info('Database seeded successfully.');
|
logger.info('Database seeded successfully.');
|
||||||
logger.info({
|
logger.info({
|
||||||
numberOfUsers: users.length,
|
numberOfUsers: users.length,
|
||||||
|
numberOfUserAvatars: userAvatars.length,
|
||||||
numberOfBreweryPosts: breweryPosts.length,
|
numberOfBreweryPosts: breweryPosts.length,
|
||||||
numberOfBeerPosts: beerPosts.length,
|
numberOfBeerPosts: beerPosts.length,
|
||||||
numberOfBeerStyles: beerStyles.length,
|
numberOfBeerStyles: beerStyles.length,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const createNewBeerComment = async ({
|
|||||||
id: true,
|
id: true,
|
||||||
content: true,
|
content: true,
|
||||||
rating: true,
|
rating: true,
|
||||||
postedBy: { select: { id: true, username: true } },
|
postedBy: { select: { id: true, username: true, userAvatar: true } },
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ const editBeerCommentById = async ({
|
|||||||
rating: true,
|
rating: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
postedBy: { select: { id: true, username: true, createdAt: true } },
|
postedBy: {
|
||||||
|
select: { id: true, username: true, createdAt: true, userAvatar: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ const findBeerCommentById = async ({
|
|||||||
rating: true,
|
rating: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
postedBy: { select: { id: true, username: true, createdAt: true } },
|
postedBy: {
|
||||||
|
select: { id: true, username: true, createdAt: true, userAvatar: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ const getAllBeerComments = async ({
|
|||||||
rating: true,
|
rating: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
postedBy: { select: { id: true, username: true, createdAt: true } },
|
postedBy: {
|
||||||
|
select: { id: true, username: true, createdAt: true, userAvatar: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,9 +27,11 @@ const createNewBeerStyleComment = async ({
|
|||||||
id: true,
|
id: true,
|
||||||
content: true,
|
content: true,
|
||||||
rating: true,
|
rating: true,
|
||||||
postedBy: { select: { id: true, username: true } },
|
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
|
postedBy: {
|
||||||
|
select: { id: true, username: true, createdAt: true, userAvatar: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ const getAllBeerStyleComments = async ({
|
|||||||
rating: true,
|
rating: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
postedBy: { select: { id: true, username: true, createdAt: true } },
|
postedBy: {
|
||||||
|
select: { id: true, username: true, createdAt: true, userAvatar: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,9 +27,11 @@ const createNewBreweryComment = async ({
|
|||||||
id: true,
|
id: true,
|
||||||
content: true,
|
content: true,
|
||||||
rating: true,
|
rating: true,
|
||||||
postedBy: { select: { id: true, username: true } },
|
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
|
postedBy: {
|
||||||
|
select: { id: true, username: true, createdAt: true, userAvatar: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ const getAllBreweryComments = async ({
|
|||||||
rating: true,
|
rating: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
postedBy: { select: { id: true, username: true, createdAt: true } },
|
postedBy: {
|
||||||
|
select: { id: true, username: true, createdAt: true, userAvatar: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
orderBy: { createdAt: 'desc' },
|
orderBy: { createdAt: 'desc' },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ const createNewUser = async ({
|
|||||||
accountIsVerified: true,
|
accountIsVerified: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
role: true,
|
role: true,
|
||||||
|
userAvatar: true,
|
||||||
|
bio: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ const deleteUserById = async (id: string) => {
|
|||||||
accountIsVerified: true,
|
accountIsVerified: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
role: true,
|
role: true,
|
||||||
|
userAvatar: true,
|
||||||
|
bio: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,17 @@ const findUserById = async (id: string) => {
|
|||||||
accountIsVerified: true,
|
accountIsVerified: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
role: true,
|
role: true,
|
||||||
|
userAvatar: {
|
||||||
|
select: {
|
||||||
|
path: true,
|
||||||
|
alt: true,
|
||||||
|
caption: true,
|
||||||
|
createdAt: true,
|
||||||
|
id: true,
|
||||||
|
updatedAt: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
bio: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,17 @@ const GetUserSchema = z.object({
|
|||||||
dateOfBirth: z.coerce.date(),
|
dateOfBirth: z.coerce.date(),
|
||||||
accountIsVerified: z.boolean(),
|
accountIsVerified: z.boolean(),
|
||||||
role: z.enum(['USER', 'ADMIN']),
|
role: z.enum(['USER', 'ADMIN']),
|
||||||
|
bio: z.string().nullable(),
|
||||||
|
userAvatar: z
|
||||||
|
.object({
|
||||||
|
id: z.string().cuid(),
|
||||||
|
path: z.string().url(),
|
||||||
|
alt: z.string(),
|
||||||
|
caption: z.string(),
|
||||||
|
createdAt: z.coerce.date(),
|
||||||
|
updatedAt: z.coerce.date().nullable(),
|
||||||
|
})
|
||||||
|
.nullable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default GetUserSchema;
|
export default GetUserSchema;
|
||||||
|
|||||||
@@ -17,6 +17,17 @@ const updateUserToBeConfirmedById = async (id: string) => {
|
|||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
dateOfBirth: true,
|
dateOfBirth: true,
|
||||||
role: true,
|
role: true,
|
||||||
|
bio: true,
|
||||||
|
userAvatar: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
path: true,
|
||||||
|
alt: true,
|
||||||
|
caption: true,
|
||||||
|
createdAt: true,
|
||||||
|
updatedAt: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ const CommentQueryResult = z.object({
|
|||||||
postedBy: z.object({
|
postedBy: z.object({
|
||||||
id: z.string().cuid(),
|
id: z.string().cuid(),
|
||||||
username: z.string().min(1).max(50),
|
username: z.string().min(1).max(50),
|
||||||
|
userAvatar: z
|
||||||
|
.object({
|
||||||
|
id: z.string().cuid(),
|
||||||
|
path: z.string().url(),
|
||||||
|
alt: z.string().min(1).max(50),
|
||||||
|
caption: z.string().min(1).max(50),
|
||||||
|
})
|
||||||
|
.nullable(),
|
||||||
}),
|
}),
|
||||||
updatedAt: z.coerce.date().nullable(),
|
updatedAt: z.coerce.date().nullable(),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user