feat(plans): enhance plan management with dynamic providers, improved UI, and bug fixes
Dynamic Provider Integration: - Replace hardcoded provider arrays with database-driven payment_providers lookup - Display provider status (Active/Inactive) in selection dropdowns - Add provider_variant_id and provider_product_id input fields to plan configuration - Update EditPlan and SubscriptionForm with dynamic provider selection - Add empty state handling with helpful guidance when no providers exist UI/UX Improvements: - Format billing_cycle_days to readable text (Daily, Weekly, Monthly, Quarterly, Annually) - Add color-coded badges for billing cycle frequency - Fix plan_providers and plan_feature_limits count display with eager loading - Implement intelligent color coding for count indicators - Add visual status indicators for provider availability Database Compatibility: - Fix SQLite strftime() compatibility across all dashboard widgets - Fix CAST AS REAL syntax in ChurnAnalysis widget - Add database-agnostic date and cast expression methods - Support MySQL, SQLite, PostgreSQL, and SQL Server Bug Fixes: - Fix null reference error in SubscriptionForm provider_data access - Add null safety checks for new subscription creation - Optimize queries with withCount() to prevent N+1 issues Performance Optimizations: - Add eager loading with withCount() for relationship counts - Optimize plan provider and feature limit queries - Prevent N+1 query issues in resource tables BREAKING CHANGE: Plan provider configuration now uses dynamic provider options from payment_providers table instead of hardcoded list.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\PlanResource\Pages;
|
||||
|
||||
use App\Filament\Resources\PlanResource;
|
||||
use App\Models\PaymentProvider;
|
||||
use App\Models\PlanFeature;
|
||||
use App\Models\TrialConfiguration;
|
||||
use Filament\Actions;
|
||||
@@ -188,23 +189,48 @@ class EditPlan extends EditRecord
|
||||
Grid::make(2)->schema([
|
||||
Select::make('provider')
|
||||
->label('Provider')
|
||||
->options([
|
||||
'stripe' => 'Stripe',
|
||||
'lemon_squeezy' => 'Lemon Squeezy',
|
||||
'polar' => 'Polar.sh',
|
||||
'oxapay' => 'OxaPay',
|
||||
'crypto' => 'Crypto',
|
||||
'activation_key' => 'Activation Key',
|
||||
])
|
||||
->options(function () {
|
||||
$providers = PaymentProvider::orderBy('priority', 'desc')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
if ($providers->isEmpty()) {
|
||||
return [
|
||||
'no_providers' => '⚠️ No payment providers configured - Please add providers first',
|
||||
];
|
||||
}
|
||||
|
||||
return $providers->mapWithKeys(function ($provider) {
|
||||
$status = $provider->is_active ? 'Active' : 'Inactive';
|
||||
|
||||
return [
|
||||
$provider->name => "{$provider->display_name} ({$status})",
|
||||
];
|
||||
})->toArray();
|
||||
})
|
||||
->required()
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state, callable $set) {
|
||||
match ($state) {
|
||||
'stripe' => $set('provider_price_id_label', 'Stripe Price ID'),
|
||||
'lemon_squeezy' => $set('provider_price_id_label', 'Lemon Squeezy Variant ID'),
|
||||
'polar' => $set('provider_price_id_label', 'Polar Product ID'),
|
||||
default => $set('provider_price_id_label', 'Provider ID'),
|
||||
};
|
||||
if ($state === 'no_providers') {
|
||||
$set('provider_price_id_label', 'N/A - Add providers first');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$provider = PaymentProvider::where('name', $state)->first();
|
||||
$label = $provider ? $provider->display_name : 'Provider';
|
||||
$set('provider_price_id_label', "{$label} ID");
|
||||
})
|
||||
->helperText(function (callable $get) {
|
||||
$providers = PaymentProvider::orderBy('priority', 'desc')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
if ($providers->isEmpty()) {
|
||||
return '⚠️ No payment providers available. Please configure payment providers in the Payment Providers section first.';
|
||||
}
|
||||
|
||||
return 'Select a payment provider for this plan';
|
||||
}),
|
||||
|
||||
Toggle::make('is_enabled')
|
||||
@@ -224,6 +250,16 @@ class EditPlan extends EditRecord
|
||||
->helperText('Override plan price for this provider'),
|
||||
]),
|
||||
|
||||
Grid::make(2)->schema([
|
||||
TextInput::make('provider_variant_id')
|
||||
->label('Provider Variant ID')
|
||||
->helperText('Variant ID from the provider (if applicable)'),
|
||||
|
||||
TextInput::make('provider_product_id')
|
||||
->label('Provider Product ID')
|
||||
->helperText('Product ID from the provider (if applicable)'),
|
||||
]),
|
||||
|
||||
Grid::make(2)->schema([
|
||||
TextInput::make('currency')
|
||||
->label('Currency')
|
||||
|
||||
Reference in New Issue
Block a user