@extends('frontend.layouts.user.index') @section('title', __('My Subscription')) @push('styles') @endpush @section('content') @php use App\Enums\BillingCycle; $currencyCode = $subscription?->currency_code ?? siteCurrency('code'); @endphp
@if(! $subscription) {{-- ─────────── Empty state ─────────── --}} @else @php $plan = $subscription->plan; $billingCycle = $subscription->billing_cycle; $billingKey = $billingCycle?->value; $isLifetime = (bool) $billingCycle?->isLifetime(); $prices = collect($plan?->prices ?? [])->keyBy( fn ($p) => $p->billing_cycle instanceof BillingCycle ? $p->billing_cycle->value : (string) $p->billing_cycle ); $currentPrice = $billingKey ? (float) ($prices->get($billingKey)?->price ?? 0) : 0; $monthlyPrice = (float) ($prices->get('monthly')?->price ?? 0); $features = collect($plan?->features ?? []); $featureCount = $features->count(); $enabledCount = $features->filter(fn ($f) => ! $f->isToggle() || $f->isEnabled())->count(); $utilization = $featureCount > 0 ? (int) round(($enabledCount / $featureCount) * 100) : 0; $transactions = $subscription->transactions; $statusKey = $subscription->status->value; $isFree = $currentPrice <= 0 && $monthlyPrice <= 0; $isCancelled = (bool) $subscription->cancelled_at; $isTrial = $statusKey === 'trial'; $startedAt = $subscription->started_at; $periodEnd = $subscription->current_period_end; $trialEndsAt = $subscription->trial_ends_at; $daysRemaining = $subscription->daysRemaining(); $memberDays = $startedAt ? max(0, $startedAt->diffInDays(now())) : 0; $statusPillClass = match($statusKey) { 'active' => 'ms-pill--active', 'trial' => 'ms-pill--trial', 'grace' => 'ms-pill--grace', default => 'ms-pill--neutral', }; $statusLabel = strtoupper($subscription->status->label()); // Action visibility — derived once, used everywhere $canRenew = ! $isTrial && ! $isFree && ! $isLifetime && $subscription->isActive() && ! $isCancelled; $canCancel = ! $isFree && $subscription->isActive() && ! $isCancelled; // Hero meta — "next renewal" sub copy $nextRenewalSub = match (true) { $isLifetime => __('Lifetime — no renewal'), $isFree => __('Free plan — no renewal'), $isTrial && $trialEndsAt => __('Trial ends in :n days', ['n' => max(0, (int) now()->diffInDays($trialEndsAt, false))]), $isCancelled => __('Cancelled — access until end of period'), ! is_null($daysRemaining) => __('In :n days', ['n' => $daysRemaining]), default => __('Pending'), }; $nextRenewalDate = match (true) { $isLifetime || $isFree => '—', $isTrial && $trialEndsAt => $trialEndsAt->format('M d'), $periodEnd => $periodEnd->format('M d'), default => '—', }; // Upgrade plan cost $upgradeMonthlyPrice = $upgradePlan?->prices->firstWhere('billing_cycle', BillingCycle::Monthly)?->price ?? 0; $upgradeFeatureDelta = $upgradePlan ? max(0, $upgradePlan->features->count() - $featureCount) : 0; @endphp
{{-- ═══════════ HERO ═══════════ --}}
{{ strtoupper($plan->name) }}
{{ $statusLabel }} {{ __('PLAN') }}

{{ $plan->name }} @if($isFree) / {{ __('Free forever') }} @elseif($billingCycle) / {{ $billingCycle->label() }} @endif

{{ $plan->description ?: __('Your active subscription on this account.') }}

