<!DOCTYPE html>
<html>
<head>
<title>ICE Locator Heatmap Demo</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.header {
text-align: center;
color: #333;
margin-bottom: 30px;
}
.container {
display: flex;
gap: 20px;
margin-bottom: 30px;
}
.panel {
flex: 1;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.panel h2 {
margin-top: 0;
color: #444;
border-bottom: 2px solid #007cba;
padding-bottom: 10px;
}
button {
background-color: #007cba;
color: white;
border: none;
padding: 12px 24px;
font-size: 16px;
border-radius: 4px;
cursor: pointer;
margin: 10px 0;
}
button:hover {
background-color: #005a87;
}
#map {
height: 500px;
width: 100%;
background-color: #e9e9e9;
border-radius: 8px;
margin-top: 20px;
}
#data-display {
background-color: #f8f8f8;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
max-height: 400px;
overflow-y: auto;
font-family: monospace;
white-space: pre-wrap;
}
.facility-item {
padding: 10px;
border-bottom: 1px solid #eee;
}
.facility-name {
font-weight: bold;
color: #007cba;
}
.detainee-count {
background-color: #c00;
color: white;
padding: 2px 8px;
border-radius: 12px;
font-size: 14px;
}
.legend {
display: flex;
gap: 15px;
margin: 15px 0;
flex-wrap: wrap;
}
.legend-item {
display: flex;
align-items: center;
gap: 5px;
}
.legend-color {
width: 20px;
height: 20px;
border-radius: 3px;
}
</style>
</head>
<body>
<div class="header">
<h1>ICE Locator Heatmap Demo</h1>
<p>Interactive visualization of ICE facility locations and detainee counts</p>
</div>
<div class="container">
<div class="panel">
<h2>Controls</h2>
<button id="fetch-data">Fetch Heatmap Data</button>
<button id="show-map">Show Map Visualization</button>
<button id="show-list">Show Facility List</button>
<div class="legend">
<div class="legend-item">
<div class="legend-color" style="background-color: #90EE90;"></div>
<span>0 detainees</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background-color: #9ACD32;"></div>
<span>1-9 detainees</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background-color: #FFD700;"></div>
<span>10-49 detainees</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background-color: #FF8C00;"></div>
<span>50-99 detainees</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background-color: #FF4500;"></div>
<span>100+ detainees</span>
</div>
</div>
<h3>API Endpoints</h3>
<ul>
<li><strong>GET</strong> <a href="http://localhost:8082/api/heatmap-data" target="_blank">/api/heatmap-data</a> - Aggregated heatmap data</li>
<li><strong>GET</strong> <a href="http://localhost:8082/api/facilities" target="_blank">/api/facilities</a> - All facilities</li>
<li><strong>GET</strong> <a href="http://localhost:8082/docs" target="_blank">/docs</a> - API Documentation</li>
</ul>
</div>
<div class="panel">
<h2>Data Display</h2>
<div id="data-display">Click "Fetch Heatmap Data" to load information</div>
</div>
</div>
<div class="panel">
<h2>Map Visualization</h2>
<div id="map">
<p style="text-align: center; padding-top: 200px; color: #666;">
Click "Show Map Visualization" after fetching data to display the interactive map
</p>
</div>
</div>
<script>
let heatmapData = [];
document.getElementById('fetch-data').addEventListener('click', async () => {
try {
const response = await fetch('http://localhost:8082/api/heatmap-data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
heatmapData = await response.json();
// Display raw data
document.getElementById('data-display').innerHTML = JSON.stringify(heatmapData, null, 2);
// Show notification
alert(`Loaded data for ${heatmapData.length} facilities`);
} catch (error) {
document.getElementById('data-display').innerHTML = `Error: ${error.message}`;
console.error('Error fetching heatmap data:', error);
}
});
document.getElementById('show-map').addEventListener('click', () => {
if (heatmapData.length === 0) {
alert('Please fetch data first!');
return;
}
let mapHTML = `
<div style="padding: 20px; background: #f0f8ff; border-radius: 8px; margin-bottom: 20px;">
<h3 style="margin-top: 0;">Map Visualization</h3>
<p>This is a simplified representation. In the full application, this would be an interactive map with markers.</p>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 15px;">
`;
heatmapData.forEach(facility => {
// Determine color based on detainee count
let color;
if (facility.current_detainee_count === 0) color = '#90EE90';
else if (facility.current_detainee_count < 10) color = '#9ACD32';
else if (facility.current_detainee_count < 50) color = '#FFD700';
else if (facility.current_detainee_count < 100) color = '#FF8C00';
else color = '#FF4500';
mapHTML += `
<div style="background: white; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); border-left: 5px solid ${color};">
<h4 style="margin: 0 0 10px 0; color: #333;">${facility.name}</h4>
<p style="margin: 5px 0; color: #666;">📍 ${facility.address}</p>
<p style="margin: 5px 0; color: #666;">📍 Coordinates: ${facility.latitude.toFixed(4)}, ${facility.longitude.toFixed(4)}</p>
<p style="margin: 10px 0 0 0;">
<span class="detainee-count" style="background-color: ${color};">
${facility.current_detainee_count} detainees
</span>
</p>
</div>
`;
});
mapHTML += `</div>`;
document.getElementById('map').innerHTML = mapHTML;
});
document.getElementById('show-list').addEventListener('click', () => {
if (heatmapData.length === 0) {
alert('Please fetch data first!');
return;
}
let listHTML = `<h3>Facility List (${heatmapData.length} facilities)</h3><div>`;
heatmapData.forEach(facility => {
// Determine color based on detainee count
let color;
if (facility.current_detainee_count === 0) color = '#90EE90';
else if (facility.current_detainee_count < 10) color = '#9ACD32';
else if (facility.current_detainee_count < 50) color = '#FFD700';
else if (facility.current_detainee_count < 100) color = '#FF8C00';
else color = '#FF4500';
listHTML += `
<div class="facility-item">
<span class="facility-name">${facility.name}</span>
<span style="float: right;">
<span class="detainee-count" style="background-color: ${color};">
${facility.current_detainee_count} detainees
</span>
</span>
<br>
<span style="color: #666; font-size: 14px;">${facility.address}</span>
<br>
<span style="color: #999; font-size: 12px;">ID: ${facility.id} | Coordinates: ${facility.latitude.toFixed(4)}, ${facility.longitude.toFixed(4)}</span>
</div>
`;
});
listHTML += `</div>`;
document.getElementById('data-display').innerHTML = listHTML;
});
</script>
</body>
</html>