Download index.html from theflu/undefined: direct link, hf CLI and curl.
- Browser
- Download file 22.1 kB
-
https://huggingface.co/spaces/theflu/undefined/resolve/main/index.html
- Command line
-
hf download hf://spaces/theflu/undefined/index.html
-
curl -L -o index.html https://huggingface.co/spaces/theflu/undefined/resolve/main/index.html
22.1 kB
| <html lang="en" class="dark"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>RoofPrint Wizard - Blueprint Analyzer</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script> | |
| tailwind.config = { | |
| darkMode: 'class', | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: { | |
| 500: '#f43f5e', | |
| }, | |
| secondary: { | |
| 500: '#f97316', | |
| } | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js"></script> | |
| <script src="https://unpkg.com/dotenv@16.0.0/dist/dotenv.umd.js"></script> | |
| </head> | |
| <body class="bg-gray-900 min-h-screen text-gray-100"> | |
| <!-- Navigation --> | |
| <nav class="bg-gray-800 border-b border-gray-700 px-4 py-3"> | |
| <div class="max-w-7xl mx-auto flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <a href="index.html"><i data-feather="home" class="text-primary-500"></i></a> | |
| <a href="index.html" class="text-xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-primary-500 to-secondary-500">RoofPrint Wizard</a> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <a href="projects.html" class="bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-lg flex items-center space-x-2 transition-all"> | |
| <i data-feather="folder"></i> | |
| <span>My Projects</span> | |
| </a> | |
| <button class="bg-primary-500 hover:bg-primary-600 text-white px-4 py-2 rounded-lg flex items-center space-x-2 transition-all"> | |
| <i data-feather="upload"></i> | |
| <span>Upload Blueprint</span> | |
| </button> | |
| </div> | |
| </div> | |
| </nav> | |
| <!-- Hero Section --> | |
| <div class="relative overflow-hidden"> | |
| <div class="absolute inset-0 bg-gradient-to-br from-gray-900 to-gray-800 opacity-90"></div> | |
| <div class="max-w-7xl mx-auto px-4 py-20 relative z-10"> | |
| <div class="text-center"> | |
| <h1 class="text-4xl md:text-5xl font-bold mb-6">Smart Blueprint Processing <br> for <span class="text-transparent bg-clip-text bg-gradient-to-r from-primary-500 to-secondary-500">Roofing Professionals</span></h1> | |
| <p class="text-xl text-gray-300 max-w-3xl mx-auto mb-10">Upload your commercial roof blueprints and get instant material calculations, cost estimates, and project summaries.</p> | |
| <div class="flex flex-col sm:flex-row justify-center gap-4"> | |
| <a href="estimate.html" class="bg-primary-500 hover:bg-primary-600 text-white px-8 py-4 rounded-lg font-semibold text-lg flex items-center justify-center space-x-2 transition-all"> | |
| <i data-feather="upload-cloud"></i> | |
| <span>Upload Blueprint</span> | |
| </a> | |
| <a href="#how-it-works" class="bg-gray-700 hover:bg-gray-600 text-white px-8 py-4 rounded-lg font-semibold text-lg flex items-center justify-center space-x-2 transition-all"> | |
| <i data-feather="info"></i> | |
| <span>How It Works</span> | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="max-w-7xl mx-auto px-4 py-12"> | |
| <div class="mb-12"> | |
| <h2 class="text-3xl font-bold mb-6 text-center">Recent Projects</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |
| <!-- Project Card 1 --> | |
| <div class="bg-gray-800 rounded-xl overflow-hidden border border-gray-700 hover:border-primary-500 transition-all"> | |
| <div class="h-48 bg-gradient-to-br from-gray-700 to-gray-800 flex items-center justify-center"> | |
| <i data-feather="file-text" class="w-16 h-16 text-primary-500"></i> | |
| </div> | |
| <div class="p-6"> | |
| <h3 class="text-xl font-semibold mb-2">Downtown Office Complex</h3> | |
| <p class="text-gray-400 mb-4">Uploaded: 2 days ago</p> | |
| <div class="flex justify-between items-center"> | |
| <span class="bg-gray-700 text-primary-500 px-3 py-1 rounded-full text-sm font-medium">Processed</span> | |
| <a href="estimate.html" class="text-secondary-500 hover:text-secondary-400 flex items-center space-x-1"> | |
| <span>View Estimate</span> | |
| <i data-feather="arrow-right" class="w-4 h-4"></i> | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Project Card 2 --> | |
| <div class="bg-gray-800 rounded-xl overflow-hidden border border-gray-700 hover:border-primary-500 transition-all"> | |
| <div class="h-48 bg-gradient-to-br from-gray-700 to-gray-800 flex items-center justify-center"> | |
| <i data-feather="file-text" class="w-16 h-16 text-primary-500"></i> | |
| </div> | |
| <div class="p-6"> | |
| <h3 class="text-xl font-semibold mb-2">Mall Roof Replacement</h3> | |
| <p class="text-gray-400 mb-4">Uploaded: 1 week ago</p> | |
| <div class="flex justify-between items-center"> | |
| <span class="bg-gray-700 text-primary-500 px-3 py-1 rounded-full text-sm font-medium">Processed</span> | |
| <button class="text-secondary-500 hover:text-secondary-400 flex items-center space-x-1"> | |
| <span>View Estimate</span> | |
| <i data-feather="arrow-right" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Project Card 3 --> | |
| <div class="bg-gray-800 rounded-xl overflow-hidden border border-gray-700 hover:border-primary-500 transition-all"> | |
| <div class="h-48 bg-gradient-to-br from-gray-700 to-gray-800 flex items-center justify-center"> | |
| <i data-feather="file-text" class="w-16 h-16 text-primary-500"></i> | |
| </div> | |
| <div class="p-6"> | |
| <h3 class="text-xl font-semibold mb-2">Warehouse Repair</h3> | |
| <p class="text-gray-400 mb-4">Uploaded: 3 weeks ago</p> | |
| <div class="flex justify-between items-center"> | |
| <span class="bg-gray-700 text-primary-500 px-3 py-1 rounded-full text-sm font-medium">Processed</span> | |
| <button class="text-secondary-500 hover:text-secondary-400 flex items-center space-x-1"> | |
| <span>View Estimate</span> | |
| <i data-feather="arrow-right" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Features Section --> | |
| <div class="py-12"> | |
| <h2 class="text-3xl font-bold mb-12 text-center">How It Works</h2> | |
| <div class="grid md:grid-cols-3 gap-8"> | |
| <!-- Feature 1 --> | |
| <div class="bg-gray-800 p-6 rounded-xl border border-gray-700 hover:border-primary-500 transition-all"> | |
| <div class="w-14 h-14 bg-primary-500 rounded-full flex items-center justify-center mb-4"> | |
| <i data-feather="upload" class="w-6 h-6 text-white"></i> | |
| </div> | |
| <h3 class="text-xl font-semibold mb-3">Upload Blueprint</h3> | |
| <p class="text-gray-400">Simply upload your commercial roof blueprint PDF. Our system accepts all standard blueprint formats.</p> | |
| </div> | |
| <!-- Feature 2 --> | |
| <div class="bg-gray-800 p-6 rounded-xl border border-gray-700 hover:border-primary-500 transition-all"> | |
| <div class="w-14 h-14 bg-primary-500 rounded-full flex items-center justify-center mb-4"> | |
| <i data-feather="search" class="w-6 h-6 text-white"></i> | |
| </div> | |
| <h3 class="text-xl font-semibold mb-3">Automated Analysis</h3> | |
| <p class="text-gray-400">Our system automatically detects scale, measures square footage, and extracts material specifications using advanced OCR.</p> | |
| </div> | |
| <!-- Feature 3 --> | |
| <div class="bg-gray-800 p-6 rounded-xl border border-gray-700 hover:border-primary-500 transition-all"> | |
| <div class="w-14 h-14 bg-primary-500 rounded-full flex items-center justify-center mb-4"> | |
| <i data-feather="dollar-sign" class="w-6 h-6 text-white"></i> | |
| </div> | |
| <h3 class="text-xl font-semibold mb-3">Instant Estimate</h3> | |
| <p class="text-gray-400">Get a detailed cost breakdown with materials, labor, and equipment. Customize pricing or use our industry averages.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <footer class="bg-gray-800 border-t border-gray-700 py-8"> | |
| <div class="max-w-7xl mx-auto px-4"> | |
| <div class="flex flex-col md:flex-row justify-between items-center"> | |
| <div class="mb-4 md:mb-0"> | |
| <h2 class="text-xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-primary-500 to-secondary-500">RoofPrint Wizard</h2> | |
| <p class="text-gray-400 mt-2">Smart blueprint processing for roofing professionals</p> | |
| </div> | |
| <div class="flex space-x-6"> | |
| <a href="#" class="text-gray-400 hover:text-white transition-colors"> | |
| <i data-feather="twitter"></i> | |
| </a> | |
| <a href="#" class="text-gray-400 hover:text-white transition-colors"> | |
| <i data-feather="linkedin"></i> | |
| </a> | |
| <a href="#" class="text-gray-400 hover:text-white transition-colors"> | |
| <i data-feather="mail"></i> | |
| </a> | |
| </div> | |
| </div> | |
| <div class="mt-8 pt-8 border-t border-gray-700 text-center text-gray-500 text-sm"> | |
| <p>© 2023 RoofPrint Wizard. All rights reserved.</p> | |
| </div> | |
| </div> | |
| </footer> | |
| <!-- Upload Modal --> | |
| <div id="uploadModal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-gray-800 rounded-xl max-w-2xl w-full mx-4 border border-gray-700 overflow-hidden"> | |
| <div class="p-6 border-b border-gray-700 flex justify-between items-center"> | |
| <h3 class="text-xl font-semibold">Upload Blueprint PDF</h3> | |
| <button id="closeModal" class="text-gray-400 hover:text-white"> | |
| <i data-feather="x"></i> | |
| </button> | |
| </div> | |
| <div class="p-6"> | |
| <div class="border-2 border-dashed border-gray-600 rounded-lg p-8 text-center mb-6 hover:border-primary-500 transition-colors cursor-pointer" id="dropZone"> | |
| <div class="flex flex-col items-center justify-center"> | |
| <i data-feather="upload-cloud" class="w-12 h-12 text-primary-500 mb-4"></i> | |
| <h4 class="text-lg font-medium mb-2">Drag & Drop Blueprint PDF</h4> | |
| <p class="text-gray-400 mb-4">or click to browse files</p> | |
| <input type="file" id="fileInput" class="hidden" accept=".pdf"> | |
| <button class="bg-primary-500 hover:bg-primary-600 text-white px-6 py-2 rounded-lg transition-all"> | |
| Select File | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-gray-700 rounded-lg p-4 hidden" id="fileInfo"> | |
| <div class="flex items-center space-x-4"> | |
| <i data-feather="file-text" class="w-8 h-8 text-secondary-500"></i> | |
| <div class="flex-1"> | |
| <h5 class="font-medium" id="fileName">Filename.pdf</h5> | |
| <p class="text-sm text-gray-400" id="fileSize">2.4 MB</p> | |
| </div> | |
| <button id="removeFile" class="text-gray-400 hover:text-red-400"> | |
| <i data-feather="trash-2"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="mt-6"> | |
| <div class="flex items-center justify-between mb-2"> | |
| <label for="projectName" class="block text-sm font-medium text-gray-300">Project Name</label> | |
| </div> | |
| <input type="text" id="projectName" class="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent" placeholder="e.g. Downtown Office Roof Replacement"> | |
| </div> | |
| </div> | |
| <div class="p-6 bg-gray-700 border-t border-gray-600 flex justify-end space-x-3"> | |
| <button id="cancelUpload" class="px-4 py-2 rounded-lg border border-gray-500 text-gray-300 hover:bg-gray-600 transition-colors">Cancel</button> | |
| <button id="processUpload" class="px-6 py-2 bg-primary-500 hover:bg-primary-600 text-white rounded-lg transition-colors flex items-center space-x-2 disabled:opacity-50 disabled:cursor-not-allowed" disabled> | |
| <span>Process Blueprint</span> | |
| <i data-feather="arrow-right" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Load environment variables | |
| require('dotenv').config(); | |
| // Modal functionality | |
| document.addEventListener('DOMContentLoaded', function() { | |
| feather.replace(); | |
| const uploadModal = document.getElementById('uploadModal'); | |
| const closeModal = document.getElementById('closeModal'); | |
| const cancelUpload = document.getElementById('cancelUpload'); | |
| const uploadButtons = document.querySelectorAll('button:has(i[data-feather="upload"]), button:has(i[data-feather="upload-cloud"])'); | |
| const dropZone = document.getElementById('dropZone'); | |
| const fileInput = document.getElementById('fileInput'); | |
| const fileInfo = document.getElementById('fileInfo'); | |
| const fileName = document.getElementById('fileName'); | |
| const fileSize = document.getElementById('fileSize'); | |
| const removeFile = document.getElementById('removeFile'); | |
| const processUpload = document.getElementById('processUpload'); | |
| // Open modal when any upload button is clicked | |
| uploadButtons.forEach(button => { | |
| button.addEventListener('click', () => { | |
| uploadModal.classList.remove('hidden'); | |
| }); | |
| }); | |
| // Close modal | |
| function closeUploadModal() { | |
| uploadModal.classList.add('hidden'); | |
| } | |
| closeModal.addEventListener('click', closeUploadModal); | |
| cancelUpload.addEventListener('click', closeUploadModal); | |
| // Handle file selection | |
| dropZone.addEventListener('click', () => { | |
| fileInput.click(); | |
| }); | |
| fileInput.addEventListener('change', handleFileSelect); | |
| // Handle drag and drop | |
| ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { | |
| dropZone.addEventListener(eventName, preventDefaults, false); | |
| }); | |
| function preventDefaults(e) { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| } | |
| ['dragenter', 'dragover'].forEach(eventName => { | |
| dropZone.addEventListener(eventName, highlight, false); | |
| }); | |
| ['dragleave', 'drop'].forEach(eventName => { | |
| dropZone.addEventListener(eventName, unhighlight, false); | |
| }); | |
| function highlight() { | |
| dropZone.classList.add('border-primary-500'); | |
| } | |
| function unhighlight() { | |
| dropZone.classList.remove('border-primary-500'); | |
| } | |
| dropZone.addEventListener('drop', handleDrop, false); | |
| function handleDrop(e) { | |
| const dt = e.dataTransfer; | |
| const files = dt.files; | |
| fileInput.files = files; | |
| handleFileSelect({ target: fileInput }); | |
| } | |
| function handleFileSelect(e) { | |
| const files = e.target.files; | |
| if (files.length > 0) { | |
| const file = files[0]; | |
| // Check if it's a PDF | |
| if (file.type !== 'application/pdf') { | |
| alert('Please upload a PDF file.'); | |
| return; | |
| } | |
| // Display file info | |
| fileName.textContent = file.name; | |
| fileSize.textContent = formatFileSize(file.size); | |
| fileInfo.classList.remove('hidden'); | |
| processUpload.disabled = false; | |
| } | |
| } | |
| function formatFileSize(bytes) { | |
| if (bytes === 0) return '0 Bytes'; | |
| const k = 1024; | |
| const sizes = ['Bytes', 'KB', 'MB', 'GB']; | |
| const i = Math.floor(Math.log(bytes) / Math.log(k)); | |
| return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; | |
| } | |
| removeFile.addEventListener('click', () => { | |
| fileInput.value = ''; | |
| fileInfo.classList.add('hidden'); | |
| processUpload.disabled = true; | |
| }); | |
| processUpload.addEventListener('click', async () => { | |
| const file = fileInput.files[0]; | |
| const projectName = document.getElementById('projectName').value || 'Untitled Project'; | |
| if (!file) return; | |
| processUpload.disabled = true; | |
| processUpload.innerHTML = '<span>Processing...</span>'; | |
| try { | |
| const formData = new FormData(); | |
| formData.append('blueprint', file); | |
| formData.append('projectName', projectName); | |
| // Connect to Grok API for processing | |
| const grokResponse = await fetch('https://api.groq.com/v1/process-blueprint', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${process.env.GROQ_API_KEY}` | |
| }, | |
| body: JSON.stringify({ | |
| file: await file.arrayBuffer(), | |
| projectName: projectName | |
| }) | |
| }); | |
| if (!grokResponse.ok) { | |
| throw new Error('Grok processing failed'); | |
| } | |
| const grokData = await grokResponse.json(); | |
| // Save project details to localStorage with Grok results | |
| const projectId = 'project-' + Date.now(); | |
| const projectData = { | |
| id: projectId, | |
| name: projectName, | |
| date: new Date().toLocaleDateString(), | |
| file: file.name, | |
| status: 'processed', | |
| area: grokData.area || 0, | |
| cost: grokData.costEstimate || 0, | |
| materials: grokData.materials || [], | |
| notes: grokData.notes || [], | |
| labor: grokData.labor || [] | |
| }; | |
| // Save to localStorage | |
| let projects = JSON.parse(localStorage.getItem('projects') || '[]'); | |
| projects.push(projectData); | |
| localStorage.setItem('projects', JSON.stringify(projects)); | |
| // Redirect to estimate page with project ID | |
| window.location.href = `estimate.html?project=${projectId}`; | |
| } catch (error) { | |
| console.error('Processing failed:', error); | |
| alert('Error processing blueprint. Please try again.'); | |
| } finally { | |
| processUpload.disabled = false; | |
| processUpload.innerHTML = '<span>Process Blueprint</span><i data-feather="arrow-right" class="w-4 h-4"></i>'; | |
| feather.replace(); | |
| } | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |