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', 'changeOrders' // Load change orders for this project ])->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 (we can fetch from media table if needed, but for now we'll keep simulated or link to real) // For simplicity, we'll try to get some media images for the project $mediaImages = $project->media() ->where('category', 'image') ->latest() ->take(3) ->get() ->map(function($media) { return [ 'url' => $media->url, 'title' => $media->name, 'date' => $media->created_at->format('d/m/Y') ]; }) ->toArray(); // If we don't have 3 images, we can fallback to placeholders or just use what we have if (count($mediaImages) > 0) { $this->galleryImages = $mediaImages; } else { // Fallback to placeholders $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 for this project $this->changeOrders = $project->changeOrders ->orderBy('requested_at', 'desc') ->get() ->map(function($order) { return [ 'id' => $order->id, 'title' => $order->title, 'description' => $order->description, 'status' => $order->status, 'requested_at' => $order->requested_at->format('d/m/Y'), 'amount' => $order->amount ]; }) ->toArray(); } public function approveChangeOrder($orderId) { // Update the change order in the database $changeOrder = ChangeOrder::find($orderId); if ($changeOrder) { // Check that the change order belongs to the selected project (security) if ($changeOrder->project_id == $this->selectedProject) { $changeOrder->status = 'approved'; $changeOrder->responded_at = now()->toDateString(); $changeOrder->responded_by = auth()->id(); $changeOrder->save(); // Refresh the change orders list $this->loadProjectDetails(); // Notify any listeners (optional) $this->dispatch('changeOrderUpdated', ['id' => $orderId, 'status' => 'approved']); } } } public function rejectChangeOrder($orderId) { // Update the change order in the database $changeOrder = ChangeOrder::find($orderId); if ($changeOrder) { // Check that the change order belongs to the selected project (security) if ($changeOrder->project_id == $this->selectedProject) { $changeOrder->status = 'rejected'; $changeOrder->responded_at = now()->toDateString(); $changeOrder->responded_by = auth()->id(); $changeOrder->save(); // Refresh the change orders list $this->loadProjectDetails(); // Notify any listeners (optional) $this->dispatch('changeOrderUpdated', ['id' => $orderId, 'status' => 'rejected']); } } } public function render() { return view('livewire.client.client-projects'); } }