{{-- Single capability tag — features count only --}}
{{ trans_choice(':count feature included|:count features included', $featureCount, ['count' => $featureCount]) }}
{{-- Smart hero actions — picks based on state --}}
@if($canRenew)
@csrf
@elseif($upgradePlan) {{ __('Upgrade to') }} {{ $upgradePlan->name }} @endif {{ __('Compare all plans') }}
{{-- 4 distinct meta cards — cost, usage, age, renewal --}}
{{ __('Plan cost') }}
{{ $currencyCode }} {{ number_format($currentPrice,siteDecimalPlaces()) }} /{{ $isLifetime ? __('once') : __('mo') }}
{{ $isFree ? __('No billing cycle') : ($billingCycle?->label() ?? __('Custom')) }}
{{ __('Features active') }}
{{ $enabledCount }} {{ __('of') }} {{ $featureCount }}
{{ $utilization }}% {{ __('enabled') }}
{{ __('Member since') }}
{{ $startedAt?->format('M d') ?? '—' }}
{{ $startedAt?->format('Y') ?? '' }} · {{ trans_choice(':count day|:count days', $memberDays, ['count' => $memberDays]) }}
{{ __('Next renewal') }}
{{ $nextRenewalDate }}
{{ $nextRenewalSub }}
{{-- ═══════════ NOTICES ═══════════ --}} @if($subscription->isActive() && $periodEnd && ! is_null($daysRemaining) && $daysRemaining <= 7 && ! $isLifetime && ! $isFree && ! $isCancelled)
{{ __('Your subscription expires in :days days. Renew now to avoid interruption.', ['days' => $daysRemaining]) }}
@endif @if($isCancelled && $subscription->isActive())
{{ __('Cancelled — access continues until :date.', ['date' => $periodEnd?->format('d M Y') ?? __('period end')]) }}
@endif @if($isTrial && $trialEndsAt)
{{ __('Trial ends on :date. You will be charged :price after that.', ['date' => $trialEndsAt->format('d M Y'), 'price' => $currencyCode.' '.number_format($currentPrice,siteDecimalPlaces())]) }}
@endif {{-- ═══════════ ACCOUNT ACTIVITY STATS ═══════════ --}}
{{ __('Total deposits') }}
{{ $currencyCode }} {{ number_format($stats['deposits'],siteDecimalPlaces()) }}
@if($stats['deposits'] > 0) {{ __('Lifetime total') }} @else — {{ __('No deposits yet') }} @endif
{{ __('Money sent') }}
{{ $currencyCode }} {{ number_format($stats['sent'], siteDecimalPlaces()) }}
@if($stats['sent'] > 0) {{ __('Lifetime total') }} @else — {{ __('No transfers yet') }} @endif
{{ __('Referrals') }}
{{ $stats['referrals'] }}
{{ __('Total invited') }}
{{ __('Vouchers redeemed') }}
{{ $stats['vouchers'] }}
{{ __('Lifetime total') }}
{{-- ═══════════ PLAN ACCESS + BILLING ═══════════ --}}
{{-- Plan access — real usage meters --}}

{{ __('Plan usage') }}

{{ __('Live usage against the limits on your plan.') }}
@php // Build the rendered list — only features that have a usage entry $usageFeatures = $features->filter(fn ($f) => isset($usage[$f->feature_key]))->values(); $iconMap = [ 'deposit_money' => 'fa-arrow-down', 'withdraw_money' => 'fa-arrow-up', 'send_money' => 'fa-paper-plane', 'request_money' => 'fa-hand-holding-usd', 'exchange_money' => 'fa-sync-alt', 'vouchers' => 'fa-tag', 'transaction_history' => 'fa-history', 'two_factor_auth' => 'fa-shield-alt', 'push_notifications' => 'fa-bell', 'p2p_marketplace' => 'fa-handshake', 'virtual_card' => 'fa-credit-card', 'virtual_card_limit' => 'fa-credit-card', 'virtual_cards' => 'fa-credit-card', 'wallet_earn' => 'fa-piggy-bank', 'wallet_balance_cap' => 'fa-wallet', 'referral_program' => 'fa-users', 'payment_link' => 'fa-link', 'bank_transfer' => 'fa-university', 'api_access' => 'fa-code', 'support_priority' => 'fa-headset', 'daily_transaction_limit' => 'fa-tachometer-alt', 'monthly_transaction_limit' => 'fa-chart-line', 'monthly_withdraw_limit' => 'fa-money-bill', 'monthly_send_limit' => 'fa-paper-plane', 'p2p_ad_limit' => 'fa-bullhorn', ]; @endphp @if($usageFeatures->isEmpty()) @else
@foreach($usageFeatures as $feature) @php $u = $usage[$feature->feature_key]; $palettes = ['blue', 'green', 'lav', 'amber', 'rose']; $palette = $palettes[$loop->index % count($palettes)]; $iconCls = $iconMap[strtolower((string) $feature->feature_key)] ?? ($u['is_unlimited'] ? 'fa-infinity' : 'fa-bolt'); // Format used / limit values consistently $isInt = ! $u['is_currency']; $usedFmt = $u['is_currency'] ? $currencyCode.' '.number_format($u['used'], siteDecimalPlaces()) : number_format($u['used'], $isInt && fmod($u['used'], 1) === 0.0 ? 0 : 2); $limitFmt = $u['is_unlimited'] ? __('Unlimited') : ($u['is_currency'] ? $currencyCode.' '.number_format((float) $u['limit'],siteDecimalPlaces()) : number_format((float) $u['limit'], 0)); // Highlight when usage is at or near the cap $isOver = ! $u['is_unlimited'] && $u['percentage'] >= 100; $isWarn = ! $u['is_unlimited'] && $u['percentage'] >= 80 && ! $isOver; if ($isOver) { $palette = 'rose'; } elseif ($isWarn) { $palette = 'amber'; } @endphp
{{ $feature->feature_label }} @if($u['reset_label']) · {{ $u['reset_label'] }} @endif
{{ $usedFmt }} {{ __('of') }} {{ $limitFmt }}
@if($isOver)
{{ __('Limit reached for this period') }}
@elseif($isWarn)
{{ __(':p% used — close to your cap', ['p' => $u['percentage']]) }}
@endif
@endforeach
@endif
{{-- Billing summary — payment-only focus --}}

