You are an autonomous full-stack app builder. Your task: produce a complete, production-ready Progressive Web App (PWA) that allows users to upload files and folders from their browser to a cloud PACS server. The output must be a ready-to-run repository (all files written to disk) and you must run `npm install` and produce a build. Follow these specifications exactly.
5d66421
verified
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>DICOM Cloud Express Uploader</title> | |
| <link rel="manifest" href="/manifest.webmanifest"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: { | |
| 500: '#3B82F6', | |
| }, | |
| secondary: { | |
| 500: '#10B981', | |
| } | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <div id="root" class="container mx-auto px-4 py-8"> | |
| <header class="mb-10"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center space-x-2"> | |
| <i data-feather="upload-cloud" class="w-8 h-8 text-primary-500"></i> | |
| <h1 class="text-2xl font-bold text-gray-800">DICOM Cloud Express</h1> | |
| </div> | |
| <button id="auth-button" class="px-4 py-2 bg-primary-500 text-white rounded-md hover:bg-primary-600 transition"> | |
| Sign In | |
| </button> | |
| </div> | |
| <p class="text-gray-600 mt-2">Secure DICOM uploads to the cloud with offline support</p> | |
| </header> | |
| <main> | |
| <!-- Upload Dropzone --> | |
| <div id="dropzone" class="border-2 border-dashed border-gray-300 rounded-lg p-10 text-center mb-8 bg-white hover:border-primary-500 transition cursor-pointer"> | |
| <div class="flex flex-col items-center"> | |
| <i data-feather="upload" class="w-12 h-12 text-primary-500 mb-4"></i> | |
| <h2 class="text-xl font-semibold text-gray-700">Drag & Drop files or folders</h2> | |
| <p class="text-gray-500 mb-4">or</p> | |
| <button id="file-select" class="px-6 py-2 bg-primary-500 text-white rounded-md hover:bg-primary-600 transition"> | |
| Select Files | |
| </button> | |
| <input type="file" id="file-input" class="hidden" multiple webkitdirectory> | |
| </div> | |
| </div> | |
| <!-- File Tree Preview --> | |
| <div id="file-preview" class="hidden mb-8 bg-white rounded-lg shadow p-4"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="font-medium text-gray-700">Selected Files</h3> | |
| <div class="text-sm text-gray-500"> | |
| <span id="file-count">0</span> files | | |
| <span id="total-size">0B</span> | |
| </div> | |
| </div> | |
| <div id="file-tree" class="border rounded-md p-2 max-h-64 overflow-y-auto"> | |
| <!-- File tree will be populated here --> | |
| </div> | |
| </div> | |
| <!-- Metadata Editor --> | |
| <div id="metadata-editor" class="hidden mb-8 bg-white rounded-lg shadow p-4"> | |
| <h3 class="font-medium text-gray-700 mb-4">DICOM Metadata</h3> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Patient Name</label> | |
| <input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Patient ID</label> | |
| <input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Accession Number</label> | |
| <input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Study Description</label> | |
| <input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md"> | |
| </div> | |
| </div> | |
| <div class="mt-4 flex justify-end"> | |
| <button id="auto-fill" class="text-sm text-primary-500{"ok":false,"message":"terminated"} | |
| </body> | |
| </html> |