mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 11:51:11 -05:00
Implement LocationDisplayComponent and LocationMapComponent for interactive map features; add event handling and state management
This commit is contained in:
118
app/Livewire/Location/LocationDisplayComponent.php
Normal file
118
app/Livewire/Location/LocationDisplayComponent.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Location;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Models\Location;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class LocationDisplayComponent extends Component
|
||||
{
|
||||
// Map Configuration
|
||||
public array $markers = [];
|
||||
public bool $showClusters = true;
|
||||
public int $clusterRadius = 50;
|
||||
public int $defaultZoom = 13;
|
||||
public ?array $bounds = null;
|
||||
|
||||
// Display Settings
|
||||
public bool $showInfoWindow = false;
|
||||
public ?array $activeMarker = null;
|
||||
public array $customMarkers = [];
|
||||
public array $markerCategories = [];
|
||||
|
||||
// State Management
|
||||
public bool $isLoading = true;
|
||||
public ?string $error = null;
|
||||
public array $visibleMarkers = [];
|
||||
|
||||
// Lifecycle Hooks
|
||||
public function mount(array $markers = [], ?array $bounds = null, array $categories = [])
|
||||
{
|
||||
$this->markers = $markers;
|
||||
$this->bounds = $bounds;
|
||||
$this->markerCategories = $categories;
|
||||
$this->visibleMarkers = $markers;
|
||||
}
|
||||
|
||||
// Event Handlers
|
||||
public function markerClicked($markerId)
|
||||
{
|
||||
$this->activeMarker = collect($this->markers)->firstWhere('id', $markerId);
|
||||
$this->showInfoWindow = true;
|
||||
}
|
||||
|
||||
public function clusterClicked($clusterMarkers)
|
||||
{
|
||||
if (count($clusterMarkers) === 1) {
|
||||
$this->markerClicked($clusterMarkers[0]['id']);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->bounds = $this->calculateBounds($clusterMarkers);
|
||||
}
|
||||
|
||||
public function closeInfoWindow()
|
||||
{
|
||||
$this->showInfoWindow = false;
|
||||
$this->activeMarker = null;
|
||||
}
|
||||
|
||||
public function boundsChanged($bounds)
|
||||
{
|
||||
$this->bounds = $bounds;
|
||||
$this->visibleMarkers = $this->getVisibleMarkers($bounds);
|
||||
}
|
||||
|
||||
public function updateMarkersVisibility($visible)
|
||||
{
|
||||
$this->visibleMarkers = collect($this->markers)
|
||||
->filter(fn ($marker) => in_array($marker['id'], $visible))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
// Helper Methods
|
||||
protected function calculateBounds($markers): array
|
||||
{
|
||||
if (empty($markers)) {
|
||||
return [
|
||||
'north' => 0,
|
||||
'south' => 0,
|
||||
'east' => 0,
|
||||
'west' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$lats = array_column($markers, 'lat');
|
||||
$lons = array_column($markers, 'lng');
|
||||
|
||||
return [
|
||||
'north' => max($lats),
|
||||
'south' => min($lats),
|
||||
'east' => max($lons),
|
||||
'west' => min($lons),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getVisibleMarkers($bounds): array
|
||||
{
|
||||
if (!$bounds) {
|
||||
return $this->markers;
|
||||
}
|
||||
|
||||
return collect($this->markers)
|
||||
->filter(function ($marker) use ($bounds) {
|
||||
return $marker['lat'] >= $bounds['south'] &&
|
||||
$marker['lat'] <= $bounds['north'] &&
|
||||
$marker['lng'] >= $bounds['west'] &&
|
||||
$marker['lng'] <= $bounds['east'];
|
||||
})
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.location.location-display');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user