import { Suspense } from "react"; import Link from "next/link"; import { Play, Info, Sparkles } from "lucide-react"; import type { GameCard as GameCardData, PublicUser } from "@spinza/shared"; import { Button } from "@/components/ui"; import { ServerUnavailable } from "@/components/shell/api-error"; import { GameArt } from "./game-art"; import { GameCard, GameRow, GameTile, VolatilityMeter } from "./game-card"; import { RewardsStrip } from "./rewards-strip"; import { WelcomeOverlay } from "./welcome-overlay"; import { timeAgo } from "@/lib/utils"; export interface LobbyProps { user: PublicUser; games: GameCardData[] | null; livePlayers: number; recommendations: string[]; } const FLAGSHIP_SLUG = "spinza-original"; export function Lobby({ user, games, livePlayers, recommendations }: LobbyProps) { const list = games ?? []; const slots = list.filter((g) => (g.kind ?? "slot") === "slot"); const risk = list.filter((g) => g.kind === "crash"); const originals = list.filter((g) => g.kind === "arcade"); const flagship = list.find((g) => g.slug === FLAGSHIP_SLUG) ?? list.find((g) => g.isFeatured) ?? list[0] ?? null; const continuePlaying = list.filter((g) => g.lastPlayedAt).sort((a, b) => new Date(b.lastPlayedAt!).getTime() - new Date(a.lastPlayedAt!).getTime()); const featured = list.filter((g) => g.isFeatured); const fresh = list.filter((g) => g.isNew); const popular = [...list].sort((a, b) => b.popularity - a.popularity).slice(0, 10); const highVol = slots.filter((g) => g.volatility === "high" || g.volatility === "extreme"); const relaxed = slots.filter((g) => g.volatility === "low" || g.volatility === "medium"); const jackpots = slots.filter((g) => g.isJackpot); const picks = recommendations.map((s) => list.find((g) => g.slug === s)).filter((g): g is GameCardData => !!g); const welcomePicks = picks.length ? picks : list.slice(0, 3); return (
{/* ---------------------------------------------------------- hero */} {flagship ? (
{flagship.slug === FLAGSHIP_SLUG ? "Flagship title" : "Featured"}

{flagship.name}

{flagship.tagline}

{flagship.grid.reels}×{flagship.grid.rows} · {flagship.features.slice(0, 2).join(" · ")}
) : games === null ? ( ) : (
Lobby

Welcome back, {user.username}.

New games are being certified and will appear here as soon as they pass. Your credits and progress are safe.

)} {/* --------------------------------------------------------- strip */} {games === null && flagship ? : null} {/* ------------------------------------------------------ sections */} {continuePlaying.length ? (
Pick up where you left off

Continue playing

{continuePlaying.slice(0, 6).map((g) => ( ))}
) : null} {list.length ? (
{list.length} titles

All games

Filter & search
{list.map((g) => ( ))}
) : null}

Virtual credits only. No deposits. No withdrawals. No cash value. 18+.

); }