| | <!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> |