59 lines
1.9 KiB
TypeScript
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;
|