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 @@
-