loadSubscriptionData(); } public function loadSubscriptionData(): void { $this->loading = true; $user = Auth::user(); $this->subscription = $user->subscription('default'); if ($this->subscription) { $this->plan = $this->subscription->plan->load([ 'planFeatureLimits.planFeature', 'trialConfiguration', 'planTier', ]); $this->loadUsageData(); $this->loadUpgradePaths(); $this->loadTrialExtensions(); } $this->loading = false; } private function loadUsageData(): void { if (! $this->subscription) { return; } $this->usageData = PlanUsage::where('user_id', Auth::id()) ->where('plan_id', $this->subscription->plan_id) ->with('planFeature') ->get() ->map(function ($usage) { $limit = $this->plan->planFeatureLimits ->where('plan_feature_id', $usage->plan_feature_id) ->first(); return [ 'feature' => $usage->planFeature, 'usage' => $usage->usage_value, 'period' => $usage->period_type, 'limit' => $limit, 'remaining' => $limit ? $limit->getRemainingUsage($usage->usage_value, $this->subscription->onTrial()) : 0, 'percentage_used' => $limit && $limit->limit_value ? min(100, ($usage->usage_value / $limit->limit_value) * 100) : 0, ]; }); } private function loadUpgradePaths(): void { if (! $this->subscription) { return; } $this->upgradePaths = $this->plan->getUpgradePath(); } private function loadTrialExtensions(): void { if (! $this->subscription) { return; } $this->trialExtensions = TrialExtension::where('subscription_id', $this->subscription->id) ->orderBy('created_at', 'desc') ->get(); } public function requestTrialExtension(): void { if (! $this->subscription || ! $this->subscription->onTrial()) { session()->flash('error', 'You can only request extensions for active trials.'); return; } $trialConfig = $this->plan->getTrialConfig(); if (! $trialConfig) { session()->flash('error', 'This plan does not support trial extensions.'); return; } $currentExtensions = $this->trialExtensions->count(); if (! $trialConfig->canExtendTrial($currentExtensions)) { session()->flash('error', 'You have reached the maximum number of trial extensions.'); return; } // Create trial extension request TrialExtension::create([ 'subscription_id' => $this->subscription->id, 'user_id' => Auth::id(), 'original_ends_at' => $this->subscription->trial_ends_at, 'extension_days' => $trialConfig->trial_duration_days, 'status' => 'pending', 'reason' => 'User requested extension via dashboard', ]); session()->flash('success', 'Trial extension request submitted successfully.'); $this->loadTrialExtensions(); } public function cancelSubscription(): void { if (! $this->subscription) { return; } $this->subscription->cancel(); session()->flash('success', 'Subscription cancelled successfully.'); $this->loadSubscriptionData(); } public function pauseSubscription(): void { if (! $this->subscription) { return; } // Implement pause logic based on your business requirements session()->flash('info', 'Pause functionality coming soon.'); } public function resumeSubscription(): void { if (! $this->subscription) { return; } $this->subscription->resume(); session()->flash('success', 'Subscription resumed successfully.'); $this->loadSubscriptionData(); } public function getSubscriptionStatus(): string { if (! $this->subscription) { return 'No Subscription'; } return match ($this->subscription->status) { 'active' => 'Active', 'trialing' => 'Trial', 'cancelled' => 'Cancelled', 'past_due' => 'Past Due', 'unpaid' => 'Unpaid', default => 'Unknown', }; } public function getSubscriptionStatusColor(): string { if (! $this->subscription) { return 'gray'; } return match ($this->subscription->status) { 'active' => 'green', 'trialing' => 'blue', 'cancelled' => 'red', 'past_due' => 'yellow', 'unpaid' => 'red', default => 'gray', }; } public function getDaysRemaining(): int { if (! $this->subscription) { return 0; } $endsAt = $this->subscription->trial_ends_at ?? $this->subscription->ends_at; return $endsAt ? max(0, $endsAt->diffInDays(now())) : 0; } public function getNextBillingDate(): string { if (! $this->subscription || $this->subscription->cancelled()) { return 'N/A'; } return $this->subscription->ends_at?->format('M j, Y') ?? 'N/A'; } public function getUsagePercentage($usageData): int { return (int) round($usageData['percentage_used']); } public function getUsageColor($percentage): string { return match (true) { $percentage >= 90 => 'red', $percentage >= 75 => 'yellow', $percentage >= 50 => 'blue', default => 'green', }; } public function render() { return view('livewire.dashboard.subscription-dashboard'); } }