refactor(livewire): organizar componentes y vistas por dominio en subnamespaces

- app/Livewire: 34 componentes agrupados en Issues/, Projects/, Phases/,
  Companies/, Users/, Admin/, Inspections/, Layers/, Media/, Common/
  (Client/, Reports/, Forms/, Actions/ ya estaban). Namespaces actualizados.
- resources/views/livewire: vistas sueltas movidas a subcarpetas espejo
  (companies/, users/, phases/, roles/, inspections/, media/, common/);
  render() actualizado.
- Referencias actualizadas sin romper nada: rutas (FQN, nombres de ruta intactos),
  tags <livewire:...>/@livewire() a alias con punto, y use de los tests.
- No tocado: Volt de Breeze (auth/profile/navigation), y el portal cliente
  (user-nav/client-projects) que ya tenía referencias inconsistentes.

Verificado: 69 rutas OK, vistas compilan, suite 69 passing (solo 2 pre-existentes
sqlite). autoload regenerado con --ignore-platform-reqs (PHP 8.2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-19 16:54:09 +02:00
parent 9c164bb7ef
commit 7d390872c3
68 changed files with 191 additions and 107 deletions
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Admin;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Admin;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -102,7 +102,7 @@ class RolePermissionManager extends Component
public function render() public function render()
{ {
return view('livewire.role-permission-manager', [ return view('livewire.roles.role-permission-manager', [
'roles' => Role::with('permissions')->orderBy('name')->get(), 'roles' => Role::with('permissions')->orderBy('name')->get(),
'permissions' => Permission::orderBy('name')->get(), 'permissions' => Permission::orderBy('name')->get(),
]); ]);
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Admin;
use Rappasoft\LaravelLivewireTables\DataTableComponent; use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column; use Rappasoft\LaravelLivewireTables\Views\Column;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Admin;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Common;
use Livewire\Component; use Livewire\Component;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
@@ -38,6 +38,6 @@ class LanguageSwitcher extends Component
public function render() public function render()
{ {
return view('livewire.language-switcher'); return view('livewire.common.language-switcher');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Common;
use Livewire\Component; use Livewire\Component;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@@ -37,6 +37,6 @@ class NotificationBell extends Component
public function render() public function render()
{ {
return view('livewire.notification-bell'); return view('livewire.common.notification-bell');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Companies;
use Livewire\Component; use Livewire\Component;
use Livewire\WithFileUploads; use Livewire\WithFileUploads;
@@ -101,6 +101,6 @@ class CompanyForm extends Component
public function render() public function render()
{ {
return view('livewire.company-form'); return view('livewire.companies.company-form');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Companies;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -62,6 +62,6 @@ class CompanyManagement extends Component
public function render() public function render()
{ {
return view('livewire.company-management'); return view('livewire.companies.company-management');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Companies;
use Rappasoft\LaravelLivewireTables\DataTableComponent; use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column; use Rappasoft\LaravelLivewireTables\Views\Column;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Companies;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -152,6 +152,6 @@ class CompanyView extends Component
public function render() public function render()
{ {
return view('livewire.company-view'); return view('livewire.companies.company-view');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Inspections;
use Livewire\Component; use Livewire\Component;
use Livewire\WithFileUploads; use Livewire\WithFileUploads;
@@ -430,6 +430,6 @@ class TemplateManager extends Component
public function render() public function render()
{ {
return view('livewire.template-manager'); return view('livewire.inspections.template-manager');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Issues;
use App\Models\IssueChecklistTemplate; use App\Models\IssueChecklistTemplate;
use App\Models\Project; use App\Models\Project;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Issues;
use App\Models\Issue; use App\Models\Issue;
use App\Models\IssueChecklistTemplate; use App\Models\IssueChecklistTemplate;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Issues;
use App\Models\Issue; use App\Models\Issue;
use App\Models\Project; use App\Models\Project;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Issues;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Issues;
use App\Models\Issue; use App\Models\Issue;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Layers;
use Livewire\Component; use Livewire\Component;
use Livewire\WithFileUploads; use Livewire\WithFileUploads;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Media;
use Livewire\Component; use Livewire\Component;
use Livewire\WithFileUploads; use Livewire\WithFileUploads;
@@ -160,7 +160,7 @@ class MediaManager extends Component
public function render() public function render()
{ {
return view('livewire.media-manager', [ return view('livewire.media.media-manager', [
'entityName' => class_basename($this->entity) . ': ' . ($this->entity->name ?? $this->entity->id), 'entityName' => class_basename($this->entity) . ': ' . ($this->entity->name ?? $this->entity->id),
'images' => $this->mediaItems->filter(fn($m) => $m->is_image), 'images' => $this->mediaItems->filter(fn($m) => $m->is_image),
'documents' => $this->mediaItems->filter(fn($m) => !$m->is_image), 'documents' => $this->mediaItems->filter(fn($m) => !$m->is_image),
@@ -1,5 +1,5 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Phases;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
use App\Models\Project; use App\Models\Project;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Phases;
use App\Models\Phase; use App\Models\Phase;
use App\Models\Project; use App\Models\Project;
@@ -137,6 +137,6 @@ class PhaseList extends Component
public function render() public function render()
{ {
return view('livewire.phase-list'); return view('livewire.phases.phase-list');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Phases;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -37,6 +37,6 @@ class PhaseProgress extends Component
public function render() public function render()
{ {
return view('livewire.phase-progress'); return view('livewire.phases.phase-progress');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Phases;
use App\Models\Phase; use App\Models\Phase;
use App\Models\Project; use App\Models\Project;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use App\Models\Company; use App\Models\Company;
use App\Models\Project; use App\Models\Project;
@@ -56,7 +56,7 @@ class ProjectCompanies extends Component
public function render() public function render()
{ {
return view('livewire.project-companies', [ return view('livewire.projects.project-companies', [
'roles' => ProjectCompaniesTable::ROLES, 'roles' => ProjectCompaniesTable::ROLES,
]); ]);
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use App\Models\Company; use App\Models\Company;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use Livewire\Component; use Livewire\Component;
use Livewire\WithPagination; use Livewire\WithPagination;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use Livewire\Component; use Livewire\Component;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use Rappasoft\LaravelLivewireTables\DataTableComponent; use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column; use Rappasoft\LaravelLivewireTables\Views\Column;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use App\Models\Project; use App\Models\Project;
use App\Models\User; use App\Models\User;
@@ -56,7 +56,7 @@ class ProjectUsers extends Component
public function render() public function render()
{ {
return view('livewire.project-users', [ return view('livewire.projects.project-users', [
'roles' => ProjectUsersTable::ROLES, 'roles' => ProjectUsersTable::ROLES,
]); ]);
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Projects;
use App\Models\User; use App\Models\User;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Users;
use Livewire\Component; use Livewire\Component;
use App\Models\User; use App\Models\User;
@@ -41,6 +41,6 @@ class AdminUsers extends Component
public function render() public function render()
{ {
return view('livewire.admin-users'); return view('livewire.users.admin-users');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Users;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -173,6 +173,6 @@ class UserForm extends Component
public function render() public function render()
{ {
return view('livewire.user-form'); return view('livewire.users.user-form');
} }
} }
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Users;
use Rappasoft\LaravelLivewireTables\DataTableComponent; use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column; use Rappasoft\LaravelLivewireTables\Views\Column;
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Livewire; namespace App\Livewire\Users;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
@@ -149,7 +149,7 @@ class UserView extends Component
return $i === false ? 999 : $i; return $i === false ? 999 : $i;
}); });
return view('livewire.user-view', [ return view('livewire.users.user-view', [
'grouped' => $grouped, 'grouped' => $grouped,
'directPerms' => $this->user->getDirectPermissions()->pluck('name')->toArray(), 'directPerms' => $this->user->getDirectPermissions()->pluck('name')->toArray(),
'rolePerms' => $this->user->getPermissionsViaRoles()->pluck('name')->toArray(), 'rolePerms' => $this->user->getPermissionsViaRoles()->pluck('name')->toArray(),
+1 -1
View File
@@ -18,7 +18,7 @@
<div class="py-12"> <div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white rounded-lg shadow p-6"> <div class="bg-white rounded-lg shadow p-6">
<livewire:role-table /> <livewire:admin.role-table />
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -20,7 +20,7 @@
<div class="py-12"> <div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white rounded-lg shadow p-6"> <div class="bg-white rounded-lg shadow p-6">
<livewire:user-table /> <livewire:users.user-table />
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -84,7 +84,7 @@
</div> </div>
</div> </div>
<div class="hidden md:block"> <div class="hidden md:block">
@livewire('language-switcher') @livewire('common.language-switcher')
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -17,7 +17,7 @@
<body class="font-sans text-gray-900 antialiased"> <body class="font-sans text-gray-900 antialiased">
<div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100"> <div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100">
<div class="mb-4 text-center"> <div class="mb-4 text-center">
@livewire('language-switcher') @livewire('common.language-switcher')
</div> </div>
<div> <div>
<a href="/" wire:navigate> <a href="/" wire:navigate>
@@ -21,7 +21,7 @@
{{ __('New Company') }} {{ __('New Company') }}
</a> </a>
</div> </div>
<livewire:company-table /> <livewire:companies.company-table />
</div> </div>
</div> </div>
@@ -60,5 +60,5 @@
{{-- ================================================================ {{-- ================================================================
ISSUES TABLE (Rappasoft) ISSUES TABLE (Rappasoft)
================================================================ --}} ================================================================ --}}
<livewire:issue-table :project-id="$project->id" :key="'issue-table-'.$project->id" /> <livewire:issues.issue-table :project-id="$project->id" :key="'issue-table-'.$project->id" />
</div> </div>
@@ -60,12 +60,12 @@ new class extends Component
<!-- Language Switcher --> <!-- Language Switcher -->
<div class="hidden sm:flex sm:items-center sm:ms-6"> <div class="hidden sm:flex sm:items-center sm:ms-6">
@livewire('language-switcher') @livewire('common.language-switcher')
</div> </div>
<!-- Notification Bell --> <!-- Notification Bell -->
<div class="hidden sm:flex sm:items-center sm:ms-2"> <div class="hidden sm:flex sm:items-center sm:ms-2">
@livewire('notification-bell') @livewire('common.notification-bell')
</div> </div>
<!-- Settings Dropdown --> <!-- Settings Dropdown -->
@@ -127,7 +127,7 @@ new class extends Component
<div class="mt-3 space-y-1"> <div class="mt-3 space-y-1">
<div class="mb-2 text-center text-sm"> <div class="mb-2 text-center text-sm">
@livewire('language-switcher') @livewire('common.language-switcher')
</div> </div>
<x-responsive-nav-link :href="route('profile')" wire:navigate> <x-responsive-nav-link :href="route('profile')" wire:navigate>
{{ __('Profile') }} {{ __('Profile') }}
@@ -12,7 +12,7 @@
</div> </div>
{{-- Tabla Rappasoft de fases --}} {{-- Tabla Rappasoft de fases --}}
<livewire:phase-table :project-id="$project->id" :key="'phase-table-'.$project->id" /> <livewire:phases.phase-table :project-id="$project->id" :key="'phase-table-'.$project->id" />
{{-- ================================================================ {{-- ================================================================
MODAL crear / editar fase MODAL crear / editar fase
@@ -25,5 +25,5 @@
@endcan @endcan
{{-- Tabla Rappasoft de empresas asignadas --}} {{-- Tabla Rappasoft de empresas asignadas --}}
<livewire:project-companies-table :project-id="$project->id" :key="'project-companies-table-'.$project->id" /> <livewire:projects.project-companies-table :project-id="$project->id" :key="'project-companies-table-'.$project->id" />
</div> </div>
@@ -21,13 +21,13 @@
@include('livewire.projects.partials.project-data-form') @include('livewire.projects.partials.project-data-form')
</div> </div>
<div x-show="tab==='phases'" x-cloak> <div x-show="tab==='phases'" x-cloak>
<livewire:phase-list :project="$project" :key="'phases-'.$project->id" /> <livewire:phases.phase-list :project="$project" :key="'phases-'.$project->id" />
</div> </div>
<div x-show="tab==='users'" x-cloak> <div x-show="tab==='users'" x-cloak>
<livewire:project-users :project="$project" :key="'users-'.$project->id" /> <livewire:projects.project-users :project="$project" :key="'users-'.$project->id" />
</div> </div>
<div x-show="tab==='companies'" x-cloak> <div x-show="tab==='companies'" x-cloak>
<livewire:project-companies :project="$project" :key="'companies-'.$project->id" /> <livewire:projects.project-companies :project="$project" :key="'companies-'.$project->id" />
</div> </div>
</div> </div>
@else @else
@@ -30,7 +30,7 @@
📎 {{ __("Files of element") }} 📎 {{ __("Files of element") }}
</summary> </summary>
<div class="p-2"> <div class="p-2">
@livewire('media-manager', [ @livewire('media.media-manager', [
'mediableType' => 'App\\Models\\Feature', 'mediableType' => 'App\\Models\\Feature',
'mediableId' => $selectedFeature->id, 'mediableId' => $selectedFeature->id,
], key('media-feature-' . $selectedFeature->id)) ], key('media-feature-' . $selectedFeature->id))
@@ -181,7 +181,7 @@
<x-heroicon-o-paper-clip class="w-4 h-4 inline" /> {{ __('Files of element') }} <x-heroicon-o-paper-clip class="w-4 h-4 inline" /> {{ __('Files of element') }}
</summary> </summary>
<div class="p-2"> <div class="p-2">
@livewire('media-manager', [ @livewire('media.media-manager', [
'mediableType' => 'App\\Models\\Feature', 'mediableType' => 'App\\Models\\Feature',
'mediableId' => $selectedFeature->id, 'mediableId' => $selectedFeature->id,
], key('media-feature-' . $selectedFeature->id)) ], key('media-feature-' . $selectedFeature->id))
@@ -351,7 +351,7 @@
@endif @endif
@elseif($activeTab === 'issues') @elseif($activeTab === 'issues')
<!-- Issues tab: render embedded IssueManager component --> <!-- Issues tab: render embedded IssueManager component -->
@livewire('issue-manager', ['project' => $project], key('issues-tab-' . $project->id)) @livewire('issues.issue-manager', ['project' => $project], key('issues-tab-' . $project->id))
@endif @endif
</div> </div>
@@ -25,5 +25,5 @@
@endcan @endcan
{{-- Tabla Rappasoft de usuarios asignados --}} {{-- Tabla Rappasoft de usuarios asignados --}}
<livewire:project-users-table :project-id="$project->id" :key="'project-users-table-'.$project->id" /> <livewire:projects.project-users-table :project-id="$project->id" :key="'project-users-table-'.$project->id" />
</div> </div>
@@ -320,6 +320,90 @@
</div> </div>
</div> </div>
{{-- Validez y estado --}}
<div class="card bg-base-100 shadow">
<div class="card-body p-6">
<h3 class="font-semibold text-base flex items-center gap-2 mb-4">
<x-heroicon-o-calendar-days class="w-5 h-5 text-primary" />
Validez de acceso
</h3>
<div class="space-y-3 text-sm">
<div class="flex justify-between items-center py-2 border-b border-base-200">
<span class="text-gray-500">Estado</span>
<span class="badge {{ $statusBadge[0] }}">{{ $statusBadge[1] }}</span>
</div>
<div class="flex justify-between items-center py-2 border-b border-base-200">
<span class="text-gray-500">Válido desde</span>
<span class="font-medium">
{{ $user->valid_from ? $user->valid_from->format('d/m/Y') : '— (sin límite)' }}
</span>
</div>
<div class="flex justify-between items-center py-2 border-b border-base-200">
<span class="text-gray-500">Válido hasta</span>
<span class="font-medium {{ isset($isExpired) && $isExpired ? 'text-error font-bold' : '' }}">
{{ $user->valid_until ? $user->valid_until->format('d/m/Y') : '— (sin límite)' }}
</span>
</div>
<div class="flex justify-between items-center py-2">
<span class="text-gray-500">Email verificado</span>
@if($user->email_verified_at)
<span class="flex items-center gap-1 text-success text-xs font-medium">
<x-heroicon-o-check-circle class="w-4 h-4" />
{{ $user->email_verified_at->format('d/m/Y') }}
</span>
@else
<span class="text-warning text-xs flex items-center gap-1">
<x-heroicon-o-clock class="w-4 h-4" />
Pendiente
</span>
@endif
</div>
</div>
</div>
</div>
{{-- Empresa --}}
@if($user->company)
<div class="card bg-base-100 shadow md:col-span-2">
<div class="card-body p-6">
<h3 class="font-semibold text-base flex items-center gap-2 mb-3">
<x-heroicon-o-building-office-2 class="w-5 h-5 text-primary" />
Empresa
</h3>
<div class="flex items-center gap-4">
@if($user->company->logo_path && \Illuminate\Support\Facades\Storage::disk('public')->exists($user->company->logo_path))
<img src="{{ \Illuminate\Support\Facades\Storage::disk('public')->url($user->company->logo_path) }}"
class="w-14 h-14 object-contain border border-base-300 rounded-lg" alt="" />
@else
<div class="w-14 h-14 bg-base-200 rounded-lg flex items-center justify-center">
<x-heroicon-o-building-office class="w-7 h-7 opacity-30" />
</div>
@endif
<div>
<p class="font-semibold">{{ $user->company->name }}</p>
@if($user->company->apodo)
<p class="text-sm text-gray-500">{{ $user->company->apodo }}</p>
@endif
@if($user->company->email)
<p class="text-xs text-gray-400">{{ $user->company->email }}</p>
@endif
</div>
@php
$typeBadge = match($user->company->type) {
'owner' => ['badge-success', 'Promotor'],
'constructor' => ['badge-primary', 'Constructor'],
'subcontractor' => ['badge-secondary','Subcontratista'],
'consultant' => ['badge-info', 'Consultor'],
'supplier' => ['badge-warning', 'Proveedor'],
default => ['badge-ghost', 'Otro'],
};
@endphp
<span class="badge {{ $typeBadge[0] }} ml-auto">{{ $typeBadge[1] }}</span>
</div>
</div>
</div>
@endif
{{-- Permisos directos del usuario --}} {{-- Permisos directos del usuario --}}
<div class="card bg-base-100 shadow md:col-span-2"> <div class="card bg-base-100 shadow md:col-span-2">
<div class="card-body p-6"> <div class="card-body p-6">
+1 -1
View File
@@ -22,7 +22,7 @@
@endif @endif
<div class="bg-white rounded-xl shadow p-6"> <div class="bg-white rounded-xl shadow p-6">
<livewire:project-table /> <livewire:projects.project-table />
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -1,5 +1,5 @@
<x-app-layout> <x-app-layout>
<div class="relative"> <div class="relative">
<livewire:project-map :project="$project" /> <livewire:projects.project-map :project="$project" />
</div> </div>
</x-app-layout> </x-app-layout>
+1 -1
View File
@@ -11,7 +11,7 @@
<a href="{{ route('projects.map', $project) }}" class="btn btn-outline btn-sm"> {{ __('Back to map') }}</a> <a href="{{ route('projects.map', $project) }}" class="btn btn-outline btn-sm"> {{ __('Back to map') }}</a>
</div> </div>
@livewire('media-manager', [ @livewire('media.media-manager', [
'mediableType' => 'App\Models\Project', 'mediableType' => 'App\Models\Project',
'mediableId' => $project->id, 'mediableId' => $project->id,
]) ])
+24 -24
View File
@@ -4,10 +4,10 @@ use App\Http\Controllers\ProfileController;
use App\Livewire\Reports\ReportsDashboard; use App\Livewire\Reports\ReportsDashboard;
use App\Http\Controllers\ProjectController; use App\Http\Controllers\ProjectController;
use App\Http\Controllers\OfflineSyncController; use App\Http\Controllers\OfflineSyncController;
use App\Livewire\ProjectMap; use App\Livewire\Projects\ProjectMap;
use App\Livewire\ProjectList; use App\Livewire\Projects\ProjectList;
use App\Livewire\PhaseProgress; use App\Livewire\Phases\PhaseProgress;
use App\Livewire\PhaseGantt; use App\Livewire\Phases\PhaseGantt;
use App\Http\Controllers\ProjectReportController; use App\Http\Controllers\ProjectReportController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
@@ -97,8 +97,8 @@ Route::get('/reports/dashboard', ReportsDashboard::class)->name('reports.dashboa
// Gestión de proyectos // Gestión de proyectos
// ------------------------------------------------------------ // ------------------------------------------------------------
// Create/Edit handled by unified Livewire component // Create/Edit handled by unified Livewire component
Route::get('/projects/create', \App\Livewire\ProjectForm::class)->name('projects.create'); Route::get('/projects/create', \App\Livewire\Projects\ProjectForm::class)->name('projects.create');
Route::get('/projects/{project}/edit', \App\Livewire\ProjectForm::class)->name('projects.edit'); Route::get('/projects/{project}/edit', \App\Livewire\Projects\ProjectForm::class)->name('projects.edit');
Route::resource('projects', ProjectController::class)->except(['create', 'edit']); Route::resource('projects', ProjectController::class)->except(['create', 'edit']);
// Ruta personalizada para ver el mapa de un proyecto específico // Ruta personalizada para ver el mapa de un proyecto específico
Route::get('/projects/{project}/map', [ProjectController::class, 'map'])->name('projects.map'); Route::get('/projects/{project}/map', [ProjectController::class, 'map'])->name('projects.map');
@@ -111,21 +111,21 @@ Route::get('/reports/dashboard', ReportsDashboard::class)->name('reports.dashboa
})->name('projects.templates')->middleware('can:edit projects'); })->name('projects.templates')->middleware('can:edit projects');
// Rutas para el LayerManager: // Rutas para el LayerManager:
Route::get('/projects/{project}/phases/{phase}/layers/manage', \App\Livewire\LayerManager::class)->name('layers.manage'); Route::get('/projects/{project}/phases/{phase}/layers/manage', \App\Livewire\Layers\LayerManager::class)->name('layers.manage');
// Cronograma Gantt y reporte del proyecto // Cronograma Gantt y reporte del proyecto
Route::get('/projects/{project}/gantt', PhaseGantt::class)->name('projects.gantt'); Route::get('/projects/{project}/gantt', PhaseGantt::class)->name('projects.gantt');
Route::get('/projects/{project}/report', [ProjectReportController::class, 'show'])->name('projects.report'); Route::get('/projects/{project}/report', [ProjectReportController::class, 'show'])->name('projects.report');
// Issues del proyecto // Issues del proyecto
Route::get('/projects/{project}/issues', \App\Livewire\IssueManager::class)->name('projects.issues'); Route::get('/projects/{project}/issues', \App\Livewire\Issues\IssueManager::class)->name('projects.issues');
Route::get('/projects/{project}/issues/create', \App\Livewire\IssueForm::class)->name('projects.issues.create'); Route::get('/projects/{project}/issues/create', \App\Livewire\Issues\IssueForm::class)->name('projects.issues.create');
Route::get('/projects/{project}/issues/checklists', \App\Livewire\IssueChecklistManager::class)->name('projects.issues.checklists'); Route::get('/projects/{project}/issues/checklists', \App\Livewire\Issues\IssueChecklistManager::class)->name('projects.issues.checklists');
Route::get('/projects/{project}/issues/{issue}', \App\Livewire\IssueDetail::class)->name('projects.issues.show'); Route::get('/projects/{project}/issues/{issue}', \App\Livewire\Issues\IssueDetail::class)->name('projects.issues.show');
Route::get('/projects/{project}/issues/{issue}/edit', \App\Livewire\IssueForm::class)->name('projects.issues.edit'); Route::get('/projects/{project}/issues/{issue}/edit', \App\Livewire\Issues\IssueForm::class)->name('projects.issues.edit');
// Dashboard por proyecto // Dashboard por proyecto
Route::get('/projects/{project}/dashboard', \App\Livewire\ProjectDashboard::class)->name('projects.dashboard'); Route::get('/projects/{project}/dashboard', \App\Livewire\Projects\ProjectDashboard::class)->name('projects.dashboard');
// Cliente: portal cliente // Cliente: portal cliente
Route::middleware(['auth', 'role:client'])->prefix('client')->name('client.')->group(function () { Route::middleware(['auth', 'role:client'])->prefix('client')->name('client.')->group(function () {
@@ -137,24 +137,24 @@ Route::get('/reports/dashboard', ReportsDashboard::class)->name('reports.dashboa
// Admin: gestión de usuarios y roles (cada ruta protegida por su permiso) // Admin: gestión de usuarios y roles (cada ruta protegida por su permiso)
Route::prefix('admin')->name('admin.')->group(function () { Route::prefix('admin')->name('admin.')->group(function () {
Route::get('/users', function () { return view('admin.users'); })->middleware('can:view users')->name('users'); Route::get('/users', function () { return view('admin.users'); })->middleware('can:view users')->name('users');
Route::get('/users/create', \App\Livewire\UserForm::class)->middleware('can:create users')->name('users.create'); Route::get('/users/create', \App\Livewire\Users\UserForm::class)->middleware('can:create users')->name('users.create');
Route::get('/users/{user}', \App\Livewire\UserView::class)->middleware('can:view users')->name('users.show'); Route::get('/users/{user}', \App\Livewire\Users\UserView::class)->middleware('can:view users')->name('users.show');
Route::get('/users/{user}/edit', \App\Livewire\UserForm::class)->middleware('can:edit users')->name('users.edit'); Route::get('/users/{user}/edit', \App\Livewire\Users\UserForm::class)->middleware('can:edit users')->name('users.edit');
Route::get('/roles', function () { return view('admin.roles'); })->middleware('can:manage roles')->name('roles'); Route::get('/roles', function () { return view('admin.roles'); })->middleware('can:manage roles')->name('roles');
Route::get('/roles/create', \App\Livewire\RoleForm::class)->middleware('can:manage roles')->name('roles.create'); Route::get('/roles/create', \App\Livewire\Admin\RoleForm::class)->middleware('can:manage roles')->name('roles.create');
Route::get('/roles/{role}/edit', \App\Livewire\RoleForm::class)->middleware('can:manage roles')->name('roles.edit'); Route::get('/roles/{role}/edit', \App\Livewire\Admin\RoleForm::class)->middleware('can:manage roles')->name('roles.edit');
Route::get('/roles/{role}', \App\Livewire\RoleView::class)->middleware('can:manage roles')->name('roles.show'); Route::get('/roles/{role}', \App\Livewire\Admin\RoleView::class)->middleware('can:manage roles')->name('roles.show');
Route::get('/permissions', \App\Livewire\RolePermissionManager::class)->middleware('can:manage roles')->name('permissions'); Route::get('/permissions', \App\Livewire\Admin\RolePermissionManager::class)->middleware('can:manage roles')->name('permissions');
}); });
// Gestor de medios // Gestor de medios
Route::get('/projects/{project}/media', function (\App\Models\Project $project) { Route::get('/projects/{project}/media', function (\App\Models\Project $project) {
return view('projects.media', compact('project')); return view('projects.media', compact('project'));
})->name('projects.media'); })->name('projects.media');
Route::get('/companies', \App\Livewire\CompanyManagement::class)->name('companies.manage'); Route::get('/companies', \App\Livewire\Companies\CompanyManagement::class)->name('companies.manage');
Route::get('/companies/create', \App\Livewire\CompanyForm::class)->name('companies.create'); Route::get('/companies/create', \App\Livewire\Companies\CompanyForm::class)->name('companies.create');
Route::get('/companies/{company}', \App\Livewire\CompanyView::class)->name('companies.show'); Route::get('/companies/{company}', \App\Livewire\Companies\CompanyView::class)->name('companies.show');
Route::get('/companies/{company}/edit', \App\Livewire\CompanyForm::class)->name('companies.edit'); Route::get('/companies/{company}/edit', \App\Livewire\Companies\CompanyForm::class)->name('companies.edit');
// ------------------------------------------------------------ // ------------------------------------------------------------
// Sincronización offline (para trabajadores en campo) // Sincronización offline (para trabajadores en campo)
+3 -3
View File
@@ -2,9 +2,9 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Livewire\IssueChecklistManager; use App\Livewire\Issues\IssueChecklistManager;
use App\Livewire\IssueDetail; use App\Livewire\Issues\IssueDetail;
use App\Livewire\IssueForm; use App\Livewire\Issues\IssueForm;
use App\Models\Feature; use App\Models\Feature;
use App\Models\Issue; use App\Models\Issue;
use App\Models\IssueChecklistTemplate; use App\Models\IssueChecklistTemplate;
+2 -2
View File
@@ -2,8 +2,8 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Livewire\IssueManager; use App\Livewire\Issues\IssueManager;
use App\Livewire\IssueTable; use App\Livewire\Issues\IssueTable;
use App\Models\Issue; use App\Models\Issue;
use App\Models\Project; use App\Models\Project;
use App\Models\User; use App\Models\User;
+2 -2
View File
@@ -2,8 +2,8 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Livewire\PhaseList; use App\Livewire\Phases\PhaseList;
use App\Livewire\PhaseTable; use App\Livewire\Phases\PhaseTable;
use App\Models\Phase; use App\Models\Phase;
use App\Models\Project; use App\Models\Project;
use App\Models\User; use App\Models\User;
+4 -4
View File
@@ -2,10 +2,10 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Livewire\ProjectCompanies; use App\Livewire\Projects\ProjectCompanies;
use App\Livewire\ProjectCompaniesTable; use App\Livewire\Projects\ProjectCompaniesTable;
use App\Livewire\ProjectUsers; use App\Livewire\Projects\ProjectUsers;
use App\Livewire\ProjectUsersTable; use App\Livewire\Projects\ProjectUsersTable;
use App\Models\Company; use App\Models\Company;
use App\Models\Project; use App\Models\Project;
use App\Models\User; use App\Models\User;
+1 -1
View File
@@ -2,7 +2,7 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Livewire\UserForm; use App\Livewire\Users\UserForm;
use App\Models\Company; use App\Models\Company;
use App\Models\User; use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;