Spacesaver / index (1).html
AA
Upload 5 files
5c02bda verified
Raw
History Blame Contribute Delete
43.1 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WaterHub - Your Local Water Quality Report</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js"></script>
<style>
.gradient-bg {
background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);
}
.water-wave {
position: relative;
overflow: hidden;
}
.water-wave::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 20px;
background: url('data:image/svg+xml;utf8,<svg viewBox="0 0 1200 120" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none"><path d="M0,0V46.29c47.79,22.2,103.59,32.17,158,28,70.36-5.37,136.33-33.31,206.8-37.5C438.64,32.43,512.34,53.67,583,72.05c69.27,18,138.3,24.88,209.4,13.08,36.15-6,69.85-17.84,104.45-29.34C989.49,25,1113-14.29,1200,52.47V0Z" fill="%23f8fafc" opacity=".25"/><path d="M0,0V15.81C13,36.92,27.64,56.86,47.69,72.05,99.41,111.27,165,111,224.58,91.58c31.15-10.15,60.09-26.07,89.67-39.8,40.92-19,84.73-46,130.83-49.67,36.26-2.85,70.9,9.42,98.6,31.56,31.77,25.39,62.32,62,103.63,73,40.44,10.79,81.35-6.69,119.13-24.28s75.16-39,116.92-43.05c59.73-5.85,113.28,22.88,168.9,38.84,30.2,8.66,59,6.17,87.09-7.5,22.43-10.89,48-26.93,60.65-49.24V0Z" fill="%23f8fafc" opacity=".5"/><path d="M0,0V5.63C149.93,59,314.09,71.32,475.83,42.57c43-7.64,84.23-20.12,127.61-26.46,59-8.63,112.48,12.24,165.56,35.4C827.93,77.22,886,95.24,951.2,90c86.53-7,172.46-45.71,248.8-84.81V0Z" fill="%23f8fafc"/></svg>');
background-size: cover;
}
.score-ring {
stroke-dasharray: 440;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
.contaminant-bar {
transition: width 0.5s ease-in-out;
}
.map-container {
height: 300px;
border-radius: 0.5rem;
position: relative;
overflow: hidden;
}
.gradient-bar {
background: linear-gradient(90deg, #ef4444 0%, #f59e0b 50%, #10b981 100%);
}
.location-search {
position: relative;
}
.location-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
border: 1px solid #e5e7eb;
border-radius: 0.375rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
z-index: 10;
max-height: 200px;
overflow-y: auto;
}
.location-dropdown-item {
padding: 0.5rem 1rem;
cursor: pointer;
}
.location-dropdown-item:hover {
background-color: #f3f4f6;
}
#map {
width: 100%;
height: 100%;
}
.map-marker {
background-color: #ef4444;
border-radius: 50%;
width: 20px;
height: 20px;
border: 2px solid white;
box-shadow: 0 0 0 10px rgba(239, 68, 68, 0.3);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
}
70% {
box-shadow: 0 0 0 15px rgba(239, 68, 68, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
}
}
.map-radius {
border-radius: 50%;
background-color: rgba(239, 68, 68, 0.2);
border: 2px solid #ef4444;
}
</style>
</head>
<body class="bg-gray-50 font-sans">
<!-- Header -->
<header class="gradient-bg text-white water-wave">
<div class="container mx-auto px-4 py-8">
<div class="flex justify-center">
<img src="https://waterhub.co/wp-content/uploads/2025/04/WaterHub-Updated-Logo.png" alt="WaterHub Logo" class="h-16">
</div>
<div class="mt-12 mb-16 text-center">
<h2 class="text-4xl font-bold mb-4">Your Local Water Quality</h2>
<p class="text-xl max-w-2xl mx-auto">See how clean and safe your drinking water is based on your location in Southern Ontario</p>
</div>
</div>
</header>
<!-- Main Content -->
<main class="container mx-auto px-4 py-12 -mt-10">
<div class="bg-white rounded-xl shadow-lg overflow-hidden">
<!-- Location Info -->
<div class="p-6 border-b border-gray-200">
<div class="flex flex-col md:flex-row justify-between items-start md:items-center">
<div class="w-full md:w-auto">
<h3 class="text-2xl font-semibold text-gray-800">Water Quality Report For:</h3>
<div class="location-search mt-2 w-full md:w-96">
<div class="flex items-center">
<i class="fas fa-map-marker-alt text-blue-500 mr-2"></i>
<input type="text" id="location-input" class="flex-1 border-b border-gray-300 py-1 px-2 focus:outline-none focus:border-blue-500" placeholder="Enter your location...">
<button id="use-my-location" class="ml-2 text-blue-600 hover:text-blue-800">
<i class="fas fa-location-arrow"></i>
</button>
</div>
<div id="location-dropdown" class="location-dropdown hidden"></div>
</div>
<p id="location-display" class="mt-2 text-lg text-gray-600 hidden"></p>
</div>
<button id="refresh-btn" class="mt-4 md:mt-0 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition flex items-center">
<i class="fas fa-sync-alt mr-2"></i> Refresh
</button>
</div>
</div>
<!-- Water Quality Dashboard -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 p-6">
<!-- Score Card -->
<div class="bg-gray-50 p-6 rounded-lg">
<h4 class="text-lg font-medium text-gray-700 mb-4">Overall Water Quality Score</h4>
<div class="relative w-40 h-40 mx-auto mb-6">
<svg class="w-full h-full" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="45" fill="none" stroke="#e5e7eb" stroke-width="8"/>
<circle id="score-circle" cx="50" cy="50" r="45" fill="none" stroke="#3b82f6" stroke-width="8" stroke-linecap="round" class="score-ring" stroke-dashoffset="440"/>
</svg>
<div class="absolute inset-0 flex items-center justify-center flex-col">
<span id="score-value" class="text-4xl font-bold text-gray-800">--</span>
<span class="text-gray-500">out of 100</span>
</div>
</div>
<div id="score-message" class="text-center text-gray-600">
Loading your water quality score...
</div>
</div>
<!-- Contaminants Breakdown -->
<div class="lg:col-span-2">
<h4 class="text-lg font-medium text-gray-700 mb-4">Contaminants Breakdown</h4>
<div id="contaminants-container" class="space-y-4">
<div class="animate-pulse space-y-4">
<div class="h-4 bg-gray-200 rounded w-3/4"></div>
<div class="h-4 bg-gray-200 rounded"></div>
<div class="h-4 bg-gray-200 rounded w-5/6"></div>
<div class="h-4 bg-gray-200 rounded w-2/3"></div>
</div>
</div>
<div class="mt-8">
<h4 class="text-lg font-medium text-gray-700 mb-4">Safety Information</h4>
<div id="safety-info" class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-r">
<p class="text-blue-800">Your water meets Health Canada's safety standards. No immediate health risks detected.</p>
</div>
</div>
</div>
</div>
<!-- Map and Additional Info -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 p-6 border-t border-gray-200">
<div class="map-container">
<div id="map"></div>
</div>
<div>
<h4 class="text-lg font-medium text-gray-700 mb-4">How to Improve Your Water Quality</h4>
<div class="space-y-4">
<div class="flex items-start">
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
<i class="fas fa-filter"></i>
</div>
<div>
<h5 class="font-medium text-gray-800">Install a Water Filter</h5>
<p class="text-gray-600 mt-1">Our advanced filtration systems can remove up to 99.9% of contaminants.</p>
</div>
</div>
<div class="flex items-start">
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
<i class="fas fa-tint"></i>
</div>
<div>
<h5 class="font-medium text-gray-800">Test Your Water Regularly</h5>
<p class="text-gray-600 mt-1">Water quality can change. Regular testing ensures ongoing safety.</p>
</div>
</div>
<div class="flex items-start">
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
<i class="fas fa-info-circle"></i>
</div>
<div>
<h5 class="font-medium text-gray-800">Learn About Your Water</h5>
<p class="text-gray-600 mt-1">Understanding contaminants helps you make informed decisions.</p>
</div>
</div>
</div>
<div class="mt-8">
<a href="https://waterhub.co/shop" class="inline-flex items-center px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition">
Shop Water Solutions
<i class="fas fa-arrow-right ml-2"></i>
</a>
</div>
</div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="bg-gray-800 text-white py-12">
<div class="container mx-auto px-4">
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
<div>
<img src="https://waterhub.co/wp-content/uploads/2025/04/WaterHub-Updated-Logo.png" alt="WaterHub Logo" class="h-10 mb-4">
<p class="text-gray-400">Providing clean, safe water solutions for Southern Ontario homes and businesses.</p>
</div>
<div>
<h5 class="text-lg font-medium mb-4">Quick Links</h5>
<ul class="space-y-2">
<li><a href="https://waterhub.co/" class="text-gray-400 hover:text-white transition">Home</a></li>
<li><a href="https://waterhub.co/shop" class="text-gray-400 hover:text-white transition">Shop</a></li>
<li><a href="https://waterhub.co/about" class="text-gray-400 hover:text-white transition">About Us</a></li>
<li><a href="https://waterhub.co/contact" class="text-gray-400 hover:text-white transition">Contact</a></li>
</ul>
</div>
<div>
<h5 class="text-lg font-medium mb-4">Resources</h5>
<ul class="space-y-2">
<li><a href="https://waterhub.co/blog" class="text-gray-400 hover:text-white transition">Blog</a></li>
<li><a href="https://waterhub.co/water-quality" class="text-gray-400 hover:text-white transition">Water Quality Guide</a></li>
<li><a href="https://waterhub.co/faq" class="text-gray-400 hover:text-white transition">FAQs</a></li>
</ul>
</div>
<div>
<h5 class="text-lg font-medium mb-4">Contact Us</h5>
<ul class="space-y-2 text-gray-400">
<li class="flex items-center"><i class="fas fa-phone-alt mr-2"></i> +1 (647) 560-2795</li>
<li class="flex items-center"><i class="fas fa-envelope mr-2"></i> info@waterhub.co</li>
<li class="flex items-center"><i class="fas fa-map-marker-alt mr-2"></i> Toronto, ON</li>
</ul>
</div>
</div>
<div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400">
<p>&copy; 2023 WaterHub. All rights reserved.</p>
</div>
</div>
</footer>
<script>
// Database of Southern Ontario water quality data with coordinates
const waterQualityData = {
"toronto": {
score: 87,
contaminants: [
{ name: "Chlorine", level: 0.8, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 2.1, safeLevel: 10, unit: "mg/L" }
],
message: "Toronto's water meets all provincial and federal standards. Chlorine levels are slightly elevated but within safe limits.",
coordinates: [-79.3832, 43.6532]
},
"mississauga": {
score: 92,
contaminants: [
{ name: "Chlorine", level: 0.5, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.001, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.6, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 1.8, safeLevel: 10, unit: "mg/L" }
],
message: "Mississauga has good water quality with all contaminants well below safety thresholds.",
coordinates: [-79.6441, 43.5890]
},
"brampton": {
score: 85,
contaminants: [
{ name: "Chlorine", level: 1.2, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.8, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 3.5, safeLevel: 10, unit: "mg/L" }
],
message: "Brampton's water is safe to drink. Chlorine levels are higher than average but still within safe limits.",
coordinates: [-79.7593, 43.7315]
},
"hamilton": {
score: 72,
contaminants: [
{ name: "Chlorine", level: 1.5, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.004, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 1.1, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 5.2, safeLevel: 10, unit: "mg/L" }
],
message: "Hamilton's water meets safety standards but has elevated levels of several contaminants. Consider filtration for improved taste.",
coordinates: [-79.8711, 43.2557]
},
"london": {
score: 83,
contaminants: [
{ name: "Chlorine", level: 1.0, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 4.1, safeLevel: 10, unit: "mg/L" }
],
message: "London's water quality is fair with all contaminants within safe levels. Nitrates are slightly elevated but not concerning.",
coordinates: [-81.2453, 42.9849]
},
"markham": {
score: 89,
contaminants: [
{ name: "Chlorine", level: 0.7, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.6, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 2.8, safeLevel: 10, unit: "mg/L" }
],
message: "Markham's water quality is excellent with all contaminants well within safe limits.",
coordinates: [-79.3297, 43.8561]
},
"vaughan": {
score: 88,
contaminants: [
{ name: "Chlorine", level: 0.9, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 3.0, safeLevel: 10, unit: "mg/L" }
],
message: "Vaughan's water quality is very good with all contaminants within safe levels.",
coordinates: [-79.4985, 43.8361]
},
"ajax": {
score: 86,
contaminants: [
{ name: "Chlorine", level: 1.0, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.8, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 3.2, safeLevel: 10, unit: "mg/L" }
],
message: "Ajax's water quality is good with all contaminants within safe levels.",
coordinates: [-79.0207, 43.8509]
},
"peterborough": {
score: 81,
contaminants: [
{ name: "Chlorine", level: 1.3, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.004, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 1.0, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 4.5, safeLevel: 10, unit: "mg/L" }
],
message: "Peterborough's water meets safety standards but has slightly elevated levels of some contaminants.",
coordinates: [-78.3168, 44.3091]
},
"newmarket": {
score: 87,
contaminants: [
{ name: "Chlorine", level: 0.8, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 3.0, safeLevel: 10, unit: "mg/L" }
],
message: "Newmarket's water quality is very good with all contaminants within safe levels.",
coordinates: [-79.4593, 44.0553]
},
"barrie": {
score: 84,
contaminants: [
{ name: "Chlorine", level: 1.1, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.9, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 3.8, safeLevel: 10, unit: "mg/L" }
],
message: "Barrie's water quality is good with all contaminants within safe levels.",
coordinates: [-79.6900, 44.3894]
},
"milton": {
score: 90,
contaminants: [
{ name: "Chlorine", level: 0.6, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.001, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.6, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 2.5, safeLevel: 10, unit: "mg/L" }
],
message: "Milton's water quality is excellent with all contaminants well within safe limits.",
coordinates: [-79.8770, 43.5183]
},
"waterloo": {
score: 85,
contaminants: [
{ name: "Chlorine", level: 1.0, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.8, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 3.5, safeLevel: 10, unit: "mg/L" }
],
message: "Waterloo's water quality is good with all contaminants within safe levels.",
coordinates: [-80.5204, 43.4643]
},
"kitchener": {
score: 83,
contaminants: [
{ name: "Chlorine", level: 1.2, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.9, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 4.0, safeLevel: 10, unit: "mg/L" }
],
message: "Kitchener's water quality is fair with all contaminants within safe levels.",
coordinates: [-80.4926, 43.4516]
},
"st. catharines": {
score: 80,
contaminants: [
{ name: "Chlorine", level: 1.4, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.004, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 1.1, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 4.8, safeLevel: 10, unit: "mg/L" }
],
message: "St. Catharines' water meets safety standards but has elevated levels of some contaminants.",
coordinates: [-79.2461, 43.1594]
},
"collingwood": {
score: 82,
contaminants: [
{ name: "Chlorine", level: 1.2, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.9, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 4.2, safeLevel: 10, unit: "mg/L" }
],
message: "Collingwood's water quality is fair with all contaminants within safe levels.",
coordinates: [-80.2164, 44.5008]
},
"bowmanville": {
score: 86,
contaminants: [
{ name: "Chlorine", level: 0.9, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 3.1, safeLevel: 10, unit: "mg/L" }
],
message: "Bowmanville's water quality is good with all contaminants within safe levels.",
coordinates: [-78.6833, 43.9167]
},
"kingston": {
score: 79,
contaminants: [
{ name: "Chlorine", level: 1.5, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.004, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 1.2, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 5.0, safeLevel: 10, unit: "mg/L" }
],
message: "Kingston's water meets safety standards but has elevated levels of several contaminants.",
coordinates: [-76.4850, 44.2312]
},
"ottawa": {
score: 88,
contaminants: [
{ name: "Chlorine", level: 0.7, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.6, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 2.9, safeLevel: 10, unit: "mg/L" }
],
message: "Ottawa's water quality is excellent with all contaminants well within safe limits.",
coordinates: [-75.6972, 45.4215]
},
"default": {
score: 82,
contaminants: [
{ name: "Chlorine", level: 0.9, safeLevel: 4, unit: "mg/L" },
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
{ name: "Nitrates", level: 3.8, safeLevel: 10, unit: "mg/L" }
],
message: "Your water meets all safety standards. No immediate health risks detected.",
coordinates: [-79.3832, 43.6532] // Default to Toronto
}
};
// Initialize map
mapboxgl.accessToken = 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/satellite-v9',
center: [-79.3832, 43.6532], // Default to Toronto
zoom: 8
});
// Add navigation controls
map.addControl(new mapboxgl.NavigationControl());
let marker = null;
let radiusCircle = null;
// Function to update the map with marker and radius
function updateMap(lngLat) {
// Remove existing marker and radius if they exist
if (marker) marker.remove();
if (radiusCircle) radiusCircle.remove();
// Add new marker
const el = document.createElement('div');
el.className = 'map-marker';
marker = new mapboxgl.Marker(el)
.setLngLat(lngLat)
.addTo(map);
// Add radius circle (50km)
radiusCircle = new mapboxgl.Popup({ closeButton: false, closeOnClick: false })
.setLngLat(lngLat)
.setHTML('<div class="map-radius" style="width: 100px; height: 100px;"></div>')
.addTo(map);
// Fly to the location
map.flyTo({
center: lngLat,
zoom: 9,
essential: true
});
}
// Function to update the UI with water quality data
function updateWaterQuality(city) {
const cityLower = city.toLowerCase();
const data = waterQualityData[cityLower] || waterQualityData["default"];
// Update score
document.getElementById('score-value').textContent = data.score;
const circle = document.getElementById('score-circle');
const offset = 440 - (440 * data.score / 100);
circle.style.strokeDashoffset = offset;
// Update score message
document.getElementById('score-message').textContent = getScoreMessage(data.score);
// Update safety info with recommendation
const safetyRating = data.score >= 95 ? "Excellent" :
data.score >= 90 ? "Fair" : "Poor";
document.getElementById('safety-info').innerHTML = `
<p class="text-blue-800">${data.message}</p>
<p class="mt-2 font-medium">Safety Rating: ${safetyRating}</p>
<p class="mt-2">${getRecommendation(data.score)}</p>
`;
// Update contaminants
const container = document.getElementById('contaminants-container');
container.innerHTML = '';
data.contaminants.forEach(contaminant => {
const percentage = Math.min(100, (contaminant.level / contaminant.safeLevel) * 100);
const isSafe = percentage <= 100;
const contaminantEl = document.createElement('div');
contaminantEl.className = 'space-y-2';
contaminantEl.innerHTML = `
<div class="flex justify-between">
<span class="font-medium">${contaminant.name}</span>
<span class="text-sm ${isSafe ? 'text-green-600' : 'text-red-600'}">
${contaminant.level} ${contaminant.unit} / ${contaminant.safeLevel} ${contaminant.unit}
</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="contaminant-bar gradient-bar h-2.5 rounded-full"
style="width: ${percentage}%"></div>
</div>
`;
container.appendChild(contaminantEl);
});
// Update map
updateMap(data.coordinates);
}
// Get appropriate message based on score
function getScoreMessage(score) {
if (score >= 95) return "Excellent Water Quality";
if (score >= 90) return "Fair Water Quality";
if (score >= 80) return "Poor Water Quality";
return "Very Poor Water Quality";
}
// Get recommendation based on score
function getRecommendation(score) {
if (score >= 95) return "Your water is excellent quality. Consider water softening solutions from <a href='https://waterhub.co/' class='text-blue-600 hover:underline'>WaterHub.co</a> for ideal conditions.";
if (score >= 90) return "Your water is fair quality. A filter is recommended to ensure ideal conditions. Check <a href='https://waterhub.co/' class='text-blue-600 hover:underline'>WaterHub.co</a> for solutions.";
if (score >= 80) return "Your water is poor quality. We recommend solutions from <a href='https://waterhub.co/' class='text-blue-600 hover:underline'>WaterHub.co</a>.";
return "Your water quality is very poor. You need a water filter solution. Visit <a href='https://waterhub.co/' class='text-blue-600 hover:underline'>WaterHub.co</a> for options.";
}
// Function to get user's location via IP
async function getLocationByIP() {
try {
const response = await fetch('https://ipapi.co/json/');
const data = await response.json();
// Check if the location is in Ontario
if (data.region === "Ontario") {
// Find the closest city in our database
let closestCity = "toronto";
let minDistance = Infinity;
for (const city in waterQualityData) {
if (city === "default") continue;
const cityData = waterQualityData[city];
const distance = Math.sqrt(
Math.pow(data.longitude - cityData.coordinates[0], 2) +
Math.pow(data.latitude - cityData.coordinates[1], 2)
);
if (distance < minDistance) {
minDistance = distance;
closestCity = city;
}
}
return closestCity;
} else {
return "toronto"; // Default to Toronto if not in Ontario
}
} catch (error) {
console.error("Error getting location by IP:", error);
return "toronto"; // Default to Toronto on error
}
}
// Function to get user's precise location via geolocation API
function getPreciseLocation() {
return new Promise((resolve, reject) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
// Find the closest city in our database
let closestCity = "toronto";
let minDistance = Infinity;
for (const city in waterQualityData) {
if (city === "default") continue;
const cityData = waterQualityData[city];
const distance = Math.sqrt(
Math.pow(position.coords.longitude - cityData.coordinates[0], 2) +
Math.pow(position.coords.latitude - cityData.coordinates[1], 2)
);
if (distance < minDistance) {
minDistance = distance;
closestCity = city;
}
}
resolve(closestCity);
},
(error) => {
console.error("Geolocation error:", error);
resolve("toronto"); // Default to Toronto on error
}
);
} else {
resolve("toronto"); // Default to Toronto if geolocation not supported
}
});
}
// Function to search for locations as user types
function searchLocations(query) {
const results = [];
const queryLower = query.toLowerCase();
for (const city in waterQualityData) {
if (city === "default") continue;
if (city.includes(queryLower)) {
results.push({
name: city.charAt(0).toUpperCase() + city.slice(1),
key: city
});
}
}
return results;
}
// Initialize
document.addEventListener('DOMContentLoaded', async () => {
// Set default to Toronto
let currentLocation = "toronto";
document.getElementById('location-input').value = "Toronto";
document.getElementById('location-display').textContent = "Toronto, ON";
document.getElementById('location-display').classList.remove('hidden');
updateWaterQuality(currentLocation);
// Try to get more accurate location
try {
const preciseLocation = await getPreciseLocation();
if (preciseLocation !== "toronto") {
currentLocation = preciseLocation;
const displayName = preciseLocation.charAt(0).toUpperCase() + preciseLocation.slice(1);
document.getElementById('location-input').value = displayName;
document.getElementById('location-display').textContent = `${displayName}, ON`;
updateWaterQuality(currentLocation);
} else {
// Fall back to IP-based location if precise location not available
const ipLocation = await getLocationByIP();
if (ipLocation !== "toronto") {
currentLocation = ipLocation;
const displayName = ipLocation.charAt(0).toUpperCase() + ipLocation.slice(1);
document.getElementById('location-input').value = displayName;
document.getElementById('location-display').textContent = `${displayName}, ON`;
updateWaterQuality(currentLocation);
}
}
} catch (error) {
console.error("Error getting location:", error);
}
// Location input event listeners
const locationInput = document.getElementById('location-input');
const locationDropdown = document.getElementById('location-dropdown');
locationInput.addEventListener('input', () => {
const query = locationInput.value.trim();
if (query.length > 1) {
const results = searchLocations(query.toLowerCase());
if (results.length > 0) {
locationDropdown.innerHTML = '';
results.forEach(result => {
const item = document.createElement('div');
item.className = 'location-dropdown-item';
item.textContent = result.name;
item.addEventListener('click', () => {
locationInput.value = result.name;
document.getElementById('location-display').textContent = `${result.name}, ON`;
document.getElementById('location-display').classList.remove('hidden');
locationDropdown.classList.add('hidden');
updateWaterQuality(result.key);
});
locationDropdown.appendChild(item);
});
locationDropdown.classList.remove('hidden');
} else {
locationDropdown.classList.add('hidden');
}
} else {
locationDropdown.classList.add('hidden');
}
});
locationInput.addEventListener('focus', () => {
if (locationInput.value.trim().length > 1 && locationDropdown.children.length > 0) {
locationDropdown.classList.remove('hidden');
}
});
document.addEventListener('click', (e) => {
if (!locationInput.contains(e.target) && !locationDropdown.contains(e.target)) {
locationDropdown.classList.add('hidden');
}
});
// Use my location button
document.getElementById('use-my-location').addEventListener('click', async () => {
locationInput.value = "Detecting your location...";
document.getElementById('location-display').classList.add('hidden');
try {
const location = await getPreciseLocation();
const displayName = location.charAt(0).toUpperCase() + location.slice(1);
locationInput.value = displayName;
document.getElementById('location-display').textContent = `${displayName}, ON`;
document.getElementById('location-display').classList.remove('hidden');
updateWaterQuality(location);
} catch (error) {
console.error("Error getting location:", error);
locationInput.value = "Toronto";
document.getElementById('location-display').textContent = "Toronto, ON";
document.getElementById('location-display').classList.remove('hidden');
updateWaterQuality("toronto");
}
});
// Refresh button
document.getElementById('refresh-btn').addEventListener('click', () => {
const currentValue = locationInput.value.trim();
if (currentValue && waterQualityData[currentValue.toLowerCase()]) {
updateWaterQuality(currentValue.toLowerCase());
} else {
updateWaterQuality("toronto");
locationInput.value = "Toronto";
document.getElementById('location-display').textContent = "Toronto, ON";
}
});
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Pandafacewin/beta3" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>