7d854ffb0a
- Translation system: lang/es/ PHP files (auth, validation, pagination, passwords)
- Rappasoft vendor translations published (lang/vendor/livewire-tables/es/)
- JSON files synced to 391 keys (EN + ES, full parity)
- APP_LOCALE changed to 'es', users.locale column default changed to 'es'
- Language switcher fixed: JS event + window.location.reload() avoids /livewire/update redirect
- SetLocale middleware fallback uses config('app.locale') instead of hardcoded 'en'
- setSortingPillsEnabled(false) on ProjectTable, CompanyTable, UserTable
- Translated 17 blade views: project-map, template-manager, layer-manager,
company-management, phase-list, media-manager, reports-dashboard,
client-projects, layer-upload, project-form, project-map-editor-tab,
admin/users, projects/media, projects/templates, layouts/client
- Navigation 'Empresas' link uses __('Companies')
- Fixed typo key 'Fases and layers' -> 'Phases and layers'
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
226 lines
11 KiB
PHP
226 lines
11 KiB
PHP
<div>
|
|
@if(!$selectedProject)
|
|
<!-- Project Selection -->
|
|
<div class="mb-6">
|
|
<h2 class="text-xl font-bold mb-4">{{ __('Select a project to view details') }}</h2>
|
|
|
|
<div class="space-y-4">
|
|
@foreach($projects as $project)
|
|
<div class="project-card cursor-pointer hover:shadow-lg transition-shadow"
|
|
wire:click="selectProject({{ $project['id'] }})">
|
|
<div class="p-4">
|
|
<h3 class="text-lg font-medium text-gray-900 mb-2">{{ $project['name'] }}</h3>
|
|
<p class="text-sm text-gray-500 mb-2">
|
|
{{ $project['description'] ?? __('No description available') }}
|
|
</p>
|
|
<div class="flex items-center justify-between">
|
|
<span class="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded-full">
|
|
{{ ucfirst($project['pivot']['role_in_project']) }}
|
|
</span>
|
|
<span class="text-sm font-medium">
|
|
@php
|
|
$progress = collect($project['phases'])->avg('progress_percent') ?? 0;
|
|
@endphp
|
|
{{ number_format($progress, 1) }}% {{ __('completed') }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@else
|
|
<!-- Project Details -->
|
|
<div class="mb-6">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h2 class="text-xl font-bold">{{ $projectDetails['name'] }}</h2>
|
|
<button wire:click="selectedProject = null"
|
|
class="px-3 py-1 bg-gray-200 text-gray-700 text-sm rounded hover:bg-gray-300">
|
|
← {{ __('Back to projects') }}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
|
<div class="bg-gray-50 p-4 rounded-lg">
|
|
<h3 class="text-sm font-medium text-gray-500 mb-2">{{ __('Status') }}</h3>
|
|
<p class="text-2xl font-bold text-gray-900">
|
|
{{ __(ucfirst(str_replace('_', ' ', $projectDetails['status'] ?? ''))) }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="bg-gray-50 p-4 rounded-lg">
|
|
<h3 class="text-sm font-medium text-gray-500 mb-2">{{ __('Start date') }}</h3>
|
|
<p class="text-2xl font-bold text-gray-900">
|
|
{{ $projectDetails['start_date'] ?? __('Not defined') }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="bg-gray-50 p-4 rounded-lg">
|
|
<h3 class="text-sm font-medium text-gray-500 mb-2">{{ __('Estimated end date') }}</h3>
|
|
<p class="text-2xl font-bold text-gray-900">
|
|
{{ $projectDetails['end_date'] ?? __('Not defined') }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-gray-50 p-4 rounded-lg mb-6">
|
|
<h3 class="text-sm font-medium text-gray-500 mb-2">{{ __('Description') }}</h3>
|
|
<p class="text-gray-700">
|
|
{{ $projectDetails['description'] ?? __('No description available') }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Overview -->
|
|
<div class="mb-6">
|
|
<h2 class="text-xl font-bold mb-4">{{ __('Progress overview') }}</h2>
|
|
|
|
<div class="bg-white rounded-lg shadow p-6">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h3 class="text-lg font-medium">{{ __('General progress') }}</h3>
|
|
<div class="text-2xl font-bold text-green-600">
|
|
{{ number_format($projectDetails['progress'] ?? 0, 1) }}%
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full bg-gray-200 rounded-full h-2.5 mb-4">
|
|
<div class="bg-green-600 h-2.5 rounded-full"
|
|
style="width: {{ min(max($projectDetails['progress'] ?? 0, 0), 100) }}%"></div>
|
|
</div>
|
|
|
|
<div class="text-sm text-gray-500">
|
|
{{ $projectDetails['progress'] ?? 0 }}% {{ __('completed') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Phases Progress -->
|
|
<div class="mb-6">
|
|
<h2 class="text-xl font-bold mb-4">{{ __('Progress by phase') }}</h2>
|
|
|
|
@php
|
|
$project = \App\Models\Project::find($selectedProject);
|
|
$phases = $project->phases ?? collect();
|
|
@endphp
|
|
|
|
@if($phases->isNotEmpty())
|
|
<div class="space-y-4">
|
|
@foreach($phases as $phase)
|
|
<div class="bg-white rounded-lg shadow p-4">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<h3 class="text-lg font-medium">{{ $phase->name }}</h3>
|
|
<span class="px-2 py-1 bg-indigo-100 text-indigo-800 text-xs rounded-full">
|
|
{{ __('Phase') }} {{ $phase->id }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="w-full bg-gray-200 rounded-full h-2.5">
|
|
<div class="bg-indigo-600 h-2.5 rounded-full"
|
|
style="width: {{ min(max($phase->progress_percent ?? 0, 0), 100) }}%"></div>
|
|
</div>
|
|
|
|
<div class="text-sm text-gray-500 mt-1">
|
|
{{ $phase->progress_percent ?? 0 }}% {{ __('completed') }}
|
|
</div>
|
|
|
|
@if($phase->features->isNotEmpty())
|
|
<div class="mt-3 pt-2 border-t border-gray-200">
|
|
<h4 class="text-sm font-medium text-gray-600 mb-2">{{ __('Features') }}:</h4>
|
|
<div class="space-y-1 text-sm">
|
|
@foreach($phase->features as $feature)
|
|
<div class="flex items-start">
|
|
<span class="flex-shrink-0">•</span>
|
|
<span class="ml-2">
|
|
{{ $feature->name }}:
|
|
<span class="font-medium">{{ $feature->completion_status ?? __('Pending') }}</span>
|
|
</span>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@else
|
|
<div class="bg-gray-50 p-6 text-center rounded-lg">
|
|
<p class="text-gray-500">{{ __('No phases defined for this project') }}</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Gallery -->
|
|
<div class="mb-6">
|
|
<h2 class="text-xl font-bold mb-4">{{ __('Progress gallery') }}</h2>
|
|
|
|
<div class="gallery-grid">
|
|
@foreach($galleryImages as $image)
|
|
<div class="gallery-item">
|
|
<img src="{{ $image['url'] }}"
|
|
alt="{{ $image['title'] }}"
|
|
class="w-full h-48 object-cover">
|
|
<div class="p-3">
|
|
<h4 class="text-sm font-medium">{{ $image['title'] }}</h4>
|
|
<p class="text-xs text-gray-500">{{ $image['date'] }}</p>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Change Orders -->
|
|
<div class="mb-6">
|
|
<h2 class="text-xl font-bold mb-4">{{ __('Change orders') }}</h2>
|
|
|
|
@if($changeOrders->isNotEmpty())
|
|
<div class="space-y-4">
|
|
@foreach($changeOrders as $order)
|
|
<div class="change-order-card change-order-{{ strtolower($order['status']) }} p-4">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<h3 class="text-lg font-medium">{{ $order['title'] }}</h3>
|
|
<span class="px-2 py-1 text-xs rounded-full
|
|
@if($order['status'] == 'pending') bg-yellow-100 text-yellow-800
|
|
@elseif($order['status'] == 'approved') bg-green-100 text-green-800
|
|
@elseif($order['status'] == 'rejected') bg-red-100 text-red-800
|
|
@endif">
|
|
{{ ucfirst($order['status']) }}
|
|
</span>
|
|
</div>
|
|
|
|
<p class="text-gray-600 mb-2">{{ $order['description'] }}</p>
|
|
|
|
<div class="flex items-center space-x-3 text-sm">
|
|
<span class="mr-4">
|
|
<span class="font-medium">{{ __('Requested') }}:</span> {{ $order['requested_at'] }}
|
|
</span>
|
|
<span class="mr-4">
|
|
<span class="font-medium">{{ __('Amount') }}:</span> ${{ number_format($order['amount'], 2) }}
|
|
</span>
|
|
</div>
|
|
|
|
@if($order['status'] == 'pending')
|
|
<div class="mt-3 pt-2 border-t border-gray-200">
|
|
<div class="flex items-center space-x-3">
|
|
<button wire:click="approveChangeOrder({{ $order['id'] }})"
|
|
class="flex-1 px-3 py-2 bg-green-600 text-white text-sm rounded hover:bg-green-700 disabled:opacity-50">
|
|
{{ __('Approve') }}
|
|
</button>
|
|
<button wire:click="rejectChangeOrder({{ $order['id'] }})"
|
|
class="flex-1 px-3 py-2 bg-red-600 text-white text-sm rounded hover:bg-red-700 disabled:opacity-50">
|
|
{{ __('Reject') }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@else
|
|
<div class="bg-gray-50 p-6 text-center rounded-lg">
|
|
<p class="text-gray-500">{{ __('No pending change orders') }}</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
</div>
|