From 99b89347d08952d67cf1fe891930d349d42a4ae5 Mon Sep 17 00:00:00 2001 From: Adrian Bonpin Date: Sat, 16 May 2026 17:33:36 +0800 Subject: [PATCH] feat: show existing screenshots when editing entries with remove support --- components/wizard/game-entry-wizard.tsx | 28 ++++++++++++++- components/wizard/steps/review-step.tsx | 48 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/components/wizard/game-entry-wizard.tsx b/components/wizard/game-entry-wizard.tsx index 467e9c7..c93e708 100644 --- a/components/wizard/game-entry-wizard.tsx +++ b/components/wizard/game-entry-wizard.tsx @@ -9,7 +9,7 @@ import { type AntiCheatData } from "@/components/wizard/steps/anti-cheat-step" import { PerformanceStep, type PerformanceData } from "@/components/wizard/steps/performance-step" import { SettingsStep } from "@/components/wizard/steps/settings-step" import { EnvironmentStep, type EnvironmentData } from "@/components/wizard/steps/environment-step" -import { ReviewStep } from "@/components/wizard/steps/review-step" +import { ReviewStep, type ExistingScreenshot } from "@/components/wizard/steps/review-step" import type { SettingCategory } from "@/components/wizard/settings-editor" import { performanceEntries } from "@/lib/db/schema" @@ -46,6 +46,8 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn const [error, setError] = useState(null) const [screenshotFiles, setScreenshotFiles] = useState([]) const [submitPhase, setSubmitPhase] = useState<"idle" | "uploading" | "saving" | "success" | "error">("idle") + const [existingScreenshots, setExistingScreenshots] = useState([]) + const [removedScreenshotIds, setRemovedScreenshotIds] = useState([]) // Step 0: Setup — Hardware const [hardwareSlug, setHardwareSlug] = useState(editEntry?.hardwareSlug ?? "") @@ -200,6 +202,11 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn return v.versionString || (v.buildId ? `Build ${v.buildId}` : "Unknown version") }, [selectedVersionId, newVersionString, gameVersions, steamdbVersion]) + const handleRemoveExistingScreenshot = useCallback((id: string) => { + setExistingScreenshots((prev) => prev.filter((ss) => ss.id !== id)) + setRemovedScreenshotIds((prev) => [...prev, id]) + }, []) + const fetchSteamDBVersion = useCallback(async () => { setSteamdbLoading(true) try { @@ -219,6 +226,22 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn } }, [gameId]) + // Initialize existing screenshots when editing + useEffect(() => { + if (editEntry && (editEntry as any).screenshots && Array.isArray((editEntry as any).screenshots)) { + setExistingScreenshots( + (editEntry as any).screenshots.map((ss: any) => ({ + type: "existing" as const, + id: ss.id, + url: ss.url, + width: ss.width, + height: ss.height, + orderIndex: ss.orderIndex, + })) + ) + } + }, [editEntry]) + // Fetch SteamDB version on mount useEffect(() => { fetchSteamDBVersion() @@ -339,6 +362,7 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn frameGenMethod: environment.frameGenMethod ?? "none", launchOptions: environment.launchOptions || null, customSystem: environment.customSystem ?? false, + removedScreenshotIds: removedScreenshotIds.length > 0 ? removedScreenshotIds : undefined, settingsJson: settingsJson.length > 0 ? settingsJson : null, userNotes: userNotes || null, antiCheatRelevant: antiCheat.antiCheatRelevant, @@ -467,6 +491,8 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn screenshotFiles={screenshotFiles} onScreenshotFilesChange={setScreenshotFiles} submitPhase={submitPhase} + existingScreenshots={existingScreenshots} + onRemoveExistingScreenshot={handleRemoveExistingScreenshot} /> )} diff --git a/components/wizard/steps/review-step.tsx b/components/wizard/steps/review-step.tsx index 4650b83..8648dc4 100644 --- a/components/wizard/steps/review-step.tsx +++ b/components/wizard/steps/review-step.tsx @@ -23,6 +23,15 @@ import type { PerformanceData } from "./performance-step" import type { EnvironmentData } from "./environment-step" import { UPSCALER_TYPE_OPTIONS, FRAME_GEN_OPTIONS } from "./environment-step" +export interface ExistingScreenshot { + type: "existing" + id: string + url: string + width: number + height: number + orderIndex: number +} + export interface ReviewData { hardwareSlug: string hardwareName: string @@ -49,6 +58,8 @@ interface ReviewStepProps { screenshotFiles: File[] onScreenshotFilesChange: (files: File[]) => void submitPhase: "idle" | "uploading" | "saving" | "success" | "error" + existingScreenshots?: ExistingScreenshot[] + onRemoveExistingScreenshot?: (id: string) => void } function SectionHeader({ @@ -185,6 +196,8 @@ export function ReviewStep({ screenshotFiles, onScreenshotFilesChange, submitPhase, + existingScreenshots, + onRemoveExistingScreenshot, }: ReviewStepProps) { const { hardwareName, @@ -528,6 +541,41 @@ export function ReviewStep({ ) : (
+ {/* Existing screenshots (from edit mode) */} + {existingScreenshots && existingScreenshots.length > 0 && ( +
+

Existing screenshots

+
+ {existingScreenshots.map((ss) => ( +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {`Screenshot +
+ +
+ Existing · #{ss.orderIndex + 1} +
+
+ ))} +
+
+ )} + {/* Screenshot grid with drag-to-reorder */} {screenshotFiles && screenshotFiles.length > 0 && (