Section 6 COmpleted

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-27 03:41:51 +00:00
parent 4e9bf0ba56
commit e5959c3e72
22 changed files with 310 additions and 314 deletions

View File

@@ -1,12 +1,13 @@
/**
* Plans & Billing Page - Subscription & Payment Management
* Tabs: Current Plan, Upgrade Plan, Billing History
* Tab selection driven by URL path for sidebar navigation
*
* Note: Usage tracking is consolidated in UsageAnalyticsPage (/account/usage)
*/
import { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';
import { Link, useLocation } from 'react-router-dom';
import {
CreditCard, Package, TrendingUp, FileText, Wallet, ArrowUpCircle,
Loader2, AlertCircle, CheckCircle, Download, Zap, Globe, Users, X
@@ -49,8 +50,17 @@ import { useAuthStore } from '../../store/authStore';
type TabType = 'plan' | 'upgrade' | 'invoices';
// Map URL paths to tab types
function getTabFromPath(pathname: string): TabType {
if (pathname.includes('/upgrade')) return 'upgrade';
if (pathname.includes('/history')) return 'invoices';
return 'plan';
}
export default function PlansAndBillingPage() {
const [activeTab, setActiveTab] = useState<TabType>('plan');
const location = useLocation();
// Derive active tab from URL path
const activeTab = getTabFromPath(location.pathname);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string>('');
const [planLoadingId, setPlanLoadingId] = useState<number | null>(null);
@@ -347,18 +357,25 @@ export default function PlansAndBillingPage() {
const subscriptionStatus = currentSubscription?.status || (hasActivePlan ? 'active' : 'none');
const hasPendingManualPayment = payments.some((p) => p.status === 'pending_approval');
const tabs = [
{ id: 'plan' as TabType, label: 'Current Plan', icon: <Package className="w-4 h-4" /> },
{ id: 'upgrade' as TabType, label: 'Upgrade Plan', icon: <Wallet className="w-4 h-4" /> },
{ id: 'invoices' as TabType, label: 'History', icon: <FileText className="w-4 h-4" /> },
];
// Page titles based on active tab
const pageTitles = {
plan: { title: 'Current Plan', description: 'View your subscription details and features' },
upgrade: { title: 'Upgrade Plan', description: 'Compare plans and upgrade your subscription' },
invoices: { title: 'Billing History', description: 'View invoices and manage payment methods' },
};
return (
<div className="p-6">
{/* Page Header with Breadcrumb */}
<div className="mb-6">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Your Subscription</h1>
<div className="flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 mb-2">
<span>Plans & Billing</span>
<span></span>
<span className="text-gray-900 dark:text-white font-medium">{pageTitles[activeTab].title}</span>
</div>
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">{pageTitles[activeTab].title}</h1>
<p className="text-gray-600 dark:text-gray-400 mt-1">
Manage your plan and view usage
{pageTitles[activeTab].description}
</p>
</div>
@@ -367,7 +384,7 @@ export default function PlansAndBillingPage() {
<div className="mb-4 p-4 rounded-lg border border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-800 dark:bg-amber-900/20 dark:text-amber-200">
No active plan. Choose a plan below to activate your account.
</div>
)}
)}}
{hasPendingManualPayment && (
<div className="mb-4 p-4 rounded-lg border border-[var(--color-info-200)] bg-[var(--color-info-50)] text-[var(--color-info-800)] dark:border-[var(--color-info-800)] dark:bg-[var(--color-info-900)]/20 dark:text-[var(--color-info-100)]">
We received your manual payment. Its pending admin approval; activation will complete once approved.
@@ -381,29 +398,6 @@ export default function PlansAndBillingPage() {
</div>
)}
{/* Tabs */}
<div className="mb-6 border-b border-gray-200 dark:border-gray-700">
<nav className="-mb-px flex space-x-8 overflow-x-auto">
{tabs.map((tab) => (
<button
type="button"
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`
flex items-center gap-2 py-4 px-1 border-b-2 font-medium text-sm whitespace-nowrap
${activeTab === tab.id
? 'border-[var(--color-brand-500)] text-[var(--color-brand-500)]'
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300'
}
`}
>
{tab.icon}
{tab.label}
</button>
))}
</nav>
</div>
{/* Tab Content */}
<div className="mt-6">
{/* Current Plan Tab */}
@@ -476,7 +470,8 @@ export default function PlansAndBillingPage() {
<Button
variant="primary"
tone="brand"
onClick={() => setActiveTab('upgrade')}
as={Link}
to="/account/plans/upgrade"
startIcon={<ArrowUpCircle className="w-4 h-4" />}
>
Upgrade Plan