- Create public/utils.js with shared frontend utility functions - Extract parseUTCDate, getTimeAgo, getTimeRemaining, getRemainingClass to utils.js - Remove duplicate functions from admin.js, app-mapbox.js, app-google.js, and app.js - Add utils.js script import to index.html and admin.html - Add comprehensive JSDoc documentation for all utility functions - Ensure consistent UTC timestamp parsing across all frontend scripts This addresses Copilot AI feedback about function duplication across multiple frontend scripts. Now all timestamp and time calculation logic is centralized in one maintainable module. Benefits: - Single source of truth for time-related utilities - Easier maintenance and updates - Consistent behavior across all frontend components - Better code organization and documentation - Reduced bundle size through deduplication
115 lines
7 KiB
HTML
115 lines
7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Great Lakes Ice Report</title>
|
|
<link rel="icon" type="image/svg+xml" href="https://iceymi.b-cdn.net/favicon.svg">
|
|
<link rel="icon" type="image/x-icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLnNub3dmbGFrZSB7IGZpbGw6ICMyMTk2RjM7IH0KICAgICAgLmNlbnRlciB7IGZpbGw6ICMxOTc2RDI7IH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIAogIDxnIGNsYXNzPSJzbm93Zmxha2UiPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiAvPgogICAgPHJlY3QgeD0iMiIgeT0iMTUiIHdpZHRoPSIyOCIgaGVpZ2h0PSIyIiAvPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cmVjdCB4PSIxNSIgeT0iMiIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjE2LDIgMTQsNiAxOCw2IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSIxNiwzMCAxNCwyNiAxOCwyNiIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMiwxNiA2LDE0IDYsMTgiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjMwLDE2IDI2LDE0IDI2LDE4IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSI2LjMsNi4zIDguNiw0IDkuOSw3LjciIHRyYW5zZm9ybT0icm90YXRlKDQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNywyNS43IDIzLjQsMjggMjIuMSwyNC4zIiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYuMywyNS43IDguNiwyOCA5LjksMjQuMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNyw2LjMgMjMuNCw0IDIyLjEsNy43IiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUgMTYgMTYpIiAvPgogIDwvZz4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIzIiBjbGFzcz0iY2VudGVyIiAvPgo8L3N2Zz4K">
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
<link rel="stylesheet" href="style.css">
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<header>
|
|
<div class="header-content">
|
|
<div class="header-text">
|
|
<h1>❄️ Great Lakes Ice Report</h1>
|
|
<p>Community-reported ICEy road conditions and winter hazards (auto-expire after 48 hours)</p>
|
|
</div>
|
|
<button id="theme-toggle" class="theme-toggle" title="Toggle dark mode">
|
|
<span class="theme-icon">🌙</span>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="content">
|
|
<div class="form-section">
|
|
<h2>Report ICEy Conditions</h2>
|
|
<form id="location-form">
|
|
<div class="form-group">
|
|
<label for="address">Address or Location *</label>
|
|
<div class="autocomplete-container">
|
|
<input type="text" id="address" name="address" required
|
|
placeholder="Enter address, intersection (e.g., Main St & Second St, City), or landmark"
|
|
autocomplete="off">
|
|
<div id="autocomplete-list" class="autocomplete-list"></div>
|
|
</div>
|
|
<small class="input-help">Examples: "123 Main St, City" or "Main St & Oak Ave, City" or "CVS Pharmacy, City"</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="description">Additional Details (Optional)</label>
|
|
<textarea id="description" name="description" rows="3"
|
|
placeholder="Number of vehicles, time observed, etc." aria-describedby="description-help"></textarea>
|
|
<small id="description-help" class="input-help">Keep descriptions appropriate and relevant to road conditions. Submissions with inappropriate language will be rejected.</small>
|
|
</div>
|
|
|
|
<button type="submit" id="submit-btn">
|
|
<span id="submit-text">Report Location</span>
|
|
<span id="submit-loading" style="display: none;">Submitting...</span>
|
|
</button>
|
|
</form>
|
|
|
|
<div id="message" class="message"></div>
|
|
</div>
|
|
|
|
<div class="map-section">
|
|
<div class="reports-header">
|
|
<h2>Current Reports</h2>
|
|
<div class="view-toggle">
|
|
<button id="map-view-btn" class="toggle-btn active">📍 Map View</button>
|
|
<button id="table-view-btn" class="toggle-btn">📋 Table View</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="map-view" class="view-container">
|
|
<div id="map"></div>
|
|
<div class="map-info">
|
|
<p><strong>🔴 Red markers:</strong> Icy conditions reported</p>
|
|
<p><strong>⏰ Auto-cleanup:</strong> Reports disappear after 48 hours</p>
|
|
<p id="location-count">Loading locations...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="table-view" class="view-container" style="display: none;">
|
|
<div class="table-controls">
|
|
<div class="table-info">
|
|
<p id="table-location-count">Loading locations...</p>
|
|
</div>
|
|
</div>
|
|
<div class="table-container">
|
|
<table class="reports-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Location</th>
|
|
<th>Details</th>
|
|
<th>Reported</th>
|
|
<th>Time Remaining</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="reports-tbody">
|
|
<tr>
|
|
<td colspan="4" class="loading">Loading reports...</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<footer>
|
|
<p><strong>Safety Notice:</strong> This is a community tool for awareness. Stay safe and <a href="https://www.aclu.org/know-your-rights/immigrants-rights" target="_blank" rel="noopener noreferrer" style="color: #007bff; text-decoration: underline;">know your rights</a>.</p>
|
|
<div class="disclaimer">
|
|
<small>This website is for informational purposes only. Verify information independently.
|
|
Reports are automatically deleted after 48 hours. • <a href="/privacy" style="color: #007bff; text-decoration: underline;">Privacy Policy</a></small>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
<script src="utils.js"></script>
|
|
<script src="app-mapbox.js"></script>
|
|
</body>
|
|
</html>
|