{{ __('Billing summary') }}

@if($isFree) {{ __('No payment scheduled') }} @elseif($isLifetime) {{ __('One-time charge — no renewals') }} @else {{ __('Charged from your wallet each cycle') }} @endif
{{ $currencyCode }} {{ number_format($currentPrice,siteDecimalPlaces()) }}/ {{ $isLifetime ? __('once') : __('mo') }}
@if($isFree) {{ __('Always free') }} @elseif($isLifetime) {{ __('No renewal') }} @elseif($isCancelled && $periodEnd) {{ __('Access ends') }} {{ $periodEnd->format('d M Y') }} @elseif($periodEnd) {{ __('Renews on') }} {{ $periodEnd->format('d M Y') }} @else {{ __('Pending') }} @endif
{{ __('Payment method') }}
{{ __('Wallet balance') }} · {{ __('default') }}
{{ __('Charges are taken from your default wallet') }}
{{ __('Plan summary') }}
{{ __('Auto-renew') }} {{ $subscription->auto_renew ? __('Enabled') : __('Disabled') }}
@if($plan->trial_days > 0)
{{ __('Trial period') }} {{ $plan->trial_days }} {{ __('days') }}
@endif @if($plan->grace_days > 0)
{{ __('Grace period') }} {{ $plan->grace_days }} {{ __('days') }}
@endif
{{ __('Started') }} {{ $startedAt?->format('d M Y') ?? '—' }}
{{-- ═══════════ UPGRADE STRIP ═══════════ --}} @if($upgradePlan && ! $isCancelled)

@if($upgradeFeatureDelta > 0) {{ __('Unlock') }} {{ $upgradeFeatureDelta }} {{ trans_choice('more feature|more features', $upgradeFeatureDelta) }} {{ __('on') }} {{ $upgradePlan->name }} @if($upgradeMonthlyPrice > 0) {{ __('for :price/mo', ['price' => $currencyCode.' '.number_format($upgradeMonthlyPrice,siteDecimalPlaces())]) }} @endif @else {{ __('Step up to') }} {{ $upgradePlan->name }} @if($upgradeMonthlyPrice > 0) {{ __('for :price/mo', ['price' => $currencyCode.' '.number_format($upgradeMonthlyPrice,siteDecimalPlaces())]) }} @endif @endif

{{ $upgradePlan->description ?: __('Higher limits, more features, priority support — all included.') }}

@endif {{-- ═══════════ BILLING HISTORY ═══════════ --}}

{{ __('Billing history') }}

{{ __('Recent invoices for this subscription') }}
{{ __('View all') }}
@if($transactions->isEmpty()) @else
@foreach($transactions as $trx) @php $statusClass = match (strtolower((string) $trx->status)) { 'completed', 'success', 'paid' => 'ms-s-paid', 'pending', 'processing' => 'ms-s-pending', 'failed', 'cancelled' => 'ms-s-failed', 'refunded' => 'ms-s-free', default => 'ms-s-free', }; $invoiceId = $trx->trx_id ? 'INV-'.strtoupper(substr($trx->trx_id, 0, 12)) : 'DK-'.$trx->created_at->format('Ymd').'-'.str_pad($trx->id, 3, '0', STR_PAD_LEFT); $typeLabel = ucfirst((string) $trx->type); @endphp @endforeach
{{ __('Invoice') }} {{ __('Description') }} {{ __('Date') }} {{ __('Amount') }} {{ __('Status') }}
{{ $invoiceId }} {{ $plan->name }} · {{ $typeLabel }} {{ $trx->created_at->format('d M Y') }} @if((float) $trx->amount > 0) {{ $trx->currency_code }} {{ number_format($trx->amount,siteDecimalPlaces()) }} @else {{ __('Free') }} @endif ● {{ ucfirst((string) $trx->status) }}
@endif
{{-- ═══════════ DANGER ZONE ═══════════ --}} @if($canCancel)

{{ __('Cancel subscription') }}

{{ __('Your access continues until :date, then the plan ends.', ['date' => $periodEnd?->format('d M Y') ?? __('period end')]) }}

@csrf
@endif
@endif
@endsection