game-master/src/app/_components/lobby-page.tsx
2025-03-26 17:08:31 +01:00

59 lines
1.9 KiB
TypeScript

"use client";
import React from "react";
import type { PublicUser } from "@/server/auth/config";
import type { Lobby } from "@/server/db/schema";
import UserCard from "@/components/user-card";
import DeleteLobbyDialog from "@/app/_components/delete-lobby-dialog";
import LobbyMembershipDialog from "@/app/_components/lobby-membership-dialog";
import { type Session } from "next-auth";
import { getSocket } from "@/lib/hooks/use-socket";
import { LOBBY_USER_PRESENCE_EVENT } from "@/server/socket/event-const";
function LobbyPage({
session,
initialMembers,
lobby,
}: {
session: Session | null;
lobby: Pick<Lobby, "id" | "name" | "createdAt" | "createdById">;
initialMembers: Array<{ leader: boolean } & PublicUser>;
}) {
const [members, setMembers] = React.useState(initialMembers);
const isJoined = members.find((member) => member.id === session?.user.id);
const isOwner = lobby.createdById === session?.user.id;
const socket = session ? getSocket() : undefined;
React.useEffect(() => {
if (!session || !isJoined || !socket) return;
socket.emit(LOBBY_USER_PRESENCE_EVENT, lobby.id, session.user.id, true);
return () => {
if (!session || !isJoined || !socket) return;
socket.emit(LOBBY_USER_PRESENCE_EVENT, lobby.id, session.user.id, false);
socket.disconnect();
};
}, [socket]);
return (
<div>
<h1 className="text-2xl font-bold capitalize">{lobby.name}</h1>
<ul>
{members?.map((member, idx) => (
<li key={idx}>
<UserCard name={member.name!} image={member.image!}>
{member?.leader && <label>Leader</label>}
</UserCard>
</li>
))}
</ul>
{isOwner && <DeleteLobbyDialog lobbyId={lobby.id} />}
{!isOwner && (
<LobbyMembershipDialog lobbyId={lobby.id} join={!isJoined} />
)}
</div>
);
}
export default LobbyPage;