Files
thrillwiki_laravel/app/Livewire/Location/LocationDisplayComponent.php

118 lines
3.1 KiB
PHP

<?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');
}
}