From 38c5c5534b05213eeb4e44da92754618e3ee5575 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Nov 2025 03:55:52 +0000 Subject: [PATCH 1/7] Modernize codebase: Bootstrap 5, vanilla JS, improved code structure Major refactoring to modernize the school catchment map application: HTML Changes: - Upgraded from Bootstrap 3 to Bootstrap 5 - Replaced jasny-bootstrap with native Bootstrap 5 offcanvas - Removed jQuery UI dependencies - Updated to latest Leaflet (1.9.4) and related libraries - Improved semantic HTML structure - Added proper ARIA labels and accessibility attributes - Replaced Glyphicons with inline SVG icons - Cleaner modal and navigation markup JavaScript Changes: - Complete removal of jQuery dependencies - Migrated to modern ES6+ syntax (const/let, arrow functions, async/await) - Replaced $.ajax with native fetch API - Implemented custom autocomplete without jQuery UI - Better code organization with clear sections and JSDoc comments - Centralized configuration in CONFIG object - Proper state management with AppState object - Enhanced error handling throughout - Debounced autocomplete for better performance - Keyboard navigation support for autocomplete (arrow keys, Enter, Escape) - Better separation of concerns (init, events, data loading) CSS Changes: - Updated for Bootstrap 5 compatibility - Reorganized with clear section headers - Improved autocomplete dropdown styling - Better responsive design for all screen sizes - Enhanced offcanvas behavior on desktop (always visible sidebar) - Added print styles - Removed unused/redundant styles - Better Leaflet control positioning - Improved form control styling Benefits: - No jQuery dependency (smaller bundle size, better performance) - Modern JavaScript patterns (easier to maintain and extend) - Better error handling and user feedback - Improved accessibility - Cleaner, more maintainable code structure - Updated to current library versions with security patches - Better mobile/desktop responsive behavior --- css/catchment.css | 284 +++++++++++++--- index.html | 828 ++++++++++++++++++++++++---------------------- js/map.js | 758 ++++++++++++++++++++++++++++-------------- 3 files changed, 1188 insertions(+), 682 deletions(-) diff --git a/css/catchment.css b/css/catchment.css index 9d3b1a1..b9446cc 100644 --- a/css/catchment.css +++ b/css/catchment.css @@ -1,62 +1,272 @@ -/* This is used to specify the map area. */ -html, body, .row, .container, .container-map, #map { +/** + * School Catchment Map - Custom Styles + * Bootstrap 5 compatible + */ + +/* ============================================================================ + Layout & Container Styles + ============================================================================ */ + +html, body { height: 100%; - padding-bottom: 16px; + margin: 0; + padding: 0; } -/* Add padding on the top and bottom so the top and bottom of map align with nav bars */ body { - padding: 54px 0; -} + padding-top: 56px; + padding-bottom: 56px; +} + +.container-map { + height: 100%; + position: relative; +} + +#map { + height: 100%; + width: 100%; +} + +/* ============================================================================ + Navigation & Offcanvas + ============================================================================ */ + +/* Ensure offcanvas is properly sized on desktop */ +@media (min-width: 992px) { + body { + padding-right: 0; + } + + .offcanvas-end { + width: 300px; + } +} + +/* Offcanvas body scrolling */ +.offcanvas-body { + overflow-y: auto; +} + +/* ============================================================================ + Address Search / Geocoder + ============================================================================ */ -/* To remove border and shading in footer */ -.panel-footer { - line-height: 1.8; - background-color: #f8f8f8; - border-top: 0px; - } +.address-search { + position: absolute; + top: 10px; + left: 50%; + transform: translateX(-50%); + z-index: 1000; + width: 90%; + max-width: 400px; +} + +.address-search .input-group { + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); +} + +/* Autocomplete dropdown */ +.autocomplete-items { + position: absolute; + top: 100%; + left: 0; + right: 0; + z-index: 1001; + background-color: white; + border: 1px solid #ced4da; + border-top: none; + border-radius: 0 0 0.25rem 0.25rem; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); + max-height: 200px; + overflow-y: auto; + display: none; +} + +.autocomplete-item { + padding: 10px; + cursor: pointer; + background-color: white; + border-bottom: 1px solid #e9ecef; + font-size: 0.9rem; +} + +.autocomplete-item:hover, +.autocomplete-item.autocomplete-active { + background-color: #e9ecef; +} + +.autocomplete-item:last-child { + border-bottom: none; +} + +/* ============================================================================ + Filter Menu Styles + ============================================================================ */ + +.offcanvas-body .form-check { + margin-bottom: 0.5rem; +} + +.offcanvas-body .form-check-label { + cursor: pointer; + user-select: none; +} + +.offcanvas-body .badge { + display: inline-block; + width: 100%; + text-align: left; + padding: 0.5rem; + font-size: 0.875rem; + font-weight: 600; +} -/* This sets the mobile size of the off cavas menus */ -.navmenu { - padding: 0 10px; - width: 250px; +/* Section headers within filter groups */ +.offcanvas-body strong.small { + display: block; + margin-bottom: 0.25rem; + color: #495057; } -/* To accommodate header with filter and see Leaflet Control */ -@media (max-width: 365px) { - .navbar-brand { - font-size: 12px; - padding-left: 10px; +/* ============================================================================ + Responsive Adjustments + ============================================================================ */ + +/* Small screens */ +@media (max-width: 576px) { + .address-search { + width: 95%; + max-width: none; + } + + .navbar-brand span { + font-size: 0.9rem; } - .panel-footer { - font-size: 11px; + .offcanvas-body .form-check-label { + font-size: 0.85rem; } } -/* To accommodate iPad portrait mode */ -@media (min-width: 0px) { - .navbar-toggle { - display: block; /* force showing the toggle */ +/* Medium screens and up */ +@media (min-width: 768px) { + .address-search { + width: 400px; } } -/* This is for the "normal" size off canvas menu */ +/* Large screens - offcanvas becomes always visible sidebar */ @media (min-width: 992px) { body { - padding: 50px 250px 50px 0; + padding-right: 300px; + } + + .offcanvas-end { + visibility: visible !important; + transform: none !important; + position: fixed; + top: 56px; + bottom: 56px; + right: 0; + border-left: 1px solid rgba(0, 0, 0, 0.125); } - .navmenu { - padding: 50px 10px; + .offcanvas-backdrop { + display: none; } - .navmenu-toggle { - display: none !important; + /* Hide toggle button on desktop */ + .navbar .btn[data-bs-toggle="offcanvas"] { + display: none; } } -/* Geocoder */ -.ui-autocomplete { - z-index: 1000; -} \ No newline at end of file +/* Extra large screens */ +@media (min-width: 1200px) { + .offcanvas-end { + width: 350px; + } + + body { + padding-right: 350px; + } +} + +/* ============================================================================ + Footer Styles + ============================================================================ */ + +.navbar-fixed-bottom { + border-top: 1px solid rgba(0, 0, 0, 0.125); +} + +/* ============================================================================ + Leaflet Override Styles + ============================================================================ */ + +/* Ensure Leaflet controls don't overlap with search bar */ +.leaflet-top.leaflet-left { + margin-top: 60px; +} + +/* Better popup styling */ +.leaflet-popup-content { + margin: 13px 19px; + line-height: 1.4; +} + +.leaflet-popup-content b { + font-weight: 600; +} + +/* Marker cluster styling adjustments */ +.marker-cluster-small, +.marker-cluster-medium, +.marker-cluster-large { + background-color: rgba(51, 136, 255, 0.6); +} + +.marker-cluster-small div, +.marker-cluster-medium div, +.marker-cluster-large div { + background-color: rgba(51, 136, 255, 0.8); + color: white; + font-weight: bold; +} + +/* ============================================================================ + Utility Classes + ============================================================================ */ + +/* Smooth transitions */ +.form-check-input { + cursor: pointer; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; +} + +/* Loading state (can be used later for better UX) */ +.loading { + opacity: 0.6; + pointer-events: none; +} + +/* ============================================================================ + Print Styles + ============================================================================ */ + +@media print { + .navbar, + .offcanvas, + .address-search { + display: none; + } + + body { + padding: 0; + } + + #map { + height: 100vh; + } +} diff --git a/index.html b/index.html index 7e188dd..cdc801e 100755 --- a/index.html +++ b/index.html @@ -1,424 +1,458 @@ - + - + + + + + + + + + Catchment Areas | SD8 + + + + + + + + + + + + + + + + + + - - Catchment Areas | SD8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -