dayName = Carbon::now()->locale('it_IT')->dayName; Log::info('Day name set', ['day' => $this->dayName]); $this->loadBasicStats(); $this->loadUserStats(); $this->loadFinancialStats(); $this->loadRecentData(); $this->loadSavedNotes(); $endTime = microtime(true); $executionTime = round(($endTime - $startTime) * 1000, 2); Log::info('Dashboard mount completed', [ 'execution_time_ms' => $executionTime, 'active_users' => $this->activeUsers, 'courses_count' => count($this->courses), 'participation_count' => count($this->coursesParticipation) ]); } private function loadBasicStats() { Log::info('Loading basic stats'); $startTime = microtime(true); try { $this->totMembers = \App\Models\Member::count(); $this->totSuppliers = \App\Models\Supplier::count(); Log::info('Basic counts loaded', [ 'total_members' => $this->totMembers, 'total_suppliers' => $this->totSuppliers ]); // Calculate today's income and expenses $this->totTodayIn = 0; $todayRecordsIn = \App\Models\Record::where('type', 'IN') ->where('date', date("Y-m-d")) ->get(); foreach($todayRecordsIn as $record) { foreach($record->rows as $row) { $this->totTodayIn += $row->amount; } } $this->totTodayOut = 0; $todayRecordsOut = \App\Models\Record::where('type', 'OUT') ->where('date', date("Y-m-d")) ->get(); foreach($todayRecordsOut as $record) { foreach($record->rows as $row) { $this->totTodayOut += $row->amount; } } $endTime = microtime(true); Log::info('Basic stats loaded successfully', [ 'today_income' => $this->totTodayIn, 'today_expenses' => $this->totTodayOut, 'execution_time_ms' => round(($endTime - $startTime) * 1000, 2) ]); } catch (\Exception $e) { Log::error('Error loading basic stats', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); } } private function loadUserStats() { Log::info('Loading user stats'); $startTime = microtime(true); try { $this->activeUsers = \App\Models\Member::where('is_archived', 0)->orWhere('is_archived', NULL)->count(); $this->registeredUsers = \App\Models\Member::where('current_status', 2)->count(); $this->suspendedSubscriptions = \App\Models\Member::where('current_status', 1)->count(); Log::info('User counts loaded', [ 'active_users' => $this->activeUsers, 'registered_users' => $this->registeredUsers, 'suspended_subscriptions' => $this->suspendedSubscriptions ]); $this->expiredCertificates = \App\Models\Member::whereHas('certificates', function($query) { $query->where('expire_date', '<', now()); })->whereDoesntHave('certificates', function($query) { $query->where('expire_date', '>=', now()); })->count(); Log::info('Expired certificates count', ['expired_certificates' => $this->expiredCertificates]); // Calculate changes from last month $lastMonth = now()->subMonth(); $endOfLastMonth = $lastMonth->copy()->endOfMonth(); $lastMonthActiveUsers = \App\Models\Member::where('is_archived', false) ->where('created_at', '<=', $endOfLastMonth) ->count(); $lastMonthRegisteredUsers = \App\Models\Member::where('current_status', 2) ->where('updated_at', '<=', $endOfLastMonth) ->count(); $lastMonthSuspendedSubscriptions = \App\Models\Member::where('current_status', 1) ->where('updated_at', '<=', $endOfLastMonth) ->count(); $lastMonthExpiredCertificates = \App\Models\Member::whereHas('certificates', function($query) use ($endOfLastMonth) { $query->where('expire_date', '<', $endOfLastMonth); })->whereDoesntHave('certificates', function($query) use ($endOfLastMonth) { $query->where('expire_date', '>=', $endOfLastMonth); })->count(); $this->activeUsersChange = $this->activeUsers - $lastMonthActiveUsers; $this->registeredUsersChange = $this->registeredUsers - $lastMonthRegisteredUsers; $this->expiredCertificatesChange = $this->expiredCertificates - $lastMonthExpiredCertificates; $this->suspendedSubscriptionsChange = $this->suspendedSubscriptions - $lastMonthSuspendedSubscriptions; $endTime = microtime(true); Log::info('User stats loaded successfully', [ 'changes' => [ 'active_users' => $this->activeUsersChange, 'registered_users' => $this->registeredUsersChange, 'expired_certificates' => $this->expiredCertificatesChange, 'suspended_subscriptions' => $this->suspendedSubscriptionsChange ], 'execution_time_ms' => round(($endTime - $startTime) * 1000, 2) ]); } catch (\Exception $e) { Log::error('Error loading user stats', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); } } private function loadFinancialStats() { Log::info('Loading financial stats'); $startTime = microtime(true); try { $currentMonth = now()->format('Y-m'); Log::info('Calculating financial stats for month', ['month' => $currentMonth]); $this->toReceive = \App\Models\Record::where('type', 'IN') ->whereRaw('DATE_FORMAT(date, "%Y-%m") = ?', [$currentMonth]) ->where(function ($query) { $query->where('deleted', false)->orWhere('deleted', null); }) ->sum('amount') ?? 0; $this->toPay = \App\Models\Record::where('type', 'OUT') ->whereRaw('DATE_FORMAT(date, "%Y-%m") = ?', [$currentMonth]) ->where(function ($query) { $query->where('deleted', false)->orWhere('deleted', null); }) ->sum('amount') ?? 0; $endTime = microtime(true); Log::info('Financial stats loaded successfully', [ 'to_receive' => $this->toReceive, 'to_pay' => $this->toPay, 'execution_time_ms' => round(($endTime - $startTime) * 1000, 2) ]); } catch (\Exception $e) { Log::error('Error loading financial stats', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); } } private function loadRecentData() { Log::info('Loading recent data'); $startTime = microtime(true); try { // Load recent users $recentMembers = \App\Models\Member::where('is_archived', 0) ->orWhere('is_archived', NULL) ->orderBy('created_at', 'desc') ->limit(5) ->get(); $this->recentUsers = $recentMembers->map(function($member) { return [ 'surname' => strtoupper($member->last_name), 'name' => strtoupper($member->first_name), 'phone' => $member->phone ?? '', 'email' => $member->email ?? '' ]; })->toArray(); Log::info('Recent users loaded', ['count' => count($this->recentUsers)]); // Load recent transactions $recentRecords = \App\Models\Record::where('date', '>=', now()->subDays(30)) ->with(['member', 'supplier']) ->orderBy('date', 'desc') ->orderBy('created_at', 'desc') ->limit(10) ->get(); $this->recentTransactions = $recentRecords->map(function($record) { if ($record->type == 'IN') { $name = $record->member ? strtoupper($record->member->last_name) . ' ' . strtoupper($record->member->first_name) : 'MEMBRO SCONOSCIUTO'; } else { $name = $record->supplier ? strtoupper($record->supplier->name) : 'FORNITORE SCONOSCIUTO'; } $totalAmount = 0; foreach($record->rows as $row) { $totalAmount += $row->amount; } return [ 'name' => $name, 'amount' => $totalAmount, 'type' => $record->type == 'IN' ? 'ENTRATA' : 'USCITA' ]; })->toArray(); Log::info('Recent transactions loaded', ['count' => count($this->recentTransactions)]); $this->loadCoursesData(); $this->loadCoursesParticipation(); $endTime = microtime(true); Log::info('Recent data loaded successfully', [ 'execution_time_ms' => round(($endTime - $startTime) * 1000, 2) ]); } catch (\Exception $e) { Log::error('Error loading recent data', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); } } private function loadCoursesData() { Log::info('Loading courses data'); $startTime = microtime(true); try { $today = now()->format('N'); $dayNames = [ 1 => 'lun', 2 => 'mar', 3 => 'mer', 4 => 'gio', 5 => 'ven', 6 => 'sab', 7 => 'dom' ]; $todayName = $dayNames[$today]; Log::info('Searching courses for today', [ 'today_number' => $today, 'today_name' => $todayName ]); // Try with status = 0 first (inactive), then status = 1 (active) as fallback $activeCourses = \App\Models\MemberCourse::with(['course', 'member']) ->whereIn('status', [0, 1]) // Include both statuses ->whereRaw('JSON_EXTRACT(`when`, "$[*].day") LIKE ?', ['%"' . $todayName . '"%']) ->get(); Log::info('Raw query for courses', [ 'today_name' => $todayName, 'query_like' => '%"' . $todayName . '"%', 'total_member_courses' => \App\Models\MemberCourse::count() ]); // Debug: let's also try a direct query to see what we get $allMemberCourses = \App\Models\MemberCourse::with(['course']) ->limit(10) ->get(); Log::info('Sample member courses from database', [ 'sample_courses' => $allMemberCourses->map(function($mc) { return [ 'id' => $mc->id, 'course_id' => $mc->course_id, 'course_name' => $mc->course->name ?? 'No name', 'status' => $mc->status, 'when' => $mc->when ]; })->toArray() ]); Log::info('Active courses found', [ 'count' => $activeCourses->count(), 'courses_ids' => $activeCourses->pluck('id')->toArray() ]); $this->courses = $activeCourses->map(function($memberCourse) use ($todayName) { $whenData = json_decode($memberCourse->when, true); Log::debug('Processing course when data', [ 'member_course_id' => $memberCourse->id, 'when_data' => $whenData, 'looking_for_day' => $todayName ]); $todaySchedule = null; if (is_array($whenData)) { foreach($whenData as $schedule) { if (isset($schedule['day']) && is_array($schedule['day']) && in_array($todayName, $schedule['day'])) { $todaySchedule = $schedule; Log::debug('Found matching schedule', [ 'schedule' => $schedule, 'member_course_id' => $memberCourse->id ]); break; } } } if ($todaySchedule) { $days = implode('-', array_map('ucfirst', $todaySchedule['day'])); return [ 'time' => $todaySchedule['from'] . ' - ' . $todaySchedule['to'], 'course_name' => $memberCourse->course->name ?? 'Corso Sconosciuto', 'days' => $days, 'type' => $memberCourse->course->type ?? 'Standard' ]; } else { Log::debug('No matching schedule found for today', [ 'member_course_id' => $memberCourse->id, 'when_data' => $whenData ]); } return null; })->filter()->values()->toArray(); $this->courses = array_slice($this->courses, 0, 5); $endTime = microtime(true); Log::info('Courses data loaded successfully', [ 'final_courses_count' => count($this->courses), 'execution_time_ms' => round(($endTime - $startTime) * 1000, 2), 'courses' => $this->courses ]); } catch (\Exception $e) { Log::error('Error loading courses data', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); $this->courses = []; } } private function loadCoursesParticipation() { Log::info('Loading courses participation'); $startTime = microtime(true); try { // Conta le partecipazioni per corso (include tutti gli status) $courseStats = \App\Models\MemberCourse::with('course') ->whereIn('status', [0, 1]) // Include both statuses ->selectRaw('course_id, COUNT(*) as participants') ->groupBy('course_id') ->orderBy('participants', 'desc') ->limit(4) ->get(); Log::info('Course participation stats', [ 'courses_found' => $courseStats->count(), 'stats' => $courseStats->map(function($stat) { return [ 'course_id' => $stat->course_id, 'course_name' => $stat->course->name ?? 'Unknown', 'participants' => $stat->participants ]; })->toArray() ]); $totalParticipants = $courseStats->sum('participants'); $this->coursesParticipation = $courseStats->map(function($stat) use ($totalParticipants) { $percentage = $totalParticipants > 0 ? ($stat->participants / $totalParticipants) * 100 : 0; $courseName = $stat->course->name ?? 'Corso Sconosciuto'; // Assegna colori basati sul nome del corso $color = $this->getCourseColor($courseName); return [ 'course_name' => $courseName, 'participants' => $stat->participants, 'percentage' => round($percentage, 1), 'color' => $color ]; })->toArray(); $endTime = microtime(true); Log::info('Courses participation loaded successfully', [ 'total_participants' => $totalParticipants, 'participation_data' => $this->coursesParticipation, 'execution_time_ms' => round(($endTime - $startTime) * 1000, 2) ]); } catch (\Exception $e) { Log::error('Error loading courses participation', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); $this->coursesParticipation = []; } } private function getCourseColor($courseName) { $courseName = strtolower($courseName); $color = 'default'; if (strpos($courseName, 'padel') !== false) { $color = 'padel'; // #FFD700 } elseif (strpos($courseName, 'tennis') !== false) { $color = 'tennis'; // #8B4CF7 } elseif (strpos($courseName, 'pallavolo') !== false || strpos($courseName, 'volley') !== false) { $color = 'pallavolo'; // #FF6B35 } elseif (strpos($courseName, 'yoga') !== false) { $color = 'yoga'; // #339E8E } Log::debug('Course color assigned', [ 'course_name' => $courseName, 'assigned_color' => $color ]); return $color; } private function loadSavedNotes() { Log::info('Loading saved notes'); try { // Load saved notes from session or database $this->savedNotes = session()->get('dashboard_notes', []); Log::info('Saved notes loaded', [ 'notes_count' => count($this->savedNotes) ]); } catch (\Exception $e) { Log::error('Error loading saved notes', [ 'error' => $e->getMessage() ]); $this->savedNotes = []; } } private function saveSavedNotes() { try { // Save notes to session (you can change this to save to database) session()->put('dashboard_notes', $this->savedNotes); Log::info('Notes saved to session', [ 'notes_count' => count($this->savedNotes) ]); } catch (\Exception $e) { Log::error('Error saving notes', [ 'error' => $e->getMessage() ]); } } public function saveNote() { Log::info('Save note called', ['note_text' => $this->notes]); try { if (trim($this->notes) !== '') { $newNote = [ 'id' => uniqid(), 'text' => trim($this->notes), 'created_at' => now()->format('d/m/Y H:i'), 'completed' => false ]; // Add note to the beginning of the array array_unshift($this->savedNotes, $newNote); // Save to session/database $this->saveSavedNotes(); // Clear the input $this->notes = ''; // Emit event for success message $this->dispatchBrowserEvent('note-saved'); Log::info('Note saved successfully', [ 'note_id' => $newNote['id'], 'total_notes' => count($this->savedNotes) ]); } else { Log::warning('Attempted to save empty note'); } } catch (\Exception $e) { Log::error('Error saving note', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); } } public function completeNote($noteId) { Log::info('Complete note called', ['note_id' => $noteId]); try { $initialCount = count($this->savedNotes); // Find and remove the note from savedNotes $this->savedNotes = array_filter($this->savedNotes, function($note) use ($noteId) { return $note['id'] !== $noteId; }); // Reindex the array $this->savedNotes = array_values($this->savedNotes); $finalCount = count($this->savedNotes); if ($initialCount > $finalCount) { // Save to session/database $this->saveSavedNotes(); // Emit event for success message $this->dispatchBrowserEvent('note-completed'); Log::info('Note completed successfully', [ 'note_id' => $noteId, 'remaining_notes' => $finalCount ]); } else { Log::warning('Note not found for completion', ['note_id' => $noteId]); } } catch (\Exception $e) { Log::error('Error completing note', [ 'note_id' => $noteId, 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); } } // Existing methods with logging public function addMember() { Log::info('Redirecting to add member'); return redirect()->to('/members?new=1'); } public function addSupplier() { Log::info('Redirecting to add supplier'); return redirect()->to('/suppliers?new=1'); } public function addIn() { Log::info('Redirecting to add income record'); return redirect()->to('/in?new=1'); } public function addOut() { Log::info('Redirecting to add expense record'); return redirect()->to('/out?new=1'); } // Existing methods (keeping original implementation) private function getLabels() { $labels = array(); for($i = 6; $i >= 0; $i--) { $labels[] = date("d/M", strtotime('-' . $i . ' days')); } return $labels; } private function getRecordData($type) { $data = []; for($i = 6; $i >= 0; $i--) { $found = false; $records = $type == 'IN' ? $this->in : $this->out; foreach($records as $record) { if (date("Y-m-d", strtotime($record->date)) == date("Y-m-d", strtotime('-' . $i . ' days'))) { $data[] = $record->total; $found = true; break; } } if (!$found) { $data[] = 0; } } return $data; } private function getMemberData() { $data = []; for($i = 6; $i >= 0; $i--) { $found = false; foreach($this->members as $member) { if (date("Y-m-d", strtotime($member->created_at)) == date("Y-m-d", strtotime('-' . $i . ' days'))) { $data[] = $member->total; $found = true; break; } } if (!$found) { $data[] = 0; } } return $data; } }