feat(submissions): scoped submissions per user/matchs, sync from polylan
This commit is contained in:
@@ -8,15 +8,18 @@ import { provideEventPath } from "@/composables/useEventPath";
|
||||
|
||||
interface Props {
|
||||
eventPath: string;
|
||||
gamePath?: string;
|
||||
scopeId: string;
|
||||
scopeName?: string;
|
||||
gameName?: string;
|
||||
gamePath?: string;
|
||||
gameImage?: string;
|
||||
gameSteamId?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
gamePath: "",
|
||||
scopeName: "Match",
|
||||
gameName: "Game",
|
||||
gamePath: "",
|
||||
gameImage: "",
|
||||
gameSteamId: "",
|
||||
});
|
||||
@@ -403,7 +406,7 @@ const submitSubmission = async () => {
|
||||
try {
|
||||
await submissionsApiCreateSubmission({
|
||||
path: { event_path: props.eventPath },
|
||||
query: { game_path: props.gamePath },
|
||||
query: { scope_id: props.scopeId },
|
||||
body: {
|
||||
files: uploadedFiles.value,
|
||||
notes: notes.value || null,
|
||||
@@ -423,7 +426,7 @@ const submitSubmission = async () => {
|
||||
};
|
||||
|
||||
const goHome = () => {
|
||||
window.location.href = `/${props.eventPath}/`;
|
||||
window.location.href = `/${props.eventPath}/submissions/${props.gamePath}`;
|
||||
};
|
||||
|
||||
const formatFileSize = (bytes: number) => {
|
||||
@@ -454,13 +457,11 @@ const getOCRStatusColor = (status: string) => {
|
||||
};
|
||||
|
||||
const loadUserSubmissions = async () => {
|
||||
if (!props.gamePath) return;
|
||||
|
||||
isLoadingSubmissions.value = true;
|
||||
try {
|
||||
const { data } = await submissionsApiListUserSubmissions({
|
||||
path: { event_path: props.eventPath },
|
||||
query: { game_path: props.gamePath },
|
||||
query: { scope_id: props.scopeId },
|
||||
});
|
||||
if (data && Array.isArray(data)) {
|
||||
userSubmissions.value = data;
|
||||
@@ -522,7 +523,7 @@ onUnmounted(() => {
|
||||
<i class="mdi mdi-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
<h1 class="text-xl font-bold">{{ gameName }} Submissions</h1>
|
||||
<h1 class="text-xl font-bold">{{ gameName }} Submissions — {{ scopeName }}</h1>
|
||||
<div class="flex-1"></div>
|
||||
|
||||
<!-- WebSocket Status Indicator -->
|
||||
@@ -555,7 +556,8 @@ onUnmounted(() => {
|
||||
</figure>
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-2xl">{{ gameName }}</h2>
|
||||
<p class="text-base-content/70">Submit your best results for this game</p>
|
||||
<p class="text-base-content/70">Submitting for match: <span class="font-semibold">{{ scopeName }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -568,10 +570,11 @@ onUnmounted(() => {
|
||||
</h2>
|
||||
|
||||
<!-- Upload Area -->
|
||||
<div @dragover="handleDragover" @dragleave="handleDragleave" @drop="handleDrop" @mouseenter="isUploadAreaHovered = true" @mouseleave="isUploadAreaHovered = false" :class="[
|
||||
'border-2 border-dashed rounded-lg p-8 text-center transition-colors cursor-pointer bg-base-200/50 mb-6',
|
||||
isDragover ? 'border-primary bg-primary/10' : 'border-base-300 hover:border-primary'
|
||||
]">
|
||||
<div @dragover="handleDragover" @dragleave="handleDragleave" @drop="handleDrop"
|
||||
@mouseenter="isUploadAreaHovered = true" @mouseleave="isUploadAreaHovered = false" :class="[
|
||||
'border-2 border-dashed rounded-lg p-8 text-center transition-colors cursor-pointer bg-base-200/50 mb-6',
|
||||
isDragover ? 'border-primary bg-primary/10' : 'border-base-300 hover:border-primary'
|
||||
]">
|
||||
<input type="file" multiple @change="handleFileUpload" class="hidden" id="file-upload" />
|
||||
<label for="file-upload" class="cursor-pointer flex flex-col items-center gap-3">
|
||||
<i :class="[
|
||||
@@ -625,7 +628,7 @@ onUnmounted(() => {
|
||||
<span class="label-text-alt">0/500</span>
|
||||
</label>
|
||||
|
||||
<textarea class="flex textarea textarea-bordered h-24 w-full resize-none"
|
||||
<textarea v-model="notes" class="flex textarea textarea-bordered h-24 w-full resize-none"
|
||||
placeholder="Add any notes special for this upload" maxlength="500"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
@@ -699,15 +702,6 @@ onUnmounted(() => {
|
||||
processed.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="bg-base-200 p-4 rounded-lg">
|
||||
<p class="text-base-content/70 text-sm">
|
||||
<i class="mdi mdi-lightbulb-on mr-2 text-warning"></i>
|
||||
Pro tip: Include clear screenshots or documentation with your submission for faster verification.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -925,8 +919,7 @@ onUnmounted(() => {
|
||||
<p class="text-base-content/70">OCR processing failed</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!selectedSubmissionFile?.ocr_raw_data"
|
||||
class="flex items-center justify-center py-8">
|
||||
<div v-else-if="!selectedSubmissionFile?.ocr_raw_data" class="flex items-center justify-center py-8">
|
||||
<div class="text-center">
|
||||
<i class="mdi mdi-clock-outline text-4xl text-base-content/30 mb-2"></i>
|
||||
<p class="text-base-content/70">Waiting for OCR processing...</p>
|
||||
@@ -934,9 +927,9 @@ onUnmounted(() => {
|
||||
</div>
|
||||
|
||||
<!-- Crops OCR Data -->
|
||||
<div v-if="selectedSubmissionFile?.crops?.length"
|
||||
class="space-y-3 pt-4 border-t border-base-300">
|
||||
<p class="text-xs font-semibold text-base-content/70">Crop OCR Results ({{ selectedSubmissionFile.crops.length }}):</p>
|
||||
<div v-if="selectedSubmissionFile?.crops?.length" class="space-y-3 pt-4 border-t border-base-300">
|
||||
<p class="text-xs font-semibold text-base-content/70">Crop OCR Results ({{
|
||||
selectedSubmissionFile.crops.length }}):</p>
|
||||
<div v-for="crop in selectedSubmissionFile.crops" :key="crop.id" class="space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-xs font-medium">{{ crop.label || `Crop (${crop.x1}, ${crop.y1})` }}</p>
|
||||
@@ -946,7 +939,8 @@ onUnmounted(() => {
|
||||
class="bg-base-100 p-2 rounded text-xs whitespace-pre-wrap break-words font-mono max-h-32 overflow-y-auto">
|
||||
{{ crop.ocr_raw_data }}
|
||||
</div>
|
||||
<div v-else-if="crop.ocr_status === 'processing'" class="text-xs text-base-content/70 text-center py-2">
|
||||
<div v-else-if="crop.ocr_status === 'processing'"
|
||||
class="text-xs text-base-content/70 text-center py-2">
|
||||
<span class="loading loading-spinner loading-sm inline-block"></span>
|
||||
Processing...
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user