From 11d6fc423a5f553af6263ae9145a85cbb141115a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Gremaud?= Date: Mon, 25 May 2026 01:50:27 +0200 Subject: [PATCH] fix(submissions): fix upload + bucket path --- polylan_submitter/src/Submissions.vue | 189 +++++++++++++++++------ polylan_submitter/src/api/index.ts | 4 +- polylan_submitter/src/api/sdk.gen.ts | 9 +- polylan_submitter/src/api/types.gen.ts | 41 +++-- polylan_submitter/submissions/api.py | 34 ++-- polylan_submitter/submissions/models.py | 4 +- polylan_submitter/submissions/schemas.py | 10 +- 7 files changed, 213 insertions(+), 78 deletions(-) diff --git a/polylan_submitter/src/Submissions.vue b/polylan_submitter/src/Submissions.vue index b00702c..602fd28 100644 --- a/polylan_submitter/src/Submissions.vue +++ b/polylan_submitter/src/Submissions.vue @@ -2,6 +2,7 @@ import { ref, onMounted } from "vue"; import { storeToRefs } from "pinia"; import { useUserStore } from "@/stores/user"; +import { submissionsApiCreateSubmission, submissionsApiListUserSubmissions } from "@/api"; interface Props { gamePath?: string; @@ -27,6 +28,8 @@ const notes = ref(""); const selectedFile = ref(null); const filePreviewUrl = ref(""); const isModalOpen = ref(false); +const userSubmissions = ref([]); +const isLoadingSubmissions = ref(false); const openFilePreview = async (file: File) => { selectedFile.value = file; @@ -65,13 +68,13 @@ const getGameHeaderImage = () => { return null; }; -const getFileIcon = (file: File | null) => { +const getFileIcon = (file: File | null | { type?: string }) => { if (!file) return "mdi-file"; - const type = file.type; - if (type.startsWith("image/")) return "mdi-image"; + const type = (file as any).type; + if (type?.startsWith("image/")) return "mdi-image"; if (type === "application/pdf") return "mdi-file-pdf"; - if (type.startsWith("text/")) return "mdi-file-document"; - if (type.includes("video")) return "mdi-video"; + if (type?.startsWith("text/")) return "mdi-file-document"; + if (type?.includes("video")) return "mdi-video"; return "mdi-file"; }; @@ -113,36 +116,18 @@ const submitSubmission = async () => { isUploading.value = true; try { - const formData = new FormData(); - - // Add files - uploadedFiles.value.forEach((file) => { - formData.append("files", file); + await submissionsApiCreateSubmission({ + query: { game_path: props.gamePath }, + body: { + files: uploadedFiles.value, + notes: notes.value || null, + }, }); - // Add form fields - formData.append("notes", notes.value); - - // Build URL with query parameters - const url = new URL("/api/submissions/create", window.location.origin); - url.searchParams.append("game_path", props.gamePath); - - const response = await fetch(url.toString(), { - method: "POST", - body: formData, - }); - - if (!response.ok) { - const errorData = await response.json(); - const errorMsg = Array.isArray(errorData.detail) - ? errorData.detail.map((e: any) => e.msg).join(", ") - : errorData.detail || "Failed to submit"; - throw new Error(errorMsg); - } - uploadedFiles.value = []; notes.value = ""; alert("Submission successful!"); + await loadUserSubmissions(); } catch (error) { console.error("Error submitting:", error); alert(`Error submitting: ${error instanceof Error ? error.message : "Please try again."}`); @@ -163,8 +148,46 @@ const formatFileSize = (bytes: number) => { return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + " " + sizes[i]; }; +const formatDate = (dateString: string) => { + return new Date(dateString).toLocaleString(); +}; + +const getOCRStatusColor = (status: string) => { + switch (status) { + case "processed": + return "badge badge-success"; + case "processing": + return "badge badge-warning"; + case "to_process": + return "badge badge-info"; + case "error": + return "badge badge-error"; + default: + return "badge"; + } +}; + +const loadUserSubmissions = async () => { + if (!props.gamePath) return; + + isLoadingSubmissions.value = true; + try { + const { data } = await submissionsApiListUserSubmissions({ + query: { game_path: props.gamePath }, + }); + if (data && Array.isArray(data)) { + userSubmissions.value = data; + } + } catch (error) { + console.error("Error loading submissions:", error); + } finally { + isLoadingSubmissions.value = false; + } +}; + onMounted(() => { userStore.loadUserData(); + loadUserSubmissions(); }); @@ -188,7 +211,23 @@ onMounted(() => {
-
+
+ +
+
+ +
+
+
+ +
+
+

{{ gameName }}

+

Submit your best results for this game

+
+
+ +

@@ -269,22 +308,7 @@ onMounted(() => {

-
- -
-
- -
-
-
- -
-
-

{{ gameName }}

-

Submit your best results for this game

-
-
- +
@@ -347,6 +371,77 @@ onMounted(() => {
+ +
+
+
+

+ + Your Submissions +

+ +
+ +
+ +
+

No submissions yet

+

Upload your first submission above to get started

+
+ +
+ + + + + + + + + + + + + + + + + + + +
DateFilesFile StatusOCR StatusNotes
{{ formatDate(submission.created_at) }} +
+
+ + + {{ file.original_filename }} + + ({{ formatFileSize(file.file_size) }}) +
+
+
+
+
+ {{ file.content_type }} +
+
+
+
+
+ {{ file.ocr_status }} +
+
+
+ + {{ submission.notes }} + + - +
+
+
+
+
+