diff --git a/app/Livewire/LayerManager copy.php b/app/Livewire/LayerManager copy.php deleted file mode 100644 index 64c97c5..0000000 --- a/app/Livewire/LayerManager copy.php +++ /dev/null @@ -1,210 +0,0 @@ - 'required|file|mimes:geojson,kmz,kml,shp,dwg,zip|max:51200', - 'layerName' => 'required|string|max:255', - 'layerColor' => 'nullable|string|size:7', - ]; - - public function mount(Project $project, Phase $phase) - { - $this->project = $project; - $this->phase = $phase; - $this->loadLayers(); - if ($this->phase->project_id !== $this->project->id) { - abort(404); - } - // Por defecto todas visibles - $this->visibleLayers = $this->layers->pluck('id')->toArray(); - $this->emitInitialLayersData(); - } - - public function loadLayers() - { - $this->layers = Layer::where('phase_id', $this->phase->id)->latest()->get(); - // Eliminar de visibles las que ya no existen - $this->visibleLayers = array_intersect($this->visibleLayers, $this->layers->pluck('id')->toArray()); - } - - private function emitInitialLayersData() - { - $layersData = $this->layers->map(function($layer) { - return [ - 'id' => $layer->id, - 'geojson' => $layer->geojson_data, - 'color' => $layer->geojson_data['style']['color'] ?? '#3b82f6', - ]; - }); - $this->dispatch('initialLayersData', [ - 'layers' => $layersData, - 'visibleLayers' => $this->visibleLayers, - 'selectedLayerId' => $this->selectedLayer?->id, - ]); - } - - public function toggleLayerVisibility($layerId) - { - if ($this->selectedLayer && $this->selectedLayer->id == $layerId) { - session()->flash('info', 'No puedes ocultar la capa que estás editando.'); - return; - } - if (in_array($layerId, $this->visibleLayers)) { - $this->visibleLayers = array_diff($this->visibleLayers, [$layerId]); - } else { - $this->visibleLayers[] = $layerId; - } - $this->dispatch('visibilityChanged', $this->visibleLayers); - } - - public function selectLayer($layerId) - { - $this->selectedLayer = Layer::find($layerId); - if (!$this->selectedLayer) return; - // Asegurar que la capa seleccionada está visible - if (!in_array($layerId, $this->visibleLayers)) { - $this->visibleLayers[] = $layerId; - $this->dispatch('visibilityChanged', $this->visibleLayers); - } - $geojson = $this->selectedLayer->geojson_data; - $this->dispatch('layerSelectedForEdit', [ - 'layerId' => $layerId, - 'geojson' => $geojson, - 'color' => $geojson['style']['color'] ?? '#3b82f6', - ]); - session()->flash('info', 'Editando capa: ' . $this->selectedLayer->name); - } - - public function importFile() - { - $this->validate(); - $user = Auth::user(); - if (!$user->can('upload layers') && !$user->hasRole('Admin')) { - session()->flash('error', 'Sin permisos.'); - return; - } - - $projectDir = "uploads/projects/{$this->project->id}/layers"; - $originalPath = $this->uploadFile->store($projectDir, 'public'); - $geojson = SpatialFileConverter::convertToGeoJson($this->uploadFile); - if (!$geojson) { - session()->flash('error', 'Conversión fallida.'); - return; - } - $geojson['style'] = ['color' => $this->layerColor ?: '#3b82f6']; - - $layer = Layer::create([ - 'project_id' => $this->project->id, - 'phase_id' => $this->phase->id, - 'name' => $this->layerName, - 'geojson_data' => $geojson, - 'original_file' => $originalPath, - 'uploaded_by' => $user->id, - ]); - - $this->loadLayers(); - $this->visibleLayers[] = $layer->id; - $this->reset(['uploadFile', 'layerName']); - $this->emitInitialLayersData(); - session()->flash('message', 'Capa importada.'); - } - - public function createEmptyLayer() - { - $user = Auth::user(); - $emptyGeojson = [ - 'type' => 'FeatureCollection', - 'features' => [], - 'style' => ['color' => $this->layerColor ?: '#3b82f6'] - ]; - $layer = Layer::create([ - 'project_id' => $this->project->id, - 'phase_id' => $this->phase->id, - 'name' => $this->layerName ?: 'Nueva capa', - 'geojson_data' => $emptyGeojson, - 'original_file' => null, - 'uploaded_by' => $user->id, - ]); - $this->loadLayers(); - $this->visibleLayers[] = $layer->id; - $this->selectLayer($layer->id); - $this->emitInitialLayersData(); - session()->flash('message', 'Capa vacía creada y seleccionada.'); - } - - public function saveManualGeojson($geojsonString) - { - if (!$this->selectedLayer) { - session()->flash('error', 'No hay capa seleccionada.'); - return; - } - $geojson = json_decode($geojsonString, true); - if (json_last_error() !== JSON_ERROR_NONE) { - session()->flash('error', 'GeoJSON inválido.'); - return; - } - $geojson['style'] = ['color' => $this->layerColor ?: ($this->selectedLayer->geojson_data['style']['color'] ?? '#3b82f6')]; - $this->selectedLayer->geojson_data = $geojson; - $this->selectedLayer->save(); - - $this->loadLayers(); // recargar por si acaso - $this->selectLayer($this->selectedLayer->id); - $this->emitInitialLayersData(); - session()->flash('message', 'Capa guardada.'); - } - - public function deleteLayer($layerId) - { - $user = Auth::user(); - if (!$user->can('delete layers') && !$user->hasRole('Admin')) abort(403); - $layer = Layer::find($layerId); - if (!$layer) return; - if ($layer->original_file) Storage::disk('public')->delete($layer->original_file); - $layer->delete(); - $this->loadLayers(); - if ($this->selectedLayer && $this->selectedLayer->id == $layerId) { - $this->selectedLayer = null; - } - $this->emitInitialLayersData(); - session()->flash('message', 'Capa eliminada.'); - } - - public function cancelEditing() - { - $this->selectedLayer = null; - $this->dispatch('layerSelectedForEdit', null); - } - - public function render() - { - return view('livewire.layer-manager'); - } -} \ No newline at end of file diff --git a/app/Livewire/LayerManager.php b/app/Livewire/LayerManager.php index c1f7f20..7678f53 100644 --- a/app/Livewire/LayerManager.php +++ b/app/Livewire/LayerManager.php @@ -58,6 +58,9 @@ class LayerManager extends Component private function emitInitialLayersData() { $layersData = $this->layers->map(function($layer) { + // Usar el color guardado en BD o el color del formulario + $color = $layer->color ?: ($this->layerColor ?: '#3b82f6'); + // Construir FeatureCollection a partir de los features de esta capa $features = $layer->features->map(function($feature) { return [ @@ -76,13 +79,13 @@ class LayerManager extends Component $geojson = [ 'type' => 'FeatureCollection', 'features' => $features, - 'style' => ['color' => $this->layerColor ?: '#3b82f6'] // Podrías guardar el color en la tabla layers + 'style' => ['color' => $color] ]; return [ 'id' => $layer->id, 'geojson' => $geojson, - 'color' => $geojson['style']['color'], + 'color' => $color, ]; }); @@ -132,16 +135,17 @@ class LayerManager extends Component ]; })->values()->toArray(); + $color = $this->selectedLayer->color ?: ($this->layerColor ?: '#3b82f6'); $geojson = [ 'type' => 'FeatureCollection', 'features' => $features, - 'style' => ['color' => $this->layerColor ?: '#3b82f6'] + 'style' => ['color' => $color] ]; $this->dispatch('layerSelectedForEdit', [ 'layerId' => $layerId, 'geojson' => $geojson, - 'color' => $geojson['style']['color'], + 'color' => $color, ]); session()->flash('info', 'Editando capa: ' . $this->selectedLayer->name); } @@ -192,13 +196,14 @@ class LayerManager extends Component return; } - $geojson['style'] = ['color' => $this->layerColor ?: '#3b82f6']; + $layerColor = $this->layerColor ?: '#3b82f6'; + $geojson['style'] = ['color' => $layerColor]; $layer = Layer::create([ 'project_id' => $this->project->id, 'phase_id' => $this->phase->id, 'name' => $this->layerName, - //'geojson_data' => $geojson, + 'color' => $layerColor, 'original_file' => $originalPath, 'uploaded_by' => $user->id, ]); @@ -232,9 +237,9 @@ class LayerManager extends Component 'project_id' => $this->project->id, 'phase_id' => $this->phase->id, 'name' => $this->layerName ?: 'Nueva capa', + 'color' => $this->layerColor ?: '#3b82f6', 'original_file' => null, 'uploaded_by' => $user->id, - // Opcional: guarda el color en una columna 'color' de la tabla layers ]); $this->loadLayers(); $this->visibleLayers[] = $layer->id; diff --git a/app/Livewire/ProjectList.php b/app/Livewire/ProjectList.php index 038d070..52e3fb3 100644 --- a/app/Livewire/ProjectList.php +++ b/app/Livewire/ProjectList.php @@ -32,7 +32,7 @@ class ProjectList extends Component if ($this->statusFilter) { $query->where('status', $this->statusFilter); } - $projects = $query->latest()->paginate(10); + $projects = $query->with('phases')->latest()->paginate(10); return view('livewire.projects.project-list', ['projects' => $projects]); } } \ No newline at end of file diff --git a/app/Livewire/ProjectMap copy.php b/app/Livewire/ProjectMap copy.php deleted file mode 100644 index 509a3df..0000000 --- a/app/Livewire/ProjectMap copy.php +++ /dev/null @@ -1,227 +0,0 @@ -project = $project; - $this->phases = $project->phases()->with('currentLayer')->get(); - $this->activeLayers = $this->phases->pluck('id')->toArray(); - - $this->loadTemplates(); - } - - public function toggleLayer($phaseId) - { - if (in_array($phaseId, $this->activeLayers)) { - $this->activeLayers = array_diff($this->activeLayers, [$phaseId]); - } else { - $this->activeLayers[] = $phaseId; - } - $this->dispatch('layersUpdated', $this->activeLayers); - } - - public function updateProgress($featureId, $newProgress, $comment = null) - { - $feature = Feature::findOrFail($featureId); - $user = Auth::user(); - - if (!$user->can('update progress') && !$user->hasRole('Admin')) { - $this->dispatch('notify', 'Sin permisos'); - return; - } - - $feature->progress = min(100, max(0, $newProgress)); - $feature->save(); - - // Actualizar progreso de la fase (sumar promedio) - $phase = Phase::find($feature->layer->phase_id); - $phase->progress_percent = $phase->features()->avg('progress'); - $phase->save(); - - $phase->progressUpdates()->create([ - 'user_id' => $user->id, - 'progress_percent' => $phase->progress_percent, - 'comment' => $comment, - ]); - - $this->dispatch('progressUpdated', $featureId, $feature->progress); - $this->dispatch('notify', 'Progreso actualizado'); - $this->editProgress = $feature->progress; - } - - public function loadTemplates() - { - $this->templates = InspectionTemplate::where('project_id', $this->project->id)->get(); - } - - public function selectFeature($featureId, $featureProps) - { - $feature = Feature::with('template')->find($featureId); - if (!$feature) return; - - $this->selectedFeature = $feature; - $this->selectedPhaseId = $feature->layer->phase_id; - $this->editProgress = $feature->progress; - $this->editResponsible = $feature->responsible; - $this->selectedTemplateId = $feature->template_id; - - $this->loadInspectionHistory(); - $this->resetInspectionForm(); - - $this->dispatch('featureSelected', $featureId); - } - - public function saveFeatureProgress() - { - if (!$this->selectedFeature || !$this->selectedPhaseId) { - return; - } - $this->updateProgress($this->selectedPhaseId, $this->editProgress, $this->editComment); - $this->editComment = ''; - } - - public function resetInspectionForm() - { - $this->inspectionFormData = []; - if ($this->selectedTemplateId) { - $template = InspectionTemplate::find($this->selectedTemplateId); - if ($template) { - foreach ($template->fields as $field) { - $this->inspectionFormData[$field['name']] = ''; - } - } - } - } - - public function loadInspectionHistory() - { - if (!$this->selectedFeature || !$this->selectedPhaseId) { - $this->inspectionHistory = []; - return; - } - $layer = Phase::find($this->selectedPhaseId)->currentLayer; - if ($layer) { - $this->inspectionHistory = Inspection::where('layer_id', $layer->id) - ->where('feature_id', $this->selectedFeature['id']) - ->with('user', 'template') - ->orderBy('created_at', 'desc') - ->get(); - } - } - - public function saveInspection() - { - if (!$this->selectedFeature || !$this->selectedPhaseId) { - return; - } - $this->validate([ - 'selectedTemplateId' => 'required|exists:inspection_templates,id', - ]); - $layer = Phase::find($this->selectedPhaseId)->currentLayer; - if (!$layer) return; - - $inspection = Inspection::create([ - 'project_id' => $this->project->id, - 'layer_id' => $this->selectedFeature->layer_id, - 'feature_id' => $this->selectedFeature->id, - 'template_id' => $this->selectedTemplateId, - 'user_id' => auth()->id(), - 'data' => $this->inspectionFormData, - ]); - - // Opcional: actualizar el progreso del elemento en el GeoJSON - if (isset($this->inspectionFormData['progress'])) { - $this->updateProgress($this->selectedPhaseId, $this->inspectionFormData['progress'], 'Inspección registrada'); - } - - $this->loadInspectionHistory(); - $this->resetInspectionForm(); - $this->dispatch('notify', 'Inspección guardada'); - } - - public function updateFeatureTemplate($templateId) - { - // Actualizar el template asociado al elemento (podrías guardarlo en la capa GeoJSON) - if ($this->selectedFeature && $this->selectedPhaseId) { - $layer = Phase::find($this->selectedPhaseId)->currentLayer; - if ($layer) { - $geojson = $layer->geojson_data; - foreach ($geojson['features'] as &$feature) { - if ($feature['properties']['id'] == $this->selectedFeature['id']) { - $feature['properties']['template_id'] = $templateId; - break; - } - } - $layer->geojson_data = $geojson; - $layer->save(); - } - } - $this->selectedTemplateId = $templateId; - $this->resetInspectionForm(); - } - - public function toggleFullscreen() - { - $this->formFullscreen = !$this->formFullscreen; - if (!$this->formFullscreen) { - $this->dispatch('mapResize'); - } - } - - // Añadir al final de la clase ProjectMap - public function refreshTemplates() - { - $this->templates = InspectionTemplate::where('project_id', $this->project->id)->get(); - } - - // Asignar template ahora actualiza el campo template_id - public function assignTemplateToFeature($templateId) - { - if (!$this->selectedFeature) return; - $this->selectedFeature->template_id = $templateId; - $this->selectedFeature->save(); - $this->selectedTemplateId = $templateId; - $this->resetInspectionForm(); - $this->dispatch('notify', 'Template asignado'); - } - - public function render() - { - return view('livewire.projects.project-map', [ - 'project' => $this->project, - 'phases' => $this->phases, - ]); - } -} \ No newline at end of file diff --git a/app/Livewire/ProjectMap.php b/app/Livewire/ProjectMap.php index 8bfa047..4bc4481 100644 --- a/app/Livewire/ProjectMap.php +++ b/app/Livewire/ProjectMap.php @@ -16,6 +16,7 @@ class ProjectMap extends Component public Project $project; public $phases; public $activeLayers = []; + public $showLayerModal = false; // Editor properties public $selectedFeature = null; // será instancia de Feature @@ -57,6 +58,16 @@ class ProjectMap extends Component $this->dispatch('layersUpdated', $this->activeLayers); } + public function openLayerModal() + { + $this->showLayerModal = true; + } + + public function closeLayerModal() + { + $this->showLayerModal = false; + } + /** * Actualizar el progreso de un Feature y recalcular el progreso de la fase. */ diff --git a/app/Models/Layer.php b/app/Models/Layer.php index db4d01a..626ea92 100644 --- a/app/Models/Layer.php +++ b/app/Models/Layer.php @@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Model; class Layer extends Model { protected $fillable = [ - 'project_id', 'phase_id', 'name', 'geojson_data', 'original_file', 'uploaded_by' + 'project_id', 'phase_id', 'name', 'color', 'geojson_data', 'original_file', 'uploaded_by' ]; protected $casts = [ diff --git a/resources/views/livewire/layer-upload.blade.php b/resources/views/livewire/layer-upload.blade.php new file mode 100644 index 0000000..a388320 --- /dev/null +++ b/resources/views/livewire/layer-upload.blade.php @@ -0,0 +1,19 @@ +
Sin capas. Crea una o importa.
- @endif -{{ $phase->project->name ?? '' }}
+ +{{ $phase->progress_percent }}%
+{{ $update->comment }}
+ @endif +Configura las capas y elementos visibles del proyecto.
+