@php $numberFormat = fn ($value) => number_format((int) $value, 0, ',', ' '); $now = now(); $userStats = [ 'total' => User::count(), 'admins' => User::where('is_admin', true)->count(), ]; $userStats['members'] = max($userStats['total'] - $userStats['admins'], 0); $companyStats = [ 'total' => Company::count(), 'enriched' => Company::where('enrichment_status', 'completed')->count(), 'running' => Company::where('enrichment_status', 'running')->count(), 'failed' => Company::where('enrichment_status', 'failed')->count(), 'with_users' => Company::has('users')->count(), ]; $companyStats['pending'] = max($companyStats['total'] - ($companyStats['enriched'] + $companyStats['running'] + $companyStats['failed']), 0); $tenderStats = [ 'total' => Tender::count(), 'active' => Tender::whereNotNull('deadline_at')->where('deadline_at', '>=', $now)->count(), 'assessed' => Tender::whereNotNull('ai_category')->count(), 'recent' => Tender::where('created_at', '>=', now()->subDays(7))->count(), ]; $companyStatusRows = Company::selectRaw("COALESCE(NULLIF(enrichment_status, ''), 'Non démarré') as status, COUNT(*) as total") ->groupBy(DB::raw("COALESCE(NULLIF(enrichment_status, ''), 'Non démarré')")) ->orderByDesc('total') ->get(); $companyStatusChart = $companyStatusRows->map(function ($row) { $label = match ($row->status) { 'completed' => 'Profil prêt', 'running' => 'Enrichissement en cours', 'failed' => 'Enrichissement en échec', default => 'Non démarré', }; return [ 'label' => $label, 'value' => (int) $row->total, ]; })->values(); $tenderCategoryRows = Tender::selectRaw("COALESCE(NULLIF(ai_category, ''), 'Non catégorisé') as category, COUNT(*) as total") ->groupBy(DB::raw("COALESCE(NULLIF(ai_category, ''), 'Non catégorisé')")) ->orderByDesc('total') ->limit(6) ->get(); $tenderFeasibilityRows = DB::table('tenders') ->selectRaw('CASE ' ."WHEN ai_feasibility IS NULL THEN 'Non évalué' " ."WHEN ai_feasibility < 20 THEN '0-19' " ."WHEN ai_feasibility < 40 THEN '20-39' " ."WHEN ai_feasibility < 60 THEN '40-59' " ."WHEN ai_feasibility < 80 THEN '60-79' " ."ELSE '80-100' END as label, COUNT(*) as total") ->groupBy('label') ->get(); $feasibilityOrder = collect(['0-19','20-39','40-59','60-79','80-100','Non évalué']); $feasibilityMap = $tenderFeasibilityRows->pluck('total', 'label'); $timelineStart = now()->subDays(9)->startOfDay(); $timelineRows = Tender::selectRaw('DATE(created_at) as day, COUNT(*) as total') ->where('created_at', '>=', $timelineStart) ->groupBy('day') ->orderBy('day') ->get() ->keyBy('day'); $timelineLabels = []; $timelineValues = []; for ($i = 9; $i >= 0; $i--) { $day = now()->subDays($i); $key = $day->toDateString(); $timelineLabels[] = $day->format('d/m'); $timelineValues[] = isset($timelineRows[$key]) ? (int) $timelineRows[$key]->total : 0; } $chartData = [ 'userRoles' => [ 'labels' => ['Admins', 'Utilisateurs'], 'values' => [$userStats['admins'], $userStats['members']], ], 'companyStatuses' => [ 'labels' => $companyStatusChart->pluck('label')->all(), 'values' => $companyStatusChart->pluck('value')->all(), ], 'tenderCategories' => [ 'labels' => $tenderCategoryRows->pluck('category')->all(), 'values' => $tenderCategoryRows->pluck('total')->map(fn ($v) => (int) $v)->all(), ], 'tenderFeasibility' => [ 'labels' => $feasibilityOrder->all(), 'values' => $feasibilityOrder->map(fn ($label) => (int) ($feasibilityMap[$label] ?? 0))->all(), ], 'tenderTimeline' => [ 'labels' => $timelineLabels, 'values' => $timelineValues, ], ]; @endphp

Pilotage

Vue d’ensemble

Données temps réel sur les utilisateurs, entreprises et appels d’offres.

Utilisateurs

{{ $numberFormat($userStats['total']) }}

{{ $numberFormat($userStats['admins']) }} admins – {{ $numberFormat($userStats['members']) }} membres

Entreprises suivies

{{ $numberFormat($companyStats['total']) }}

{{ $numberFormat($companyStats['with_users']) }} liées à un utilisateur

Profils enrichis

{{ $numberFormat($companyStats['enriched']) }}

{{ $numberFormat($companyStats['running']) }} en cours • {{ $numberFormat($companyStats['failed']) }} en échec

Appels d’offres

{{ $numberFormat($tenderStats['total']) }}

{{ $numberFormat($tenderStats['active']) }} actifs • {{ $numberFormat($tenderStats['recent']) }} nouveaux 7j

Répartition des utilisateurs

{{ $numberFormat($userStats['total']) }} comptes

Statut d’enrichissement

{{ $numberFormat($companyStats['total']) }} entreprises

Catégories d’AO les plus fréquentes

{{ $numberFormat($tenderStats['assessed']) }} évaluées

Volume d’AO importés

Derniers 10 jours

Scores de faisabilité

{{ $numberFormat($tenderStats['assessed']) }} AO scorées

Raccourcis d’administration

@push('scripts') @endpush