diff --git a/docs/Manual.docx b/docs/Manual.docx new file mode 100644 index 0000000..dc90462 Binary files /dev/null and b/docs/Manual.docx differ diff --git a/resources/views/livewire/projects/project-dashboard.blade.php b/resources/views/livewire/projects/project-dashboard.blade.php index b776b2a..ecf61c2 100644 --- a/resources/views/livewire/projects/project-dashboard.blade.php +++ b/resources/views/livewire/projects/project-dashboard.blade.php @@ -1,396 +1,406 @@
- -
-
- - - -
-

{{ $project->name }}

- @if($project->description) -

{{ Str::limit($project->description, 80) }}

- @endif + +
+ {{-- Izquierda: avatar + datos --}} +
+ {{-- Avatar --}} +
+

{{ $project->name }}

+ @if($project->description) +

{{ Str::limit($project->description, 80) }}

+ @endif +
+
+ + {{-- Derecha: estado + botones --}} +
+
+ + Volver + + {{-- Estado --}} + @php + $statusCfg = match($project->status) { + 'in_progress' => ['badge-primary', 'En progreso'], + 'completed' => ['badge-success', 'Completado'], + 'paused' => ['badge-warning', 'Pausado'], + 'planning' => ['badge-ghost', 'Planificación'], + default => ['badge-ghost', ucfirst(str_replace('_',' ',$project->status))], + }; + @endphp + {{ $statusCfg[1] }} +
+ {{-- Botones --}} +
- @php - $statusCfg = match($project->status) { - 'in_progress' => ['badge-primary', 'En progreso'], - 'completed' => ['badge-success', 'Completado'], - 'paused' => ['badge-warning', 'Pausado'], - 'planning' => ['badge-ghost', 'Planificación'], - default => ['badge-ghost', ucfirst(str_replace('_',' ',$project->status))], - }; - @endphp - {{ $statusCfg[1] }}
- -
- + -
-
+
+
- {{-- ── KPIs fila 1 ────────────────────────────────────────────────────── --}} -
+ {{-- ── KPIs fila 1 ────────────────────────────────────────────────────── --}} +
- {{-- Avance global --}} -
-
-
-
-

Avance global

-

{{ $stats['global_progress'] }}%

-
-
+ {{-- Avance global --}} +
+
+
+
+

Avance global

+

{{ $stats['global_progress'] }}%

+
+
+
+
+
+ +
-
- +
+ + {{-- Fases --}} +
+
+
+
+

Fases

+

{{ $stats['total_phases'] }}

+ @if($stats['delayed_phases'] > 0) +

{{ $stats['delayed_phases'] }} con retraso

+ @else +

Sin retrasos

+ @endif +
+
+ +
+
+
+
+ + {{-- Elementos --}} +
+
+
+
+

Elementos

+

{{ $stats['total_features'] }}

+

+ {{ $stats['completed_features'] }} completados + · {{ $stats['verified_features'] }} verificados +

+
+
+ +
+
+
+
+ + {{-- Issues --}} +
+
+
+
+

Issues abiertos

+

+ {{ $stats['open_issues'] }} +

+ @if($stats['critical_issues'] > 0) +

{{ $stats['critical_issues'] }} críticos

+ @else +

0 críticos

+ @endif +
+
+ +
+
+
+
+ +
+ + {{-- ── KPIs fila 2: Inspecciones ────────────────────────────────────────── --}} +
+
+
+
+ +
+
+

Total inspecciones

+

{{ $stats['total_inspections'] }}

+
+
+
+
+
+
+ +
+
+

Aprobadas

+

{{ $stats['passed_inspections'] }}

+
+
+
+
+
+
+ +
+
+

Rechazadas

+

+ {{ $stats['failed_inspections'] }} +

+
-
- {{-- Fases --}} -
-
-
-
-

Fases

-

{{ $stats['total_phases'] }}

- @if($stats['delayed_phases'] > 0) -

{{ $stats['delayed_phases'] }} con retraso

- @else -

Sin retrasos

- @endif -
-
- -
-
-
-
+ {{-- ── Main grid: fases + actividad reciente ───────────────────────────── --}} +
- {{-- Elementos --}} -
-
-
-
-

Elementos

-

{{ $stats['total_features'] }}

-

- {{ $stats['completed_features'] }} completados - · {{ $stats['verified_features'] }} verificados -

