diff --git a/app/(setup)/page.tsx b/app/(setup)/page.tsx new file mode 100644 index 0000000..5534fa7 --- /dev/null +++ b/app/(setup)/page.tsx @@ -0,0 +1,26 @@ +import { redirect } from "next/navigation"; + +import { db } from "@/lib/db"; +import { initialProfile } from "@/lib/initial-profile"; + +const SetupPage = async () => { + const profile = await initialProfile(); + + const server = await db.server.findFirst({ + where: { + members: { + some: { + profileId: profile.id, + }, + }, + } + }); + + if (server) { + return redirect(`/servers/${server.id}`); + } + + return
Create a Server
; +} + +export default SetupPage; \ No newline at end of file diff --git a/lib/db.ts b/lib/db.ts new file mode 100644 index 0000000..f603f47 --- /dev/null +++ b/lib/db.ts @@ -0,0 +1,9 @@ +import { PrismaClient } from '@prisma/client' + +declare global { + var prisma: PrismaClient | undefined; +}; + +export const db = globalThis.prisma || new PrismaClient() + +if (process.env.NODE_ENV !== 'production') globalThis.prisma = db \ No newline at end of file diff --git a/lib/initial-profile.ts b/lib/initial-profile.ts new file mode 100644 index 0000000..bea2097 --- /dev/null +++ b/lib/initial-profile.ts @@ -0,0 +1,32 @@ +import { currentUser, redirectToSignIn } from "@clerk/nextjs"; + +import { db } from "@/lib/db"; + +export const initialProfile = async () => { + const user = await currentUser(); + + if (!user) { + return redirectToSignIn(); + } + + const profile = await db.profile.findUnique({ + where: { + userId: user.id, + }, + }); + + if (profile) { + return profile; + } + + const newProfile = await db.profile.create({ + data: { + userId: user.id, + name: `${user.firstName} ${user.lastName}`, + imageUrl : user.imageUrl, + email: user.emailAddresses[0].emailAddress, + }, + }); + + return newProfile; +} \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..8779f36 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,89 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "mysql" + url = env("DATABASE_URL") + relationMode = "prisma" +} + +model Profile{ + id String @id @default(uuid()) + userId String @unique + name String + imageUrl String @db.Text + email String @db.Text + + servers Server[] + members Member[] + channels Channel[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Server{ + id String @id @default(uuid()) + name String + imageUrl String @db.Text + inviteCode String @db.Text + + profileId String + profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade) + + members Member[] + channels Channel[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([profileId]) +} + +enum MemberRole{ + ADMIN + MODERATOR + GUEST +} + +model Member{ + id String @id @default(uuid()) + role MemberRole @default(GUEST) + + profileId String + profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade) + + serverId String + server Server @relation(fields: [serverId], references: [id], onDelete: Cascade) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([profileId]) + @@index([serverId]) +} + +enum ChannelType{ + TEXT + AUDIO + VIDEO +} + +model Channel{ + id String @id @default(uuid()) + name String + type ChannelType @default(TEXT) + + profileId String + profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade) + + serverId String + server Server @relation(fields: [serverId], references: [id], onDelete: Cascade) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([profileId]) + @@index([serverId]) +} \ No newline at end of file