From 199fb487c274d4ff773351ab67b90ee5f24c76d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Bra=C3=B1a?= Date: Fri, 8 May 2026 01:16:20 +0200 Subject: [PATCH] fix: correcciones parciales - ProjectController, ProfileController, Phase features, project-map JS --- app/Http/Controllers/ProfileController.php | 55 +++++++++++++++++++ app/Http/Controllers/ProjectController.php | 5 +- app/Livewire/ProjectMap.php | 1 + app/Models/Phase.php | 8 +++ .../livewire/projects/project-map.blade.php | 43 +++++++++++---- 5 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 app/Http/Controllers/ProfileController.php diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php new file mode 100644 index 0000000..dfafa0c --- /dev/null +++ b/app/Http/Controllers/ProfileController.php @@ -0,0 +1,55 @@ +validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|max:255|unique:users,email,' . $user->id, + ]); + + $user->update($validated); + + return redirect()->route('profile')->with('success', 'Perfil actualizado.'); + } + + /** + * Delete the user's account. + */ + public function destroy(Request $request) + { + $request->validate([ + 'password' => ['required', 'current_password'], + ]); + + $user = Auth::user(); + Auth::logout(); + $user->delete(); + + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return redirect('/'); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 6b96a38..5429d5b 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -8,6 +8,7 @@ use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Gate; +use App\Models\Project; class ProjectController extends Controller { @@ -53,9 +54,9 @@ class ProjectController extends Controller /** * Display the specified resource. */ - public function show(string $id) + public function show(Project $project) { - // No usamos show, redirigimos al mapa o a edición + // No usamos show, redirigimos al mapa return redirect()->route('projects.map', $project); } diff --git a/app/Livewire/ProjectMap.php b/app/Livewire/ProjectMap.php index fee066c..8bfa047 100644 --- a/app/Livewire/ProjectMap.php +++ b/app/Livewire/ProjectMap.php @@ -101,6 +101,7 @@ class ProjectMap extends Component */ public function selectFeature($featureId) { + $this->selectedFeature = null; $feature = Feature::with('template')->find($featureId); if (!$feature) return; diff --git a/app/Models/Phase.php b/app/Models/Phase.php index 9633399..e3cb9d3 100644 --- a/app/Models/Phase.php +++ b/app/Models/Phase.php @@ -30,4 +30,12 @@ class Phase extends Model { return $this->hasOne(Layer::class)->latestOfMany(); } + + /** + * Get all features across all layers of this phase. + */ + public function features() + { + return $this->hasManyThrough(Feature::class, Layer::class); + } } \ No newline at end of file diff --git a/resources/views/livewire/projects/project-map.blade.php b/resources/views/livewire/projects/project-map.blade.php index 27989f6..ff3bbff 100644 --- a/resources/views/livewire/projects/project-map.blade.php +++ b/resources/views/livewire/projects/project-map.blade.php @@ -140,31 +140,50 @@ attribution: '© OpenStreetMap' }).addTo(map);*/ - // Add geojson layers for active phases + // Add geojson layers for active phases - features loaded from DB via features() relationship @foreach($phases as $phase) - const phase{{ $phase->id }}Data = @json($phase->currentLayer?->geojson_data); - if (phase{{ $phase->id }}Data) { + @php + $phaseFeatures = $phase->features()->with('layer')->get(); + $fc = [ + 'type' => 'FeatureCollection', + 'features' => $phaseFeatures->map(function($f) { + return [ + 'type' => 'Feature', + 'id' => $f->id, + 'geometry' => $f->geometry, + 'properties' => array_merge($f->properties ?? [], [ + 'name' => $f->name, + 'progress' => $f->progress, + 'responsible' => $f->responsible, + 'template_id' => $f->template_id, + '_feature_id' => $f->id, + ]) + ]; + })->values()->toArray() + ]; + @endphp + const phase{{ $phase->id }}Data = @json($fc); + if (phase{{ $phase->id }}Data && phase{{ $phase->id }}Data.features && phase{{ $phase->id }}Data.features.length > 0) { layers[{{ $phase->id }}] = L.geoJSON(phase{{ $phase->id }}Data, { style: { color: '{{ $phase->color }}', weight: 3, opacity: 0.8, fillOpacity: 0.3 }, onEachFeature: function (feature, layer) { - const props = feature.properties; + const props = feature.properties || {}; + const featId = props._feature_id || feature.id; let content = `${props.name || 'Elemento'}
Progreso: ${props.progress || 'N/A'}%
Responsable: ${props.responsible || '-'}
- - - `; + + `; layer.bindPopup(content); layer.on('click', function(e) { - @this.selectFeature(feature.properties.id, feature.properties); + @this.selectFeature(featId); }); } }); if (@json(in_array($phase->id, $activeLayers))) { layers[{{ $phase->id }}].addTo(map); } - } - @endforeach + // 🔁 Forzar que el mapa recalcule su tamaño (por si el contenedor no está visible al 100%) setTimeout(() => { @@ -242,8 +261,8 @@ } } - window.updatePhaseProgress = function(phaseId, progress) { - @this.updateProgress(phaseId, progress); + window.updateFeatureProgress = function(featureId, progress) { + @this.updateProgress(featureId, progress, 'Actualizado desde mapa'); } @endpush \ No newline at end of file