feat: Add client portal with project selection, progress overview, gallery, and change order approval
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Client;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Models\Project;
|
||||
use App\Models\Phase;
|
||||
use App\Models\Inspection;
|
||||
use App\Models\Feature;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class ClientProjects extends Component
|
||||
{
|
||||
public $projects = [];
|
||||
public $selectedProject = null;
|
||||
public $projectDetails = [];
|
||||
public $galleryImages = [];
|
||||
public $changeOrders = [];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadProjects();
|
||||
}
|
||||
|
||||
public function loadProjects()
|
||||
{
|
||||
// Get projects where the user has the 'client' role
|
||||
$user = auth()->user();
|
||||
$this->projects = $user->projects()
|
||||
->wherePivot('role_in_project', 'client')
|
||||
->with(['phases' => function($query) {
|
||||
$query->select('id', 'project_id', 'name', 'progress_percent');
|
||||
}])
|
||||
->get()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function selectProject($projectId)
|
||||
{
|
||||
$this->selectedProject = $projectId;
|
||||
$this->loadProjectDetails();
|
||||
}
|
||||
|
||||
public function loadProjectDetails()
|
||||
{
|
||||
if (!$this->selectedProject) {
|
||||
return;
|
||||
}
|
||||
|
||||
$project = Project::with([
|
||||
'phases.features',
|
||||
'inspections.template'
|
||||
])->find($this->selectedProject);
|
||||
|
||||
if (!$project) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->projectDetails = [
|
||||
'id' => $project->id,
|
||||
'name' => $project->name,
|
||||
'description' => $project->description,
|
||||
'start_date' => $project->start_date,
|
||||
'end_date' => $project->end_date,
|
||||
'status' => $project->status,
|
||||
'progress' => $project->phases->avg('progress_percent') ?? 0,
|
||||
];
|
||||
|
||||
// Get recent images (simulated for now)
|
||||
$this->galleryImages = [
|
||||
[
|
||||
'url' => 'https://via.placeholder.com/400x300?text=Avance+1',
|
||||
'title' => 'Avance inicial',
|
||||
'date' => now()->subDays(30)->format('d/m/Y')
|
||||
],
|
||||
[
|
||||
'url' => 'https://via.placeholder.com/400x300?text=Avance+2',
|
||||
'title' => 'Estructura levantada',
|
||||
'date' => now()->subDays(15)->format('d/m/Y')
|
||||
],
|
||||
[
|
||||
'url' => 'https://via.placeholder.com/400x300?text=Avance+3',
|
||||
'title' => 'Instalaciones',
|
||||
'date' => now()->subDays(5)->format('d/m/Y')
|
||||
]
|
||||
];
|
||||
|
||||
// Get change orders (simulated for now)
|
||||
$this->changeOrders = [
|
||||
[
|
||||
'id' => 124,
|
||||
'title' => 'Ampliación de zona de almacenamiento',
|
||||
'description' => 'Solicitud de ampliación de zona de almacenamiento debido a cambios logísticos.',
|
||||
'status' => 'pending',
|
||||
'requested_at' => now()->subDays(10)->format('d/m/Y'),
|
||||
'amount' => 1500.00
|
||||
],
|
||||
[
|
||||
'id' => 125,
|
||||
'title' => 'Cambio de material en acabados interiores',
|
||||
'description' => 'Cambio de cerámica estándar a porcelanato en baños y cocinas.',
|
||||
'status' => 'pending',
|
||||
'requested_at' => now()->subDays(5)->format('d/m/Y'),
|
||||
'amount' => 3200.00
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function approveChangeOrder($orderId)
|
||||
{
|
||||
// In a real app, this would update the database
|
||||
foreach ($this->changeOrders as &$order) {
|
||||
if ($order['id'] == $orderId) {
|
||||
$order['status'] = 'approved';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->dispatch('changeOrderUpdated', ['id' => $orderId, 'status' => 'approved']);
|
||||
}
|
||||
|
||||
public function rejectChangeOrder($orderId)
|
||||
{
|
||||
// In a real app, this would update the database
|
||||
foreach ($this->changeOrders as &$order) {
|
||||
if ($order['id'] == $orderId) {
|
||||
$order['status'] = 'rejected';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->dispatch('changeOrderUpdated', ['id' => $orderId, 'status' => 'rejected']);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.client.client-projects');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user