@extends('layouts.app') @section('title', __('Workspace dashboard')) @section('page-title', $tenant->name) @section('page-subtitle', __('Workspace admin')) @php $fmt = fn ($v, $d = 0) => number_format((float) $v, $d, ',', ' '); $money = fn ($v) => number_format((float) $v, 2, ',', ' ').' '.$kpis['currency']; $pal = \App\Services\Charting\ChartRenderer::PALETTE; @endphp @section('content') {{-- ─── Suggestions strip ──────────────────────────────────────── --}} @if(!empty($suggestions))
@foreach($suggestions as $s) @php $tone = match($s['level']) { 'danger' => 'border-rose-200 dark:border-rose-800/60 bg-rose-50/70 dark:bg-rose-900/20', 'warn' => 'border-amber-200 dark:border-amber-800/60 bg-amber-50/70 dark:bg-amber-900/20', default => 'border-sky-200 dark:border-sky-800/60 bg-sky-50/70 dark:bg-sky-900/20', }; $iconTone = match($s['level']) { 'danger' => 'text-rose-600 dark:text-rose-300 bg-rose-100 dark:bg-rose-900/40', 'warn' => 'text-amber-600 dark:text-amber-300 bg-amber-100 dark:bg-amber-900/40', default => 'text-sky-600 dark:text-sky-300 bg-sky-100 dark:bg-sky-900/40', }; @endphp
{{ $s['title'] }}
{{ $s['detail'] }}
{{ $s['cta'] }}
@endforeach
@endif {{-- ─── Operational KPI strip ─────────────────────────────────── --}}
{{-- Analyses --}}
{{ __('Analyses') }}
{{ $fmt($kpis['analyses_month']) }}
{{ __('this month') }} @if(!is_null($kpis['analyses_delta'])) @php $up = $kpis['analyses_delta'] >= 0; @endphp {{ $up ? '▲' : '▼' }} {{ $fmt(abs($kpis['analyses_delta']), 1) }}% @endif
{{ __('Lifetime') }}: {{ $fmt($kpis['analyses_lifetime']) }} · {{ $kpis['analyses_done'] }} ✓ {{ $kpis['analyses_failed'] }} ✗
{{-- Submissions --}}
{{ __('Submissions') }}
{{ $fmt($kpis['submissions_month']) }}
{{ __('this month') }} @if(!is_null($kpis['submissions_delta'])) @php $up = $kpis['submissions_delta'] >= 0; @endphp {{ $up ? '▲' : '▼' }} {{ $fmt(abs($kpis['submissions_delta']), 1) }}% @endif
{{ __('Lifetime') }}: {{ $fmt($kpis['submissions_lifetime']) }} @if($kpis['pending_submissions'] > 0) · {{ $kpis['pending_submissions'] }} {{ __('pending') }} @endif
{{-- Awaiting action --}}
{{ __('Awaiting action') }}
{{ $fmt($kpis['awaiting_review']) }}
{{ __('analyses to review') }}
{{ __('Unpaid invoices') }}: @if($kpis['outstanding_count'] > 0) {{ $kpis['outstanding_count'] }} · {{ $money($kpis['outstanding_total']) }} @else 0 @endif
{{-- ─── Revenue grid ──────────────────────────────────────────── --}} @php $unitPriceFmt = number_format((float) $kpis['unit_price'], 2, ',', ' ').' '.$kpis['currency']; $vatRateFmt = rtrim(rtrim(number_format((float) $kpis['vat_rate'], 2, '.', ''), '0'), '.').' %'; @endphp

{{ __('Revenue') }}

{{ __('Unit price') }}: {{ $unitPriceFmt }} · {{ __('VAT') }}: {{ $vatRateFmt }} @if($kpis['has_user_overrides']) ⚠ {{ __('per-user overrides apply') }} @endif

{{ __('Edit pricing') }}
{{-- Approved revenue --}}
{{ __('Approved revenue') }}
{{ $money($kpis['approved_month']) }}
{{ __('this month') }} @if(!is_null($kpis['approved_delta'])) @php $up = $kpis['approved_delta'] >= 0; @endphp {{ $up ? '▲' : '▼' }} {{ $fmt(abs($kpis['approved_delta']), 1) }}% @endif
{{ $kpis['approved_count_month'] }} × {{ $unitPriceFmt }}{{ $kpis['has_user_overrides'] ? ' *' : '' }}
{{ __('Lifetime') }}: {{ $money($kpis['approved_lifetime']) }} ({{ $kpis['approved_count_lifetime'] }} {{ __('analyses') }})
{{-- Potential revenue --}}
{{ __('Potential revenue') }}
{{ $money($kpis['potential_month']) }}
{{ __('this month') }} @if(!is_null($kpis['potential_delta'])) @php $up = $kpis['potential_delta'] >= 0; @endphp {{ $up ? '▲' : '▼' }} {{ $fmt(abs($kpis['potential_delta']), 1) }}% @endif
{{ $kpis['potential_count_month'] }} × {{ $unitPriceFmt }}{{ $kpis['has_user_overrides'] ? ' *' : '' }}
{{ __('Lifetime') }}: {{ $money($kpis['potential_lifetime']) }} ({{ $kpis['potential_count_lifetime'] }} {{ __('analyses') }})
{{-- VAT collected --}}
{{ __('VAT collected') }}
{{ $money($kpis['vat_month']) }}
{{ __('this month') }} @if(!is_null($kpis['vat_delta'])) @php $up = $kpis['vat_delta'] >= 0; @endphp {{ $up ? '▲' : '▼' }} {{ $fmt(abs($kpis['vat_delta']), 1) }}% @endif
{{ $money($kpis['approved_month']) }} × {{ $vatRateFmt }}
{{ __('Lifetime') }}: {{ $money($kpis['vat_lifetime']) }}
@if($kpis['has_user_overrides'])
* {{ __('Total reflects per-user negotiated prices — not a flat multiplication.') }}
@endif
{{-- ─── Main charts row ────────────────────────────────────────── --}}
{{-- 14-day activity (spans 2 columns) --}}