-
-
- -
-
-
-
+ {{-- LEFT 2/3: Fases con progreso --}} +
+
+
+
+

+ + Fases del proyecto +

+ + + Gantt + +
- {{-- Issues --}} -
-
-
-
-

Issues abiertos

-

- {{ $stats['open_issues'] }} -

- @if($stats['critical_issues'] > 0) -

{{ $stats['critical_issues'] }} críticos

- @else -

0 críticos

- @endif -
-
- -
-
-
-
- -
- - {{-- ── KPIs fila 2: Inspecciones ────────────────────────────────────────── --}} -
-
-
-
- -
-
-

Total inspecciones

-

{{ $stats['total_inspections'] }}

-
-
-
-
-
-
- -
-
-

Aprobadas

-

{{ $stats['passed_inspections'] }}

-
-
-
-
-
-
- -
-
-

Rechazadas

-

- {{ $stats['failed_inspections'] }} -

-
-
-
-
- - {{-- ── Main grid: fases + actividad reciente ───────────────────────────── --}} -
- - {{-- LEFT 2/3: Fases con progreso --}} -
-
-
-
-

- - Fases del proyecto -

- - - Gantt - + @if($phases->isEmpty()) +

Sin fases aún.

+ @else +
+ @foreach($phases as $phase) + @php + $pct = round($phase->progress_percent ?? 0); + $isDelayed = $phase->planned_end && $phase->planned_end < now() && $pct < 100; + $barColor = $isDelayed ? 'bg-red-500' : ($pct >= 100 ? 'bg-green-500' : 'bg-blue-500'); + $featureCount = $phase->layers->sum('features_count'); + @endphp +
+
+
+

{{ $phase->name }}

+
+ {{ $phase->layers_count }} capa(s) + · + {{ $featureCount }} elementos + @if($phase->planned_start && $phase->planned_end) + · + {{ $phase->planned_start->format('d/m/y') }} – {{ $phase->planned_end->format('d/m/y') }} + @endif +
+
+
+ @if($isDelayed) + Retraso + @elseif($pct >= 100) + Completada + @endif + + {{ $pct }}% + +
+
+
+
+
+
+ @endforeach +
+ @endif +
- @if($phases->isEmpty()) -

Sin fases aún.

- @else -
- @foreach($phases as $phase) - @php - $pct = round($phase->progress_percent ?? 0); - $isDelayed = $phase->planned_end && $phase->planned_end < now() && $pct < 100; - $barColor = $isDelayed ? 'bg-red-500' : ($pct >= 100 ? 'bg-green-500' : 'bg-blue-500'); - $featureCount = $phase->layers->sum('features_count'); - @endphp -
-
-
-

{{ $phase->name }}

-
- {{ $phase->layers_count }} capa(s) - · - {{ $featureCount }} elementos - @if($phase->planned_start && $phase->planned_end) - · - {{ $phase->planned_start->format('d/m/y') }} – {{ $phase->planned_end->format('d/m/y') }} + {{-- Empresas participantes --}} + @if($companies->isNotEmpty()) +
+
+

+ + Empresas participantes +

+
+ @foreach($companies as $company) +
+ @if($company->logo_path && \Illuminate\Support\Facades\Storage::disk('public')->exists($company->logo_path)) + + @else + + @endif +
+

{{ $company->apodo ?: $company->name }}

+ @if($company->pivot->role_in_project) +

{{ $company->pivot->role_in_project }}

@endif
-
- @if($isDelayed) - Retraso - @elseif($pct >= 100) - Completada - @endif - - {{ $pct }}% - -
-
-
-
-
-
- @endforeach -
- @endif -
-
- - {{-- Empresas participantes --}} - @if($companies->isNotEmpty()) -
-
-

- - Empresas participantes -

-
- @foreach($companies as $company) -
- @if($company->logo_path && \Illuminate\Support\Facades\Storage::disk('public')->exists($company->logo_path)) - - @else - - @endif -
-

{{ $company->apodo ?: $company->name }}

- @if($company->pivot->role_in_project) -

{{ $company->pivot->role_in_project }}

- @endif -
-
- @endforeach -
-
-
- @endif -
- - {{-- RIGHT 1/3: Actividad reciente --}} -
- - {{-- Equipo --}} - @if($teamMembers->isNotEmpty()) -
-
-

