feat(submissions): admin call to process ocr data

This commit is contained in:
2026-05-25 02:39:51 +02:00
parent 0fc1fb255f
commit 202e04a554
5 changed files with 146 additions and 14 deletions
+52 -11
View File
@@ -2,7 +2,7 @@
import { ref, onMounted } from "vue";
import { storeToRefs } from "pinia";
import { useUserStore } from "@/stores/user";
import { submissionsApiCreateSubmission, submissionsApiListUserSubmissions, submissionsApiCreateImageCrop, submissionsApiDeleteImageCrop } from "@/api";
import { submissionsApiCreateSubmission, submissionsApiListUserSubmissions, submissionsApiCreateImageCrop, submissionsApiDeleteImageCrop, submissionsApiProcessFileOcr, submissionsApiProcessCropOcr } from "@/api";
interface Props {
gamePath?: string;
@@ -285,6 +285,38 @@ const cancelCrop = () => {
redrawCropCanvas();
};
const processFileOcr = async () => {
if (!selectedSubmissionFile.value) return;
try {
await submissionsApiProcessFileOcr({
path: { file_id: selectedSubmissionFile.value.id },
});
selectedSubmissionFile.value.ocr_status = "processing";
} catch (error) {
console.error("Error processing OCR:", error);
alert(`Error processing OCR: ${error instanceof Error ? error.message : "Please try again."}`);
}
};
const processCropOcr = async (cropId: string) => {
try {
await submissionsApiProcessCropOcr({
path: { crop_id: cropId },
});
// Update the crop status in the list
if (selectedSubmissionFile.value?.crops) {
const crop = selectedSubmissionFile.value.crops.find((c: any) => c.id === cropId);
if (crop) {
crop.ocr_status = "processing";
}
}
} catch (error) {
console.error("Error processing crop OCR:", error);
alert(`Error processing OCR: ${error instanceof Error ? error.message : "Please try again."}`);
}
};
const getGameHeaderImage = () => {
if (props.gameImage) {
return props.gameImage;
@@ -770,16 +802,15 @@ onMounted(() => {
<div class="gap-4 w-full overflow-hidden flex flex-row flex-1">
<!-- OCR Data -->
<div class="flex flex-col overflow-hidden flex-1">
<p class="text-sm text-base-content/70 mb-2">OCR Data</p>
<div class="flex items-center justify-between mb-2">
<p class="text-sm text-base-content/70 mb-2">OCR Data</p>
<span :class="getOCRStatusColor(selectedSubmissionFile?.ocr_status)">
{{ selectedSubmissionFile?.ocr_status }}
</span>
</div>
<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>
@@ -863,9 +894,15 @@ onMounted(() => {
<span :class="getOCRStatusColor(crop.ocr_status)">{{ crop.ocr_status }}</span>
</p>
</div>
<button @click="deleteCrop(crop.id)" class="btn btn-xs btn-ghost text-error flex-shrink-0">
<i class="mdi mdi-delete"></i>
</button>
<div class="flex gap-1 flex-shrink-0">
<button @click="processCropOcr(crop.id)" class="btn btn-xs btn-ghost" title="Process OCR">
<i class="mdi mdi-lightning-bolt"></i>
</button>
<button @click="deleteCrop(crop.id)" class="btn btn-xs btn-ghost text-error"
title="Delete crop">
<i class="mdi mdi-delete"></i>
</button>
</div>
</div>
</div>
</div>
@@ -878,6 +915,10 @@ onMounted(() => {
</div>
<div class="modal-action mt-4">
<button v-if="userInfo.isStaff" @click="processFileOcr" class="btn btn-warning gap-1">
<i class="mdi mdi-lightning-bolt"></i>
Process OCR
</button>
<a v-if="selectedSubmissionFile?.file_url" :href="selectedSubmissionFile.file_url" download
class="btn btn-outline">
<i class="mdi mdi-download mr-2"></i>