@extends('layouts.dashboard') @section('content') @php /** * Platform Analytics → Revenue: the subscription business behind the marketplace — * recurring revenue, the movement that produced it, churn, and the share of partner * sales the platform keeps. * * @var array $mrr @var float $arr @var array $arpu * @var float|null $ltv @var float $grossChurn @var float $netChurn @var array $churnMove @var array $churnSpark * @var array $takeRate * @var float $opening @var float $lost @var float $shrunk @var float $grown * @var array $planStats @var array $accountRows @var array $accountsPager * @var array $bridgeChart @var array $bridgeMeta @var array $mrrChart @var array $mrrMeta * @var array $takeChart @var array $takeMeta @var array $arpuChart @var array $arpuMeta * @var array $planMrrChart @var array $planMrrMeta @var array $statusChart @var array $statusMeta * @var array $planArpuChart @var array $planArpuMeta * @var int $rangeDays @var string $rangeMode @var array $rangeLinks */ $kpiMeta = static fn (array $m, string $caption): string => kpi_trend((int) $m['pct'], (string) $m['dir']) . '' . $caption . ''; // Annual recurring revenue moves exactly as MRR does — it is the same balance read // over twelve months — so it reuses MRR's own movement rather than a second reading. $arrMove = ['pct' => $mrr['pct'], 'dir' => $mrr['dir']]; $statusPill = static fn (string $s): string => match ($s) { 'active' => 'qm-pill-green', 'pending' => 'qm-pill-amber', 'cancelled' => 'qm-pill-red', default => 'qm-pill-grey', }; // Franchise brands the platform's take as a royalty billed on franchise sales, not commission // kept from a marketplace sale — same figures, franchise wording. Marketplace is the default. $producesInvoices = $producesInvoices ?? false; @endphp @php /* .qm-d2: the dashboard density standard (app.css §35) */ @endphp

{{ t_raw('dashboard.sec.snapshot') }}

{{ t_raw($producesInvoices ? 'admin.analytics.revenue_sub_invoice' : 'admin.analytics.revenue_sub') }}

@foreach ($rangeLinks['options'] as $val => $text) @php $on = ((string) $val === $rangeLinks['selected']); @endphp {{ $text }} @endforeach
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'green', 'icon' => 'fa-sync-alt', 'label' => t_raw('admin.analytics.kpi_mrr'), 'value' => money($mrr['total']), 'href' => route('admin.subscriptions'), 'spark' => $mrr['cur'], 'meta' => $kpiMeta($mrr, t('admin.analytics.meta_recurring_run_rate'))]) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'teal', 'icon' => 'fa-calendar-alt', 'label' => t_raw('admin.analytics.kpi_arr'), 'value' => money($arr), 'spark' => $mrr['cur'], 'meta' => $kpiMeta($arrMove, t('admin.analytics.meta_mrr_annualised'))]) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'rose', 'icon' => 'fa-user-slash', 'label' => t_raw('admin.analytics.kpi_gross_churn'), 'value' => number_format($grossChurn, 1) . '%', 'spark' => $churnSpark, 'meta' => $kpiMeta($churnMove, t('admin.analytics.meta_of_opening_mrr'))]) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'blue', 'icon' => 'fa-user-tag', 'label' => t_raw('admin.analytics.kpi_arpu'), 'value' => money($arpu['total']), 'spark' => $arpu['cur'], 'meta' => $kpiMeta($arpu, t('admin.analytics.meta_per_paying_account'))]) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'violet', 'icon' => 'fa-infinity', 'label' => t_raw('admin.analytics.kpi_ltv'), 'value' => $ltv !== null ? money($ltv) : "\u{2014}", 'spark' => $arpu['cur'], 'meta' => '' . ($ltv !== null ? t('admin.analytics.meta_arpu_over_churn') : t('admin.analytics.meta_needs_churn_history')) . '']) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'amber', 'icon' => 'fa-percentage', 'label' => t_raw($producesInvoices ? 'admin.analytics.kpi_royalty_rate' : 'admin.analytics.kpi_take_rate'), 'value' => number_format($takeRate['total'], 1) . '%', 'spark' => $takeRate['cur'], 'meta' => $kpiMeta($takeRate, t($producesInvoices ? 'admin.analytics.meta_royalty_over_gmv' : 'admin.analytics.meta_commission_over_gmv'))])

{{ t_raw('dashboard.sec.trends') }}

