Add nightly town sync from ArcGIS API with autocomplete
All checks were successful
linter / quality (pull_request) Successful in 1m21s
security / Dependency Audit (pull_request) Successful in 1m25s
security / Static Analysis (pull_request) Successful in 1m49s
tests / ci (8.4) (pull_request) Successful in 1m23s
tests / ci (8.5) (pull_request) Successful in 1m27s
All checks were successful
linter / quality (pull_request) Successful in 1m21s
security / Dependency Audit (pull_request) Successful in 1m25s
security / Static Analysis (pull_request) Successful in 1m49s
tests / ci (8.4) (pull_request) Successful in 1m23s
tests / ci (8.5) (pull_request) Successful in 1m27s
- 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
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
<?php
|
||||
|
||||
use App\Jobs\SyncTowns;
|
||||
use Illuminate\Foundation\Inspiring;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Schedule;
|
||||
|
||||
Artisan::command('inspire', function () {
|
||||
$this->comment(Inspiring::quote());
|
||||
})->purpose('Display an inspiring quote');
|
||||
|
||||
Schedule::job(new SyncTowns)->dailyAt('02:00');
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Town;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
@@ -11,9 +13,34 @@ Route::post('/logout', function () {
|
||||
Auth::logout();
|
||||
session()->invalidate();
|
||||
session()->regenerateToken();
|
||||
|
||||
return redirect()->route('login');
|
||||
})->name('logout')->middleware('auth');
|
||||
|
||||
// Town autocomplete search
|
||||
Route::middleware(['auth'])->get('/towns/search', function (Request $request) {
|
||||
$query = $request->string('query')->trim();
|
||||
|
||||
if ($query->length() < 2) {
|
||||
return response()->json([]);
|
||||
}
|
||||
|
||||
$towns = Town::active()
|
||||
->search($query)
|
||||
->when($request->filled('state'), fn ($q) => $q->where('state', $request->integer('state')))
|
||||
->orderBy('town_name')
|
||||
->limit(10)
|
||||
->get(['town_name', 'state']);
|
||||
|
||||
return response()->json(
|
||||
$towns->map(fn ($town) => [
|
||||
'name' => $town->town_name,
|
||||
'state' => $town->state->abbreviation(),
|
||||
'label' => $town->town_name.', '.$town->state->abbreviation(),
|
||||
])
|
||||
);
|
||||
})->name('towns.search');
|
||||
|
||||
// Authenticated
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::livewire('/dashboard', 'dashboard')->name('dashboard');
|
||||
|
||||
Reference in New Issue
Block a user