From 7c3675f01c65935bd962b45a78f5a38d11a81b2e Mon Sep 17 00:00:00 2001 From: Benjamin Takats Date: Thu, 1 Dec 2022 22:29:53 +0100 Subject: [PATCH] proximitySearch added --- .blueprint | 4 +- app/Http/Livewire/Tables/CityTable.php | 17 +++- app/Http/Livewire/Tables/EventTable.php | 4 +- app/Models/City.php | 2 + app/Nova/City.php | 22 ++++-- app/Policies/CityPolicy.php | 2 +- composer.json | 1 + composer.lock | 60 +++++++++++++- ..._210526_add_geo_fields_to_cities_table.php | 30 +++++++ database/seeders/DatabaseSeeder.php | 6 ++ .../views/columns/cities/action.blade.php | 2 +- resources/views/dashboard.blade.php | 39 ++++++++- resources/views/layouts/app.blade.php | 79 ++++++++++--------- resources/views/layouts/guest.blade.php | 7 +- resources/views/navigation-menu.blade.php | 66 ++++++++++------ 15 files changed, 262 insertions(+), 79 deletions(-) create mode 100644 database/migrations/2022_12_01_210526_add_geo_fields_to_cities_table.php diff --git a/.blueprint b/.blueprint index 1c9ac7cf..b397293d 100644 --- a/.blueprint +++ b/.blueprint @@ -1,11 +1,11 @@ models: Category: { name: string, slug: string } - City: { country_id: biginteger, name: string, slug: string } + City: { country_id: biginteger, name: string, slug: string, longitude: 'float:10', latitude: 'float:10' } Country: { name: string, code: string } Course: { lecturer_id: biginteger, name: string } Event: { course_id: biginteger, venue_id: biginteger, '"from"': datetime, '"to"': datetime } Lecturer: { team_id: biginteger, name: string, slug: string, active: 'boolean default:1' } - LoginKey: { } + LoginKey: { k1: string, user_id: biginteger } Membership: { team_id: biginteger, user_id: biginteger, role: 'string nullable' } Participant: { first_name: string, last_name: string } Registration: { event_id: biginteger, participant_id: biginteger, active: 'boolean default:1' } diff --git a/app/Http/Livewire/Tables/CityTable.php b/app/Http/Livewire/Tables/CityTable.php index 0973c57d..3b8c8c31 100644 --- a/app/Http/Livewire/Tables/CityTable.php +++ b/app/Http/Livewire/Tables/CityTable.php @@ -6,16 +6,20 @@ use App\Models\City; use Illuminate\Database\Eloquent\Builder; use Rappasoft\LaravelLivewireTables\DataTableComponent; use Rappasoft\LaravelLivewireTables\Views\Column; +use WireUi\Traits\Actions; class CityTable extends DataTableComponent { + use Actions; + public string $country; protected $model = City::class; public function configure(): void { - $this->setPrimaryKey('id'); + $this->setPrimaryKey('id') + ->setAdditionalSelects(['id']); } public function columns(): array @@ -44,4 +48,15 @@ class CityTable extends DataTableComponent return City::query() ->whereHas('country', fn($query) => $query->where('code', $this->country)); } + + public function proximitySearch($id) + { + $city = City::query() + ->find($id); + $query = City::radius($city->latitude, $city->longitude, 100) + ->where('id', '!=', $id); + $this->notification() + ->success('Proximity Search', 'Found '.$query->count().' cities. '.$query->pluck('name') + ->implode(', ')); + } } diff --git a/app/Http/Livewire/Tables/EventTable.php b/app/Http/Livewire/Tables/EventTable.php index 94fafb8f..9d8f8d0b 100644 --- a/app/Http/Livewire/Tables/EventTable.php +++ b/app/Http/Livewire/Tables/EventTable.php @@ -38,12 +38,12 @@ class EventTable extends DataTableComponent ->sortable(), Column::make("Zuletzt geändert", "updated_at") ->sortable(), - Column::make("Teilnehmer") + /*Column::make("Teilnehmer") ->label( fn($row, Column $column) => ''.$row->registrations->count().'' ) ->html() - ->sortable(), + ->sortable(),*/ Column::make('') ->label( fn($row, Column $column) => view('columns.events.action')->withRow($row) diff --git a/app/Models/City.php b/app/Models/City.php index a2497f1e..0192fb8a 100644 --- a/app/Models/City.php +++ b/app/Models/City.php @@ -2,6 +2,7 @@ namespace App\Models; +use Akuechler\Geoly; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Spatie\Sluggable\HasSlug; @@ -11,6 +12,7 @@ class City extends Model { use HasFactory; use HasSlug; + use Geoly; /** * The attributes that aren't mass assignable. diff --git a/app/Nova/City.php b/app/Nova/City.php index 848f9f8f..0cb212b1 100644 --- a/app/Nova/City.php +++ b/app/Nova/City.php @@ -2,30 +2,28 @@ namespace App\Nova; -use Laravel\Nova\Fields\ID; use Illuminate\Http\Request; -use Laravel\Nova\Fields\Text; use Laravel\Nova\Fields\BelongsTo; +use Laravel\Nova\Fields\ID; +use Laravel\Nova\Fields\Number; +use Laravel\Nova\Fields\Text; class City extends Resource { /** * The model the resource corresponds to. - * * @var string */ public static $model = \App\Models\City::class; /** * The single value that should be used to represent the resource when being displayed. - * * @var string */ public static $title = 'name'; /** * The columns that should be searched. - * * @var array */ public static $search = [ @@ -37,12 +35,14 @@ class City extends Resource * Get the fields displayed by the resource. * * @param \Illuminate\Http\Request $request + * * @return array */ public function fields(Request $request) { return [ - ID::make()->sortable(), + ID::make() + ->sortable(), Text::make('Name') ->rules('required', 'string'), @@ -50,6 +50,12 @@ class City extends Resource Text::make('Slug') ->exceptOnForms(), + Number::make('Latitude') + ->rules('required', 'numeric')->step(0.00001), + + Number::make('Longitude') + ->rules('required', 'numeric')->step(0.00001), + BelongsTo::make('Country'), ]; @@ -59,6 +65,7 @@ class City extends Resource * Get the cards available for the request. * * @param \Illuminate\Http\Request $request + * * @return array */ public function cards(Request $request) @@ -70,6 +77,7 @@ class City extends Resource * Get the filters available for the resource. * * @param \Illuminate\Http\Request $request + * * @return array */ public function filters(Request $request) @@ -81,6 +89,7 @@ class City extends Resource * Get the lenses available for the resource. * * @param \Illuminate\Http\Request $request + * * @return array */ public function lenses(Request $request) @@ -92,6 +101,7 @@ class City extends Resource * Get the actions available for the resource. * * @param \Illuminate\Http\Request $request + * * @return array */ public function actions(Request $request) diff --git a/app/Policies/CityPolicy.php b/app/Policies/CityPolicy.php index 790d254b..6abe0dd5 100644 --- a/app/Policies/CityPolicy.php +++ b/app/Policies/CityPolicy.php @@ -53,7 +53,7 @@ class CityPolicy */ public function update(User $user, City $city) { - // + return $user->is_lecturer; } /** diff --git a/composer.json b/composer.json index af375965..d5215b34 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "license": "MIT", "require": { "php": "^8.1", + "akuechler/laravel-geoly": "^1.0", "ezadr/lnurl-php": "^1.0", "guzzlehttp/guzzle": "^7.2", "itsmejoshua/novaspatiepermissions": "^1.0", diff --git a/composer.lock b/composer.lock index 228f4843..a6fb242a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,66 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d1978838425670301ad666b43b7517ec", + "content-hash": "b619fdadb0135e8be1b5114237433108", "packages": [ + { + "name": "akuechler/laravel-geoly", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/akuechler/laravel-geoly.git", + "reference": "07b76c573abe1049d9a3f65ee870649443903dbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/akuechler/laravel-geoly/zipball/07b76c573abe1049d9a3f65ee870649443903dbf", + "reference": "07b76c573abe1049d9a3f65ee870649443903dbf", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "orchestra/testbench": "^6.0@dev", + "phpunit/phpunit": "^9.2@dev" + }, + "type": "library", + "autoload": { + "psr-4": { + "Akuechler\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexsander Küchler", + "email": "composer@alexsander-kuechler.com" + } + ], + "description": "Perform fast and efficient radius searches on your Laravel Eloquent models.", + "keywords": [ + "distance", + "framework", + "geo", + "laravel", + "lat", + "latitude", + "lng", + "lon", + "longitude", + "models", + "radius", + "search" + ], + "support": { + "issues": "https://github.com/akuechler/laravel-geoly/issues", + "source": "https://github.com/akuechler/laravel-geoly/tree/v1.0.6" + }, + "time": "2021-04-20T07:17:32+00:00" + }, { "name": "bacon/bacon-qr-code", "version": "2.0.7", diff --git a/database/migrations/2022_12_01_210526_add_geo_fields_to_cities_table.php b/database/migrations/2022_12_01_210526_add_geo_fields_to_cities_table.php new file mode 100644 index 00000000..57f66685 --- /dev/null +++ b/database/migrations/2022_12_01_210526_add_geo_fields_to_cities_table.php @@ -0,0 +1,30 @@ +double('longitude'); + $table->double('latitude'); + }); + } + + /** + * Reverse the migrations. + * @return void + */ + public function down() + { + Schema::table('cities', function (Blueprint $table) { + // + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 92d40c52..5f2c346d 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -61,14 +61,20 @@ class DatabaseSeeder extends Seeder City::create([ 'country_id' => 1, 'name' => 'Füssen', + 'latitude' => 47.57143, + 'longitude' => 10.70171, ]); City::create([ 'country_id' => 2, 'name' => 'Wien', + 'latitude' => 48.20835, + 'longitude' => 16.37250, ]); City::create([ 'country_id' => 3, 'name' => 'Zürich', + 'latitude' => 47.41330, + 'longitude' => 8.65639, ]); Venue::create([ 'city_id' => 1, diff --git a/resources/views/columns/cities/action.blade.php b/resources/views/columns/cities/action.blade.php index 3593ff56..89101821 100644 --- a/resources/views/columns/cities/action.blade.php +++ b/resources/views/columns/cities/action.blade.php @@ -1 +1 @@ -Umkreis-Suche Füssen +Umkreis-Suche {{ $row->name }} (100km) diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 64a46575..9b2dd330 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -7,8 +7,43 @@
-
- HIER KOMMEN QUICK LINKS FÜR DOZENTEN TEAMS REIN +
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 18a31b20..9423a227 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -1,41 +1,44 @@ - - - - - {{ config('app.name', 'Laravel') }} - - @googlefonts - - - @vite(['resources/css/app.css', 'resources/js/app.js']) - - @livewireStyles - - - - -
- @auth - @livewire('navigation-menu') - @endauth - - @if (isset($header)) -
-
- {{ $header }} -
-
- @endif - -
- {{ $slot }} -
-
- @stack('modals') - @livewireScripts - + + + + + {{ config('app.name', 'Laravel') }} + + @googlefonts + + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + @livewireStyles + + + + + +
+ @auth + @livewire('navigation-menu') + @endauth + + @if (isset($header)) +
+
+ {{ $header }} +
+
+ @endif + +
+ {{ $slot }} +
+
+@stack('modals') +@livewireScripts + diff --git a/resources/views/layouts/guest.blade.php b/resources/views/layouts/guest.blade.php index a52c03a3..d419cadd 100644 --- a/resources/views/layouts/guest.blade.php +++ b/resources/views/layouts/guest.blade.php @@ -8,15 +8,18 @@ @googlefonts - + @vite(['resources/css/app.css', 'resources/js/app.js']) @livewireStyles + {{ $slot }} @stack('modals') @livewireScripts diff --git a/resources/views/navigation-menu.blade.php b/resources/views/navigation-menu.blade.php index ea30f6dc..42a6f9e7 100644 --- a/resources/views/navigation-menu.blade.php +++ b/resources/views/navigation-menu.blade.php @@ -1,6 +1,6 @@