'handleMapLocation', 'clearLocation' => 'clearSelection', ]; public function mount(GeocodeService $geocodeService) { $this->geocodeService = $geocodeService; } public function render() { return view('livewire.location.location-selector'); } public function updatedSearchQuery() { if (strlen($this->searchQuery) < 3) { $this->searchResults = []; $this->showSearchResults = false; return; } try { $this->isSearching = true; $this->searchResults = $this->geocodeService->geocode($this->searchQuery); $this->showSearchResults = true; $this->validationError = null; } catch (GeocodingException $e) { $this->validationError = $e->getMessage(); } finally { $this->isSearching = false; } } public function selectLocation(array $location) { try { if (!isset($location['lat'], $location['lon'])) { throw new ValidationException('Invalid location data'); } $this->setCoordinates($location['lat'], $location['lon']); $this->formattedAddress = $location['display_name'] ?? null; $this->showSearchResults = false; $this->searchQuery = ''; $this->isValidLocation = true; $this->validationError = null; $this->dispatch('locationSelected', [ 'latitude' => $this->latitude, 'longitude' => $this->longitude, 'address' => $this->formattedAddress, ]); } catch (ValidationException $e) { $this->validationError = $e->getMessage(); $this->isValidLocation = false; } } public function setCoordinates(float $lat, float $lon) { try { if (!$this->geocodeService->validateCoordinates($lat, $lon)) { throw new ValidationException('Invalid coordinates'); } $this->latitude = $lat; $this->longitude = $lon; $this->isValidLocation = true; $this->validationError = null; $this->dispatch('coordinatesChanged', [ 'latitude' => $this->latitude, 'longitude' => $this->longitude, ]); } catch (ValidationException $e) { $this->validationError = $e->getMessage(); $this->isValidLocation = false; } } public function handleMapLocation($lat, $lon) { $this->setCoordinates($lat, $lon); try { $address = $this->geocodeService->reverseGeocode($lat, $lon); $this->formattedAddress = $address['display_name'] ?? null; } catch (GeocodingException $e) { $this->validationError = $e->getMessage(); } } public function detectCurrentLocation() { $this->mode = 'current'; $this->isLoadingLocation = true; $this->dispatch('requestCurrentLocation'); } public function clearSelection() { $this->reset([ 'latitude', 'longitude', 'formattedAddress', 'isValidLocation', 'searchQuery', 'searchResults', 'showSearchResults', 'validationError', ]); $this->mode = 'search'; } public function switchMode(string $mode) { if (!in_array($mode, ['search', 'coordinates', 'current'])) { return; } $this->mode = $mode; $this->clearSelection(); $this->dispatch('modeChanged', ['mode' => $mode]); } protected function rules() { return [ 'latitude' => 'required|numeric|between:-90,90', 'longitude' => 'required|numeric|between:-180,180', 'searchQuery' => 'nullable|string|min:3|max:200', ]; } }