{{ __('Last 14 days') }}

{{ __('Analyses created per day') }}

@php $totalRecent = array_sum($recentChart['vals']); $peakRecent = max($recentChart['vals'] ?: [0]); @endphp
{{ __('Total') }}
{{ $fmt($totalRecent) }}
{{ __('Peak') }}
{{ $fmt($peakRecent) }}
{{ __('Avg') }}
{{ $fmt($totalRecent / 14, 1) }}
@if($totalRecent === 0)
{{ __('No recent activity yet.') }}
@else
{!! \App\Services\Charting\ChartRenderer::render('area', [[ 'label' => __('Analyses'), 'values' => $recentChart['vals'], ]], [ 'categories' => $recentChart['cats'], 'width' => 760, 'height' => 240, ]) !!}
@endif
{{-- Submission status donut --}}

{{ __('Submission status') }}

{{ __('Active items in the inbox') }}

@php $statusOrder = [ \App\Models\FileSubmission::STATUS_RECEIVED => __('Received'), \App\Models\FileSubmission::STATUS_SEEN => __('Seen'), \App\Models\FileSubmission::STATUS_ANALYSING => __('Analysing'), \App\Models\FileSubmission::STATUS_READY => __('Ready'), \App\Models\FileSubmission::STATUS_SENT => __('Sent'), \App\Models\FileSubmission::STATUS_OPENED => __('Opened'), \App\Models\FileSubmission::STATUS_EVALUATED_GOOD => __('Approved'), \App\Models\FileSubmission::STATUS_EVALUATED_BAD => __('Rejected'), \App\Models\FileSubmission::STATUS_EVALUATED_UPDATE => __('Update requested'), \App\Models\FileSubmission::STATUS_FAILED => __('Failed'), ]; $donutSeries = []; foreach ($statusOrder as $st => $label) { $v = (int) ($statusBreakdown[$st] ?? 0); if ($v > 0) $donutSeries[] = ['label' => $label, 'value' => $v]; } $donutTotal = array_sum(array_column($donutSeries, 'value')); @endphp @if($donutTotal === 0)
{{ __('Inbox is empty.') }}
@else
{!! \App\Services\Charting\ChartRenderer::render('donut', $donutSeries, [ 'width' => 240, 'height' => 220, ]) !!}
    @foreach($donutSeries as $i => $row)
  • {{ $row['label'] }} {{ $row['value'] }}
  • @endforeach
@endif
{{-- ─── Mid row: by type + top users ──────────────────────────── --}}
{{-- Analyses by type --}}

{{ __('Analyses by type') }}

{{ __('Volume + revenue split') }}

@if($byType->isNotEmpty())
{{ __('Total') }}
{{ $fmt($byType->sum('c')) }}
@endif
@if($byType->isEmpty())
{{ __('No analyses yet.') }}
@else @php $byTypeTotal = max(1, $byType->sum('c')); $byTypeMax = max(1, $byType->max('c')); @endphp
    @foreach($byType as $i => $row) @php $label = __($typeLabels[$row->analysis_type] ?? $row->analysis_type); $count = (int) $row->c; $pct = $count / $byTypeTotal * 100; $barPct = $count / $byTypeMax * 100; $color = $pal[$i % count($pal)]; @endphp
  • {{ $label }} {{ $fmt($count) }} {{ number_format($pct, 1) }}%
    @if((float) $row->revenue > 0)
    {{ number_format((float) $row->revenue, 2, ',', ' ') }} {{ $kpis['currency'] }}
    @endif
  • @endforeach
@endif
{{-- Top users this month --}}

{{ __('Most active users') }}

{{ __('By submissions this month') }}

{{ __('View all') }}
@forelse($topUsers as $row) @php $u = $row->uploader; @endphp
{{ $u?->initials() ?? '?' }}
{{ $u?->name ?? __('Unknown user') }}
{{ $u?->email }}
{{ $row->submissions_count }}
@empty
{{ __('No activity this month yet.') }}
@endforelse
{{-- ─── Workspace footer row ─────────────────────────────────── --}}
{{-- Recent members --}}

{{ __('Recent members') }}

{{ $totalUsers }} {{ __('total') }} · {{ $endUsers }} {{ __('clients') }} · {{ $tenantAdmins }} {{ __('admins') }}

{{ __('Manage all') }}
@forelse($recentUsers as $member)
{{ $member->initials() }}
{{ $member->name }}
{{ $member->email }}
{{ str_replace('_', ' ', $member->role) }}
@empty
{{ __('No users yet — invite your first one.') }}
@endforelse
{{-- Quick actions --}}

{{ __('Quick actions') }}

@endsection