import { cookies } from "next/headers" import { redirect } from "next/navigation" import { auth } from "@/auth" import { prisma } from "@/lib/prisma" import { verifyJoinLinkToken } from "@/lib/join-link" import { guestIdentityCookieName } from "@/lib/participant-identity" import { AppShell } from "@/components/shell/app-shell" import { Card, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card" import { JoinFlow } from "@/components/join/join-flow" // Reads the session/cookies and queries the DB on every request to // resolve "who is this visitor and what's their access state" — same // reasoning as the dashboard page (see its own comment) for opting out // of Cache Components' static-shell validation. export const instant = false function JoinShell({ title, children, }: { title?: string children: React.ReactNode }) { return (
{title ? (

{title}

) : null} {children}
) } function JoinMessage({ title, description, }: { title: string description: string }) { return ( {title} {description} ) } export default async function JoinPage({ params, searchParams, }: { params: Promise<{ meetingUuid: string }> searchParams: Promise<{ token?: string }> }) { const { meetingUuid } = await params const { token } = await searchParams if (!token) { return ( ) } const verified = await verifyJoinLinkToken(token) if (!verified || verified.meetingUuid !== meetingUuid) { return ( ) } const meeting = await prisma.meeting.findUnique({ where: { uuid: meetingUuid }, }) if (!meeting) { return ( ) } if (meeting.status === "ended") { return ( ) } const session = await auth() if (session?.user?.id) { const userId = Number(session.user.id) const identity = `user-${userId}` if (meeting.hostUserId === userId) { await prisma.meetingParticipant.upsert({ where: { meetingId_identity: { meetingId: meeting.id, identity }, }, update: {}, create: { meetingId: meeting.id, userId, identity, role: "host", status: "admitted", admittedAt: new Date(), }, }) redirect(`/room/${meetingUuid}`) } const participant = await prisma.meetingParticipant.findUnique({ where: { meetingId_identity: { meetingId: meeting.id, identity }, }, }) if (participant) { if (participant.status === "admitted") { redirect(`/room/${meetingUuid}`) } if (participant.status === "denied") { return ( ) } return ( ) } return ( ) } // Anonymous visitor: recognize a returning guest via cookie before // falling back to the name-entry form. const cookieStore = await cookies() const guestIdentity = cookieStore.get( guestIdentityCookieName(meetingUuid) )?.value if (guestIdentity) { const participant = await prisma.meetingParticipant.findUnique({ where: { meetingId_identity: { meetingId: meeting.id, identity: guestIdentity }, }, }) if (participant) { if (participant.status === "admitted") { redirect(`/room/${meetingUuid}`) } if (participant.status === "denied") { return ( ) } return ( ) } } return ( ) }