"use client"; import { AnimatePresence, motion } from "framer-motion"; import { Bot, Copy, UserPlus, X } from "lucide-react"; import { useEffect, useState } from "react"; import { ScreenHeader, ScreenShell } from "@/components/online/ScreenHeader"; import { useGameStore } from "@/lib/game-store"; import { useOnlineStore } from "@/lib/online-store"; import { useUIStore } from "@/lib/ui-store"; import { useI18n } from "@/lib/i18n"; import { Friend, RoomSeat, avatarEmoji } from "@/lib/online/types"; import { cn } from "@/lib/cn"; export function RoomScreen() { const { t } = useI18n(); const room = useOnlineStore((s) => s.room); const friends = useOnlineStore((s) => s.friends); const loadFriends = useOnlineStore((s) => s.loadFriends); const setPartner = useOnlineStore((s) => s.setPartner); const inviteToSeat = useOnlineStore((s) => s.inviteToSeat); const addBot = useOnlineStore((s) => s.addBot); const clearSeat = useOnlineStore((s) => s.clearSeat); const startRoom = useOnlineStore((s) => s.startRoom); const leaveRoom = useOnlineStore((s) => s.leaveRoom); const newOnlineMatch = useGameStore((s) => s.newOnlineMatch); const goGame = useUIStore((s) => s.goGame); const go = useUIStore((s) => s.go); const [picker, setPicker] = useState(null); const [copied, setCopied] = useState(false); useEffect(() => { loadFriends(); }, [loadFriends]); if (!room) return null; const seat = (n: number) => room.seats.find((s) => s.seat === n)!; const pick = async (friend: Friend) => { if (!picker) return; if (picker.seat === 2) await setPartner(friend.id); else await inviteToSeat(picker.seat, friend.id); setPicker(null); }; const copyCode = async () => { try { await navigator.clipboard.writeText(room.code); setCopied(true); setTimeout(() => setCopied(false), 1500); } catch { /* ignore */ } }; const start = async () => { await startRoom(); const r = useOnlineStore.getState().room!; const players = r.seats .slice() .sort((a, b) => a.seat - b.seat) .map((s) => ({ displayName: s.player!.displayName, avatar: s.player!.avatar, level: s.player!.level, })); newOnlineMatch({ players, targetScore: r.targetScore, stake: r.stake, ranked: r.ranked }); goGame("home"); }; const leave = async () => { await leaveRoom(); go("online"); }; return ( {copied ? t("common.copied") : room.code} } /> {/* your team */}

{t("team.us")}

{}} onBot={() => {}} onClear={() => {}} /> setPicker({ seat: 2 })} onBot={() => addBot(2)} onClear={() => clearSeat(2)} />
{/* opponents */}

{t("room.opponents")}

setPicker({ seat: 1 })} onBot={() => addBot(1)} onClear={() => clearSeat(1)} /> setPicker({ seat: 3 })} onBot={() => addBot(3)} onClear={() => clearSeat(3)} />
{/* friend picker */} {picker && ( setPicker(null)} className="fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-navy-950/80 backdrop-blur-sm p-4" > e.stopPropagation()} className="glass rounded-3xl p-5 w-full max-w-sm max-h-[70vh] overflow-y-auto" >

{t("room.pickFriend")}

{friends.map((f) => ( ))}
)}
); } function SeatCard({ seat, role, onInvite, onBot, onClear, }: { seat: RoomSeat; role: "you" | "partner" | "opp"; onInvite: () => void; onBot: () => void; onClear: () => void; }) { const { t } = useI18n(); const filled = seat.kind !== "empty"; const label = role === "you" ? t("seat.you") : role === "partner" ? t("room.partner") : t("room.opponents"); return (
{label} {filled ? ( <> {avatarEmoji(seat.player?.avatar ?? "a-fox")} {seat.player?.displayName} {seat.kind === "bot" && 🤖} {seat.kind === "invited" ? ( {t("room.waiting")} ) : ( role !== "you" && ( ) )} ) : (
)}
); }