|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>ToxiTrack - Dashboard</title> |
|
|
<link rel="icon" type="image/x-icon" href="/static/favicon.ico"> |
|
|
<script src="https://cdn.tailwindcss.com"> |
|
|
</script> |
|
|
|
|
|
|
|
|
<div id="scanModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50"> |
|
|
<div class="bg-white rounded-lg p-6 max-w-md w-full"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<h3 class="text-lg font-bold text-gray-800">Scan Results</h3> |
|
|
<button id="closeModal" class="text-gray-500 hover:text-gray-700"> |
|
|
<i data-feather="x"></i> |
|
|
</button> |
|
|
</div> |
|
|
<div class="mb-4"> |
|
|
<img id="scanImage" src="" alt="Scanned Food" class="w-full h-48 object-cover rounded-lg mb-4"> |
|
|
<div class="grid grid-cols-2 gap-4"> |
|
|
<div> |
|
|
<p class="text-sm text-gray-500">Toxin Level</p> |
|
|
<p id="toxinLevel" class="font-bold"></p> |
|
|
</div> |
|
|
<div> |
|
|
<p class="text-sm text-gray-500">Safety</p> |
|
|
<p id="safetyLevel" class="font-bold"></p> |
|
|
</div> |
|
|
</div> |
|
|
<div class="mt-4"> |
|
|
<p class="text-sm text-gray-500">Recommendation</p> |
|
|
<p id="recommendation" class="text-sm"></p> |
|
|
</div> |
|
|
</div> |
|
|
<button id="saveScan" class="w-full bg-emerald-500 hover:bg-emerald-600 text-white py-2 rounded-lg"> |
|
|
Save to History |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
const modal = document.getElementById('scanModal'); |
|
|
const closeModal = document.getElementById('closeModal'); |
|
|
const saveScan = document.getElementById('saveScan'); |
|
|
|
|
|
closeModal.addEventListener('click', () => { |
|
|
modal.classList.add('hidden'); |
|
|
}); |
|
|
|
|
|
saveScan.addEventListener('click', () => { |
|
|
|
|
|
|
|
|
modal.classList.add('hidden'); |
|
|
location.reload(); |
|
|
}); |
|
|
</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/chart.js"></script> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); |
|
|
body { |
|
|
font-family: 'Poppins', sans-serif; |
|
|
} |
|
|
.sidebar { |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
.chart-container { |
|
|
position: relative; |
|
|
height: 300px; |
|
|
width: 100%; |
|
|
} |
|
|
.toxin-level-low { |
|
|
background-color: #10B981; |
|
|
} |
|
|
.toxin-level-medium { |
|
|
background-color: #F59E0B; |
|
|
} |
|
|
.toxin-level-high { |
|
|
background-color: #EF4444; |
|
|
} |
|
|
.active-tab { |
|
|
border-bottom: 3px solid #10B981; |
|
|
color: #10B981; |
|
|
font-weight: 600; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-50"> |
|
|
<div class="flex h-screen overflow-hidden"> |
|
|
|
|
|
<div class="sidebar bg-white w-64 border-r border-gray-200 flex-shrink-0 hidden md:block"> |
|
|
<div class="p-4 border-b border-gray-200"> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<i data-feather="shield" class="text-emerald-500"></i> |
|
|
<span class="text-xl font-bold text-gray-800">ToxiTrack</span> |
|
|
</div> |
|
|
</div> |
|
|
<nav class="p-4"> |
|
|
<div class="mb-8"> |
|
|
<div class="flex items-center space-x-3 mb-6 p-3 rounded-lg bg-emerald-50"> |
|
|
<div class="w-10 h-10 rounded-full bg-emerald-100 flex items-center justify-center"> |
|
|
<i data-feather="user" class="text-emerald-500"></i> |
|
|
</div> |
|
|
<div> |
|
|
<p class="font-medium text-gray-700">Welcome back</p> |
|
|
<p class="text-sm text-gray-500">John Doe</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="space-y-2"> |
|
|
<a href="index.html" class="flex items-center space-x-3 p-3 text-gray-600 hover:bg-gray-100 rounded-lg"> |
|
|
<i data-feather="home" class="w-5 h-5"></i> |
|
|
<span>Home</span> |
|
|
</a> |
|
|
<a href="#" class="flex items-center space-x-3 p-3 bg-emerald-50 text-emerald-500 rounded-lg"> |
|
|
<i data-feather="activity" class="w-5 h-5"></i> |
|
|
<span>Dashboard</span> |
|
|
</a> |
|
|
<a href="#" class="flex items-center space-x-3 p-3 text-gray-600 hover:bg-gray-100 rounded-lg"> |
|
|
<i data-feather="camera" class="w-5 h-5"></i> |
|
|
<span>Food Scanner</span> |
|
|
</a> |
|
|
<a href="#" class="flex items-center space-x-3 p-3 text-gray-600 hover:bg-gray-100 rounded-lg"> |
|
|
<i data-feather="map-pin" class="w-5 h-5"></i> |
|
|
<span>Air Quality</span> |
|
|
</a> |
|
|
<a href="#" class="flex items-center space-x-3 p-3 text-gray-600 hover:bg-gray-100 rounded-lg"> |
|
|
<i data-feather="trending-up" class="w-5 h-5"></i> |
|
|
<span>Trends</span> |
|
|
</a> |
|
|
<a href="#" class="flex items-center space-x-3 p-3 text-gray-600 hover:bg-gray-100 rounded-lg"> |
|
|
<i data-feather="settings" class="w-5 h-5"></i> |
|
|
<span>Settings</span> |
|
|
</a> |
|
|
</div> |
|
|
</nav> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="flex-1 overflow-auto"> |
|
|
|
|
|
<header class="bg-white border-b border-gray-200 p-4 flex items-center justify-between md:hidden"> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<i data-feather="shield" class="text-emerald-500"></i> |
|
|
<span class="text-lg font-bold text-gray-800">ToxiTrack</span> |
|
|
</div> |
|
|
<button id="mobile-menu-button"> |
|
|
<i data-feather="menu" class="w-6 h-6 text-gray-600"></i> |
|
|
</button> |
|
|
</header> |
|
|
|
|
|
|
|
|
<main class="p-6"> |
|
|
<div class="flex justify-between items-center mb-8"> |
|
|
<h1 class="text-2xl font-bold text-gray-800">Health Dashboard</h1> |
|
|
<div class="relative"> |
|
|
<select class="appearance-none bg-white border border-gray-300 rounded-lg py-2 pl-4 pr-8 text-gray-700 focus:outline-none focus:ring-2 focus:ring-emerald-500"> |
|
|
<option>Last 7 days</option> |
|
|
<option>Last 30 days</option> |
|
|
<option>Last 90 days</option> |
|
|
<option>Last year</option> |
|
|
<option>Custom range</option> |
|
|
</select> |
|
|
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700"> |
|
|
<i data-feather="chevron-down" class="w-4 h-4"></i> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8"> |
|
|
<div class="bg-white p-6 rounded-xl shadow-sm"> |
|
|
<div class="flex items-center justify-between mb-4"> |
|
|
<h3 class="text-gray-500 font-medium">Toxin Exposure</h3> |
|
|
<div class="w-8 h-8 rounded-full bg-emerald-100 flex items-center justify-center"> |
|
|
<i data-feather="alert-triangle" class="text-emerald-500 w-4 h-4"></i> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex items-end space-x-2"> |
|
|
<p class="text-3xl font-bold text-gray-800">24%</p> |
|
|
<p class="text-sm text-emerald-500 flex items-center"> |
|
|
<i data-feather="arrow-down" class="w-4 h-4 mr-1"></i> 8% from last week |
|
|
</p> |
|
|
</div> |
|
|
<div class="mt-4 bg-gray-200 rounded-full h-2"> |
|
|
<div class="bg-emerald-500 h-2 rounded-full" style="width: 24%"></div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="bg-white p-6 rounded-xl shadow-sm"> |
|
|
<div class="flex items-center justify-between mb-4"> |
|
|
<h3 class="text-gray-500 font-medium">Food Safety Score</h3> |
|
|
<div class="w-8 h-8 rounded-full bg-blue-100 flex items-center justify-center"> |
|
|
<i data-feather="check-circle" class="text-blue-500 w-4 h-4"></i> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex items-end space-x-2"> |
|
|
<p class="text-3xl font-bold text-gray-800">82</p> |
|
|
<p class="text-sm text-blue-500 flex items-center"> |
|
|
<i data-feather="arrow-up" class="w-4 h-4 mr-1"></i> 5 from last week |
|
|
</p> |
|
|
</div> |
|
|
<div class="mt-4 bg-gray-200 rounded-full h-2"> |
|
|
<div class="bg-blue-500 h-2 rounded-full" style="width: 82%"></div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="bg-white p-6 rounded-xl shadow-sm"> |
|
|
<div class="flex items-center justify-between mb-4"> |
|
|
<h3 class="text-gray-500 font-medium">Air Quality Index</h3> |
|
|
<div class="w-8 h-8 rounded-full bg-yellow-100 flex items-center justify-center"> |
|
|
<i data-feather="wind" class="text-yellow-500 w-4 h-4"></i> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex items-end space-x-2"> |
|
|
<p class="text-3xl font-bold text-gray-800">Moderate</p> |
|
|
<p class="text-sm text-yellow-500 flex items-center"> |
|
|
<i data-feather="alert-circle" class="w-4 h-4 mr-1"></i> Sensitive groups |
|
|
</p> |
|
|
</div> |
|
|
<div class="mt-4 bg-gray-200 rounded-full h-2"> |
|
|
<div class="bg-yellow-500 h-2 rounded-full" style="width: 65%"></div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="border-b border-gray-200 mb-6"> |
|
|
<nav class="flex space-x-8"> |
|
|
<button class="py-4 px-1 active-tab">Overview</button> |
|
|
<button class="py-4 px-1 text-gray-500 hover:text-gray-700">Food Analysis</button> |
|
|
<button class="py-4 px-1 text-gray-500 hover:text-gray-700">Air Quality</button> |
|
|
<button class="py-4 px-1 text-gray-500 hover:text-gray-700">Trends</button> |
|
|
</nav> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8"> |
|
|
|
|
|
<div class="bg-white p-6 rounded-xl shadow-sm"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<h3 class="font-semibold text-gray-800">Toxin Exposure Over Time</h3> |
|
|
<div class="flex space-x-2"> |
|
|
<button class="text-xs px-3 py-1 rounded-full bg-emerald-100 text-emerald-600">Week</button> |
|
|
<button class="text-xs px-3 py-1 rounded-full bg-gray-100 text-gray-600">Month</button> |
|
|
<button class="text-xs px-3 py-1 rounded-full bg-gray-100 text-gray-600">Year</button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="chart-container"> |
|
|
<canvas id="mainChart"></canvas> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-white p-6 rounded-xl shadow-sm"> |
|
|
<h3 class="font-semibold text-gray-800 mb-4">Toxin Sources Breakdown</h3> |
|
|
<div class="chart-container"> |
|
|
<canvas id="sourcesChart"></canvas> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-white p-6 rounded-xl shadow-sm mb-8"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<h3 class="font-semibold text-gray-800">Recent Food Scans</h3> |
|
|
<button id="newScanButton" class="text-sm text-emerald-500 hover:text-emerald-600 flex items-center"> |
|
|
<i data-feather="plus" class="w-4 h-4 mr-1"></i> New Scan |
|
|
</button> |
|
|
<input type="file" id="fileInput" accept="image/*" class="hidden"> |
|
|
</div> |
|
|
<div class="overflow-x-auto"> |
|
|
<table class="min-w-full divide-y divide-gray-200"> |
|
|
<thead> |
|
|
<tr> |
|
|
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Food Item</th> |
|
|
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Toxin Level</th> |
|
|
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th> |
|
|
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Safety</th> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody class="bg-white divide-y divide-gray-200"> |
|
|
<tr> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0 h-10 w-10"> |
|
|
<img class="h-10 w-10 rounded-full" src="http://static.photos/food/200x200/1" alt=""> |
|
|
</div> |
|
|
<div class="ml-4"> |
|
|
<div class="text-sm font-medium text-gray-900">Organic Apples</div> |
|
|
<div class="text-sm text-gray-500">Fruits</div> |
|
|
</div> |
|
|
</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-900">Low</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-900">Today, 09:42 AM</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-emerald-100 text-emerald-800">Safe</span> |
|
|
</td> |
|
|
</tr> |
|
|
<tr> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0 h-10 w-10"> |
|
|
<img class="h-10 w-10 rounded-full" src="http://static.photos/food/200x200/2" alt=""> |
|
|
</div> |
|
|
<div class="ml-4"> |
|
|
<div class="text-sm font-medium text-gray-900">Canned Tuna</div> |
|
|
<div class="text-sm text-gray-500">Seafood</div> |
|
|
</div> |
|
|
</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-900">Medium</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-900">Yesterday, 07:15 PM</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">Caution</span> |
|
|
</td> |
|
|
</tr> |
|
|
<tr> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0 h-10 w-10"> |
|
|
<img class="h-10 w-10 rounded-full" src="http://static.photos/food/200x200/3" alt=""> |
|
|
</div> |
|
|
<div class="ml-4"> |
|
|
<div class="text-sm font-medium text-gray-900">Processed Cheese</div> |
|
|
<div class="text-sm text-gray-500">Dairy</div> |
|
|
</div> |
|
|
</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-900">High</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-900">Yesterday, 12:30 PM</div> |
|
|
</td> |
|
|
<td class="px-4 py-4 whitespace-nowrap"> |
|
|
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Avoid</span> |
|
|
</td> |
|
|
</tr> |
|
|
</tbody> |
|
|
</table> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-white p-6 rounded-xl shadow-sm"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<h3 class="font-semibold text-gray-800">Current Air Quality</h3> |
|
|
<div class="flex items-center"> |
|
|
<i data-feather="map-pin" class="w-4 h-4 text-gray-500 mr-1"></i> |
|
|
<span class="text-sm text-gray-600">New York, NY</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4"> |
|
|
<div class="bg-blue-50 p-4 rounded-lg"> |
|
|
<div class="flex items-center justify-between mb-2"> |
|
|
<span class="text-sm text-blue-600">PM2.5</span> |
|
|
<span class="text-sm font-medium text-blue-600">12 µg/m³</span> |
|
|
</div> |
|
|
<div class="h-2 bg-blue-200 rounded-full"> |
|
|
<div class="h-2 bg-blue-500 rounded-full" style="width: 24%"></div> |
|
|
</div> |
|
|
<p class="text-xs text-blue-600 mt-1">Good</p> |
|
|
</div> |
|
|
<div class="bg-yellow-50 p-4 rounded-lg"> |
|
|
<div class="flex items-center justify-between mb-2"> |
|
|
<span class="text-sm text-yellow-600">Ozone</span> |
|
|
<span class="text-sm font-medium text-yellow-600">68 ppb</span> |
|
|
</div> |
|
|
<div class="h-2 bg-yellow-200 rounded-full"> |
|
|
<div class="h-2 bg-yellow-500 rounded-full" style="width: 68%"></div> |
|
|
</div> |
|
|
<p class="text-xs text-yellow-600 mt-1">Moderate</p> |
|
|
</div> |
|
|
<div class="bg-red-50 p-4 rounded-lg"> |
|
|
<div class="flex items-center justify-between mb-2"> |
|
|
<span class="text-sm text-red-600">NO2</span> |
|
|
<span class="text-sm font-medium text-red-600">42 ppb</span> |
|
|
</div> |
|
|
<div class="h-2 bg-red-200 rounded-full"> |
|
|
<div class="h-2 bg-red-500 rounded-full" style="width: 42%"></div> |
|
|
</div> |
|
|
<p class="text-xs text-red-600 mt-1">Unhealthy for Sensitive</p> |
|
|
</div> |
|
|
</div> |
|
|
<div class="mt-6 chart-container"> |
|
|
<canvas id="airQualityChart"></canvas> |
|
|
</div> |
|
|
</div> |
|
|
</main> |
|
|
</div> |
|
|
</div> |
|
|
<script> |
|
|
feather.replace(); |
|
|
|
|
|
|
|
|
document.getElementById('newScanButton').addEventListener('click', () => { |
|
|
document.getElementById('fileInput').click(); |
|
|
}); |
|
|
|
|
|
document.getElementById('fileInput').addEventListener('change', async (e) => { |
|
|
const file = e.target.files[0]; |
|
|
if (!file) return; |
|
|
|
|
|
|
|
|
const button = document.getElementById('newScanButton'); |
|
|
button.innerHTML = '<i data-feather="loader" class="w-4 h-4 mr-1 animate-spin"></i> Analyzing...'; |
|
|
feather.replace(); |
|
|
|
|
|
try { |
|
|
|
|
|
const formData = new FormData(); |
|
|
formData.append('image', file); |
|
|
|
|
|
const response = await fetch('/api/analyze', { |
|
|
method: 'POST', |
|
|
body: formData |
|
|
}); |
|
|
|
|
|
if (!response.ok) throw new Error('Analysis failed'); |
|
|
|
|
|
const result = await response.json(); |
|
|
|
|
|
|
|
|
alert(`Analysis complete!\n\nToxin Level: ${result.toxin_level}\nSafety: ${result.safety}\nRecommendation: ${result.recommendation}`); |
|
|
|
|
|
|
|
|
|
|
|
location.reload(); |
|
|
|
|
|
} catch (error) { |
|
|
console.error('Error:', error); |
|
|
alert('Failed to analyze image. Please try again.'); |
|
|
} finally { |
|
|
|
|
|
button.innerHTML = '<i data-feather="plus" class="w-4 h-4 mr-1"></i> New Scan'; |
|
|
feather.replace(); |
|
|
e.target.value = ''; |
|
|
} |
|
|
}); |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
|
|
const mainCtx = document.getElementById('mainChart').getContext('2d'); |
|
|
const mainChart = new Chart(mainCtx, { |
|
|
type: 'line', |
|
|
data: { |
|
|
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], |
|
|
datasets: [{ |
|
|
label: 'Toxin Exposure', |
|
|
data: [30, 25, 35, 28, 22, 40, 24], |
|
|
borderColor: '#10B981', |
|
|
backgroundColor: 'rgba(16, 185, 129, 0.1)', |
|
|
borderWidth: 2, |
|
|
tension: 0.3, |
|
|
fill: true |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
maintainAspectRatio: false, |
|
|
plugins: { |
|
|
legend: { |
|
|
display: false |
|
|
} |
|
|
}, |
|
|
scales: { |
|
|
y: { |
|
|
beginAtZero: true, |
|
|
grid: { |
|
|
display: true, |
|
|
color: 'rgba(0, 0, 0, 0.05)' |
|
|
} |
|
|
}, |
|
|
x: { |
|
|
grid: { |
|
|
display: false |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const sourcesCtx = document.getElementById('sourcesChart').getContext('2d'); |
|
|
const sourcesChart = new Chart(sourcesCtx, { |
|
|
type: 'doughnut', |
|
|
data: { |
|
|
labels: ['Food', 'Air', 'Water', 'Household'], |
|
|
datasets: [{ |
|
|
data: [45, 30, 15, 10], |
|
|
backgroundColor: [ |
|
|
'#10B981', |
|
|
'#3B82F6', |
|
|
'#F59E0B', |
|
|
'#EF4444' |
|
|
], |
|
|
borderWidth: 0 |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
maintainAspectRatio: false, |
|
|
cutout: '70%', |
|
|
plugins: { |
|
|
legend: { |
|
|
position: 'bottom' |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const airCtx = document.getElementById('airQualityChart').getContext('2d'); |
|
|
const airChart = new Chart(airCtx, { |
|
|
type: 'bar', |
|
|
data: { |
|
|
labels: ['12AM', '3AM', '6AM', '9AM', '12PM', '3PM', '6PM', '9PM'], |
|
|
datasets: [{ |
|
|
label: 'Air Quality Index', |
|
|
data: [35, 30, 42, 55, 68, 72, 60, 45], |
|
|
backgroundColor: [ |
|
|
'#10B981', |
|
|
'#10B981', |
|
|
'#F59E0B', |
|
|
'#F59E0B', |
|
|
'#EF4444', |
|
|
'#EF4444', |
|
|
'#F59E0B', |
|
|
'#F59E0B' |
|
|
], |
|
|
borderRadius: 6 |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
maintainAspectRatio: false, |
|
|
plugins: { |
|
|
legend: { |
|
|
display: false |
|
|
} |
|
|
}, |
|
|
scales: { |
|
|
y: { |
|
|
beginAtZero: true, |
|
|
grid: { |
|
|
display: true, |
|
|
color: 'rgba(0, 0, 0, 0.05)' |
|
|
} |
|
|
}, |
|
|
x: { |
|
|
grid: { |
|
|
display: false |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const mobileMenuButton = document.getElementById('mobile-menu-button'); |
|
|
const sidebar = document.querySelector('.sidebar'); |
|
|
|
|
|
mobileMenuButton.addEventListener('click', function() { |
|
|
sidebar.classList.toggle('hidden'); |
|
|
}); |
|
|
|
|
|
|
|
|
const tabs = document.querySelectorAll('.border-b button'); |
|
|
tabs.forEach(tab => { |
|
|
tab.addEventListener('click', function() { |
|
|
tabs.forEach(t => t.classList.remove('active-tab')); |
|
|
tabs.forEach(t => t.classList.add('text-gray-500', 'hover:text-gray-700')); |
|
|
this.classList.add('active-tab'); |
|
|
this.classList.remove('text-gray-500', 'hover:text-gray-700'); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
|