record; $total = $customer->donations() ->whereHas('donationConfirmation', fn ($q) => $q->whereNotNull('confirmed_at')) ->sum('amount') / 100; $giftAid = $customer->donations() ->whereHas('donationPreferences', fn ($q) => $q->where('is_gift_aid', true)) ->exists(); $badges = ''; if ($total >= 1000) { $badges .= ' ⭐ Major Donor'; } if ($giftAid) { $badges .= ' Gift Aid'; } $sg = $customer->scheduledGivingDonations()->where('is_active', true)->count(); if ($sg > 0) { $badges .= ' Monthly Supporter'; } return new HtmlString($customer->name . $badges); } public function getSubheading(): ?string { $customer = $this->record; $total = $customer->donations() ->whereHas('donationConfirmation', fn ($q) => $q->whereNotNull('confirmed_at')) ->sum('amount') / 100; $count = $customer->donations() ->whereHas('donationConfirmation', fn ($q) => $q->whereNotNull('confirmed_at')) ->count(); $first = $customer->donations()->oldest()->first(); $since = $first ? $first->created_at->format('M Y') : 'N/A'; return "£" . number_format($total, 2) . " donated across {$count} donations · Supporter since {$since}"; } protected function getHeaderActions(): array { $customer = $this->record; return [ Action::make('add_note') ->label('Add Note') ->icon('heroicon-o-chat-bubble-left-ellipsis') ->color('gray') ->form([ Textarea::make('body') ->label('Note') ->placeholder("e.g. Called on " . now()->format('d M') . " — wants to update their address") ->required() ->rows(3), ]) ->action(function (array $data) use ($customer) { $customer->internalNotes()->create([ 'user_id' => auth()->id(), 'body' => $data['body'], ]); Notification::make()->title('Note added')->success()->send(); }), Action::make('resend_last_receipt') ->label('Resend Last Receipt') ->icon('heroicon-o-envelope') ->color('info') ->requiresConfirmation() ->modalDescription('This will email the most recent donation receipt to ' . $customer->email) ->visible(fn () => $customer->donations()->whereHas('donationConfirmation', fn ($q) => $q->whereNotNull('confirmed_at'))->exists()) ->action(function () use ($customer) { $donation = $customer->donations() ->whereHas('donationConfirmation', fn ($q) => $q->whereNotNull('confirmed_at')) ->latest() ->first(); if ($donation) { try { \Illuminate\Support\Facades\Mail::to($customer->email) ->send(new \App\Mail\DonationConfirmed($donation)); Notification::make()->title('Receipt sent to ' . $customer->email)->success()->send(); } catch (\Throwable $e) { Notification::make()->title('Failed to send receipt')->body($e->getMessage())->danger()->send(); } } }), Action::make('view_in_stripe') ->label('View in Stripe') ->icon('heroicon-o-arrow-top-right-on-square') ->color('gray') ->url(function () use ($customer) { $donation = $customer->donations()->whereNotNull('provider_reference')->latest()->first(); if ($donation && $donation->provider_reference) { return 'https://dashboard.stripe.com/search?query=' . urlencode($customer->email); } return 'https://dashboard.stripe.com/search?query=' . urlencode($customer->email); }) ->openUrlInNewTab(), ]; } }