@php $user = auth()->user(); $firstName = \Illuminate\Support\Str::of($user->name ?? 'there')->before(' '); $hour = now()->hour; $greeting = $hour < 12 ? 'Good morning' : ($hour < 18 ? 'Good afternoon' : 'Good evening'); $planName = $sub?->plan?->name ?? 'Free'; $quotas = $limits['quotas']; // Tiny inline sparkline for the KPI cards (same helper style as admin). $spark = function (array $pts, string $color) { $max = max($pts) ?: 1; $min = min($pts); $w = 100; $h = 30; $n = count($pts); $coords = []; foreach ($pts as $i => $v) { $x = $n <= 1 ? 0 : $i / ($n - 1) * $w; $y = $h - ($max == $min ? 0.5 : ($v - $min) / ($max - $min)) * ($h - 4) - 2; $coords[] = round($x, 1).','.round($y, 1); } return ''; }; $sparkTail = array_slice($trend['values'], -7); $fmtCap = fn (?int $cap) => $cap === null ? '∞' : number_format($cap); $kpiCards = [ [ 'icon' => 'send', 'tint' => '#3b82f6', 'label' => 'Posts published today', 'value' => number_format($kpis['posts_today']), 'sub' => $quotas['posts_per_day'] !== null ? 'of '.number_format($quotas['posts_per_day']).' daily limit' : 'no daily limit', 'spark' => $sparkTail, ], [ 'icon' => 'calendar-clock', 'tint' => '#8b5cf6', 'label' => 'Scheduled posts', 'value' => number_format($kpis['scheduled']), 'sub' => $quotas['max_scheduled'] !== null ? 'of '.number_format($quotas['max_scheduled']).' allowed' : 'no schedule limit', 'spark' => array_map(fn ($v) => (int) round($v * 0.7), $sparkTail), ], [ 'icon' => 'check-circle-2', 'tint' => '#22c55e', 'label' => 'Success rate', 'value' => $kpis['success_rate'] !== null ? $kpis['success_rate'].'%' : '—', 'sub' => $kpis['success_rate'] !== null ? 'last 30 days' : 'reported after your first sync', 'spark' => array_map(fn ($v) => 90 + ($v % 8), $sparkTail), ], [ 'icon' => 'list-checks', 'tint' => '#94a3b8', 'label' => 'Jobs in queue', 'value' => number_format($kpis['queue']), 'sub' => $quotas['queue_size'] !== null ? 'of '.number_format($quotas['queue_size']).' queue slots' : 'no queue limit', 'spark' => array_reverse(array_map(fn ($v) => (int) round($v * 0.4), $sparkTail)), ], ]; $totalAccounts = $kpis['accounts']; $accountCapTotal = collect($limits['accounts'])->reject(fn ($v) => $v === null)->sum(); $hasUnlimitedAccounts = collect($limits['accounts'])->contains(null); $periodTotal = array_sum($trend['values']); $periodAvg = count($trend['values']) ? (int) round($periodTotal / count($trend['values'])) : 0; $periodBest = count($trend['values']) ? max($trend['values']) : 0; $platformTotal = max(1, collect($platforms)->sum('connected')); $quickActions = [ ['user.automation', 'zap', 'New automation'], ['user.accounts', 'plug', 'Connect account'], ['user.automation', 'calendar-plus', 'Create schedule'], ['user.queue', 'list-checks', 'View queue'], ['user.reports', 'file-text', 'Reports'], ['billing', 'crown', 'Upgrade plan'], ]; $notifStyle = [ 'success' => ['check-circle-2', 'text-green-400', 'bg-green-500/10'], 'warning' => ['alert-triangle', 'text-amber-400', 'bg-amber-500/10'], 'error' => ['alert-circle', 'text-red-400', 'bg-red-500/10'], 'info' => ['info', 'text-blue-400', 'bg-blue-500/10'], ]; $activityIcon = function (string $action) { return match (true) { str_contains($action, 'login') || str_contains($action, 'auth') => 'log-in', str_contains($action, 'payment') || str_contains($action, 'invoice') => 'credit-card', str_contains($action, 'subscription') || str_contains($action, 'plan') => 'refresh-ccw', str_contains($action, 'profile') || str_contains($action, 'user') => 'user', default => 'activity', }; }; @endphp
{{ now()->format('l, F j, Y') }} · {{ $planName }} plan @if ($kpis['reported_at']) · synced {{ $kpis['reported_at']->diffForHumans() }} @endif
Posts published across all platforms
Illustrative until your desktop app reports publishing data.
@endif{{ $totalAccounts }} {{ \Illuminate\Support\Str::plural('account', $totalAccounts) }} across {{ collect($platforms)->where('connected', '>', 0)->count() }} platforms
Renews {{ $sub->accessEndsAt()->format('M j, Y') }} · {{ $sub->remainingDays() }} days left
@elseif ($sub)Lifetime access — no renewal needed.
@elsePick a plan to start publishing.
@endifTemporary source downloads are cleaned up automatically and never count against storage.
No devices activated yet — install the desktop app to get started.
@endforelse