@extends('layouts.public') @section('title', 'Pricing') @section('content') @php try { $heroTitle = (string) \App\Models\Setting::get('pricing_section_title', (string) \App\Models\Setting::get('pricing_hero_title', 'Simple, transparent pricing')); $heroSubtitle = (string) \App\Models\Setting::get('pricing_section_subtitle', (string) \App\Models\Setting::get('pricing_hero_subtitle', "Choose the plan that's right for your business. All plans include a 14-day free trial.")); $popularBadge = (string) \App\Models\Setting::get('pricing_section_popular_badge', (string) \App\Models\Setting::get('pricing_popular_badge', 'Most Popular')); $ctaAuth = (string) \App\Models\Setting::get('pricing_cta_auth', 'Get Started'); $ctaGuest = (string) \App\Models\Setting::get('pricing_cta_guest', 'Start Free Trial'); $faqTitle = (string) \App\Models\Setting::get('pricing_faq_title', 'Frequently asked questions'); } catch (\Throwable $e) { $heroTitle = 'Simple, transparent pricing'; $heroSubtitle = "Choose the plan that's right for your business. All plans include a 14-day free trial."; $popularBadge = 'Most Popular'; $ctaAuth = 'Get Started'; $ctaGuest = 'Start Free Trial'; $faqTitle = 'Frequently asked questions'; } $heroTitle = is_string($heroTitle) && trim($heroTitle) !== '' ? $heroTitle : 'Simple, transparent pricing'; $heroSubtitle = is_string($heroSubtitle) && trim($heroSubtitle) !== '' ? $heroSubtitle : "Choose the plan that's right for your business. All plans include a 14-day free trial."; $popularBadge = is_string($popularBadge) && trim($popularBadge) !== '' ? $popularBadge : 'Most Popular'; $ctaAuth = is_string($ctaAuth) && trim($ctaAuth) !== '' ? $ctaAuth : 'Get Started'; $ctaGuest = is_string($ctaGuest) && trim($ctaGuest) !== '' ? $ctaGuest : 'Start Free Trial'; $faqTitle = is_string($faqTitle) && trim($faqTitle) !== '' ? $faqTitle : 'Frequently asked questions'; try { $featuredPlanId = (int) \App\Models\Setting::get('pricing_featured_plan_id', 0); } catch (\Throwable $e) { $featuredPlanId = 0; } if (isset($plans) && $plans instanceof \Illuminate\Support\Collection) { $popularPlan = $plans->firstWhere('is_popular', true); if ($popularPlan) { $featuredPlanId = (int) $popularPlan->id; } } if ($featuredPlanId <= 0 && isset($plans) && $plans instanceof \Illuminate\Support\Collection) { $featuredPlanId = (int) optional($plans->first())->id; } $faqRows = isset($faq) && is_array($faq) ? $faq : [ [ 'q' => 'Can I change plans later?', 'a' => 'Yes, you can upgrade or downgrade your plan at any time. Changes will be prorated and reflected in your next billing cycle.', ], [ 'q' => 'What payment methods do you accept?', 'a' => 'We accept all major credit cards, PayPal, and bank transfers for annual plans.', ], [ 'q' => 'Is there a free trial?', 'a' => 'Yes, all plans include a 14-day free trial. No credit card required to start.', ], [ 'q' => 'What happens if I exceed my plan limits?', 'a' => "We'll notify you when you're approaching your limits. You can upgrade your plan or purchase additional credits as needed.", ], ]; $pricingPlansMonthly = isset($plans) && $plans instanceof \Illuminate\Support\Collection ? $plans->where('billing_cycle', 'monthly')->values() : collect(); $pricingPlansYearly = isset($plans) && $plans instanceof \Illuminate\Support\Collection ? $plans->where('billing_cycle', 'yearly')->values() : collect(); $pricingAnnualDefault = $pricingPlansMonthly->count() === 0 && $pricingPlansYearly->count() > 0; try { $pricingForceShowAll = (bool) \App\Models\Setting::get('pricing_section_show_all', false); $pricingColumns = (int) \App\Models\Setting::get('pricing_section_columns', 3); } catch (\Throwable $e) { $pricingForceShowAll = false; $pricingColumns = 3; } if ($pricingColumns < 1) { $pricingColumns = 1; } if ($pricingColumns > 5) { $pricingColumns = 5; } try { $pricingToggleMonthly = (string) \App\Models\Setting::get('pricing_section_toggle_monthly', 'Pay Monthly'); $pricingToggleAnnual = (string) \App\Models\Setting::get('pricing_section_toggle_annual', 'Pay Annually'); $pricingToggleSave = (string) \App\Models\Setting::get('pricing_section_toggle_save', '(save 20%)'); } catch (\Throwable $e) { $pricingToggleMonthly = 'Pay Monthly'; $pricingToggleAnnual = 'Pay Annually'; $pricingToggleSave = '(save 20%)'; } $showBillingToggle = !$pricingForceShowAll && $pricingPlansMonthly->count() > 0 && $pricingPlansYearly->count() > 0; $gridClassForColumns = function (int $columns): string { if ($columns <= 1) { return 'grid-cols-1 gap-8'; } if ($columns === 2) { return 'grid-cols-1 gap-8 sm:grid-cols-2'; } if ($columns === 3) { return 'grid-cols-1 gap-8 lg:grid-cols-3'; } if ($columns === 4) { return 'grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-4'; } return 'grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-5'; }; $gridClass = $gridClassForColumns($pricingColumns); @endphp

