|
|
@@ -4,10 +4,11 @@ namespace App\Http\Livewire;
|
|
|
|
|
|
use Livewire\Component;
|
|
|
use Carbon\Carbon;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
|
|
|
class Dashboard extends Component
|
|
|
{
|
|
|
-
|
|
|
+ // Existing properties
|
|
|
public $totMembers = 0;
|
|
|
public $totSuppliers = 0;
|
|
|
public $totTodayIn = 0;
|
|
|
@@ -17,164 +18,686 @@ class Dashboard extends Component
|
|
|
public $out;
|
|
|
public $members;
|
|
|
|
|
|
+ // New properties for the enhanced dashboard
|
|
|
+ public $activeUsers = 0;
|
|
|
+ public $registeredUsers = 0;
|
|
|
+ public $expiredCertificates = 0;
|
|
|
+ public $suspendedSubscriptions = 0;
|
|
|
+ public $activeUsersChange = 0;
|
|
|
+ public $registeredUsersChange = 0;
|
|
|
+ public $expiredCertificatesChange = 0;
|
|
|
+ public $suspendedSubscriptionsChange = 0;
|
|
|
+
|
|
|
+ public $toReceive = 0;
|
|
|
+ public $toPay = 0;
|
|
|
+
|
|
|
+ public $courses = [];
|
|
|
+ public $fields = [];
|
|
|
+ public $recentUsers = [];
|
|
|
+ public $recentTransactions = [];
|
|
|
+ public $coursesParticipation = [];
|
|
|
+ public $notes = '';
|
|
|
+ public $savedNotes = []; // Array to store saved notes
|
|
|
+
|
|
|
public array $membersDatas = [];
|
|
|
public array $recordDatas = [];
|
|
|
public array $labels = [];
|
|
|
+ public array $monthlyLabels = [];
|
|
|
+ public array $monthlyIncomeData = [];
|
|
|
+ public array $monthlyExpenseData = [];
|
|
|
|
|
|
public function render()
|
|
|
{
|
|
|
+ Log::info('Dashboard render method called');
|
|
|
return view('livewire.dashboard');
|
|
|
}
|
|
|
|
|
|
public function mount()
|
|
|
{
|
|
|
+ Log::info('Dashboard mount started');
|
|
|
+ $startTime = microtime(true);
|
|
|
|
|
|
$this->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();
|
|
|
|
|
|
- $this->totMembers = \App\Models\Member::count();
|
|
|
- $this->totSuppliers = \App\Models\Supplier::count();
|
|
|
- $this->totTodayIn = 0;
|
|
|
- $tmp = \App\Models\Record::where('type', 'IN')->where('date', date("Y-m-d"))->get();
|
|
|
- foreach($tmp as $t)
|
|
|
- {
|
|
|
- foreach($t->rows as $r)
|
|
|
- {
|
|
|
- $this->totTodayIn += $r->amount;
|
|
|
+ foreach($todayRecordsIn as $record) {
|
|
|
+ foreach($record->rows as $row) {
|
|
|
+ $this->totTodayIn += $row->amount;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- //$this->totTodayIn = \App\Models\Record::where('type', 'IN')->where('date', date("Y-m-d"))->rows->sum('amount');
|
|
|
- $tmp = \App\Models\Record::where('type', 'OUT')->where('date', date("Y-m-d"))->get();
|
|
|
- foreach($tmp as $t)
|
|
|
- {
|
|
|
- foreach($t->rows as $r)
|
|
|
- {
|
|
|
- $this->totTodayOut += $r->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()
|
|
|
+ ]);
|
|
|
}
|
|
|
- //$this->totTodayOut = \App\Models\Record::where('type', 'OUT')->where('date', date("Y-m-d"))->rows->sum('amount');
|
|
|
-
|
|
|
- $this->members = \App\Models\Member::whereBetween('created_at', [date("y-m-d", strtotime('-7 days')), date("Y-m-d 23:59:59")])->select(\DB::raw("COUNT(*) as total, created_at"))->groupBy('created_at')->get();
|
|
|
-
|
|
|
- $this->in = \App\Models\Record::where('type', 'IN')->whereBetween('date', [date("y-m-d", strtotime('-7 days')), date("Y-m-d 23:59:59")])->select(\DB::raw("SUM(amount) as total, date"))->groupBy('date')->get();
|
|
|
- $this->out = \App\Models\Record::where('type', 'OUT')->whereBetween('date', [date("y-m-d", strtotime('-7 days')), date("Y-m-d 23:59:59")])->select(\DB::raw("SUM(amount) as total, date"))->groupBy('date')->get();
|
|
|
-
|
|
|
- $this->labels = $this->getLabels();
|
|
|
-
|
|
|
- $this->memberDatas = [
|
|
|
- [
|
|
|
- 'label' => 'Utenti',
|
|
|
- 'backgroundColor' => 'blue',
|
|
|
- 'borderColor' => 'blue',
|
|
|
- // 'data' => $this->getRandomData(),
|
|
|
- 'data' => $this->getMemberData(),
|
|
|
- ]
|
|
|
- ];
|
|
|
-
|
|
|
- $this->recordDatas = [
|
|
|
- [
|
|
|
- 'label' => 'Entrate',
|
|
|
- 'backgroundColor' => 'green',
|
|
|
- 'borderColor' => 'green',
|
|
|
- // 'data' => $this->getRandomData(),
|
|
|
- 'data' => $this->getRecordData('IN'),
|
|
|
- ],
|
|
|
- [
|
|
|
- 'label' => 'Uscite',
|
|
|
- 'backgroundColor' => 'red',
|
|
|
- 'borderColor' => 'red',
|
|
|
- 'data' => $this->getRecordData('OUT'),
|
|
|
- ]
|
|
|
- ];
|
|
|
}
|
|
|
|
|
|
- private function getLabels()
|
|
|
+ private function loadUserStats()
|
|
|
{
|
|
|
- $labels = array();
|
|
|
- for($i=0; $i<=7; $i++)
|
|
|
- {
|
|
|
- $labels[] = date("d/M", strtotime('-' . $i . ' days'));
|
|
|
+ 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()
|
|
|
+ ]);
|
|
|
}
|
|
|
- return array_reverse($labels);
|
|
|
}
|
|
|
|
|
|
- private function getRecordData($type)
|
|
|
+ private function loadFinancialStats()
|
|
|
{
|
|
|
- $data = [];
|
|
|
- for($i=0; $i<=7; $i++)
|
|
|
- {
|
|
|
- if ($type == 'IN')
|
|
|
- {
|
|
|
- $found = false;
|
|
|
- foreach($this->in as $in)
|
|
|
- {
|
|
|
- if (date("Y-m-d", strtotime($in->date)) == date("Y-m-d", strtotime('-' . $i . ' days')))
|
|
|
- {
|
|
|
- $data[] = $in->total;
|
|
|
- $found = true;
|
|
|
- }
|
|
|
+ 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';
|
|
|
}
|
|
|
- if (!$found)
|
|
|
- $data[] = 0;
|
|
|
- }
|
|
|
- if ($type == 'OUT')
|
|
|
- {
|
|
|
- $found = false;
|
|
|
- foreach($this->out as $out)
|
|
|
- {
|
|
|
- if (date("Y-m-d", strtotime($out->date)) == date("Y-m-d", strtotime('-' . $i . ' days')))
|
|
|
- {
|
|
|
- $data[] = $out->total;
|
|
|
- $found = true;
|
|
|
+
|
|
|
+ $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 (!$found)
|
|
|
- $data[] = 0;
|
|
|
- }
|
|
|
+
|
|
|
+ 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');
|
|
|
|
|
|
- return array_reverse($data);
|
|
|
+ $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 getMemberData()
|
|
|
+ private function getCourseColor($courseName)
|
|
|
{
|
|
|
- $data = [];
|
|
|
- for($i=0; $i<=7; $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;
|
|
|
- }
|
|
|
+ $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');
|
|
|
}
|
|
|
- if (!$found)
|
|
|
- $data[] = 0;
|
|
|
|
|
|
+ } 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]);
|
|
|
|
|
|
- return array_reverse($data);
|
|
|
+ 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;
|
|
|
+ }
|
|
|
}
|