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(),
];
}
}