Home: - Empty state: 2-column with 'How it works' 5-step guide - Has data: 7/5 grid — pledges left, education right - Right column: status breakdown, sources, 'What to do next' contextual links, 'What the statuses mean' guide Money: - 8/4 two-column layout: table left, education right - Right column: 'How matching works' 4-step guide, status explainer, collection tips, quick action buttons - No more wasted right margin Reports: - 7/5 two-column layout: downloads left, education right - Right column: 'For your treasurer' 3-step guide, Gift Aid FAQ, 'Understanding your numbers' explainer - Activity log moved to right column Settings: - Removed max-w-2xl constraint, now uses full width - 7/5 two-column: checklist left, education right - Right column: 'What you're setting up' (5 items with Required badges), Privacy & data assurance, Common questions FAQ, 'Need help?' CTA - Every setting explained in human language
97 lines
3.3 KiB
PHP
97 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources\ScheduledGivingDonationResource\Pages;
|
|
|
|
use App\Filament\Resources\ScheduledGivingDonationResource;
|
|
use App\Models\ScheduledGivingCampaign;
|
|
use App\Models\ScheduledGivingDonation;
|
|
use Filament\Resources\Components\Tab;
|
|
use Filament\Resources\Pages\ListRecords;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class ListScheduledGivingDonations extends ListRecords
|
|
{
|
|
protected static string $resource = ScheduledGivingDonationResource::class;
|
|
|
|
public function getHeading(): string
|
|
{
|
|
return 'Scheduled Giving Subscribers';
|
|
}
|
|
|
|
public function getSubheading(): string
|
|
{
|
|
$active = ScheduledGivingDonation::where('is_active', true)->count();
|
|
return "{$active} active subscribers across all campaigns.";
|
|
}
|
|
|
|
public function getTabs(): array
|
|
{
|
|
$campaigns = ScheduledGivingCampaign::withCount([
|
|
'donations as active_count' => fn ($q) => $q->where('is_active', true),
|
|
])->get();
|
|
|
|
$tabs = [];
|
|
|
|
// All active tab first
|
|
$totalActive = ScheduledGivingDonation::where('is_active', true)->count();
|
|
$tabs['active'] = Tab::make('All Active')
|
|
->icon('heroicon-o-check-circle')
|
|
->badge($totalActive)
|
|
->badgeColor('success')
|
|
->modifyQueryUsing(fn (Builder $q) => $q->where('is_active', true));
|
|
|
|
// One tab per campaign
|
|
foreach ($campaigns as $c) {
|
|
$slug = str($c->title)->slug()->toString();
|
|
$tabs[$slug] = Tab::make($c->title)
|
|
->icon('heroicon-o-calendar')
|
|
->badge($c->active_count > 0 ? $c->active_count : null)
|
|
->badgeColor($c->active ? 'primary' : 'gray')
|
|
->modifyQueryUsing(fn (Builder $q) => $q
|
|
->where('scheduled_giving_campaign_id', $c->id)
|
|
->where('is_active', true));
|
|
}
|
|
|
|
// Failed payments tab
|
|
$failedCount = ScheduledGivingDonation::where('is_active', true)
|
|
->whereHas('payments', fn ($q) => $q
|
|
->where('is_paid', false)
|
|
->where('attempts', '>', 0))
|
|
->count();
|
|
|
|
$tabs['failed'] = Tab::make('Failed Payments')
|
|
->icon('heroicon-o-exclamation-triangle')
|
|
->badge($failedCount > 0 ? $failedCount : null)
|
|
->badgeColor('danger')
|
|
->modifyQueryUsing(fn (Builder $q) => $q
|
|
->where('is_active', true)
|
|
->whereHas('payments', fn ($sub) => $sub
|
|
->where('is_paid', false)
|
|
->where('attempts', '>', 0)));
|
|
|
|
// Cancelled
|
|
$cancelled = ScheduledGivingDonation::where('is_active', false)->count();
|
|
$tabs['cancelled'] = Tab::make('Cancelled')
|
|
->icon('heroicon-o-x-circle')
|
|
->badge($cancelled > 0 ? $cancelled : null)
|
|
->badgeColor('gray')
|
|
->modifyQueryUsing(fn (Builder $q) => $q->where('is_active', false));
|
|
|
|
// Everything
|
|
$tabs['all'] = Tab::make('Everything')
|
|
->icon('heroicon-o-squares-2x2');
|
|
|
|
return $tabs;
|
|
}
|
|
|
|
protected function getHeaderActions(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function getDefaultActiveTab(): string | int | null
|
|
{
|
|
return 'active';
|
|
}
|
|
}
|