When no active approval workflow exists, ApprovalService::submit() was
silently returning, leaving the request in Draft while showing a false
success message. Now throws a RuntimeException as a safety net, and the
Livewire component guards before creating any records and shows a clear
error to the user.
- Add towns table with town_pid, town_name, state, population, town_class, date_retired
- Add AustralianState enum with label and abbreviation helpers
- Add Town model with active() and search() scopes
- Add SyncTowns job that paginates ArcGIS API and upserts all 1977 towns
- Schedule SyncTowns to run nightly at 02:00
- Add /towns/search endpoint returning JSON suggestions filtered by name and state
- Add Alpine-powered autocomplete on origin/destination fields in create form
- Add state filter dropdown in journeys card header to narrow autocomplete results
- Change default theme from light to dark for first-time visitors
- Fix Alpine reactive theme toggle so icons and data-bs-theme update correctly
- Remove hardcoded bg-light classes that prevented dark mode from applying
- Fix broken duplicate Bootstrap bundle import in app.js
- Add missing LDAP env vars to .env.example (host, base DN, bind credentials)
- Use 'uid' instead of 'username' as the LDAP lookup attribute in Auth::attempt
- Override getLdapGuidColumn/getLdapDomainColumn in User model to match
migration column names (ldap_guid/ldap_domain vs default guid/domain)
- Make dark mode toggle reactive using Alpine x-data theme property
- Apply saved theme on page load via data-bs-theme attribute binding
- Remove hardcoded bg-light classes that broke dark mode styling
- Fix duplicate/broken Bootstrap bundle import in app.js