creaTech / templates /index.html
roshnn24's picture
Create templates/index.html
297c00b verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Construction Resource Planner</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
<style>
.phase-card {
transition: transform 0.2s;
}
.phase-card:hover {
transform: translateY(-5px);
}
.loading-spinner {
border: 4px solid #f3f3f3;
border-radius: 50%;
border-top: 4px solid #3498db;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.material-bar {
height: 24px;
background: linear-gradient(90deg, #3498db, #2980b9);
transition: width 0.5s ease-in-out;
}
.drop-zone {
border: 2px dashed #ccc;
border-radius: 8px;
padding: 20px;
text-align: center;
transition: border-color 0.3s ease;
}
.drop-zone.dragover {
border-color: #3498db;
background-color: rgba(52, 152, 219, 0.1);
}
.tab-active {
border-bottom: 2px solid #3498db;
color: #3498db;
}
</style>
</head>
<body class="bg-gray-50">
<nav class="bg-white shadow-lg">
<div class="max-w-7xl mx-auto px-4">
<div class="flex justify-between h-16">
<div class="flex items-center">
<img src="/api/placeholder/32/32" alt="Logo" class="h-8 w-8">
<span class="ml-2 text-xl font-semibold">Construction Resource Planner</span>
</div>
<div class="flex items-center space-x-4">
<button id="helpBtn" class="text-gray-600 hover:text-gray-900">
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
<div class="relative">
<img src="/api/placeholder/32/32" alt="User" class="h-8 w-8 rounded-full">
</div>
</div>
</div>
</div>
</nav>
<main class="max-w-7xl mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<!-- Project Input Section -->
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-2xl font-semibold mb-6">Project Details</h2>
<form id="projectForm" class="space-y-6">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Construction Type
</label>
<input type="text" id="constructionType" required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Number of Phases
</label>
<input type="number" id="phaseCount" min="1" required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Project Description
</label>
<textarea id="description" rows="4" required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
</div>
<div class="drop-zone" id="dropZone">
<div class="mb-4">
<svg class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" fill="none" viewBox="0 0 48 48">
<path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
<div class="text-sm text-gray-600">
<label class="relative cursor-pointer bg-white rounded-md font-medium text-blue-600 hover:text-blue-500 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-blue-500">
<span>Upload construction drawing</span>
<input id="fileInput" type="file" class="sr-only" accept="image/*">
</label>
</div>
</div>
<div id="preview" class="hidden mt-4">
<img id="imagePreview" class="max-w-full h-auto rounded-lg" alt="Preview">
</div>
</div>
<button type="submit" id="analyzeBtn"
class="w-full bg-blue-600 text-white py-3 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">
Analyze Project
</button>
</form>
</div>
<!-- Results Section -->
<div class="bg-white rounded-lg shadow-md p-6">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-semibold">Analysis Results</h2>
<div class="flex space-x-4">
<button id="exportBtn" class="text-blue-600 hover:text-blue-700 hidden">
Export Report
</button>
</div>
</div>
<div id="loadingState" class="hidden flex flex-col items-center justify-center py-12">
<div class="loading-spinner mb-4"></div>
<p class="text-gray-600">Analyzing project details...</p>
</div>
<div id="results" class="hidden space-y-6">
<div class="flex space-x-4 border-b">
<button class="tab-active px-4 py-2">Resources</button>
<button class="px-4 py-2">Timeline</button>
<button class="px-4 py-2">Dependencies</button>
</div>
<div id="phasesContainer" class="space-y-4">
<!-- Phases will be dynamically inserted here -->
</div>
</div>
</div>
</div>
</main>
<script>
document.addEventListener('DOMContentLoaded', function() {
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
const preview = document.getElementById('preview');
const imagePreview = document.getElementById('imagePreview');
const projectForm = document.getElementById('projectForm');
const loadingState = document.getElementById('loadingState');
const results = document.getElementById('results');
const exportBtn = document.getElementById('exportBtn');
const phasesContainer = document.getElementById('phasesContainer');
// File upload handling
['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(e) {
dropZone.classList.add('dragover');
}
function unhighlight(e) {
dropZone.classList.remove('dragover');
}
dropZone.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles(files);
}
fileInput.addEventListener('change', function() {
handleFiles(this.files);
});
function handleFiles(files) {
if (files.length > 0) {
const file = files[0];
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = function(e) {
preview.classList.remove('hidden');
imagePreview.src = e.target.result;
}
reader.readAsDataURL(file);
}
}
}
// Form submission
projectForm.addEventListener('submit', async function(e) {
e.preventDefault();
loadingState.classList.remove('hidden');
results.classList.add('hidden');
// Simulate API call
setTimeout(() => {
loadingState.classList.add('hidden');
results.classList.remove('hidden');
exportBtn.classList.remove('hidden');
// Example phase data
const phases = [
{
phase: 1,
materials: {
'Concrete': { quantity: 1500, unit: 'cubic_meters' },
'Steel': { quantity: 250, unit: 'tons' }
},
timeline: '3 months',
dependencies: ['Site preparation', 'Foundation work']
},
{
phase: 2,
materials: {
'Glass': { quantity: 800, unit: 'square_meters' },
'Aluminum': { quantity: 120, unit: 'tons' }
},
timeline: '2 months',
dependencies: ['Phase 1 completion', 'Material delivery']
}
];
renderPhases(phases);
}, 2000);
});
function renderPhases(phases) {
phasesContainer.innerHTML = '';
phases.forEach(phase => {
const phaseCard = document.createElement('div');
phaseCard.className = 'phase-card bg-gray-50 rounded-lg p-6';
let materialsHtml = '';
Object.entries(phase.materials).forEach(([material, info]) => {
materialsHtml += `
<div class="mb-4">
<div class="flex justify-between mb-2">
<span>${material}</span>
<span>${info.quantity} ${info.unit}</span>
</div>
<div class="bg-gray-200 rounded-full">
<div class="material-bar rounded-full" style="width: ${Math.min(info.quantity/20, 100)}%"></div>
</div>
</div>
`;
});
phaseCard.innerHTML = `
<h3 class="text-xl font-semibold mb-4">Phase ${phase.phase}</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h4 class="font-medium mb-3">Materials Required</h4>
${materialsHtml}
</div>
<div>
<h4 class="font-medium mb-3">Timeline & Dependencies</h4>
<p class="mb-2">Duration: ${phase.timeline}</p>
<ul class="list-disc list-inside">
${phase.dependencies.map(dep => `<li>${dep}</li>`).join('')}
</ul>
</div>
</div>
`;
phasesContainer.appendChild(phaseCard);
});
}
// Export functionality
exportBtn.addEventListener('click', function() {
// Implement export logic here
alert('Generating report...');
});
});
</script>
</body>
</html>