@php $c = $cards; $p = $pulse; $f = $forecast; $money = fn ($v) => \App\Support\Money::format($v); $versus = ['today' => 'vs hier, journée entière', 'week' => 'vs mêmes jours, semaine précédente', 'month' => 'vs même période, mois précédent'][$period->preset] ?? 'vs période précédente'; $number = fn ($v) => \App\Support\Money::number($v); @endphp
{{-- ============ Pouls du jour (en direct) ============ --}}
{{-- Ondes WiFi en filigrane --}}

En direct {{ $p['source'] === 'router' ? ($p['routers_read_at'] ? 'routeurs lus à '.$p['routers_read_at'] : 'routeurs pas encore lus') : 'mis à jour à '.$p['generated_at'] }}

Recettes du jour

{{ $p['revenue_label'] }}

@if ($p['pace'] !== null) {{ ($p['pace'] > 0 ? '+' : '').$p['pace'] }} % sur hier à la même heure ({{ $p['yesterday_same_time_label'] }}) @elseif ($p['revenue'] > 0) Premières ventes : hier à la même heure, rien n'était encore vendu. @else Aucune vente enregistrée aujourd'hui pour le moment. @endif

Hier, journée entière : {{ $money($router_revenue['yesterday']) }}

Tickets
{{ $number($p['tickets']) }}
Ventes
{{ $number($p['sales']) }}
Connectés WiFi
Course du jour Aujourd'hui Hier
@foreach ([6, 12, 18] as $hour) @endforeach

Dernières ventes

@can('sales.view') Voir tout @endcan
    @forelse (array_slice($p['feed'], 0, 4) as $sale)
  • {{ $sale['time'] }} {{ $sale['reseller'] }} {{ $sale['detail'] }} {{ $sale['amount'] }}
  • @empty
  • Les ventes apparaîtront ici au fil de la journée.
  • @endforelse
{{-- ============ Période et cartes ============ --}}
@foreach ($tabs as $key => $label) {{ $label }} @endforeach

{{ $period->label() }} · comparé à {{ $period->previousLabel() }}

@php $cardList = [ ['label' => 'Recettes', 'value' => $money($c['revenue']['value']), 'tone' => 'text-navy-800', 'delta' => $c['revenue']['delta'], 'invert' => false, 'spark' => $series['revenue'], 'color' => '#1a4aa8', 'hint' => null], ['label' => 'Dépenses', 'value' => $money($c['expenses']['value']), 'tone' => 'text-slate-900', 'delta' => $c['expenses']['delta'], 'invert' => true, 'spark' => $series['expenses'], 'color' => '#dc2626', 'hint' => null], ['label' => 'Bénéfice net', 'value' => $money($c['net_profit']['value']), 'tone' => $c['net_profit']['value'] < 0 ? 'text-red-600' : 'text-green-700', 'delta' => $c['net_profit']['delta'], 'invert' => false, 'spark' => $series['net_profit'], 'color' => '#16a34a', 'hint' => 'Part entreprise '.$money($c['net_profit']['company_share']).' moins les dépenses'], ['label' => 'Tickets vendus', 'value' => $number($c['tickets']['value']), 'tone' => 'text-slate-900', 'delta' => $c['tickets']['delta'], 'invert' => false, 'spark' => $series['tickets'], 'color' => '#f97316', 'hint' => null], ]; @endphp
@foreach ($cardList as $card)

{{ $card['label'] }}

{{ $card['value'] }}

@if ($card['delta'] !== null){{ $versus }}@endif

@if ($card['hint'])

{{ $card['hint'] }}

@endif
@endforeach

Revendeurs actifs

{{ $c['resellers']['active'] }}

{{ $c['resellers']['selling'] }} ont vendu sur la période @if ($c['resellers']['suspended'] > 0), {{ $c['resellers']['suspended'] }} suspendu(s)@endif

@php $receivable = $c['receivables']; @endphp

Créances

{{ $money($receivable['value']) }}

{{ $receivable['debtors'] }} revendeur(s) débiteur(s) · {{ $receivable['overdue'] }} en retard

Voir les versements

{{-- ============ Courbe 7 jours et objectif du mois ============ --}}

Recettes des 7 derniers jours

Cette semaine Semaine précédente

{{ $f['target'] > 0 ? 'Objectif de '.$f['month'] : 'Projection de '.$f['month'] }}

@php $ringPct = $f['target'] > 0 ? min(100, $f['target_pct']) : $f['elapsed_pct']; $ringProj = $f['target'] > 0 ? min(100, $f['projection_pct']) : null; $circ = 2 * M_PI * 50; @endphp
@if ($ringProj !== null && $f['reliable'] && $ringProj > $ringPct) @endif @if ($ringPct > 0) @endif
@if ($f['target'] > 0)

{{ $f['target_pct'] }} %

{{ $money($f['revenue']) }} sur {{ $money($f['target']) }}

@else

{{ $f['day'] }}/{{ $f['days_in_month'] }}

jours écoulés, {{ $money($f['revenue']) }} encaissés

@endif
Fin de mois estimée
{{ $f['reliable'] ? $money($f['projection']) : '—' }}
Rythme actuel
{{ $money($f['daily_rate']) }} / jour
Comparé à {{ $f['last_month_label'] }}
@if (! $f['reliable'])

L'estimation s'affiche à partir du 3e jour du mois.

