fix: display ocr data submissions
This commit is contained in:
@@ -30,6 +30,10 @@ const filePreviewUrl = ref<string>("");
|
||||
const isModalOpen = ref(false);
|
||||
const userSubmissions = ref<any[]>([]);
|
||||
const isLoadingSubmissions = ref(false);
|
||||
const selectedSubmissionFile = ref<any>(null);
|
||||
const isSubmissionFileModalOpen = ref(false);
|
||||
const imageAspectRatio = ref<"portrait" | "landscape">("landscape");
|
||||
const copyFeedback = ref<string>("");
|
||||
|
||||
const openFilePreview = async (file: File) => {
|
||||
selectedFile.value = file;
|
||||
@@ -58,6 +62,42 @@ const closeModal = () => {
|
||||
filePreviewUrl.value = "";
|
||||
};
|
||||
|
||||
const openSubmissionFileModal = (file: any) => {
|
||||
selectedSubmissionFile.value = file;
|
||||
isSubmissionFileModalOpen.value = true;
|
||||
|
||||
// Check image dimensions for aspect ratio
|
||||
if (file?.content_type?.startsWith("image/")) {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
imageAspectRatio.value = img.height > img.width ? "portrait" : "landscape";
|
||||
};
|
||||
img.src = file.file_url;
|
||||
}
|
||||
};
|
||||
|
||||
const closeSubmissionFileModal = () => {
|
||||
isSubmissionFileModalOpen.value = false;
|
||||
selectedSubmissionFile.value = null;
|
||||
};
|
||||
|
||||
const copyOCRText = async () => {
|
||||
if (selectedSubmissionFile.value?.ocr_raw_data) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(selectedSubmissionFile.value.ocr_raw_data);
|
||||
copyFeedback.value = "Copied!";
|
||||
setTimeout(() => {
|
||||
copyFeedback.value = "";
|
||||
}, 2000);
|
||||
} catch (err) {
|
||||
copyFeedback.value = "Failed to copy";
|
||||
setTimeout(() => {
|
||||
copyFeedback.value = "";
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getGameHeaderImage = () => {
|
||||
if (props.gameImage) {
|
||||
return props.gameImage;
|
||||
@@ -218,7 +258,8 @@ onMounted(() => {
|
||||
<img :src="getGameHeaderImage()!" :alt="gameName" class="w-full h-full object-cover" />
|
||||
<div class="absolute inset-0 bg-black/30"></div>
|
||||
</figure>
|
||||
<figure v-else class="relative h-48 bg-gradient-to-br from-blue-600 to-blue-400 flex items-center justify-center">
|
||||
<figure v-else
|
||||
class="relative h-48 bg-gradient-to-br from-blue-600 to-blue-400 flex items-center justify-center">
|
||||
<i class="mdi mdi-gamepad-variant text-6xl text-white opacity-30"></i>
|
||||
</figure>
|
||||
<div class="card-body">
|
||||
@@ -265,7 +306,8 @@ onMounted(() => {
|
||||
<p class="font-medium truncate group-hover:text-primary">{{ file.name }}</p>
|
||||
<p class="text-xs text-base-content/70">{{ formatFileSize(file.size) }}</p>
|
||||
</div>
|
||||
<button @click.stop="removeFile(index)" class="btn btn-ghost btn-xs opacity-0 group-hover:opacity-100">
|
||||
<button @click.stop="removeFile(index)"
|
||||
class="btn btn-ghost btn-xs opacity-0 group-hover:opacity-100">
|
||||
<i class="mdi mdi-close"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -407,9 +449,10 @@ onMounted(() => {
|
||||
<div class="flex flex-col gap-1">
|
||||
<div v-for="file in submission.files" :key="file.id" class="flex items-center gap-2">
|
||||
<i :class="['mdi text-primary text-sm', getFileIcon({ type: file.content_type })]"></i>
|
||||
<a :href="file.file_url" target="_blank" class="link link-primary truncate max-w-xs">
|
||||
<button @click="openSubmissionFileModal(file)"
|
||||
class="link link-primary truncate max-w-xs text-left">
|
||||
{{ file.original_filename }}
|
||||
</a>
|
||||
</button>
|
||||
<span class="text-xs text-base-content/50">({{ formatFileSize(file.file_size) }})</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -487,5 +530,115 @@ onMounted(() => {
|
||||
|
||||
<div class="modal-backdrop" @click="closeModal"></div>
|
||||
</div>
|
||||
|
||||
<!-- Submission File Modal -->
|
||||
<div :class="['modal', { 'modal-open': isSubmissionFileModalOpen }]">
|
||||
<div class="modal-box w-11/12 max-w-6xl max-h-[90vh] overflow-hidden">
|
||||
<h3 class="font-bold text-lg mb-4">
|
||||
<i :class="['mdi mr-2', getFileIcon({ type: selectedSubmissionFile?.content_type })]"></i>
|
||||
{{ selectedSubmissionFile?.original_filename }}
|
||||
</h3>
|
||||
|
||||
<!-- Responsive Layout: Portrait images side-by-side (left/right), landscape images and other files stacked (top/bottom) -->
|
||||
<div :class="['gap-4 h-[70vh]', imageAspectRatio === 'portrait' ? 'grid grid-cols-1 lg:grid-cols-2' : 'flex flex-col']">
|
||||
<!-- File Display -->
|
||||
<div class="flex flex-col overflow-hidden" :class="imageAspectRatio === 'portrait' ? 'h-full' : 'flex-1'">
|
||||
<p class="text-sm text-base-content/70 mb-2">File Preview</p>
|
||||
<div class="flex-1 overflow-auto border border-base-300 rounded-lg">
|
||||
<!-- Image Preview -->
|
||||
<div v-if="selectedSubmissionFile?.content_type.startsWith('image/')"
|
||||
class="flex items-center justify-center h-full p-4">
|
||||
<img :src="selectedSubmissionFile.file_url" :alt="selectedSubmissionFile.original_filename"
|
||||
class="max-w-full max-h-full object-contain rounded" />
|
||||
</div>
|
||||
|
||||
<!-- PDF Preview -->
|
||||
<div v-else-if="selectedSubmissionFile?.content_type === 'application/pdf'" class="h-full">
|
||||
<iframe :src="selectedSubmissionFile.file_url" class="w-full h-full border-0 rounded"></iframe>
|
||||
</div>
|
||||
|
||||
<!-- Text Preview -->
|
||||
<div v-else-if="selectedSubmissionFile?.content_type.startsWith('text/')" class="p-4">
|
||||
<div class="bg-base-200 p-4 rounded font-mono text-sm whitespace-pre-wrap break-words">
|
||||
<p class="text-base-content/70">Text content preview not available. Download file to view.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Unsupported Preview -->
|
||||
<div v-else class="flex items-center justify-center h-full">
|
||||
<div class="text-center">
|
||||
<i class="mdi mdi-file-question text-6xl text-base-content/30 mb-4"></i>
|
||||
<p class="text-base-content/70">Preview not available</p>
|
||||
<p class="text-sm text-base-content/50">{{ selectedSubmissionFile?.content_type }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<a v-if="selectedSubmissionFile?.file_url" :href="selectedSubmissionFile.file_url" download
|
||||
class="btn btn-sm btn-outline w-full">
|
||||
<i class="mdi mdi-download mr-2"></i>
|
||||
Download File
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- OCR Data -->
|
||||
<div class="flex flex-col overflow-hidden" :class="imageAspectRatio === 'portrait' ? 'h-full' : 'flex-1'">
|
||||
<p class="text-sm text-base-content/70 mb-2">OCR Data</p>
|
||||
<div class="flex-1 overflow-auto border border-base-300 rounded-lg p-4 bg-base-200">
|
||||
<div v-if="selectedSubmissionFile?.ocr_status === 'processed' && selectedSubmissionFile.ocr_raw_data">
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<p class="text-xs font-semibold text-base-content/70 mb-1">Status:</p>
|
||||
<span :class="getOCRStatusColor(selectedSubmissionFile.ocr_status)">{{
|
||||
selectedSubmissionFile.ocr_status }}</span>
|
||||
</div>
|
||||
<div class="divider my-2"></div>
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<p class="text-xs font-semibold text-base-content/70">Extracted Text:</p>
|
||||
<button @click="copyOCRText" class="btn btn-xs btn-ghost gap-1">
|
||||
<i class="mdi mdi-content-copy"></i>
|
||||
{{ copyFeedback || "Copy" }}
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="bg-base-100 p-3 rounded text-xs whitespace-pre-wrap break-words font-mono overflow-y-auto h-full">
|
||||
{{ selectedSubmissionFile.ocr_raw_data }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="selectedSubmissionFile?.ocr_status === 'processing'"
|
||||
class="flex items-center justify-center h-full">
|
||||
<div class="text-center">
|
||||
<span class="loading loading-spinner loading-lg"></span>
|
||||
<p class="text-base-content/70 mt-4">OCR is being processed...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="selectedSubmissionFile?.ocr_status === 'error'"
|
||||
class="flex items-center justify-center h-full">
|
||||
<div class="text-center">
|
||||
<i class="mdi mdi-alert-circle text-4xl text-error mb-2"></i>
|
||||
<p class="text-base-content/70">OCR processing failed</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex items-center justify-center h-full">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-action mt-4">
|
||||
<button @click="closeSubmissionFileModal" class="btn">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-backdrop" @click="closeSubmissionFileModal"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user