- {isJoined && (
-
- Invite Players
-
- )}
-
- {sessionPlayer && (
-
+
+
+
+ {isJoined && (
+
+ Invite Players
+
)}
+
+ {sessionPlayer && (
+
+ )}
+
+
+
+ {lobby.name}
+
+ {isAdmin && }
+
+
+
+ Players ({members?.length || 0}/{lobby.maxPlayers || 8})
+
+
+ {members?.length === (lobby.maxPlayers || 8)
+ ? "Lobby Full"
+ : "Waiting..."}
+
+
+
+
+ {members?.map((member, idx) => (
+ -
+
+ {member?.role === "admin" && (
+
+ Admin
+
+ )}
+
+
+ ))}
+
+
+
+
+
);
diff --git a/src/app/_components/lobby/lobby-player/kick-player-dialog.tsx b/src/app/_components/lobby/lobby-player/kick-player-dialog.tsx
new file mode 100644
index 0000000..1de3094
--- /dev/null
+++ b/src/app/_components/lobby/lobby-player/kick-player-dialog.tsx
@@ -0,0 +1,66 @@
+import type { Player } from "@/server/db/schema";
+import React from "react";
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@/components/ui/alert-dialog";
+import { ShieldQuestion, UserX } from "lucide-react";
+import { api } from "@/trpc/react";
+import { Button } from "@/components/ui/button";
+
+function KickPlayerDialog({
+ player,
+ lobbyId,
+}: {
+ player: Pick
;
+ lobbyId: string;
+}) {
+ const kickPlayer = api.lobby.kick.useMutation();
+ const handleAction = () => {
+ kickPlayer.mutate({ lobbyId: lobbyId, playerId: player.id });
+ };
+ return (
+
+
+
+ Kick Player
+
+
+
+
+ Are you absolutely sure to
+
+ kick {player.displayName}
+
+
+
+
+ This action cannot be undone. This will remove {player.displayName}
+ from the lobby.
+
+
+
+ Cancel
+
+
+
+
+ );
+}
+
+export default KickPlayerDialog;
diff --git a/src/app/_components/lobby/lobby_player-card.tsx b/src/app/_components/lobby/lobby-player/lobby-player-card.tsx
similarity index 57%
rename from src/app/_components/lobby/lobby_player-card.tsx
rename to src/app/_components/lobby/lobby-player/lobby-player-card.tsx
index f44c9f0..9b66933 100644
--- a/src/app/_components/lobby/lobby_player-card.tsx
+++ b/src/app/_components/lobby/lobby-player/lobby-player-card.tsx
@@ -1,23 +1,30 @@
import React from "react";
-import Avatar from "../../../components/avatar";
+import Avatar from "@/components/avatar";
import { cn } from "@/lib/utils";
-import { MoreHorizontal } from "lucide-react";
-import { Button } from "../../../components/ui/button";
import type { Player } from "@/server/db/schema";
+import LobbyPlayerOptions from "./lobby-player-options";
function LobbyPlayerCard({
+ lobbyId,
player,
children,
className,
+ highlight,
+ showOptions = false,
}: {
- player: Pick;
+ lobbyId: string;
+ player: Player;
children?: React.ReactNode;
className?: string;
+ highlight?: boolean;
+ showOptions?: boolean;
}) {
return (
@@ -26,13 +33,7 @@ function LobbyPlayerCard({
{player.displayName}
{children}
-
+ {showOptions && }
);
}
diff --git a/src/app/_components/lobby/lobby-player/lobby-player-options.tsx b/src/app/_components/lobby/lobby-player/lobby-player-options.tsx
new file mode 100644
index 0000000..d20692e
--- /dev/null
+++ b/src/app/_components/lobby/lobby-player/lobby-player-options.tsx
@@ -0,0 +1,86 @@
+"use client";
+import React from "react";
+import { Button } from "@/components/ui/button";
+import {
+ Ban,
+ Eye,
+ Handshake,
+ HeartHandshake,
+ MoreHorizontal,
+ UserCog,
+ UserX,
+} from "lucide-react";
+
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu";
+import type { Player } from "@/server/db/schema";
+import Link from "next/link";
+import { appRoutes } from "@/config/app.routes";
+import { cn } from "@/lib/utils";
+import KickPlayerDialog from "./kick-player-dialog";
+import { api } from "@/trpc/react";
+function LobbyPlayerOptions({
+ player,
+ lobbyId,
+}: {
+ player: Player;
+ lobbyId: string;
+}) {
+ const [open, setOpen] = React.useState(false);
+ const dropdownItemClassName = " flex items-center gap-1 ";
+ const changeRole = api.lobby.changeRole.useMutation();
+ return (
+
+
+
+
+
+
+ {player.displayName}
+
+
+
+
+
+ View Profile
+
+
+
+
+
+ My Friend
+
+
+
+
+
+
+ Change Role
+
+ e.preventDefault()}
+ className={cn(
+ dropdownItemClassName,
+ "group focus:border-destructive focus:text-destructive border border-transparent focus:font-bold",
+ )}
+ >
+
+
+
+
+ );
+}
+
+export default LobbyPlayerOptions;
diff --git a/src/app/_components/lobby/lobby-settings-dialog.tsx b/src/app/_components/lobby/lobby-settings-dialog.tsx
index db3ef61..d7f0245 100644
--- a/src/app/_components/lobby/lobby-settings-dialog.tsx
+++ b/src/app/_components/lobby/lobby-settings-dialog.tsx
@@ -14,8 +14,9 @@ import DeleteLobbyDialog from "./delete-lobby-dialog";
import { Settings } from "lucide-react";
function LobbySettingsDialog({ lobby }: { lobby: Lobby }) {
+ const [open, setOpen] = React.useState(false);
return (
-