From 1e5922462262ffcc887341cc648ad7f9c3011c0c Mon Sep 17 00:00:00 2001 From: Adrian Bonpin Date: Sat, 9 May 2026 13:19:44 +0800 Subject: [PATCH] feat: restructure game details layout, expand sys reqs by default, optimize for mobile and controller --- app/game/[id]/game-page-client.tsx | 303 ++++++++++++++--------------- 1 file changed, 150 insertions(+), 153 deletions(-) diff --git a/app/game/[id]/game-page-client.tsx b/app/game/[id]/game-page-client.tsx index cfc8928..cb6b333 100644 --- a/app/game/[id]/game-page-client.tsx +++ b/app/game/[id]/game-page-client.tsx @@ -273,7 +273,7 @@ export function GamePageClient({ }) const [loading, setLoading] = useState(true) const [selectedPresetId, setSelectedPresetId] = useState(null) - const [showSystemReq, setShowSystemReq] = useState(false) + const [showSystemReq, setShowSystemReq] = useState(true) const [reportedPresets, setReportedPresets] = useState>(new Set()) const presetsRef = useRef(null) @@ -462,7 +462,7 @@ export function GamePageClient({ >
{/* Cover image */} -
+
{coverImage && !imgError ? ( + {/* Metadata pills */} +
+ {game.releaseDate && ( + + {game.releaseDate} + + )} + {game.isFree && ( + + Free to Play + + )} + {game.priceCurrent != null && !game.isFree && game.priceCurrency && ( + + {new Intl.NumberFormat("en-US", { style: "currency", currency: game.priceCurrency }).format(game.priceCurrent / 100)} + + )} + {game.priceCurrent != null && !game.isFree && game.priceInitial != null && game.priceInitial > game.priceCurrent && game.priceCurrency && ( + + {new Intl.NumberFormat("en-US", { style: "currency", currency: game.priceCurrency }).format(game.priceInitial / 100)} + + )} + {game.metacriticScore != null && ( + + ★ {game.metacriticScore}/100 + + )} + {game.onlineMultiplayerStatus && ( + + {game.onlineMultiplayerStatus} + + )} + {game.platforms && ( + + {game.platforms.windows && } + {game.platforms.mac && } + {game.platforms.linux && } + + )} + {game.steamAppId !== null && ( + + AppID {game.steamAppId} + + )} +
+ {/* External links */}
{game.storeUrl && ( @@ -638,11 +684,12 @@ export function GamePageClient({ )} {stats && (
- + {session?.user && game.source !== "steam" && ( Edit Game @@ -652,6 +699,7 @@ export function GamePageClient({ Add Benchmark @@ -683,9 +731,9 @@ export function GamePageClient({ transition={{ duration: 0.4, delay: 0.1 }} className='px-4 md:px-[10svw]' > -
- {/* Left: Description */} -
+
+ {/* Description */} +

About

@@ -703,6 +751,7 @@ export function GamePageClient({
- {/* Right: Metadata grid */} -
-

- Details -

-
- - {game.steamAppId !== null && ( - - )} - - - {game.onlineMultiplayerStatus && ( - - )} - {game.isFree && } - {game.priceCurrent != null && !game.isFree && game.priceCurrency && ( - - )} - {game.priceCurrent != null && !game.isFree && game.priceInitial != null && game.priceInitial > game.priceCurrent && game.priceCurrency && ( - - )} - {game.metacriticScore != null && ( - - )} - {game.recommendationsTotal != null && ( - - )} - {game.releaseDate && } - {game.steamReviewScore != null && ( -
- Steam Reviews -

- {game.steamReviewSentiment} ({game.steamReviewScore}%) -

-
- )} + {/* Platforms */} + {game.platforms && ( +
+

+ Platforms +

+
+ + + + + + + + + +
- - {/* Platforms */} - {game.platforms && ( -
-

- Platforms -

-
- - - - - - - - - -
-
- )} - {platformSupport.length > 0 && ( -
-

- Platform Support -

-
- {platformSupport.map((ps) => ( -
- - {ps.hardwareSlug.replace( - /-/g, - " ", - )} + )} + {platformSupport.length > 0 && ( +
+

+ Platform Support +

+
+ {platformSupport.map((ps) => ( +
+ + {ps.hardwareSlug.replace( + /-/g, + " ", + )} + +
+ + {ps.isSupported + ? "Supported" + : "Unsupported"} + + + {ps.protonStatus} -
- - {ps.isSupported - ? "Supported" - : "Unsupported"} - - - {ps.protonStatus} - - {/* Per-device playability */} - {ps.playabilityStatus && ( - - )} + {/* Per-device playability */} + {ps.playabilityStatus && ( + + )} - {/* Per-device anti-cheat */} - {ps.antiCheatRelevant && ( - - )} -
+ {/* Per-device anti-cheat */} + {ps.antiCheatRelevant && ( + + )}
- ))} -
+
+ ))}
- )} -
+
+ )}
@@ -904,6 +886,7 @@ export function GamePageClient({ ? "bg-primary/20 border-primary text-primary" : "bg-transparent border-border text-text/60 hover:text-text/80" }`} + data-gamepad-focusable > {device.hardwareName} @@ -979,7 +962,7 @@ export function GamePageClient({
{pinnedPresets.map((preset) => { const raw = isRawPerformerPreset(preset) @@ -988,11 +971,12 @@ export function GamePageClient({ handlePresetOpen(preset.id)} - className={`shrink-0 w-72 flex flex-col gap-3 p-4 rounded-xl border transition-colors cursor-pointer hover:border-primary/30 ${ + className={`flex flex-col gap-3 p-4 rounded-xl border transition-colors cursor-pointer hover:border-primary/30 ${ raw ? "border-green-500/30 bg-green-500/5" : "border-yellow-500/30 bg-yellow-500/5" }`} + data-gamepad-focusable > {/* Header */}
@@ -1143,7 +1127,7 @@ export function GamePageClient({ ) : (
{regularPresets.map((preset) => { const raw = isRawPerformerPreset(preset) @@ -1152,11 +1136,12 @@ export function GamePageClient({ handlePresetOpen(preset.id)} - className={`shrink-0 w-72 flex flex-col gap-3 p-4 rounded-xl border transition-colors cursor-pointer hover:border-primary/30 ${ + className={`flex flex-col gap-3 p-4 rounded-xl border transition-colors cursor-pointer hover:border-primary/30 ${ raw ? "border-green-500/30 bg-green-500/5" : "border-border bg-text/3" }`} + data-gamepad-focusable > {/* Header */}
@@ -1438,10 +1423,21 @@ export function GamePageClient({ transition={{ duration: 0.4, delay: 0.3 }} className='px-4 md:px-[10svw]' > -
+
+ + {/* Mobile FAB for Add Benchmark */} + {session && ( + + + + )} {selectedPresetId && (() => { @@ -1533,6 +1529,7 @@ function FilterSelect({ value={value} onChange={(e) => onChange(e.target.value)} className='text-xs bg-background border border-border rounded-md px-2 py-1 text-text/80 focus:outline-none focus:border-primary min-w-25' + data-gamepad-focusable > {options.map((opt) => (