Adjust viewport, description, dates
This commit is contained in:
parent
2b8450951e
commit
7087dea5ab
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
<title>Select City - Water Station Tracker</title>
|
<title>Select City - Water Station Tracker</title>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
<title>Dashboard - Water Station Tracker</title>
|
<title>Dashboard - Water Station Tracker</title>
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||||
<style>
|
<style>
|
||||||
@ -15,6 +15,7 @@
|
|||||||
body {
|
body {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
|
overflow: hidden; /* Prevent scrolling on mobile */
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@ -68,6 +69,8 @@
|
|||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
height: calc(100vh - 80px);
|
height: calc(100vh - 80px);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#map {
|
#map {
|
||||||
@ -312,10 +315,7 @@
|
|||||||
<textarea id="stationDescription" name="description" placeholder="e.g., Public fountain in park"></textarea>
|
<textarea id="stationDescription" name="description" placeholder="e.g., Public fountain in park"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<input type="hidden" id="coordinates">
|
||||||
<label>Location</label>
|
|
||||||
<input type="text" id="coordinates" readonly placeholder="Right-click or long-press map to select location">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary">Add Station</button>
|
<button type="submit" class="btn btn-primary">Add Station</button>
|
||||||
</form>
|
</form>
|
||||||
@ -339,10 +339,7 @@
|
|||||||
<textarea id="editStationDescription" name="description" placeholder="e.g., Public fountain in park"></textarea>
|
<textarea id="editStationDescription" name="description" placeholder="e.g., Public fountain in park"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<input type="hidden" id="editCoordinates">
|
||||||
<label>Location</label>
|
|
||||||
<input type="text" id="editCoordinates" readonly>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary">Save Changes</button>
|
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||||||
<button type="button" class="btn btn-secondary" onclick="closeEditModal()">Cancel</button>
|
<button type="button" class="btn btn-secondary" onclick="closeEditModal()">Cancel</button>
|
||||||
@ -607,7 +604,8 @@
|
|||||||
return `
|
return `
|
||||||
<div style="min-width: 200px;">
|
<div style="min-width: 200px;">
|
||||||
<h3>${station.name}</h3>
|
<h3>${station.name}</h3>
|
||||||
<p><strong>Description:</strong> ${station.latest_description || 'No description'}</p>
|
<p style="color: #666; font-size: 0.9rem; margin-bottom: 10px;">${station.description || 'No description'}</p>
|
||||||
|
<p><strong>Status:</strong> ${station.latest_description || 'No status update'}</p>
|
||||||
<p><strong>Last Refill:</strong> ${refillTime}</p>
|
<p><strong>Last Refill:</strong> ${refillTime}</p>
|
||||||
<p><strong>Estimated Empty:</strong> ${estimatedEmpty}</p>
|
<p><strong>Estimated Empty:</strong> ${estimatedEmpty}</p>
|
||||||
<p><strong>Last Updated By:</strong> ${station.updated_by_name || 'Unknown'}</p>
|
<p><strong>Last Updated By:</strong> ${station.updated_by_name || 'Unknown'}</p>
|
||||||
@ -710,7 +708,11 @@
|
|||||||
bounds.extend([station.latitude, station.longitude]);
|
bounds.extend([station.latitude, station.longitude]);
|
||||||
});
|
});
|
||||||
|
|
||||||
map.fitBounds(bounds, { padding: [20, 20] });
|
// Add more padding and max zoom to ensure all stations are visible
|
||||||
|
map.fitBounds(bounds, {
|
||||||
|
padding: [50, 50],
|
||||||
|
maxZoom: 15 // Zoom out one more level by default
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function centerMap() {
|
function centerMap() {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
<title>Water Station Tracker</title>
|
<title>Water Station Tracker</title>
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||||
<style>
|
<style>
|
||||||
@ -15,6 +15,7 @@
|
|||||||
body {
|
body {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
|
overflow: hidden; /* Prevent scrolling on mobile */
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@ -52,6 +53,8 @@
|
|||||||
#map {
|
#map {
|
||||||
height: calc(100vh - 120px);
|
height: calc(100vh - 120px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.station-popup {
|
.station-popup {
|
||||||
@ -286,21 +289,66 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPopupContent(station) {
|
// Helper function to format dates in a human-readable way
|
||||||
const refillTime = station.last_refill_time ?
|
function formatTimeAgo(dateString) {
|
||||||
new Date(station.last_refill_time).toLocaleString() : 'Never';
|
if (!dateString) return 'Never';
|
||||||
|
|
||||||
const estimatedEmpty = station.estimated_empty_time ?
|
// Parse UTC timestamp correctly
|
||||||
new Date(station.estimated_empty_time).toLocaleString() : 'Unknown';
|
const date = new Date(dateString + (dateString.includes('Z') ? '' : 'Z'));
|
||||||
|
const now = new Date();
|
||||||
|
const diffInSeconds = Math.floor((now - date) / 1000);
|
||||||
|
|
||||||
|
if (diffInSeconds < 60) {
|
||||||
|
return 'Just now';
|
||||||
|
} else if (diffInSeconds < 3600) {
|
||||||
|
const minutes = Math.floor(diffInSeconds / 60);
|
||||||
|
return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
|
||||||
|
} else if (diffInSeconds < 86400) {
|
||||||
|
const hours = Math.floor(diffInSeconds / 3600);
|
||||||
|
return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
|
||||||
|
} else if (diffInSeconds < 604800) {
|
||||||
|
const days = Math.floor(diffInSeconds / 86400);
|
||||||
|
return `${days} day${days !== 1 ? 's' : ''} ago`;
|
||||||
|
} else {
|
||||||
|
return date.toLocaleDateString() + ' at ' + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to format estimated empty time
|
||||||
|
function formatTimeUntil(dateString) {
|
||||||
|
if (!dateString) return 'Unknown';
|
||||||
|
|
||||||
|
// Parse UTC timestamp correctly
|
||||||
|
const date = new Date(dateString + (dateString.includes('Z') ? '' : 'Z'));
|
||||||
|
const now = new Date();
|
||||||
|
const diffInSeconds = Math.floor((date - now) / 1000);
|
||||||
|
|
||||||
|
if (diffInSeconds <= 0) {
|
||||||
|
return 'Already empty';
|
||||||
|
} else if (diffInSeconds < 3600) {
|
||||||
|
const minutes = Math.floor(diffInSeconds / 60);
|
||||||
|
return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
|
||||||
|
} else if (diffInSeconds < 86400) {
|
||||||
|
const hours = Math.floor(diffInSeconds / 3600);
|
||||||
|
return `${hours} hour${hours !== 1 ? 's' : ''}`;
|
||||||
|
} else {
|
||||||
|
const days = Math.floor(diffInSeconds / 86400);
|
||||||
|
return `${days} day${days !== 1 ? 's' : ''}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPopupContent(station) {
|
||||||
|
const refillTime = formatTimeAgo(station.last_refill_time);
|
||||||
|
const estimatedEmpty = formatTimeUntil(station.estimated_empty_time);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="station-popup">
|
<div class="station-popup">
|
||||||
<h3>${station.name}</h3>
|
<h3>${station.name}</h3>
|
||||||
|
<p style="color: #666; font-size: 0.9rem; margin-bottom: 10px;">${station.description || 'No description'}</p>
|
||||||
<div class="station-info">
|
<div class="station-info">
|
||||||
<p><strong>Description:</strong> ${station.latest_description || 'No description'}</p>
|
<p><strong>Status:</strong> ${station.latest_description || 'No status update'}</p>
|
||||||
<p><strong>Last Refill:</strong> ${refillTime}</p>
|
<p><strong>Last Refill:</strong> ${refillTime}</p>
|
||||||
<p><strong>Estimated Empty:</strong> ${estimatedEmpty}</p>
|
<p><strong>Estimated Empty:</strong> ${estimatedEmpty}</p>
|
||||||
<p><strong>Last Updated:</strong> ${station.last_updated ? new Date(station.last_updated).toLocaleString() : 'Never'}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -314,7 +362,11 @@
|
|||||||
bounds.extend([station.latitude, station.longitude]);
|
bounds.extend([station.latitude, station.longitude]);
|
||||||
});
|
});
|
||||||
|
|
||||||
map.fitBounds(bounds, { padding: [20, 20] });
|
// Add more padding and max zoom to ensure all stations are visible
|
||||||
|
map.fitBounds(bounds, {
|
||||||
|
padding: [50, 50],
|
||||||
|
maxZoom: 15 // Zoom out one more level by default
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize map when page loads
|
// Initialize map when page loads
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
<title>Login - Water Station Tracker</title>
|
<title>Login - Water Station Tracker</title>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user