rvote-online/src/app/s/[slug]/members/page.tsx

60 lines
1.7 KiB
TypeScript

import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { notFound, redirect } from "next/navigation";
import { MemberList } from "@/components/MemberList";
import { InviteDialog } from "@/components/InviteDialog";
import { Badge } from "@/components/ui/badge";
export default async function SpaceMembersPage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const session = await auth();
if (!session?.user?.id) redirect("/auth/signin");
const space = await prisma.space.findUnique({ where: { slug } });
if (!space) notFound();
const membership = await prisma.spaceMember.findUnique({
where: { userId_spaceId: { userId: session.user.id, spaceId: space.id } },
});
if (!membership) redirect("/");
const members = await prisma.spaceMember.findMany({
where: { spaceId: space.id },
include: { user: { select: { id: true, name: true, email: true } } },
orderBy: [{ role: "asc" }, { joinedAt: "asc" }],
});
const serializedMembers = members.map((m) => ({
id: m.id,
role: m.role,
credits: m.credits,
joinedAt: m.joinedAt.toISOString(),
user: m.user,
}));
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<div>
<h2 className="text-2xl font-bold">Members</h2>
<p className="text-muted-foreground">
{members.length} member{members.length !== 1 ? "s" : ""}
</p>
</div>
{membership.role === "ADMIN" && <InviteDialog spaceSlug={slug} />}
</div>
<MemberList
members={serializedMembers}
spaceSlug={slug}
isAdmin={membership.role === "ADMIN"}
currentUserId={session.user.id}
/>
</div>
);
}