@partial('chart-card', ['heading' => t_raw('admin.analytics.chart_mrr_movement'), 'sub' => t_raw('admin.analytics.chart_mrr_movement_caption'), 'cfg' => $bridgeChart, 'meta' => $bridgeMeta, 'icon' => 'fa-chart-bar', 'accent' => 'green', 'opts' => ['id' => 'admRevMovementChart', 'url' => route('admin.chart-series', ['chart' => 'revMovement']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('admin.analytics.chart_mrr_level'), 'sub' => t_raw('admin.analytics.chart_mrr_level_caption'), 'cfg' => $mrrChart, 'meta' => $mrrMeta, 'accent' => 'teal', 'opts' => ['id' => 'mrrChart', 'url' => route('admin.chart-series', ['chart' => 'revMrr']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw($producesInvoices ? 'admin.analytics.chart_gmv_vs_royalty' : 'admin.analytics.chart_gmv_vs_commission'), 'sub' => t_raw($producesInvoices ? 'admin.analytics.chart_gmv_vs_royalty_caption' : 'admin.analytics.chart_gmv_vs_commission_caption'), 'cfg' => $takeChart, 'meta' => $takeMeta, 'icon' => 'fa-chart-bar', 'accent' => 'blue', 'opts' => ['id' => 'admRevTakeChart', 'url' => route('admin.chart-series', ['chart' => 'revTake']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('admin.analytics.chart_arpu_over_time'), 'sub' => t_raw('admin.analytics.chart_arpu_over_time_caption'), 'cfg' => $arpuChart, 'meta' => $arpuMeta, 'accent' => 'violet', 'opts' => ['id' => 'arpuChart', 'url' => route('admin.chart-series', ['chart' => 'revArpu']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])

{{ t_raw('dashboard.sec.breakdown') }}

@partial('chart-card', ['heading' => t_raw('admin.analytics.chart_mrr_by_plan'), 'sub' => t_raw('admin.analytics.chart_mrr_by_plan_caption'), 'cfg' => $planMrrChart, 'meta' => $planMrrMeta, 'icon' => 'fa-chart-pie', 'accent' => 'green'])
@partial('chart-card', ['heading' => t_raw('admin.analytics.chart_sub_status_mix'), 'sub' => t_raw('admin.analytics.chart_sub_status_mix_caption'), 'cfg' => $statusChart, 'meta' => $statusMeta, 'icon' => 'fa-chart-pie', 'accent' => 'blue'])
@partial('chart-card', ['heading' => t_raw('admin.analytics.chart_arpu_by_plan'), 'sub' => t_raw('admin.analytics.chart_arpu_by_plan_caption'), 'cfg' => $planArpuChart, 'meta' => $planArpuMeta, 'icon' => 'fa-chart-bar', 'accent' => 'violet'])

{{ t_raw('admin.analytics.h_plan_economics') }}

{{ t_raw('nav.plans') }}
@if ($planStats) @foreach ($planStats as $row) @endforeach @else @partial('table-empty', ['colspan' => 8, 'icon' => 'fa-layer-group', 'msg' => t('admin.analytics.empty_no_active_plans')]) @endif
{{ t_raw('admin.analytics.caption_plan_economics') }}
{{ t_raw('common.plan') }} {{ t_raw('admin.analytics.kpi_active_subs') }} {{ t_raw('admin.analytics.kpi_mrr') }} {{ t_raw('admin.analytics.kpi_arpu') }} {{ t_raw($producesInvoices ? 'admin.analytics.col_royalty_rate' : 'admin.analytics.col_commission_rate') }} {{ t_raw($producesInvoices ? 'admin.analytics.series_gmv_invoice' : 'admin.analytics.series_gmv') }} {{ t_raw($producesInvoices ? 'common.royalty' : 'common.commission') }} {{ t_raw($producesInvoices ? 'admin.analytics.kpi_royalty_rate' : 'admin.analytics.kpi_take_rate') }}
{!! plan_tag($row['slug'], $row['name']) !!} {{ number_format((int) $row['subs']) }} {{ money($row['mrr']) }} {!! (int) $row['subs'] > 0 ? money($row['mrr'] / (int) $row['subs']) : dash() !!} {{ number_format((float) $row['rate'], 2) }}% {!! (float) $row['gmv'] > 0 ? money($row['gmv']) : dash() !!} {!! (float) $row['commission'] > 0 ? money($row['commission']) : dash() !!} {!! (float) $row['gmv'] > 0 ? number_format((float) $row['commission'] / (float) $row['gmv'] * 100, 1) . '%' : dash() !!}

{{ t_raw('admin.analytics.h_recurring_accounts') }}

{{ t_raw('nav.subscriptions') }}
@if ($accountRows) @foreach ($accountRows as $row) @endforeach @else @partial('table-empty', ['colspan' => 7, 'icon' => 'fa-file-invoice-dollar', 'msg' => t('admin.analytics.empty_no_subscriptions')]) @endif
{{ t_raw('admin.analytics.caption_recurring_accounts') }}
{{ t_raw('common.restaurant') }} {{ t_raw('common.plan') }} {{ t_raw('common.status') }} {{ t_raw('admin.analytics.kpi_mrr') }} {{ t_raw($producesInvoices ? 'admin.analytics.col_royalty_rate' : 'admin.analytics.col_commission_rate') }} {{ t_raw('admin.analytics.col_started') }} {{ t_raw('admin.analytics.col_renews') }}
{!! restaurant_logo_html(['logo' => $row['logo'], 'name' => $row['restaurant']], 'md') !!}
{!! or_dash($row['restaurant']) !!}{!! $row['live'] ? t('admin.analytics.badge_contributing') : t('admin.analytics.badge_not_contributing') !!}
{!! plan_tag($row['plan_slug'], $row['plan']) !!} {{ status_label('subscription', $row['status']) }} {!! $row['mrr'] > 0 ? money($row['mrr']) : dash() !!} {{ number_format((float) $row['rate'], 2) }}% {!! fmt_day($row['starts_at']) !!} {!! $row['ends_at'] ? fmt_day($row['ends_at']) : dash() !!}
@partial('table-toolbar', ['pager' => $accountsPager, 'base' => '/admin/analytics/revenue'])
@php /* /.qm-d2 */ @endphp @endsection