diff --git a/components/wizard/game-entry-wizard.tsx b/components/wizard/game-entry-wizard.tsx index a1a0d89..6d47ea0 100644 --- a/components/wizard/game-entry-wizard.tsx +++ b/components/wizard/game-entry-wizard.tsx @@ -44,10 +44,8 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn const [currentStep, setCurrentStep] = useState(0) const [isSubmitting, setIsSubmitting] = useState(false) const [error, setError] = useState(null) - const [success, setSuccess] = useState(false) const [screenshotFiles, setScreenshotFiles] = useState([]) - const [screenshotUploading, setScreenshotUploading] = useState(false) - const [screenshotError, setScreenshotError] = useState(null) + const [submitPhase, setSubmitPhase] = useState<"idle" | "uploading" | "saving" | "success" | "error">("idle") // Step 0: Setup — Hardware const [hardwareSlug, setHardwareSlug] = useState(editEntry?.hardwareSlug ?? "") @@ -260,10 +258,10 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn const handleSubmit = async () => { setIsSubmitting(true) + setSubmitPhase("uploading") setError(null) try { - // Resolve version ID (may create a new version) const versionId = await resolveVersionId() const payload = { @@ -291,67 +289,46 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn antiCheatStatus: antiCheat.antiCheatStatus, } + const formData = new FormData() + formData.append("payload", JSON.stringify(payload)) + + for (const file of screenshotFiles) { + formData.append("screenshots", file) + } + + setSubmitPhase("saving") + const url = editEntry ? `/api/performance/${editEntry.id}/edit` : "/api/performance/submit" const method = editEntry ? "PATCH" : "POST" - const res = await fetch(url, { - method, - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(payload), - }) + const res = await fetch(url, { method, body: formData }) if (!res.ok) { const data = await res.json() throw new Error(data.error || `Failed to ${editEntry ? "update" : "submit"} entry`) } - const data = await res.json() - - // Inline screenshot upload for new entries - if (!editEntry && data.id && screenshotFiles.length > 0) { - setScreenshotUploading(true) - try { - const formData = new FormData() - screenshotFiles.forEach((file) => formData.append("screenshots", file)) - const uploadRes = await fetch(`/api/performance/${data.id}/screenshots`, { - method: "POST", - body: formData, - }) - if (!uploadRes.ok) { - console.warn("Screenshot upload failed:", await uploadRes.text()) - } - } catch (err) { - console.warn("Screenshot upload error:", err) - } finally { - setScreenshotUploading(false) - } - } - - setSuccess(true) + setSubmitPhase("success") setTimeout(() => { router.push(`/game/${gameId}`) }, 2000) } catch (err) { + setSubmitPhase("error") setError(err instanceof Error ? err.message : "An error occurred") } finally { setIsSubmitting(false) } } - if (success) { + if (submitPhase === "success") { return ( -
- - - -

Entry Submitted!

Redirecting to game page...

@@ -429,34 +406,34 @@ export function GameEntryWizard({ gameId, gameVersions, defaultVersionId, editEn error={error} screenshotFiles={screenshotFiles} onScreenshotFilesChange={setScreenshotFiles} - screenshotUploading={screenshotUploading} - screenshotError={screenshotError} + submitPhase={submitPhase} /> )} {/* Navigation Buttons */} - {currentStep < 4 && ( -
+
+ {currentStep > 0 && ( + )} + {currentStep < 4 && ( -
- )} + )} +
) } \ No newline at end of file diff --git a/components/wizard/steps/review-step.tsx b/components/wizard/steps/review-step.tsx index 77753ee..ccee5ed 100644 --- a/components/wizard/steps/review-step.tsx +++ b/components/wizard/steps/review-step.tsx @@ -34,8 +34,7 @@ interface ReviewStepProps { error: string | null screenshotFiles: File[] onScreenshotFilesChange: (files: File[]) => void - screenshotUploading: boolean - screenshotError: string | null + submitPhase: "idle" | "uploading" | "saving" | "success" | "error" } function SectionHeader({ icon: Icon, label }: { icon: React.ElementType; label: string }) { @@ -70,8 +69,7 @@ export function ReviewStep({ error, screenshotFiles, onScreenshotFilesChange, - screenshotUploading, - screenshotError, + submitPhase, }: ReviewStepProps) { const { hardwareName, gameVersionLabel, antiCheat, performance, environment, settings } = data @@ -218,7 +216,7 @@ export function ReviewStep({ ) : (
- {screenshotUploading && ( + {(submitPhase === "uploading" || submitPhase === "saving") && (
Uploading... @@ -252,7 +250,7 @@ export function ReviewStep({
)} - {(!screenshotFiles || screenshotFiles.length < 2) && !screenshotUploading && ( + {(!screenshotFiles || screenshotFiles.length < 2) && submitPhase !== "uploading" && submitPhase !== "saving" && (
)}