- - Equipo ({{ $teamMembers->count() }}) -

-
- @foreach($teamMembers->take(8) as $member) -
-
-
- {{ strtoupper(substr($member->name, 0, 1)) }} -
-
-
-

{{ $member->name }}

- @if($member->pivot->role_in_project) -

{{ $member->pivot->role_in_project }}

- @endif -
- @foreach($member->roles->take(1) as $role) - {{ $role->name }} @endforeach
- @endforeach -
-
-
- @endif - - {{-- Issues recientes --}} -
-
-
-

- - Issues abiertos -

- Ver todos -
- @if($recentIssues->isEmpty()) -
- -

Sin issues abiertos

-
- @else -
- @foreach($recentIssues as $issue) - @php - $pCfg = match($issue->priority ?? 'medium') { - 'critical' => 'badge-error', - 'high' => 'badge-warning', - 'medium' => 'badge-info', - default => 'badge-ghost', - }; - @endphp -
-
- {{ ucfirst($issue->priority ?? 'medium') }} -

{{ $issue->title }}

-
- @if($issue->feature) -

- {{ $issue->feature->name }} -

- @endif -
- @endforeach +
@endif
-
- {{-- Inspecciones recientes --}} -
-
-
-

- - Inspecciones recientes -

- Ver en mapa -
- @if($recentInspections->isEmpty()) -
- -

Sin inspecciones

-
- @else -
- @foreach($recentInspections as $ins) - @php - $iCfg = match($ins->result ?? '') { - 'pass' => ['badge-success', 'OK'], - 'fail' => ['badge-error', 'Fallo'], - default => ['badge-ghost', 'Pendiente'], - }; - @endphp -
-
-

- {{ $ins->template?->name ?? 'Inspección' }} -

- {{ $iCfg[1] }} -
-
- @if($ins->feature) -

- {{ $ins->feature->name }} -

- @endif -

{{ $ins->created_at->diffForHumans() }}

-
+ {{-- RIGHT 1/3: Actividad reciente --}} +
+ + {{-- Equipo --}} + @if($teamMembers->isNotEmpty()) +
+
+

+ + Equipo ({{ $teamMembers->count() }}) +

+
+ @foreach($teamMembers->take(8) as $member) +
+
+
+ {{ strtoupper(substr($member->name, 0, 1)) }} +
+
+
+

{{ $member->name }}

+ @if($member->pivot->role_in_project) +

{{ $member->pivot->role_in_project }}

+ @endif +
+ @foreach($member->roles->take(1) as $role) + {{ $role->name }} + @endforeach +
+ @endforeach
- @endforeach +
@endif + + {{-- Issues recientes --}} +
+
+
+

+ + Issues abiertos +

+ Ver todos +
+ @if($recentIssues->isEmpty()) +
+ +

Sin issues abiertos

+
+ @else +
+ @foreach($recentIssues as $issue) + @php + $pCfg = match($issue->priority ?? 'medium') { + 'critical' => 'badge-error', + 'high' => 'badge-warning', + 'medium' => 'badge-info', + default => 'badge-ghost', + }; + @endphp +
+
+ {{ ucfirst($issue->priority ?? 'medium') }} +

{{ $issue->title }}

+
+ @if($issue->feature) +

+ {{ $issue->feature->name }} +

+ @endif +
+ @endforeach +
+ @endif +
+
+ + {{-- Inspecciones recientes --}} +
+
+
+

+ + Inspecciones recientes +

+ Ver en mapa +
+ @if($recentInspections->isEmpty()) +
+ +

Sin inspecciones

+
+ @else +
+ @foreach($recentInspections as $ins) + @php + $iCfg = match($ins->result ?? '') { + 'pass' => ['badge-success', 'OK'], + 'fail' => ['badge-error', 'Fallo'], + default => ['badge-ghost', 'Pendiente'], + }; + @endphp +
+
+

+ {{ $ins->template?->name ?? 'Inspección' }} +

+ {{ $iCfg[1] }} +
+
+ @if($ins->feature) +

+ {{ $ins->feature->name }} +

+ @endif +

{{ $ins->created_at->diffForHumans() }}

+
+
+ @endforeach +
+ @endif +
+
+
+ {{-- end right --}} +
+ {{-- end main grid --}}
- {{-- end right --}} -
- {{-- end main grid --}} - -
-
{{-- end root --}}