diff --git a/app/components/CandidateDetailSidebar.vue b/app/components/CandidateDetailSidebar.vue index 942aa621..31f60f6a 100644 --- a/app/components/CandidateDetailSidebar.vue +++ b/app/components/CandidateDetailSidebar.vue @@ -2,7 +2,7 @@ import { X, User, Calendar, Clock, Hash, MessageSquare, FileText, ExternalLink, Mail, Phone, Upload, Download, Eye, Trash2, - ArrowLeft, AlertTriangle, Brain, History, + ArrowLeft, AlertTriangle, Brain, History, RefreshCw, } from 'lucide-vue-next' import { usePreviewReadOnly } from '~/composables/usePreviewReadOnly' @@ -176,6 +176,7 @@ const isUploading = ref(false) const uploadError = ref(null) const showDocDeleteConfirm = ref(null) const isDeletingDoc = ref(false) +const reparsingDocId = ref(null) const showPreview = ref(false) const previewUrl = ref(null) @@ -216,6 +217,26 @@ async function handleFileSelected(event: Event) { } } +async function handleReparse(docId: string) { + reparsingDocId.value = docId + try { + await $fetch(`/api/documents/${docId}/parse`, { + method: 'POST', + headers: useRequestHeaders(['cookie']), + }) + toast.add({ title: 'Resume parsed successfully', type: 'success' }) + await refreshCandidate() + } catch (err: any) { + toast.add({ + title: 'Parse failed', + message: err?.data?.statusMessage ?? 'Could not extract text from this document.', + type: 'error', + }) + } finally { + reparsingDocId.value = null + } +} + async function handlePreview(docId: string, mimeType?: string) { // Only PDFs can be previewed inline — for DOC/DOCX, download directly if (mimeType && mimeType !== 'application/pdf') { @@ -920,11 +941,23 @@ function formatInterviewDate(dateStr: string) { {{ documentTypeLabels[doc.type] ?? doc.type }} · {{ new Date(doc.createdAt).toLocaleDateString() }} - + +
+