@elseif ($f['target'] > 0 && $f['needed_per_day'] > 0)

Pour atteindre l'objectif : {{ $money($f['needed_per_day']) }} par jour pendant {{ max(1, $f['remaining_days']) }} jour(s).

@elseif ($f['target'] > 0)

Objectif atteint. Tout ce qui suit est du bonus.

@elseif (auth()->user()->can('settings.manage')) Fixez un objectif mensuel dans les paramètres pour suivre votre progression jour après jour. @endif
{{-- ============ Réseau en direct, par routeur ============ --}}

Réseau en direct

Tous les routeurs
@php $zonesWithRouters = collect($network)->filter(fn ($z) => count($z['routers']) > 0 || $z['revenue'] > 0); @endphp @if ($zonesWithRouters->isEmpty())
Aucun routeur suivi pour le moment. @can('routers.manage')Ajoutez un MikroTik pour voir ici les connectés de chaque routeur.@endcan
@else
@foreach ($zonesWithRouters as $zone) @php $down = count($zone['routers']) - $zone['online']; @endphp
{{ $zone['name'] }}

{{ $zone['resellers'] }} revendeur(s), {{ $money($zone['revenue']) }} aujourd'hui · {{ $money($zone['revenue_yesterday'] ?? 0) }} hier

@if (count($zone['routers']) > 0)
    @foreach ($zone['routers'] as $node) @php $state = ['online' => 'en ligne', 'offline' => 'hors ligne'][$node['status']] ?? 'état inconnu'; @endphp @php $tone = ['online' => 'bg-emerald-50 text-emerald-800 ring-emerald-200', 'offline' => 'bg-red-50 text-red-700 ring-red-200'][$node['status']] ?? 'bg-slate-50 text-slate-600 ring-slate-200'; @endphp @php $dot = ['online' => 'bg-emerald-500', 'offline' => 'bg-red-500'][$node['status']] ?? 'bg-slate-400'; @endphp
  • @endforeach
@else

Aucun routeur.

@endif
@endforeach
@endif

Recettes par routeur

{{ $period->label() }}

@if ($zones->isEmpty())

Aucune vente sur cette période.

@endif

Hier et aujourd'hui, routeur par routeur

Indépendant de la période choisie ci-dessus.

@foreach ($router_revenue['rows'] as $row) @endforeach
Routeur Hier Aujourd'hui
{{ $row['name'] }} {{ $money($row['yesterday']) }} {{ $money($row['today']) }}
Tout le réseau {{ $money($router_revenue['yesterday']) }} {{ $money($router_revenue['today']) }}
{{-- ============ Cartes de chaleur ============ --}}

Les heures qui comptent

Recettes par jour et par heure d'enregistrement, {{ $heatmaps['sales']['weeks'] }} dernières semaines.

Moyenne des connectés au plus fort de chaque heure, 4 dernières semaines.

@foreach (['sales' => $heatmaps['sales'], 'traffic' => $heatmaps['traffic']] as $kind => $map)
@if ($kind === 'traffic' && ! $map['has_data'])
Pas encore de relevés de connectés. Ils sont pris toutes les 5 minutes par la tâche planifiée (cron) dès qu'un routeur est en ligne.
@else
@foreach (range(0, 23) as $h) {{ $h % 3 === 0 ? $h : '' }} @endforeach @foreach ($map['cells'] as $d => $hours) {{ \App\Services\DashboardInsights::DAYS[$d] }} @foreach ($hours as $cell) @endforeach @endforeach

@if ($map['best']) Pic : {{ $map['best']['day'] }}, {{ $map['best']['hours'] }} ({{ $map['best']['value'] }}) @if ($map['quiet'])|Plus calme : {{ $map['quiet']['day'] }}, {{ $map['quiet']['hours'] }}@endif @else Aucune activité sur la période observée. @endif

@endif
@endforeach
{{-- ============ Classement et alertes ============ --}}

Top 5 revendeurs

@if ($top->isNotEmpty())

Ils réalisent {{ $top_share }} % des recettes de la période.

@endif
Tous les revendeurs
@if ($top->isEmpty()) Aucune vente sur la période. @else
@foreach ($top as $i => $row) @php $badge = ['green' => 'bg-green-50 text-green-700 ring-green-200', 'blue' => 'bg-blue-50 text-blue-700 ring-blue-200', 'amber' => 'bg-amber-50 text-amber-800 ring-amber-200', 'red' => 'bg-red-50 text-red-700 ring-red-200'][$row['color']] ?? ''; @endphp @endforeach
# Revendeur Recettes Créance Performance
{{ $i + 1 }} @if ($row['id']) {{ $row['name'] }} @else {{ $row['name'] }} @endif
{{ $money($row['revenue']) }} {{ $money($row['due']) }} {{ $row['performance'] }}
@endif

Alertes

    @forelse ($alerts as $alert) @php $tone = ['red' => 'border-red-200 bg-red-50 text-red-800', 'amber' => 'border-amber-200 bg-amber-50 text-amber-900'][$alert['level']] ?? 'border-slate-200 bg-slate-50'; @endphp
  • {{ $alert['title'] }}{{ $alert['text'] }}
  • @empty
  • Tout est en ordre.
  • @endforelse
{{-- Changement de période sans recharger la page : on relit le tableau de bord et on ne remplace que les blocs qui dépendent de la période. --}}