exists) { Gate::authorize('edit projects', $project); $this->project = $project; $this->name = $project->name; $this->reference = $project->reference ?? ''; $this->status = $project->status; $this->address = $project->address; $this->country = $project->country ?? ''; $this->lat = (string) ($project->lat ?? ''); $this->lng = (string) ($project->lng ?? ''); $this->startDate = $project->start_date->format('Y-m-d'); $this->endDateEstimated = $project->end_date_estimated?->format('Y-m-d') ?? ''; } else { Gate::authorize('create projects'); $this->startDate = today()->format('Y-m-d'); } } // Called from JS after map click / marker drag + reverse geocode public function setLocation(string $lat, string $lng, string $address = '', string $country = ''): void { $this->lat = $lat; $this->lng = $lng; if ($address) $this->address = $address; if ($country) $this->country = strtolower($country); } protected function rules(): array { return [ 'name' => 'required|string|max:255', 'reference' => 'nullable|string|max:100', 'status' => 'required|in:planning,in_progress,paused,completed', 'address' => 'required|string', 'country' => 'nullable|string|size:2', 'lat' => 'nullable|numeric|between:-90,90', 'lng' => 'nullable|numeric|between:-180,180', 'startDate' => 'required|date', 'endDateEstimated' => 'nullable|date|after_or_equal:startDate', ]; } protected $validationAttributes = [ 'name' => 'nombre', 'reference' => 'referencia', 'status' => 'estado', 'address' => 'dirección', 'country' => 'país', 'lat' => 'latitud', 'lng' => 'longitud', 'startDate' => 'fecha de inicio', 'endDateEstimated' => 'fecha de fin estimada', ]; public function save(): void { $this->validate(); $data = [ 'name' => $this->name, 'reference' => $this->reference ?: null, 'status' => $this->status, 'address' => $this->address, 'country' => $this->country ?: null, 'lat' => $this->lat ?: null, 'lng' => $this->lng ?: null, 'start_date' => $this->startDate, 'end_date_estimated' => $this->endDateEstimated ?: null, ]; if ($this->project && $this->project->exists) { $this->project->update($data); session()->flash('notify', 'Proyecto actualizado correctamente.'); } else { $project = Project::create(array_merge($data, ['created_by' => Auth::id()])); $project->users()->attach(Auth::id(), ['role_in_project' => 'supervisor']); session()->flash('notify', 'Proyecto creado correctamente.'); } $this->redirect(route('projects.index'), navigate: true); } public function render() { return view('livewire.projects.project-form', [ 'countryList' => $this->countryList(), ]); } /** * ISO alpha-2 (lowercase, matches flagcdn) => display name. */ private function countryList(): array { return [ 'es' => 'España', 'pt' => 'Portugal', 'fr' => 'Francia', 'it' => 'Italia', 'de' => 'Alemania', 'gb' => 'Reino Unido', 'ie' => 'Irlanda', 'nl' => 'Países Bajos', 'be' => 'Bélgica', 'ch' => 'Suiza', 'at' => 'Austria', 'lu' => 'Luxemburgo', 'se' => 'Suecia', 'no' => 'Noruega', 'dk' => 'Dinamarca', 'fi' => 'Finlandia', 'pl' => 'Polonia', 'cz' => 'Chequia', 'gr' => 'Grecia', 'ro' => 'Rumanía', 'us' => 'Estados Unidos', 'ca' => 'Canadá', 'mx' => 'México', 'gt' => 'Guatemala', 'cr' => 'Costa Rica', 'pa' => 'Panamá', 'co' => 'Colombia', 've' => 'Venezuela', 'ec' => 'Ecuador', 'pe' => 'Perú', 'bo' => 'Bolivia', 'cl' => 'Chile', 'ar' => 'Argentina', 'uy' => 'Uruguay', 'py' => 'Paraguay', 'br' => 'Brasil', 'do' => 'República Dominicana', 'ma' => 'Marruecos', 'gq' => 'Guinea Ecuatorial', 'ao' => 'Angola', 'cv' => 'Cabo Verde', 'us' => 'Estados Unidos', ]; } }