From 23fa7be89f960b9437c9ca81f2258f4811a7aab1 Mon Sep 17 00:00:00 2001 From: Adrian Bonpin Date: Tue, 28 Apr 2026 23:24:33 +0800 Subject: [PATCH] feat: display system requirements and store stats on game details page --- app/game/[id]/game-page-client.tsx | 93 +++++++++++++++++++++++++++++- app/game/[id]/page.tsx | 11 ++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/app/game/[id]/game-page-client.tsx b/app/game/[id]/game-page-client.tsx index ef2dd1c..6ae4ec9 100644 --- a/app/game/[id]/game-page-client.tsx +++ b/app/game/[id]/game-page-client.tsx @@ -16,6 +16,7 @@ import { ThumbsUpIcon, ThumbsDownIcon, GaugeIcon, + ChevronDownIcon, } from "lucide-react" import Link from "next/link" import { useSession } from "@/lib/auth-client" @@ -26,6 +27,7 @@ import type { GameSettingCategory } from "@/lib/db/schema/performanceEntries" import { PresetDetailModal } from "./preset-detail-modal" import { BookmarkButton } from "@/components/saved-games/bookmark-button" +import { WindowsIcon, MacIcon, LinuxIcon } from "@/app/components/PlatformIcons" // Chart imports import { HistoricalAreaChart } from "@/components/charts/HistoricalAreaChart" @@ -57,6 +59,17 @@ interface Game { createdAt: string metascore?: number | null onlineMultiplayerStatus?: string | null + systemRequirements: { minimum: string | null; recommended: string | null } | null + metacriticScore: number | null + metacriticUrl: string | null + recommendationsTotal: number | null + priceCurrent: number | null + priceInitial: number | null + priceCurrency: string | null + isFree: boolean + releaseDate: string | null + categories: string[] | null + platforms: { windows: boolean; mac: boolean; linux: boolean } | null } interface Counts { @@ -239,6 +252,7 @@ export function GamePageClient({ }) const [loading, setLoading] = useState(true) const [selectedPresetId, setSelectedPresetId] = useState(null) + const [showSystemReq, setShowSystemReq] = useState(false) const [reportedPresets, setReportedPresets] = useState>(new Set()) const presetsRef = useRef(null) @@ -607,6 +621,33 @@ export function GamePageClient({ No description available.

)} + {game.systemRequirements && (game.systemRequirements.minimum || game.systemRequirements.recommended) && ( +
+ + {showSystemReq && ( +
+ {game.systemRequirements.minimum && ( +
+

Minimum

+
+
+ )} + {game.systemRequirements.recommended && ( +
+

Recommended

+
+
+ )} +
+ )} +
+ )}
{/* Right: Metadata grid */} @@ -639,9 +680,59 @@ export function GamePageClient({ value={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 && }
- {/* Platform Support */} + {/* Platforms */} + {game.platforms && ( +
+

+ Platforms +

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

diff --git a/app/game/[id]/page.tsx b/app/game/[id]/page.tsx index 4c957c7..91e42c8 100644 --- a/app/game/[id]/page.tsx +++ b/app/game/[id]/page.tsx @@ -276,6 +276,17 @@ export default async function GamePage({ lastSync: game.lastSync ? game.lastSync.toISOString() : null, syncStatus: game.syncStatus, createdAt: game.createdAt.toISOString(), + systemRequirements: game.systemRequirements, + metacriticScore: game.metacriticScore, + metacriticUrl: game.metacriticUrl, + recommendationsTotal: game.recommendationsTotal, + priceCurrent: game.priceCurrent, + priceInitial: game.priceInitial, + priceCurrency: game.priceCurrency, + isFree: game.isFree, + releaseDate: game.releaseDate, + categories: game.categories, + platforms: game.platforms, } const serializedPresets = presetRows.map((p) => ({