$this->getUserMetrics(), 'bookingMetrics' => $this->getBookingMetrics(), 'timelineMetrics' => $this->getTimelineMetrics(), 'postMetrics' => $this->getPostMetrics(), 'chartData' => $this->getChartData(), ]; } public function updatedChartPeriod(): void { // Reset custom range when switching to preset if ($this->chartPeriod !== 'custom') { $this->customStartMonth = null; $this->customEndMonth = null; } } public function setCustomRange(): void { if ($this->customStartMonth && $this->customEndMonth) { $this->chartPeriod = 'custom'; } } private function getChartData(): array { $service = app(AnalyticsService::class); $months = match ($this->chartPeriod) { '6m' => 6, '12m' => 12, 'custom' => $this->getCustomMonthCount(), default => 6, }; $startDate = $this->chartPeriod === 'custom' && $this->customStartMonth ? Carbon::parse($this->customStartMonth)->startOfMonth() : now()->subMonths($months - 1)->startOfMonth(); return [ 'labels' => $service->getMonthLabels($startDate, $months), 'newClients' => $service->getMonthlyNewClients($startDate, $months), 'consultations' => $service->getMonthlyConsultations($startDate, $months), 'consultationBreakdown' => $service->getConsultationTypeBreakdown($startDate, $months), 'noShowRates' => $service->getMonthlyNoShowRates($startDate, $months), ]; } private function getCustomMonthCount(): int { if (! $this->customStartMonth || ! $this->customEndMonth) { return 6; } return Carbon::parse($this->customStartMonth) ->diffInMonths(Carbon::parse($this->customEndMonth)) + 1; } private function getUserMetrics(): array { return Cache::remember('admin.metrics.users', 300, fn () => [ 'total_active' => User::query() ->where('status', UserStatus::Active) ->whereIn('user_type', [UserType::Individual, UserType::Company]) ->count(), 'individual' => User::query() ->where('user_type', UserType::Individual) ->where('status', UserStatus::Active) ->count(), 'company' => User::query() ->where('user_type', UserType::Company) ->where('status', UserStatus::Active) ->count(), 'deactivated' => User::query() ->where('status', UserStatus::Deactivated) ->whereIn('user_type', [UserType::Individual, UserType::Company]) ->count(), 'new_this_month' => User::query() ->whereIn('user_type', [UserType::Individual, UserType::Company]) ->whereMonth('created_at', now()->month) ->whereYear('created_at', now()->year) ->count(), ]); } private function getBookingMetrics(): array { return Cache::remember('admin.metrics.bookings', 300, function () { $total = Consultation::query() ->whereIn('status', [ConsultationStatus::Completed, ConsultationStatus::NoShow]) ->count(); $noShows = Consultation::query() ->where('status', ConsultationStatus::NoShow) ->count(); return [ 'pending' => Consultation::query() ->where('status', ConsultationStatus::Pending) ->count(), 'today' => Consultation::query() ->whereDate('booking_date', today()) ->where('status', ConsultationStatus::Approved) ->count(), 'this_week' => Consultation::query() ->whereBetween('booking_date', [now()->startOfWeek(), now()->endOfWeek()]) ->whereIn('status', [ConsultationStatus::Approved, ConsultationStatus::Pending]) ->count(), 'this_month' => Consultation::query() ->whereMonth('booking_date', now()->month) ->whereYear('booking_date', now()->year) ->count(), 'free' => Consultation::query() ->where('consultation_type', ConsultationType::Free) ->count(), 'paid' => Consultation::query() ->where('consultation_type', ConsultationType::Paid) ->count(), 'no_show_rate' => $total > 0 ? round(($noShows / $total) * 100, 1) : 0, ]; }); } private function getTimelineMetrics(): array { return Cache::remember('admin.metrics.timelines', 300, fn () => [ 'active' => Timeline::query() ->where('status', TimelineStatus::Active) ->count(), 'archived' => Timeline::query() ->where('status', TimelineStatus::Archived) ->count(), 'updates_this_week' => TimelineUpdate::query() ->where('created_at', '>=', now()->subWeek()) ->count(), ]); } private function getPostMetrics(): array { return Cache::remember('admin.metrics.posts', 300, fn () => [ 'total_published' => Post::query() ->where('status', PostStatus::Published) ->count(), 'this_month' => Post::query() ->where('status', PostStatus::Published) ->whereMonth('published_at', now()->month) ->whereYear('published_at', now()->year) ->count(), ]); } }; ?>