{{ $heroTitle }}

{{ $heroSubtitle }}

@if($showBillingToggle)
{{ $pricingToggleMonthly }} {{ $pricingToggleAnnual }} {{ $pricingToggleSave }}
@endif
@foreach(($pricingForceShowAll ? $pricingPlansMonthly->concat($pricingPlansYearly) : $pricingPlansMonthly) as $plan) @php $hasPopular = $plans instanceof \Illuminate\Support\Collection && $plans->where('is_popular', true)->count() > 0; $isFeatured = $hasPopular ? (($plan->is_popular ?? false) === true) : (((int) $plan->id) === (int) $featuredPlanId); $cycle = $plan->billing_cycle === 'yearly' ? 'year' : 'month'; $quota = $plan->customerGroup?->limit('sending_quota.monthly_quota', 0); $maxSubscribers = $plan->customerGroup?->limit('lists.limits.max_subscribers', 0); $maxCampaigns = $plan->customerGroup?->limit('campaigns.limits.max_campaigns', 0); $quotaLabel = $quota !== null ? number_format((float) $quota) : '—'; $subsLabel = $maxSubscribers !== null ? number_format((int) $maxSubscribers) : '—'; $campaignsLabel = $maxCampaigns !== null ? number_format((int) $maxCampaigns) : '—'; $featuresView = [ 'type' => 'legacy', 'pros' => [], 'cons' => [], 'legacyItems' => [], ]; $planFeatures = $plan->features ?? null; if (is_array($planFeatures) && (array_key_exists('pros', $planFeatures) || array_key_exists('cons', $planFeatures))) { $featuresView['type'] = 'proscons'; $featuresView['pros'] = is_array($planFeatures['pros'] ?? null) ? $planFeatures['pros'] : []; $featuresView['cons'] = is_array($planFeatures['cons'] ?? null) ? $planFeatures['cons'] : []; } elseif (is_array($planFeatures) && count($planFeatures) > 0) { $featuresView['type'] = 'proscons'; $featuresView['pros'] = $planFeatures; $featuresView['cons'] = []; } else { $features = $plan->customerGroup?->displayAccessAndLimits() ?? []; foreach ($features as $row) { if (!is_array($row)) { continue; } $label = is_string($row['label'] ?? null) ? (string) $row['label'] : ''; $value = is_string($row['value'] ?? null) ? (string) $row['value'] : ''; $text = trim($label) !== '' ? trim($label) . ': ' . $value : $value; $text = trim($text); if ($text === '') { continue; } $featuresView['legacyItems'][] = [ 'status' => ($row['status'] ?? true) !== false, 'text' => $text, ]; } } $planCta = is_string($plan->cta_text ?? null) && trim((string) $plan->cta_text) !== '' ? (string) $plan->cta_text : null; @endphp
@if($isFeatured)
{{ $popularBadge }}
@endif

{{ $plan->name }}

{{ $plan->description }}

{{ $plan->currency }} {{ number_format((float) $plan->price, 2) }} /{{ $cycle }}
@if(($featuresView['type'] ?? 'legacy') === 'proscons')
{{ __('Features') }}
    @foreach(($featuresView['pros'] ?? []) as $f) @if(is_string($f) && trim($f) !== '')
  • {{ $f }}
  • @endif @endforeach @foreach(($featuresView['cons'] ?? []) as $f) @if(is_string($f) && trim($f) !== '')
  • {{ $f }}
  • @endif @endforeach
@else
    @foreach(($featuresView['legacyItems'] ?? []) as $row)
  • @if(($row['status'] ?? true) === false) @else @endif {{ $row['text'] ?? '' }}
  • @endforeach
@endif
@endforeach
@if(!$pricingForceShowAll)
@foreach($pricingPlansYearly as $plan) @php $isFeatured = ($plan->is_popular ?? false) === true; if (!$isFeatured && $pricingPlansYearly->where('is_popular', true)->count() === 0) { $isFeatured = ((int) $loop->index) === 1; } $cycle = $plan->billing_cycle === 'yearly' ? 'year' : 'month'; $quota = $plan->customerGroup?->limit('sending_quota.monthly_quota', 0); $maxSubscribers = $plan->customerGroup?->limit('lists.limits.max_subscribers', 0); $maxCampaigns = $plan->customerGroup?->limit('campaigns.limits.max_campaigns', 0); $quotaLabel = $quota !== null ? number_format((float) $quota) : '—'; $subsLabel = $maxSubscribers !== null ? number_format((int) $maxSubscribers) : '—'; $campaignsLabel = $maxCampaigns !== null ? number_format((int) $maxCampaigns) : '—'; $featuresView = [ 'type' => 'legacy', 'pros' => [], 'cons' => [], 'legacyItems' => [], ]; $planFeatures = $plan->features ?? null; if (is_array($planFeatures) && (array_key_exists('pros', $planFeatures) || array_key_exists('cons', $planFeatures))) { $featuresView['type'] = 'proscons'; $featuresView['pros'] = is_array($planFeatures['pros'] ?? null) ? $planFeatures['pros'] : []; $featuresView['cons'] = is_array($planFeatures['cons'] ?? null) ? $planFeatures['cons'] : []; } elseif (is_array($planFeatures) && count($planFeatures) > 0) { $featuresView['type'] = 'proscons'; $featuresView['pros'] = $planFeatures; $featuresView['cons'] = []; } else { $features = $plan->customerGroup?->displayAccessAndLimits() ?? []; foreach ($features as $row) { if (!is_array($row)) { continue; } $label = is_string($row['label'] ?? null) ? (string) $row['label'] : ''; $value = is_string($row['value'] ?? null) ? (string) $row['value'] : ''; $text = trim($label) !== '' ? trim($label) . ': ' . $value : $value; $text = trim($text); if ($text === '') { continue; } $featuresView['legacyItems'][] = [ 'status' => ($row['status'] ?? true) !== false, 'text' => $text, ]; } } $planCta = is_string($plan->cta_text ?? null) && trim((string) $plan->cta_text) !== '' ? (string) $plan->cta_text : null; @endphp
@if($isFeatured)
{{ $popularBadge }}
@endif

{{ $plan->name }}

{{ $plan->description }}

{{ $plan->currency }} {{ number_format((float) $plan->price, 2) }} /{{ $cycle }}
@if(($featuresView['type'] ?? 'legacy') === 'proscons')
{{ __('Features') }}
    @foreach(($featuresView['pros'] ?? []) as $f) @if(is_string($f) && trim($f) !== '')
  • {{ $f }}
  • @endif @endforeach @foreach(($featuresView['cons'] ?? []) as $f) @if(is_string($f) && trim($f) !== '')
  • {{ $f }}
  • @endif @endforeach
@else
    @foreach(($featuresView['legacyItems'] ?? []) as $row)
  • @if(($row['status'] ?? true) === false) @else @endif {{ $row['text'] ?? '' }}
  • @endforeach
@endif
@endforeach
@endif

{{ $faqTitle }}

@foreach($faqRows as $row) @php $q = is_array($row) && is_string($row['q'] ?? null) ? (string) $row['q'] : ''; $a = is_array($row) && is_string($row['a'] ?? null) ? (string) $row['a'] : ''; @endphp @if(trim($q) !== '' || trim($a) !== '')
@if(trim($q) !== '')

{{ $q }}

@endif @if(trim($a) !== '')

{{ $a }}

@endif
@endif @endforeach
@endsection