feat: add anti-cheat, playability, steam reviews, and community suggestions to game details page

This commit is contained in:
2026-04-30 20:13:08 +08:00
parent fa613dd1c3
commit 0bb8c205f9
+76
View File
@@ -30,6 +30,11 @@ import { PresetDetailModal } from "./preset-detail-modal"
import { BookmarkButton } from "@/components/saved-games/bookmark-button" import { BookmarkButton } from "@/components/saved-games/bookmark-button"
import { WindowsIcon, MacIcon, LinuxIcon } from "@/app/components/PlatformIcons" import { WindowsIcon, MacIcon, LinuxIcon } from "@/app/components/PlatformIcons"
import { AntiCheatBadge } from "@/components/anti-cheat-badge"
import { PlayabilityBadge } from "@/components/playability-badge"
import { SteamReviews } from "@/components/steam-reviews"
import { CommunitySuggestionForm } from "@/components/community-suggestion-form"
// Chart imports // Chart imports
import { HistoricalAreaChart } from "@/components/charts/HistoricalAreaChart" import { HistoricalAreaChart } from "@/components/charts/HistoricalAreaChart"
import { UpscalerBarChart } from "@/components/charts/UpscalerBarChart" import { UpscalerBarChart } from "@/components/charts/UpscalerBarChart"
@@ -71,6 +76,9 @@ interface Game {
releaseDate: string | null releaseDate: string | null
categories: string[] | null categories: string[] | null
platforms: { windows: boolean; mac: boolean; linux: boolean } | null platforms: { windows: boolean; mac: boolean; linux: boolean } | null
playabilityStatus?: "great" | "playable" | "needs_tweaks" | "unplayable" | "unknown" | null
steamReviewScore?: number | null
steamReviewSentiment?: string | null
} }
interface Counts { interface Counts {
@@ -85,6 +93,10 @@ interface PlatformSupport {
hardwareSlug: string hardwareSlug: string
isSupported: boolean isSupported: boolean
protonStatus: string protonStatus: string
playabilityStatus: "great" | "playable" | "needs_tweaks" | "unplayable" | "unknown" | null
antiCheatRelevant: boolean
antiCheatStatus: "none" | "supported" | "unsupported" | "unknown" | null
antiCheatName: string | null
} }
interface Preset { interface Preset {
@@ -481,6 +493,24 @@ export function GamePageClient({
Poor Performance Poor Performance
</span> </span>
)} )}
{/* Playability badge */}
{game.playabilityStatus && (
<PlayabilityBadge status={game.playabilityStatus} />
)}
{/* Anti-cheat badge */}
{platformSupport?.some((p) => p.antiCheatRelevant) && (
<AntiCheatBadge
antiCheatRelevant={true}
antiCheatStatus={
platformSupport.find((p) => p.antiCheatRelevant)?.antiCheatStatus ?? "unknown"
}
antiCheatName={
platformSupport.find((p) => p.antiCheatRelevant)?.antiCheatName
}
/>
)}
</div> </div>
{/* Subtitle */} {/* Subtitle */}
@@ -608,6 +638,17 @@ export function GamePageClient({
Add Benchmark Add Benchmark
</Link> </Link>
)} )}
<CommunitySuggestionForm
gameId={game.id}
gameTitle={game.title}
editableFields={[
{ name: "title", label: "Title", currentValue: game.title },
{ name: "description", label: "Description", currentValue: game.description || "" },
{ name: "developer", label: "Developer", currentValue: game.developer || "" },
{ name: "publisher", label: "Publisher", currentValue: game.publisher || "" },
{ name: "storeUrl", label: "Store URL", currentValue: game.storeUrl || "" },
]}
/>
</div> </div>
)} )}
</div> </div>
@@ -721,6 +762,14 @@ export function GamePageClient({
/> />
)} )}
{game.releaseDate && <MetaItem label="Release Date" value={game.releaseDate} />} {game.releaseDate && <MetaItem label="Release Date" value={game.releaseDate} />}
{game.steamReviewScore != null && (
<div>
<span className="text-xs text-zinc-500">Steam Reviews</span>
<p className="text-sm">
{game.steamReviewSentiment} ({game.steamReviewScore}%)
</p>
</div>
)}
</div> </div>
{/* Platforms */} {/* Platforms */}
@@ -780,6 +829,24 @@ export function GamePageClient({
<span className='text-[10px] text-text/50 capitalize'> <span className='text-[10px] text-text/50 capitalize'>
{ps.protonStatus} {ps.protonStatus}
</span> </span>
{/* Per-device playability */}
{ps.playabilityStatus && (
<PlayabilityBadge
status={ps.playabilityStatus}
compact
/>
)}
{/* Per-device anti-cheat */}
{ps.antiCheatRelevant && (
<AntiCheatBadge
antiCheatRelevant={true}
antiCheatStatus={ps.antiCheatStatus}
antiCheatName={ps.antiCheatName}
compact
/>
)}
</div> </div>
</div> </div>
))} ))}
@@ -1334,6 +1401,15 @@ export function GamePageClient({
</div> </div>
</motion.div> </motion.div>
{/* Steam Reviews */}
{game.steamAppId && (
<section className="space-y-4 px-4 md:px-[10svw]">
<div className="max-w-7xl mx-auto">
<SteamReviews gameId={game.id} steamAppId={game.steamAppId} />
</div>
</section>
)}
{/* Section 6: Comments */} {/* Section 6: Comments */}
<motion.div <motion.div
initial={{ opacity: 0, y: 12 }} initial={{ opacity: 0, y: 12 }}