|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>DocSync - Intelligent Document Automation</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pdf-lib.min.js"></script> |
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<style> |
|
.dropzone { |
|
border: 2px dashed #3b82f6; |
|
transition: all 0.3s ease; |
|
} |
|
.dropzone.active { |
|
border-color: #10b981; |
|
background-color: #f0fdf4; |
|
} |
|
.document-preview { |
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); |
|
} |
|
.confidence-meter { |
|
height: 6px; |
|
border-radius: 3px; |
|
} |
|
.sidebar-item { |
|
transition: all 0.2s ease; |
|
} |
|
.sidebar-item:hover { |
|
background-color: #f3f4f6; |
|
} |
|
.page-turner { |
|
animation: pageTurn 0.5s ease-in-out; |
|
} |
|
@keyframes pageTurn { |
|
0% { transform: rotateY(0deg); } |
|
50% { transform: rotateY(90deg); } |
|
100% { transform: rotateY(0deg); } |
|
} |
|
.highlight-field { |
|
animation: pulse 2s infinite; |
|
} |
|
@keyframes pulse { |
|
0% { background-color: rgba(255, 255, 0, 0.3); } |
|
50% { background-color: rgba(255, 255, 0, 0.7); } |
|
100% { background-color: rgba(255, 255, 0, 0.3); } |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-50 font-sans"> |
|
<div class="flex h-screen overflow-hidden"> |
|
|
|
<div class="hidden md:flex md:flex-shrink-0"> |
|
<div class="flex flex-col w-64 bg-white border-r border-gray-200"> |
|
<div class="flex items-center justify-center h-16 px-4 bg-blue-600"> |
|
<h1 class="text-white font-bold text-xl">DocSync</h1> |
|
</div> |
|
<div class="flex flex-col flex-grow p-4 overflow-y-auto"> |
|
<nav class="flex-1 space-y-2"> |
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-blue-700 bg-blue-100 rounded-md sidebar-item"> |
|
<i class="fas fa-home mr-3"></i> |
|
Dashboard |
|
</a> |
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-600 rounded-md sidebar-item"> |
|
<i class="fas fa-file-import mr-3"></i> |
|
Document Processing |
|
</a> |
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-600 rounded-md sidebar-item"> |
|
<i class="fas fa-history mr-3"></i> |
|
Processing History |
|
</a> |
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-600 rounded-md sidebar-item"> |
|
<i class="fas fa-cog mr-3"></i> |
|
Settings |
|
</a> |
|
</nav> |
|
<div class="mt-auto p-4"> |
|
<div class="flex items-center"> |
|
<img class="w-10 h-10 rounded-full" src="https://randomuser.me/api/portraits/women/44.jpg" alt="User profile"> |
|
<div class="ml-3"> |
|
<p class="text-sm font-medium text-gray-700">Sarah Johnson</p> |
|
<p class="text-xs font-medium text-gray-500">Admin</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="flex flex-col flex-1 overflow-hidden"> |
|
|
|
<div class="flex items-center justify-between h-16 px-6 bg-white border-b border-gray-200"> |
|
<div class="flex items-center"> |
|
<button class="md:hidden text-gray-500 focus:outline-none"> |
|
<i class="fas fa-bars"></i> |
|
</button> |
|
<h2 class="ml-4 text-lg font-medium text-gray-900">Document Automation</h2> |
|
</div> |
|
<div class="flex items-center space-x-4"> |
|
<button class="p-1 text-gray-400 rounded-full hover:text-gray-500 focus:outline-none"> |
|
<i class="fas fa-bell"></i> |
|
</button> |
|
<button class="p-1 text-gray-400 rounded-full hover:text-gray-500 focus:outline-none"> |
|
<i class="fas fa-question-circle"></i> |
|
</button> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="flex-1 overflow-auto p-6"> |
|
<div class="max-w-7xl mx-auto"> |
|
|
|
<div class="mb-8"> |
|
<div class="flex items-center"> |
|
<div class="flex items-center relative"> |
|
<div class="flex items-center justify-center w-10 h-10 rounded-full bg-blue-600 text-white font-semibold"> |
|
1 |
|
</div> |
|
<div class="ml-3 text-sm font-medium text-blue-600">Upload Source</div> |
|
</div> |
|
<div class="flex-auto border-t-2 border-gray-200 mx-4"></div> |
|
<div class="flex items-center"> |
|
<div class="flex items-center justify-center w-10 h-10 rounded-full bg-gray-200 text-gray-600 font-semibold"> |
|
2 |
|
</div> |
|
<div class="ml-3 text-sm font-medium text-gray-500">Upload Template</div> |
|
</div> |
|
<div class="flex-auto border-t-2 border-gray-200 mx-4"></div> |
|
<div class="flex items-center"> |
|
<div class="flex items-center justify-center w-10 h-10 rounded-full bg-gray-200 text-gray-600 font-semibold"> |
|
3 |
|
</div> |
|
<div class="ml-3 text-sm font-medium text-gray-500">Review & Export</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="sourceUploadSection" class="bg-white rounded-lg shadow p-6 mb-8"> |
|
<h3 class="text-lg font-medium text-gray-900 mb-4">Upload Source Document</h3> |
|
<p class="text-sm text-gray-500 mb-6">Upload a completed invoice, form, or PDF document that contains the data you want to extract.</p> |
|
|
|
<div id="sourceDropzone" class="dropzone rounded-lg p-8 text-center cursor-pointer mb-4"> |
|
<div class="flex flex-col items-center justify-center"> |
|
<i class="fas fa-cloud-upload-alt text-4xl text-blue-500 mb-3"></i> |
|
<p class="text-sm text-gray-600 mb-1">Drag and drop your file here</p> |
|
<p class="text-xs text-gray-400">or click to browse</p> |
|
<input type="file" id="sourceFileInput" class="hidden" accept=".pdf,.jpg,.jpeg,.png,.tiff"> |
|
</div> |
|
</div> |
|
<div class="text-xs text-gray-500 text-center">Supported formats: PDF, JPG, PNG, TIFF (Max 20MB)</div> |
|
</div> |
|
|
|
|
|
<div id="processingStatus" class="hidden bg-white rounded-lg shadow p-6 mb-8"> |
|
<div class="flex items-center justify-between mb-4"> |
|
<h3 class="text-lg font-medium text-gray-900">Processing Document</h3> |
|
<div class="text-sm text-blue-600">Step 1 of 3</div> |
|
</div> |
|
|
|
<div class="space-y-4"> |
|
<div> |
|
<div class="flex items-center justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-700">OCR Processing</span> |
|
<span class="text-xs font-medium text-green-600">Completed</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-1.5"> |
|
<div class="bg-green-600 h-1.5 rounded-full" style="width: 100%"></div> |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<div class="flex items-center justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-700">Layout Analysis</span> |
|
<span class="text-xs font-medium text-green-600">Completed</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-1.5"> |
|
<div class="bg-green-600 h-1.5 rounded-full" style="width: 100%"></div> |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<div class="flex items-center justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-700">Field Extraction</span> |
|
<span class="text-xs font-medium text-blue-600">In Progress</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-1.5"> |
|
<div class="bg-blue-600 h-1.5 rounded-full" style="width: 65%"></div> |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<div class="flex items-center justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-700">Semantic Matching</span> |
|
<span class="text-xs font-medium text-gray-600">Pending</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-1.5"> |
|
<div class="bg-gray-300 h-1.5 rounded-full" style="width: 0%"></div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="extractedDataPreview" class="hidden bg-white rounded-lg shadow overflow-hidden mb-8"> |
|
<div class="border-b border-gray-200 px-6 py-4"> |
|
<h3 class="text-lg font-medium text-gray-900">Extracted Data Preview</h3> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-0"> |
|
|
|
<div class="md:col-span-1 border-r border-gray-200"> |
|
<div class="p-4"> |
|
<div class="document-preview bg-gray-100 rounded-lg overflow-hidden relative"> |
|
<div class="absolute top-0 left-0 right-0 bg-gray-800 text-white py-1 px-3 text-sm flex justify-between items-center"> |
|
<span id="sourceFileName">source_document.pdf</span> |
|
<div class="flex space-x-2"> |
|
<button class="text-gray-300 hover:text-white"> |
|
<i class="fas fa-search-plus"></i> |
|
</button> |
|
<button class="text-gray-300 hover:text-white"> |
|
<i class="fas fa-search-minus"></i> |
|
</button> |
|
</div> |
|
</div> |
|
<div class="p-4 h-96 overflow-auto"> |
|
<img id="documentPreviewImage" src="https://via.placeholder.com/600x800?text=Document+Preview" alt="Document preview" class="mx-auto shadow-lg"> |
|
</div> |
|
<div class="absolute bottom-0 left-0 right-0 bg-gray-100 py-2 px-4 flex justify-between items-center border-t border-gray-200"> |
|
<button id="prevPage" class="text-gray-600 hover:text-blue-600 disabled:text-gray-300"> |
|
<i class="fas fa-chevron-left mr-1"></i> Previous |
|
</button> |
|
<span class="text-sm text-gray-600">Page <span id="currentPage">1</span> of <span id="totalPages">3</span></span> |
|
<button id="nextPage" class="text-gray-600 hover:text-blue-600 disabled:text-gray-300"> |
|
Next <i class="fas fa-chevron-right ml-1"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="md:col-span-2"> |
|
<div class="p-4"> |
|
<div class="flex justify-between items-center mb-4"> |
|
<div> |
|
<h4 class="font-medium text-gray-900">Extracted Fields</h4> |
|
<p class="text-sm text-gray-500">Review and edit the extracted data before proceeding</p> |
|
</div> |
|
<div class="flex space-x-2"> |
|
<button class="px-3 py-1 bg-gray-100 text-gray-700 rounded text-sm hover:bg-gray-200"> |
|
<i class="fas fa-filter mr-1"></i> Filter |
|
</button> |
|
<button class="px-3 py-1 bg-gray-100 text-gray-700 rounded text-sm hover:bg-gray-200"> |
|
<i class="fas fa-search mr-1"></i> Search |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div class="overflow-auto" style="max-height: 500px;"> |
|
<table class="min-w-full divide-y divide-gray-200"> |
|
<thead class="bg-gray-50"> |
|
<tr> |
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Field Name</th> |
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Extracted Value</th> |
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Confidence</th> |
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th> |
|
</tr> |
|
</thead> |
|
<tbody id="extractedFieldsTable" class="bg-white divide-y divide-gray-200"> |
|
|
|
</tbody> |
|
</table> |
|
</div> |
|
|
|
<div class="mt-4 flex justify-between items-center"> |
|
<div class="text-sm text-gray-500"> |
|
Showing <span id="showingStart">1</span> to <span id="showingEnd">10</span> of <span id="totalFields">24</span> fields |
|
</div> |
|
<div class="flex space-x-2"> |
|
<button class="px-3 py-1 bg-gray-100 text-gray-700 rounded text-sm hover:bg-gray-200 disabled:opacity-50"> |
|
<i class="fas fa-chevron-left"></i> |
|
</button> |
|
<button class="px-3 py-1 bg-gray-100 text-gray-700 rounded text-sm hover:bg-gray-200 disabled:opacity-50"> |
|
<i class="fas fa-chevron-right"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="templateUploadSection" class="hidden bg-white rounded-lg shadow p-6 mb-8"> |
|
<h3 class="text-lg font-medium text-gray-900 mb-4">Upload Template Document</h3> |
|
<p class="text-sm text-gray-500 mb-6">Upload a blank or partially completed template form that you want to fill with the extracted data.</p> |
|
|
|
<div id="templateDropzone" class="dropzone rounded-lg p-8 text-center cursor-pointer mb-4"> |
|
<div class="flex flex-col items-center justify-center"> |
|
<i class="fas fa-file-alt text-4xl text-blue-500 mb-3"></i> |
|
<p class="text-sm text-gray-600 mb-1">Drag and drop your template file here</p> |
|
<p class="text-xs text-gray-400">or click to browse</p> |
|
<input type="file" id="templateFileInput" class="hidden" accept=".pdf"> |
|
</div> |
|
</div> |
|
<div class="text-xs text-gray-500 text-center">Supported formats: PDF (Max 20MB)</div> |
|
</div> |
|
|
|
|
|
<div id="fieldMappingSection" class="hidden bg-white rounded-lg shadow overflow-hidden mb-8"> |
|
<div class="border-b border-gray-200 px-6 py-4"> |
|
<h3 class="text-lg font-medium text-gray-900">Field Mapping</h3> |
|
<p class="text-sm text-gray-500">Review and adjust how fields from your source document map to the template fields</p> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-0"> |
|
|
|
<div class="md:col-span-1 border-r border-gray-200 p-4"> |
|
<h4 class="font-medium text-gray-900 mb-3">Source Fields</h4> |
|
<div class="relative mb-3"> |
|
<input type="text" placeholder="Search source fields..." class="w-full pl-8 pr-4 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"> |
|
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> |
|
</div> |
|
<div class="overflow-auto" style="max-height: 500px;"> |
|
<div id="sourceFieldsList" class="space-y-2"> |
|
|
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="md:col-span-1 border-r border-gray-200 p-4"> |
|
<h4 class="font-medium text-gray-900 mb-3 text-center">Field Mapping</h4> |
|
<div class="flex flex-col items-center justify-center h-full"> |
|
<div class="w-full max-w-xs"> |
|
<div class="bg-blue-50 rounded-lg p-6 text-center"> |
|
<i class="fas fa-random text-3xl text-blue-500 mb-3"></i> |
|
<p class="text-sm text-gray-700 mb-3">Drag fields between columns to create custom mappings</p> |
|
<p class="text-xs text-gray-500">Auto-mapped fields are shown in green</p> |
|
</div> |
|
<div class="mt-6"> |
|
<h5 class="text-sm font-medium text-gray-700 mb-2">Mapping Confidence</h5> |
|
<div class="bg-white rounded-lg shadow p-4"> |
|
<canvas id="mappingConfidenceChart" height="150"></canvas> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="md:col-span-1 p-4"> |
|
<h4 class="font-medium text-gray-900 mb-3">Template Fields</h4> |
|
<div class="relative mb-3"> |
|
<input type="text" placeholder="Search template fields..." class="w-full pl-8 pr-4 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"> |
|
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> |
|
</div> |
|
<div class="overflow-auto" style="max-height: 500px;"> |
|
<div id="templateFieldsList" class="space-y-2"> |
|
|
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="finalOutputSection" class="hidden bg-white rounded-lg shadow overflow-hidden mb-8"> |
|
<div class="border-b border-gray-200 px-6 py-4"> |
|
<h3 class="text-lg font-medium text-gray-900">Final Output</h3> |
|
<p class="text-sm text-gray-500">Review and download your completed document</p> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-0"> |
|
|
|
<div class="md:col-span-1 border-r border-gray-200 p-4"> |
|
<h4 class="font-medium text-gray-900 mb-3">Completed Document Preview</h4> |
|
<div class="document-preview bg-gray-100 rounded-lg overflow-hidden relative"> |
|
<div class="absolute top-0 left-0 right-0 bg-gray-800 text-white py-1 px-3 text-sm flex justify-between items-center"> |
|
<span id="completedDocumentName">completed_document.pdf</span> |
|
<div class="flex space-x-2"> |
|
<button class="text-gray-300 hover:text-white"> |
|
<i class="fas fa-search-plus"></i> |
|
</button> |
|
<button class="text-gray-300 hover:text-white"> |
|
<i class="fas fa-search-minus"></i> |
|
</button> |
|
</div> |
|
</div> |
|
<div class="p-4 h-96 overflow-auto"> |
|
<img id="completedDocumentPreview" src="https://via.placeholder.com/600x800?text=Completed+Document+Preview" alt="Completed document preview" class="mx-auto shadow-lg"> |
|
</div> |
|
<div class="absolute bottom-0 left-0 right-0 bg-gray-100 py-2 px-4 flex justify-between items-center border-t border-gray-200"> |
|
<button id="prevCompletedPage" class="text-gray-600 hover:text-blue-600 disabled:text-gray-300"> |
|
<i class="fas fa-chevron-left mr-1"></i> Previous |
|
</button> |
|
<span class="text-sm text-gray-600">Page <span id="currentCompletedPage">1</span> of <span id="totalCompletedPages">3</span></span> |
|
<button id="nextCompletedPage" class="text-gray-600 hover:text-blue-600 disabled:text-gray-300"> |
|
Next <i class="fas fa-chevron-right ml-1"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="md:col-span-1 p-4"> |
|
<h4 class="font-medium text-gray-900 mb-3">Export Options</h4> |
|
|
|
<div class="space-y-4"> |
|
<div class="bg-gray-50 rounded-lg p-4 border border-gray-200"> |
|
<div class="flex items-start"> |
|
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600"> |
|
<i class="fas fa-file-pdf"></i> |
|
</div> |
|
<div class="ml-3"> |
|
<h5 class="text-sm font-medium text-gray-900">PDF Document</h5> |
|
<p class="text-sm text-gray-500">Download the filled-in PDF document</p> |
|
<div class="mt-2"> |
|
<button id="downloadPdf" class="inline-flex items-center px-3 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
|
<i class="fas fa-download mr-1"></i> Download PDF |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="bg-gray-50 rounded-lg p-4 border border-gray-200"> |
|
<div class="flex items-start"> |
|
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-green-100 flex items-center justify-center text-green-600"> |
|
<i class="fas fa-file-code"></i> |
|
</div> |
|
<div class="ml-3"> |
|
<h5 class="text-sm font-medium text-gray-900">JSON Data</h5> |
|
<p class="text-sm text-gray-500">Export the structured data in JSON format</p> |
|
<div class="mt-2"> |
|
<button id="downloadJson" class="inline-flex items-center px-3 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"> |
|
<i class="fas fa-download mr-1"></i> Download JSON |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="bg-gray-50 rounded-lg p-4 border border-gray-200"> |
|
<div class="flex items-start"> |
|
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-purple-100 flex items-center justify-center text-purple-600"> |
|
<i class="fas fa-file-csv"></i> |
|
</div> |
|
<div class="ml-3"> |
|
<h5 class="text-sm font-medium text-gray-900">CSV Data</h5> |
|
<p class="text-sm text-gray-500">Export the data in tabular CSV format</p> |
|
<div class="mt-2"> |
|
<button id="downloadCsv" class="inline-flex items-center px-3 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"> |
|
<i class="fas fa-download mr-1"></i> Download CSV |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="mt-6 pt-4 border-t border-gray-200"> |
|
<h5 class="text-sm font-medium text-gray-900 mb-2">Processing Summary</h5> |
|
<div class="bg-white rounded-lg shadow p-4"> |
|
<div class="grid grid-cols-2 gap-4"> |
|
<div> |
|
<p class="text-xs text-gray-500">Source Fields</p> |
|
<p class="font-medium">24</p> |
|
</div> |
|
<div> |
|
<p class="text-xs text-gray-500">Template Fields</p> |
|
<p class="font-medium">18</p> |
|
</div> |
|
<div> |
|
<p class="text-xs text-gray-500">Auto-mapped</p> |
|
<p class="font-medium text-green-600">16 (89%)</p> |
|
</div> |
|
<div> |
|
<p class="text-xs text-gray-500">Manual Mappings</p> |
|
<p class="font-medium">2</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="flex justify-between"> |
|
<button id="backButton" class="hidden px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
|
<i class="fas fa-arrow-left mr-2"></i> Back |
|
</button> |
|
<button id="nextButton" class="px-4 py-2 border border-transparent rounded-md text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
|
Continue <i class="fas fa-arrow-right ml-2"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
|
|
const extractedFields = [ |
|
{ id: 1, name: "Invoice Number", value: "INV-2023-0042", confidence: 98, page: 1, boundingBox: "100,200,300,220" }, |
|
{ id: 2, name: "Invoice Date", value: "2023-05-15", confidence: 95, page: 1, boundingBox: "100,250,300,270" }, |
|
{ id: 3, name: "Due Date", value: "2023-06-14", confidence: 92, page: 1, boundingBox: "100,300,300,320" }, |
|
{ id: 4, name: "Customer Name", value: "Acme Corporation", confidence: 97, page: 1, boundingBox: "100,350,300,370" }, |
|
{ id: 5, name: "Customer Address", value: "123 Business Ave, Suite 450", confidence: 90, page: 1, boundingBox: "100,400,300,450" }, |
|
{ id: 6, name: "Customer ID", value: "ACME-0042", confidence: 88, page: 1, boundingBox: "100,500,300,520" }, |
|
{ id: 7, name: "Subtotal", value: "$1,250.00", confidence: 96, page: 2, boundingBox: "400,200,500,220" }, |
|
{ id: 8, name: "Tax (8.25%)", value: "$103.13", confidence: 94, page: 2, boundingBox: "400,250,500,270" }, |
|
{ id: 9, name: "Total Amount", value: "$1,353.13", confidence: 99, page: 2, boundingBox: "400,300,500,320" }, |
|
{ id: 10, name: "Payment Terms", value: "Net 30", confidence: 85, page: 2, boundingBox: "400,350,500,370" }, |
|
]; |
|
|
|
const templateFields = [ |
|
{ id: 't1', name: "Invoice No.", mappedTo: 1, confidence: 95 }, |
|
{ id: 't2', name: "Date Issued", mappedTo: 2, confidence: 90 }, |
|
{ id: 't3', name: "Payment Due Date", mappedTo: 3, confidence: 88 }, |
|
{ id: 't4', name: "Client Name", mappedTo: 4, confidence: 93 }, |
|
{ id: 't5', name: "Client Address", mappedTo: 5, confidence: 85 }, |
|
{ id: 't6', name: "Client Reference", mappedTo: 6, confidence: 80 }, |
|
{ id: 't7', name: "Subtotal Amount", mappedTo: 7, confidence: 96 }, |
|
{ id: 't8', name: "Tax Amount", mappedTo: 8, confidence: 94 }, |
|
{ id: 't9', name: "Total Due", mappedTo: 9, confidence: 97 }, |
|
{ id: 't10', name: "Payment Terms", mappedTo: 10, confidence: 82 }, |
|
{ id: 't11', name: "Bank Account", mappedTo: null, confidence: null }, |
|
{ id: 't12', name: "Payment Instructions", mappedTo: null, confidence: null }, |
|
]; |
|
|
|
|
|
let currentStep = 1; |
|
let currentPage = 1; |
|
let totalPages = 3; |
|
let currentCompletedPage = 1; |
|
let totalCompletedPages = 3; |
|
let sourceFileName = ''; |
|
let templateFileName = ''; |
|
|
|
|
|
const sourceDropzone = document.getElementById('sourceDropzone'); |
|
const sourceFileInput = document.getElementById('sourceFileInput'); |
|
const templateDropzone = document.getElementById('templateDropzone'); |
|
const templateFileInput = document.getElementById('templateFileInput'); |
|
const processingStatus = document.getElementById('processingStatus'); |
|
const extractedDataPreview = document.getElementById('extractedDataPreview'); |
|
const templateUploadSection = document.getElementById('templateUploadSection'); |
|
const fieldMappingSection = document.getElementById('fieldMappingSection'); |
|
const finalOutputSection = document.getElementById('finalOutputSection'); |
|
const nextButton = document.getElementById('nextButton'); |
|
const backButton = document.getElementById('backButton'); |
|
const extractedFieldsTable = document.getElementById('extractedFieldsTable'); |
|
const sourceFieldsList = document.getElementById('sourceFieldsList'); |
|
const templateFieldsList = document.getElementById('templateFieldsList'); |
|
const documentPreviewImage = document.getElementById('documentPreviewImage'); |
|
const currentPageSpan = document.getElementById('currentPage'); |
|
const totalPagesSpan = document.getElementById('totalPages'); |
|
const prevPageButton = document.getElementById('prevPage'); |
|
const nextPageButton = document.getElementById('nextPage'); |
|
const currentCompletedPageSpan = document.getElementById('currentCompletedPage'); |
|
const totalCompletedPagesSpan = document.getElementById('totalCompletedPages'); |
|
const prevCompletedPageButton = document.getElementById('prevCompletedPage'); |
|
const nextCompletedPageButton = document.getElementById('nextCompletedPage'); |
|
const showingStartSpan = document.getElementById('showingStart'); |
|
const showingEndSpan = document.getElementById('showingEnd'); |
|
const totalFieldsSpan = document.getElementById('totalFields'); |
|
const sourceFileNameSpan = document.getElementById('sourceFileName'); |
|
const completedDocumentNameSpan = document.getElementById('completedDocumentName'); |
|
const sourceUploadSection = document.getElementById('sourceUploadSection'); |
|
const downloadPdfButton = document.getElementById('downloadPdf'); |
|
const downloadJsonButton = document.getElementById('downloadJson'); |
|
const downloadCsvButton = document.getElementById('downloadCsv'); |
|
|
|
|
|
function init() { |
|
|
|
sourceDropzone.addEventListener('click', () => sourceFileInput.click()); |
|
sourceFileInput.addEventListener('change', handleSourceFileUpload); |
|
|
|
templateDropzone.addEventListener('click', () => templateFileInput.click()); |
|
templateFileInput.addEventListener('change', handleTemplateFileUpload); |
|
|
|
nextButton.addEventListener('click', handleNextStep); |
|
backButton.addEventListener('click', handlePreviousStep); |
|
|
|
prevPageButton.addEventListener('click', () => changePage(-1)); |
|
nextPageButton.addEventListener('click', () => changePage(1)); |
|
|
|
prevCompletedPageButton.addEventListener('click', () => changeCompletedPage(-1)); |
|
nextCompletedPageButton.addEventListener('click', () => changeCompletedPage(1)); |
|
|
|
|
|
setupDragAndDrop(sourceDropzone, sourceFileInput); |
|
setupDragAndDrop(templateDropzone, templateFileInput); |
|
|
|
|
|
showingStartSpan.textContent = '1'; |
|
showingEndSpan.textContent = '10'; |
|
totalFieldsSpan.textContent = extractedFields.length; |
|
|
|
|
|
currentPageSpan.textContent = currentPage; |
|
totalPagesSpan.textContent = totalPages; |
|
currentCompletedPageSpan.textContent = currentCompletedPage; |
|
totalCompletedPagesSpan.textContent = totalCompletedPages; |
|
|
|
|
|
prevPageButton.disabled = true; |
|
prevCompletedPageButton.disabled = true; |
|
|
|
|
|
downloadPdfButton.addEventListener('click', exportPdf); |
|
downloadJsonButton.addEventListener('click', exportJson); |
|
downloadCsvButton.addEventListener('click', exportCsv); |
|
} |
|
|
|
|
|
function setupDragAndDrop(dropzone, fileInput) { |
|
dropzone.addEventListener('dragover', (e) => { |
|
e.preventDefault(); |
|
dropzone.classList.add('active'); |
|
}); |
|
|
|
dropzone.addEventListener('dragleave', () => { |
|
dropzone.classList.remove('active'); |
|
}); |
|
|
|
dropzone.addEventListener('drop', (e) => { |
|
e.preventDefault(); |
|
dropzone.classList.remove('active'); |
|
|
|
if (e.dataTransfer.files.length) { |
|
fileInput.files = e.dataTransfer.files; |
|
if (fileInput === sourceFileInput) { |
|
handleSourceFileUpload(); |
|
} else { |
|
handleTemplateFileUpload(); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
|
|
function handleSourceFileUpload() { |
|
if (sourceFileInput.files.length) { |
|
const file = sourceFileInput.files[0]; |
|
sourceFileName = file.name; |
|
sourceFileNameSpan.textContent = sourceFileName; |
|
console.log('Source file uploaded:', file.name); |
|
|
|
|
|
processingStatus.classList.remove('hidden'); |
|
sourceUploadSection.classList.add('hidden'); |
|
|
|
|
|
setTimeout(() => { |
|
processingStatus.classList.add('hidden'); |
|
extractedDataPreview.classList.remove('hidden'); |
|
populateExtractedFieldsTable(); |
|
updateProcessSteps(2); |
|
|
|
|
|
templateUploadSection.classList.remove('hidden'); |
|
}, 3000); |
|
} |
|
} |
|
|
|
|
|
function handleTemplateFileUpload() { |
|
if (templateFileInput.files.length) { |
|
const file = templateFileInput.files[0]; |
|
templateFileName = file.name; |
|
completedDocumentNameSpan.textContent = `filled_${templateFileName}`; |
|
console.log('Template file uploaded:', file.name); |
|
|
|
|
|
templateUploadSection.classList.add('hidden'); |
|
fieldMappingSection.classList.remove('hidden'); |
|
populateFieldMappingLists(); |
|
renderMappingConfidenceChart(); |
|
updateProcessSteps(3); |
|
} |
|
} |
|
|
|
|
|
function populateExtractedFieldsTable() { |
|
extractedFieldsTable.innerHTML = ''; |
|
|
|
extractedFields.forEach(field => { |
|
const row = document.createElement('tr'); |
|
row.className = field.page === currentPage ? 'bg-blue-50' : ''; |
|
row.dataset.id = field.id; |
|
row.dataset.page = field.page; |
|
|
|
row.innerHTML = ` |
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${field.name}</td> |
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${field.value}</td> |
|
<td class="px-6 py-4 whitespace-nowrap"> |
|
<div class="flex items-center"> |
|
<div class="w-full bg-gray-200 rounded-full h-2.5"> |
|
<div class="bg-blue-600 h-2.5 rounded-full" style="width: ${field.confidence}%"></div> |
|
</div> |
|
<span class="ml-2 text-xs font-medium text-gray-700">${field.confidence}%</span> |
|
</div> |
|
</td> |
|
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> |
|
<button class="text-blue-600 hover:text-blue-900 mr-3 edit-field"> |
|
<i class="fas fa-edit"></i> |
|
</button> |
|
<button class="text-red-600 hover:text-red-900 delete-field"> |
|
<i class="fas fa-trash"></i> |
|
</button> |
|
</td> |
|
`; |
|
|
|
extractedFieldsTable.appendChild(row); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.edit-field').forEach(button => { |
|
button.addEventListener('click', (e) => { |
|
const row = e.target.closest('tr'); |
|
const fieldId = parseInt(row.dataset.id); |
|
editField(fieldId); |
|
}); |
|
}); |
|
|
|
document.querySelectorAll('.delete-field').forEach(button => { |
|
button.addEventListener('click', (e) => { |
|
const row = e.target.closest('tr'); |
|
const fieldId = parseInt(row.dataset.id); |
|
deleteField(fieldId); |
|
}); |
|
}); |
|
} |
|
|
|
|
|
function populateFieldMappingLists() { |
|
sourceFieldsList.innerHTML = ''; |
|
templateFieldsList.innerHTML = ''; |
|
|
|
|
|
extractedFields.forEach(field => { |
|
const fieldElement = document.createElement('div'); |
|
fieldElement.className = 'flex items-center justify-between p-2 border border-gray-200 rounded-md cursor-move'; |
|
fieldElement.dataset.id = field.id; |
|
fieldElement.draggable = true; |
|
|
|
fieldElement.innerHTML = ` |
|
<div> |
|
<div class="text-sm font-medium text-gray-700">${field.name}</div> |
|
<div class="text-xs text-gray-500">${field.value}</div> |
|
</div> |
|
<div class="text-xs text-gray-400"> |
|
<i class="fas fa-grip-vertical"></i> |
|
</div> |
|
`; |
|
|
|
sourceFieldsList.appendChild(fieldElement); |
|
|
|
|
|
fieldElement.addEventListener('dragstart', (e) => { |
|
e.dataTransfer.setData('text/plain', `source:${field.id}`); |
|
}); |
|
}); |
|
|
|
|
|
templateFields.forEach(field => { |
|
const fieldElement = document.createElement('div'); |
|
fieldElement.className = `flex items-center justify-between p-2 border rounded-md cursor-move ${field.mappedTo ? 'border-green-200 bg-green-50' : 'border-gray-200'}`; |
|
fieldElement.dataset.id = field.id; |
|
fieldElement.draggable = true; |
|
|
|
fieldElement.innerHTML = ` |
|
<div> |
|
<div class="text-sm font-medium text-gray-700">${field.name}</div> |
|
${field.mappedTo ? |
|
`<div class="text-xs text-green-600">Mapped to: ${extractedFields.find(f => f.id === field.mappedTo).name}</div>` : |
|
`<div class="text-xs text-gray-500">Not mapped</div>`} |
|
</div> |
|
<div class="text-xs ${field.mappedTo ? 'text-green-500' : 'text-gray-400'}"> |
|
<i class="fas fa-grip-vertical"></i> |
|
</div> |
|
`; |
|
|
|
templateFieldsList.appendChild(fieldElement); |
|
|
|
|
|
fieldElement.addEventListener('dragstart', (e) => { |
|
e.dataTransfer.setData('text/plain', `template:${field.id}`); |
|
}); |
|
|
|
|
|
fieldElement.addEventListener('dragover', (e) => { |
|
e.preventDefault(); |
|
}); |
|
|
|
fieldElement.addEventListener('drop', (e) => { |
|
e.preventDefault(); |
|
const data = e.dataTransfer.getData('text/plain'); |
|
const [type, id] = data.split(':'); |
|
|
|
if (type === 'source') { |
|
|
|
const sourceFieldId = parseInt(id); |
|
const templateFieldId = field.id; |
|
mapFields(sourceFieldId, templateFieldId); |
|
} |
|
}); |
|
}); |
|
} |
|
|
|
|
|
function renderMappingConfidenceChart() { |
|
const ctx = document.getElementById('mappingConfidenceChart').getContext('2d'); |
|
const mappedFields = templateFields.filter(f => f.mappedTo !== null); |
|
const unmappedFields = templateFields.filter(f => f.mappedTo === null); |
|
|
|
new Chart(ctx, { |
|
type: 'doughnut', |
|
data: { |
|
labels: ['High Confidence', 'Medium Confidence', 'Low Confidence', 'Unmapped'], |
|
datasets: [{ |
|
data: [ |
|
mappedFields.filter(f => f.confidence >= 90).length, |
|
mappedFields.filter(f => f.confidence >= 70 && f.confidence < 90).length, |
|
mappedFields.filter(f => f.confidence < 70).length, |
|
unmappedFields.length |
|
], |
|
backgroundColor: [ |
|
'#10B981', |
|
'#3B82F6', |
|
'#F59E0B', |
|
'#EF4444' |
|
], |
|
borderWidth: 0 |
|
}] |
|
}, |
|
options: { |
|
cutout: '70%', |
|
plugins: { |
|
legend: { |
|
position: 'bottom', |
|
labels: { |
|
boxWidth: 12, |
|
padding: 20 |
|
} |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
|
|
|
|
function mapFields(sourceFieldId, templateFieldId) { |
|
const templateField = templateFields.find(f => f.id === templateFieldId); |
|
templateField.mappedTo = sourceFieldId; |
|
|
|
|
|
const sourceField = extractedFields.find(f => f.id === sourceFieldId); |
|
const sourceName = sourceField.name.toLowerCase(); |
|
const templateName = templateField.name.toLowerCase(); |
|
|
|
|
|
let similarity = 0; |
|
if (sourceName.includes('invoice') && templateName.includes('invoice')) similarity += 30; |
|
if (sourceName.includes('date') && templateName.includes('date')) similarity += 30; |
|
if (sourceName.includes('customer') && templateName.includes('client')) similarity += 20; |
|
if (sourceName.includes('total') && templateName.includes('total')) similarity += 20; |
|
|
|
templateField.confidence = Math.min(100, similarity + 50); |
|
|
|
|
|
populateFieldMappingLists(); |
|
|
|
|
|
const chartCanvas = document.getElementById('mappingConfidenceChart'); |
|
chartCanvas.innerHTML = ''; |
|
chartCanvas.width = chartCanvas.offsetWidth; |
|
chartCanvas.height = chartCanvas.offsetHeight; |
|
renderMappingConfidenceChart(); |
|
} |
|
|
|
|
|
function editField(fieldId) { |
|
const field = extractedFields.find(f => f.id === fieldId); |
|
const newValue = prompt(`Edit field: ${field.name}\nCurrent value: ${field.value}`, field.value); |
|
if (newValue !== null) { |
|
field.value = newValue; |
|
populateExtractedFieldsTable(); |
|
} |
|
} |
|
|
|
|
|
function deleteField(fieldId) { |
|
if (confirm('Are you sure you want to delete this field?')) { |
|
const index = extractedFields.findIndex(f => f.id === fieldId); |
|
if (index !== -1) { |
|
extractedFields.splice(index, 1); |
|
populateExtractedFieldsTable(); |
|
} |
|
} |
|
} |
|
|
|
|
|
function changePage(delta) { |
|
const newPage = currentPage + delta; |
|
if (newPage >= 1 && newPage <= totalPages) { |
|
currentPage = newPage; |
|
currentPageSpan.textContent = currentPage; |
|
|
|
|
|
documentPreviewImage.src = `https://via.placeholder.com/600x800?text=Document+Page+${currentPage}`; |
|
|
|
|
|
document.querySelectorAll('#extractedFieldsTable tr').forEach(row => { |
|
if (parseInt(row.dataset.page) === currentPage) { |
|
row.classList.add('bg-blue-50'); |
|
} else { |
|
row.classList.remove('bg-blue-50'); |
|
} |
|
}); |
|
|
|
|
|
prevPageButton.disabled = currentPage === 1; |
|
nextPageButton.disabled = currentPage === totalPages; |
|
|
|
|
|
documentPreviewImage.classList.add('page-turner'); |
|
setTimeout(() => { |
|
documentPreviewImage.classList.remove('page-turner'); |
|
}, 500); |
|
} |
|
} |
|
|
|
|
|
function changeCompletedPage(delta) { |
|
const newPage = currentCompletedPage + delta; |
|
if (newPage >= 1 && newPage <= totalCompletedPages) { |
|
currentCompletedPage = newPage; |
|
currentCompletedPageSpan.textContent = currentCompletedPage; |
|
|
|
|
|
document.getElementById('completedDocumentPreview').src = `https://via.placeholder.com/600x800?text=Completed+Page+${currentCompletedPage}`; |
|
|
|
|
|
prevCompletedPageButton.disabled = currentCompletedPage === 1; |
|
nextCompletedPageButton.disabled = currentCompletedPage === totalCompletedPages; |
|
|
|
|
|
document.getElementById('completedDocumentPreview').classList.add('page-turner'); |
|
setTimeout(() => { |
|
document.getElementById('completedDocumentPreview').classList.remove('page-turner'); |
|
}, 500); |
|
} |
|
} |
|
|
|
|
|
function handleNextStep() { |
|
if (currentStep === 1) { |
|
|
|
|
|
} else if (currentStep === 2) { |
|
|
|
} else if (currentStep === 3) { |
|
|
|
fieldMappingSection.classList.add('hidden'); |
|
finalOutputSection.classList.remove('hidden'); |
|
nextButton.textContent = 'Finish'; |
|
updateProcessSteps(4); |
|
} else if (currentStep === 4) { |
|
|
|
alert('Document processing completed!'); |
|
|
|
} |
|
} |
|
|
|
|
|
function handlePreviousStep() { |
|
if (currentStep === 2) { |
|
|
|
templateUploadSection.classList.add('hidden'); |
|
extractedDataPreview.classList.add('hidden'); |
|
sourceUploadSection.classList.remove('hidden'); |
|
backButton.classList.add('hidden'); |
|
nextButton.textContent = 'Continue'; |
|
updateProcessSteps(1); |
|
} else if (currentStep === 3) { |
|
|
|
fieldMappingSection.classList.add('hidden'); |
|
templateUploadSection.classList.remove('hidden'); |
|
updateProcessSteps(2); |
|
} else if (currentStep === 4) { |
|
|
|
finalOutputSection.classList.add('hidden'); |
|
fieldMappingSection.classList.remove('hidden'); |
|
nextButton.textContent = 'Continue'; |
|
updateProcessSteps(3); |
|
} |
|
} |
|
|
|
|
|
function updateProcessSteps(step) { |
|
currentStep = step; |
|
|
|
|
|
const steps = document.querySelectorAll('.flex.items-center.relative'); |
|
steps.forEach((stepElement, index) => { |
|
const stepNumber = index + 1; |
|
const circle = stepElement.querySelector('div'); |
|
const text = stepElement.querySelector('div + div'); |
|
|
|
if (stepNumber < step) { |
|
|
|
circle.classList.remove('bg-gray-200', 'text-gray-600'); |
|
circle.classList.add('bg-green-500', 'text-white'); |
|
text.classList.remove('text-gray-500'); |
|
text.classList.add('text-green-600'); |
|
} else if (stepNumber === step) { |
|
|
|
circle.classList.remove('bg-gray-200', 'text-gray-600'); |
|
circle.classList.add('bg-blue-600', 'text-white'); |
|
text.classList.remove('text-gray-500'); |
|
text.classList.add('text-blue-600'); |
|
} else { |
|
|
|
circle.classList.remove('bg-blue-600', 'bg-green-500', 'text-white'); |
|
circle.classList.add('bg-gray-200', 'text-gray-600'); |
|
text.classList.remove('text-blue-600', 'text-green-600'); |
|
text.classList.add('text-gray-500'); |
|
} |
|
}); |
|
|
|
|
|
if (step === 3) { |
|
nextButton.textContent = 'Complete Processing'; |
|
} else if (step === 4) { |
|
nextButton.textContent = 'Finish'; |
|
} else { |
|
nextButton.textContent = 'Continue'; |
|
} |
|
|
|
|
|
if (step > 1) { |
|
backButton.classList.remove('hidden'); |
|
} else { |
|
backButton.classList.add('hidden'); |
|
} |
|
} |
|
|
|
|
|
function exportPdf() { |
|
|
|
|
|
|
|
|
|
const mappedData = {}; |
|
templateFields.forEach(templateField => { |
|
if (templateField.mappedTo) { |
|
const sourceField = extractedFields.find(f => f.id === templateField.mappedTo); |
|
mappedData[templateField.name] = sourceField.value; |
|
} |
|
}); |
|
|
|
|
|
const { jsPDF } = window.jspdf; |
|
const doc = new jsPDF(); |
|
|
|
|
|
doc.setFontSize(20); |
|
doc.text('Completed Document', 105, 20, { align: 'center' }); |
|
|
|
|
|
doc.setFontSize(12); |
|
let y = 40; |
|
templateFields.forEach(templateField => { |
|
if (templateField.mappedTo) { |
|
const sourceField = extractedFields.find(f => f.id === templateField.mappedTo); |
|
doc.text(`${templateField.name}: ${sourceField.value}`, 20, y); |
|
y += 10; |
|
} |
|
}); |
|
|
|
|
|
doc.save(`filled_${templateFileName || 'document'}.pdf`); |
|
|
|
alert('PDF document generated successfully!'); |
|
} |
|
|
|
|
|
function exportJson() { |
|
|
|
const mappedData = {}; |
|
templateFields.forEach(templateField => { |
|
if (templateField.mappedTo) { |
|
const sourceField = extractedFields.find(f => f.id === templateField.mappedTo); |
|
mappedData[templateField.name] = { |
|
value: sourceField.value, |
|
confidence: templateField.confidence, |
|
sourceField: sourceField.name |
|
}; |
|
} |
|
}); |
|
|
|
|
|
const jsonStr = JSON.stringify(mappedData, null, 2); |
|
|
|
|
|
const blob = new Blob([jsonStr], { type: 'application/json' }); |
|
saveAs(blob, `document_data_${new Date().toISOString().slice(0, 10)}.json`); |
|
|
|
alert('JSON data exported successfully!'); |
|
} |
|
|
|
|
|
function exportCsv() { |
|
|
|
let csv = 'Field Name,Value,Confidence,Source Field\n'; |
|
|
|
|
|
templateFields.forEach(templateField => { |
|
if (templateField.mappedTo) { |
|
const sourceField = extractedFields.find(f => f.id === templateField.mappedTo); |
|
csv += `"${templateField.name}","${sourceField.value}",${templateField.confidence},"${sourceField.name}"\n`; |
|
} |
|
}); |
|
|
|
|
|
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); |
|
saveAs(blob, `document_data_${new Date().toISOString().slice(0, 10)}.csv`); |
|
|
|
alert('CSV data exported successfully!'); |
|
} |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', init); |
|
</script> |
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=NRbones/docsync" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |