@extends('layouts.admin') @section('title','Marketing statistics') @section('admin-content')
CAMPAIGN PERFORMANCE

Marketing statistics.

Participation, verified purchases and rewards at a glance.

Export CSV
Last 30 days

Receipts submitted {{ $from->format('d M Y') }}–{{ $to->format('d M Y') }}, Malaysia time (UTC+8). Outcomes are current as of {{ now()->format('d M Y, H:i') }}. Filters apply to receipt submission date, not purchase, approval or email date. Older branch names without a linked store are included only when no state or branch is selected.

@foreach(['Participants'=>(int)$counts->participants,'Receipts submitted'=>(int)$counts->submitted,'Approved receipts'=>(int)$counts->approved,'Spins played'=>$spinCount,'TNG PINs issued'=>$issued,'TNG value issued'=>'MYR '.number_format($issuedValue,2)] as $label=>$value)
{{ $label }}{{ is_int($value)?number_format($value):$value }}
@endforeach

Verified purchase value

@forelse($money as $currency=>$amount)

{{ $currency }} {{ number_format($amount['cents']/100,2) }}

Average recorded approved purchase: {{ $currency }} {{ number_format($amount['cents']/100/$amount['count'],2) }} · {{ $amount['count'] }} receipts

@empty

No recorded approved purchase amounts.

@endforelse{{ $missingAmounts }} approved receipts have no recorded amount. Values represent approved receipt purchases; they do not establish sales caused by this campaign.

New and returning participants

First-time participants
{{ (int)$counts->participants-$returning }}
Returning participants
{{ $returning }}
A participant has a verified customer account linked to a receipt in this selection. Returning means they submitted a receipt before this date range, across any branch. This is participation history, not account registration.

Daily receipt activity

Submitted receipts and their currently approved outcomes, grouped by submission day.

● Submitted● Approved
@php($maximum=max(1,max(array_column($series,'submitted'))))
Daily receipt activity @foreach($series as $index=>$point)@php($step=max(660,count($series)*12)/count($series)){{ $point['day'] }}: {{ $point['submitted'] }} submitted{{ $point['day'] }}: {{ $point['approved'] }} approved@if($index%max(1,(int)ceil(count($series)/6))===0){{ substr($point['day'],5) }}@endif @endforeach
View daily figures
@foreach($series as $point)@endforeach
Submission dateSubmittedCurrently approved
{{ $point['day'] }}{{ $point['submitted'] }}{{ $point['approved'] }}

Customer journey

Number of receipts reaching each milestone.

@foreach(['Submitted'=>(int)$counts->submitted,'Email verified'=>(int)$counts->verified,'At least one spin played'=>$played,'At least one confirmed result'=>$won] as $label=>$value)
{{ $label }}{{ $value }}{{ $value }}
@endforeachReceipts can be approved before or after spinning. Confirmed wheel results can include a no-prize outcome.

Receipt review

Pending review
{{ (int)$counts->pending }}
Approval rate among decisions
{{ $counts->approved+$counts->rejected ? number_format(100*$counts->approved/($counts->approved+$counts->rejected),1).'%' : '—' }}
Average submission-to-review time
{{ $reviewCount?number_format($reviewMinutes/$reviewCount/60,1).' hours':'—' }}
Approval rate excludes pending, expired and unverified receipts. Review time uses records with a recorded review timestamp.

Common rejection reasons

@forelse($reasons as $reason)

{{ $reason->reason ?: 'Not recorded' }} ({{ $reason->total }})

@empty

No rejected receipts in this selection.

@endforelse

Branch comparison

Top 20 recorded branch labels by receipt submissions. CSV includes every branch.

@forelse($branchRows->take(20) as $row)@empty@endforelse
BranchParticipantsReceiptsApprovedVerified value
{{ $row->branch }}{{ $row->participants }}{{ $row->receipts }}{{ $row->approved }}@forelse(($branchMoney[($row->branch_id??'legacy').'|'.$row->branch]??[]) as $currency=>$cents)
{{ $currency }} {{ number_format($cents/100,2) }}
@empty — @endforelse
No receipt activity in this selection.
Participants can appear in more than one branch. Historical branch labels are preserved.

Wheel results

@forelse($rewards as $reward)@empty@endforelse
Reward / outcomeResultsConfirmed
{{ $reward->prize_name }}{{ $reward->wins }}{{ $reward->confirmed }}
No spins for these receipts.
TNG issuance is counted only once per assigned PIN. It does not confirm redemption.

Currently available PINs across the whole campaign: {{ $available }}

Email and marketing audience

@foreach(['Email sent'=>'sent','Pending'=>'queued','Sending'=>'sending','Failed'=>'failed'] as $label=>$key)
{{ $label }}
{{ $email[$key]??0 }}
@endforeach
Email offers opted in
{{ (int)$audience->email }}
WhatsApp/SMS offers opted in
{{ (int)$audience->mobile }}
Spin sign-in links used
{{ (int)$links->used }}
Unused expired sign-in links
{{ (int)$links->expired }}
Email counts cover approval/reward email jobs for the selected receipts. Sent means accepted by the configured mail transport, not confirmed inbox delivery. Retry attempts are not extra emails in this count. Offer opt-ins are current consent for these participants. Link counts include replacement links and do not measure email opens.
@endsection @push('scripts')@endpush