| <!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width,initial-scale=1" /> |
| <title>RepEx - Report Express | Export</title> |
|
|
| <link rel="stylesheet" href="style.css" /> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script defer src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> |
|
|
| <style> |
| img { -webkit-print-color-adjust: exact; print-color-adjust: exact; } |
| @media print { |
| body { background: #fff !important; } |
| .no-print { display: none !important; } |
| main { box-shadow: none !important; border: none !important; margin: 0 !important; padding: 0 !important; } |
| } |
| </style> |
| </head> |
|
|
| <body class="bg-gray-50 min-h-screen"> |
| <main class="max-w-4xl mx-auto my-8 bg-white shadow-sm ring-1 ring-gray-200 rounded-xl p-6 md:p-8"> |
| |
| <header class="mb-8 border-b border-gray-200 pb-4"> |
| <div class="grid grid-cols-[auto,1fr,auto] items-center gap-4"> |
| <div class="flex items-center"> |
| <img |
| src="https://huggingface.co/spaces/ChristopherJKoen/docusnap-report-wizard/resolve/main/images/Picture3.png" |
| alt="Company logo" |
| class="h-12 w-auto object-contain" |
| loading="eager" |
| /> |
| </div> |
|
|
| <div class="text-center"> |
| <h1 class="text-2xl md:text-3xl font-bold text-gray-900 whitespace-nowrap"> |
| RepEx - Report Express |
| </h1> |
| <p class="text-gray-600 whitespace-nowrap">Export</p> |
| </div> |
|
|
| <div class="flex justify-end gap-2 no-print"> |
| <a |
| href="report-viewer.html" |
| class="inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-4 py-2 text-sm font-semibold text-gray-800 hover:bg-gray-50 transition" |
| > |
| <i data-feather="arrow-left" class="h-4 w-4"></i> |
| Back |
| </a> |
| </div> |
| </div> |
| </header> |
|
|
| |
| <nav class="mb-6 no-print" aria-label="Report workflow navigation"> |
| <div class="flex flex-wrap gap-2"> |
| <a |
| href="report-viewer.html" |
| class="inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-4 py-2 text-sm font-semibold text-gray-800 hover:bg-gray-50 transition" |
| > |
| <i data-feather="layout" class="h-4 w-4"></i> |
| Report Viewer |
| </a> |
|
|
| <a |
| href="edit-layouts.html" |
| class="inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-4 py-2 text-sm font-semibold text-gray-800 hover:bg-gray-50 transition" |
| > |
| <i data-feather="grid" class="h-4 w-4"></i> |
| Edit Page Layouts |
| </a> |
|
|
| <a |
| href="export.html" |
| class="inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-900 px-4 py-2 text-sm font-semibold text-white" |
| > |
| <i data-feather="download" class="h-4 w-4"></i> |
| Export |
| </a> |
| </div> |
| </nav> |
|
|
| <section class="grid grid-cols-1 lg:grid-cols-[1fr,360px] gap-6"> |
| |
| <div class="rounded-lg border border-gray-200 bg-white p-4"> |
| <h2 class="text-lg font-semibold text-gray-900 mb-2">Export Options</h2> |
| <p class="text-sm text-gray-600 mb-4"> |
| PDF export comes next. For now, you can export a report βpackageβ as JSON (pages + layout settings + payload). |
| </p> |
|
|
| <div class="space-y-4"> |
| <div class="rounded-lg border border-gray-200 bg-gray-50 p-4"> |
| <div class="flex items-start justify-between gap-3"> |
| <div> |
| <div class="text-sm font-semibold text-gray-900">Report package (.json)</div> |
| <div class="text-xs text-gray-500">Includes edited pages, layout settings and upload metadata</div> |
| </div> |
| <span class="text-xs font-semibold text-emerald-700 bg-emerald-50 border border-emerald-200 rounded-md px-2 py-1"> |
| Available |
| </span> |
| </div> |
|
|
| <div class="mt-3 grid grid-cols-1 sm:grid-cols-2 gap-3"> |
| <label class="inline-flex items-center gap-2 text-sm text-gray-700"> |
| <input id="incPages" type="checkbox" class="rounded border-gray-300" checked /> |
| Include pages |
| </label> |
| <label class="inline-flex items-center gap-2 text-sm text-gray-700"> |
| <input id="incLayout" type="checkbox" class="rounded border-gray-300" checked /> |
| Include layout settings |
| </label> |
| <label class="inline-flex items-center gap-2 text-sm text-gray-700"> |
| <input id="incPayload" type="checkbox" class="rounded border-gray-300" checked /> |
| Include upload payload |
| </label> |
| <label class="inline-flex items-center gap-2 text-sm text-gray-700"> |
| <input id="incTimestamp" type="checkbox" class="rounded border-gray-300" checked /> |
| Include timestamp |
| </label> |
| </div> |
|
|
| <button id="downloadJson" type="button" |
| class="mt-4 inline-flex items-center justify-center gap-2 rounded-lg bg-emerald-600 px-4 py-2.5 text-white font-semibold hover:bg-emerald-700 transition"> |
| <i data-feather="download" class="h-4 w-4"></i> |
| Download JSON package |
| </button> |
| </div> |
|
|
| <div class="rounded-lg border border-gray-200 bg-gray-50 p-4"> |
| <div class="flex items-start justify-between gap-3"> |
| <div> |
| <div class="text-sm font-semibold text-gray-900">PDF export</div> |
| <div class="text-xs text-gray-500">Will export as print-ready A4 PDF</div> |
| </div> |
| <span class="text-xs font-semibold text-gray-600 bg-white border border-gray-200 rounded-md px-2 py-1"> |
| Coming soon |
| </span> |
| </div> |
|
|
| <button type="button" disabled |
| class="mt-4 inline-flex items-center justify-center gap-2 rounded-lg bg-gray-200 px-4 py-2.5 text-gray-500 font-semibold cursor-not-allowed"> |
| <i data-feather="file-text" class="h-4 w-4"></i> |
| Export PDF (disabled) |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <aside class="rounded-lg border border-gray-200 bg-white p-4"> |
| <h2 class="text-lg font-semibold text-gray-900 mb-2">Export Summary</h2> |
| <p class="text-sm text-gray-600 mb-4">This is what will be included based on your current session.</p> |
|
|
| <div class="space-y-3"> |
| <div class="rounded-lg border border-gray-200 bg-gray-50 p-3"> |
| <div class="text-xs font-semibold text-gray-600">Pages</div> |
| <div id="sumPages" class="text-sm font-semibold text-gray-900">β</div> |
| </div> |
|
|
| <div class="rounded-lg border border-gray-200 bg-gray-50 p-3"> |
| <div class="text-xs font-semibold text-gray-600">Selected example photos</div> |
| <div id="sumPhotos" class="text-sm font-semibold text-gray-900">β</div> |
| </div> |
|
|
| <div class="rounded-lg border border-gray-200 bg-gray-50 p-3"> |
| <div class="text-xs font-semibold text-gray-600">Documents</div> |
| <div id="sumDocs" class="text-sm font-semibold text-gray-900">β</div> |
| </div> |
|
|
| <div class="rounded-lg border border-gray-200 bg-gray-50 p-3"> |
| <div class="text-xs font-semibold text-gray-600">Data files</div> |
| <div id="sumData" class="text-sm font-semibold text-gray-900">β</div> |
| </div> |
|
|
| <div class="text-xs text-gray-500"> |
| Uses storage keys: |
| <div class="mt-1 font-mono text-[11px] text-gray-700"> |
| repex_report_pages_v1<br> |
| repex_layout_settings_v1<br> |
| repex_report_payload |
| </div> |
| </div> |
| </div> |
| </aside> |
| </section> |
|
|
| <footer class="mt-12 text-center text-xs text-gray-500 no-print"> |
| <p>Prosento - Β© 2026 All Rights Reserved</p> |
| <p class="mt-1">Export: JSON package now; PDF export will be added next.</p> |
| </footer> |
| </main> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', () => { |
| if (window.feather && typeof window.feather.replace === 'function') feather.replace(); |
| |
| const PAGES_KEY = 'repex_report_pages_v1'; |
| const LAYOUT_KEY = 'repex_layout_settings_v1'; |
| const PAYLOAD_KEY = 'repex_report_payload'; |
| |
| const sumPages = document.getElementById('sumPages'); |
| const sumPhotos = document.getElementById('sumPhotos'); |
| const sumDocs = document.getElementById('sumDocs'); |
| const sumData = document.getElementById('sumData'); |
| |
| const incPages = document.getElementById('incPages'); |
| const incLayout = document.getElementById('incLayout'); |
| const incPayload = document.getElementById('incPayload'); |
| const incTimestamp = document.getElementById('incTimestamp'); |
| const downloadJson = document.getElementById('downloadJson'); |
| |
| function loadJson(key) { |
| try { |
| const raw = localStorage.getItem(key); |
| return raw ? JSON.parse(raw) : null; |
| } catch { |
| return null; |
| } |
| } |
| |
| const pagesObj = loadJson(PAGES_KEY); |
| const pages = pagesObj?.pages ?? []; |
| const layout = loadJson(LAYOUT_KEY); |
| const payload = loadJson(PAYLOAD_KEY); |
| |
| const selectedPhotos = payload?.selectedPhotoIndices?.length ?? 0; |
| const docs = payload?.uploads?.documents?.length ?? 0; |
| const dataFiles = payload?.uploads?.dataFiles?.length ?? 0; |
| |
| |
| const totalItems = pages.reduce((acc, p) => acc + ((p?.items?.length) || 0), 0); |
| |
| sumPages.textContent = pages.length ? `${pages.length} pages β’ ${totalItems} total items` : 'No saved pages yet'; |
| sumPhotos.textContent = `${selectedPhotos}`; |
| sumDocs.textContent = `${docs}`; |
| sumData.textContent = `${dataFiles}`; |
| |
| function downloadBlob(filename, text) { |
| const blob = new Blob([text], { type: 'application/json' }); |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = filename; |
| document.body.appendChild(a); |
| a.click(); |
| a.remove(); |
| URL.revokeObjectURL(url); |
| } |
| |
| downloadJson.addEventListener('click', () => { |
| const pack = {}; |
| if (incPages.checked) pack.pages = pagesObj ?? null; |
| if (incLayout.checked) pack.layout = layout ?? null; |
| if (incPayload.checked) pack.payload = payload ?? null; |
| if (incTimestamp.checked) pack.exportedAt = new Date().toISOString(); |
| |
| const filename = `repex_report_package_${new Date().toISOString().replace(/[:.]/g,'-')}.json`; |
| downloadBlob(filename, JSON.stringify(pack, null, 2)); |
| }); |
| }); |
| </script> |
| </body> |
| </html> |
|
|