"use client" import { useCallback, useState } from "react" import Image from "next/image" import { Gamepad2Icon, MessageSquareIcon, SettingsIcon, TrendingUpIcon, ExternalLinkIcon, ClockIcon, } from "lucide-react" interface Game { id: string steamAppId: number | null title: string description: string | null developer: string | null publisher: string | null genres: string[] | null headerImage: string | null capsuleImage: string | null storeUrl: string | null source: string lastSync: string | null syncStatus: string | null createdAt: string } interface Counts { benchmarks: number presets: number comments: number } interface PlatformSupport { id: string gameId: string hardwareSlug: string isSupported: boolean protonStatus: string } const TABS = [ { key: "overview", label: "Overview", icon: Gamepad2Icon }, { key: "benchmarks", label: "Benchmarks", icon: TrendingUpIcon }, { key: "presets", label: "Presets", icon: SettingsIcon }, { key: "comments", label: "Comments", icon: MessageSquareIcon }, ] as const type TabKey = (typeof TABS)[number]["key"] export function GamePageClient({ game, counts, platformSupport, }: { game: Game counts: Counts platformSupport: PlatformSupport[] }) { const [activeTab, setActiveTab] = useState("overview") const [imgError, setImgError] = useState(false) const handleImgError = useCallback(() => setImgError(true), []) const headerImage = game.capsuleImage || game.headerImage return (
{/* Hero */}
{headerImage && !imgError ? ( {game.title} ) : (
)}

{game.title}

{game.developer && {game.developer}} {game.developer && game.publisher && ( )} {game.publisher && {game.publisher}} {game.genres && game.genres.length > 0 && ( <> {game.genres.join(", ")} )}
{/* Stats bar */}
{game.storeUrl && ( Store )}
{/* Tabs */}
{TABS.map((tab) => { const Icon = tab.icon const isActive = activeTab === tab.key return ( ) })}
{/* Tab content */}
{activeTab === "overview" && ( )} {activeTab === "benchmarks" && } {activeTab === "presets" && } {activeTab === "comments" && }
) } function StatBadge({ icon: Icon, value, label, }: { icon: React.ElementType value: number label: string }) { return (
{value} {label}
) } function OverviewTab({ game, platformSupport, }: { game: Game platformSupport: PlatformSupport[] }) { return (
{game.description && (

About

{game.description}

)} {/* Platform Support */} {platformSupport.length > 0 && (

Platform Support

{platformSupport.map((ps) => (
{ps.hardwareSlug.replace(/-/g, " ")}
{ps.isSupported ? "Supported" : "Unsupported"} {ps.protonStatus}
))}
)} {/* Metadata */}

Details

{game.steamAppId && ( )} {game.lastSync && ( )}
) } function MetaItem({ label, value, icon: Icon, }: { label: string value: string icon?: React.ElementType }) { return (
{label} {Icon && } {value}
) } function formatDate(value: string | null): string { if (!value) return "—" return new Date(value).toLocaleDateString() } function BenchmarksTab({ count }: { count: number }) { if (count === 0) { return (

No benchmarks yet

) } return (

{count} benchmark{count !== 1 ? "s" : ""} — coming soon

) } function PresetsTab({ count }: { count: number }) { if (count === 0) { return (

No presets yet

) } return (

{count} preset{count !== 1 ? "s" : ""} — coming soon

) } function CommentsTab({ count }: { count: number }) { if (count === 0) { return (

No comments yet

) } return (

{count} comment{count !== 1 ? "s" : ""} — coming soon

) }