Skip to content

Billing Pages

Purpose: Subscription and billing management
Category: Account Management
Pages: 3 pages
Audience: Authenticated users


Overview

Pages for managing subscriptions, viewing invoices, and updating payment methods.


1. Subscription Plan

File: src/app/Billing_details_subscriptionplan/page.tsx (586 lines)
Route: /Billing_details_subscriptionplan
Type: Protected
Purpose: View current subscription and usage statistics

⭐ Most Comprehensive Billing Page - Usage Tracking & Plan Details


State Variables (5)

  1. isBillingDropdownOpen (boolean) - Sidebar menu state
  2. userData (UserData | null) - Complete user data from API
  3. userFeatures (UserFeatures | null) - Subscription limits and features
  4. planDetails (any) - Plan configuration
  5. loading (boolean) - Initial load state

Type Definitions

UserData Interface (34 fields):

interface UserData {
  _id: string;
  email: string;
  name: string;
  verified: boolean;
  account_status: string; // "active" | "inactive"
  payment_status: string; // "success" | "pending"
  user_created_at(DATE): string;
  subscription_id: string;
  subscription_date: string;
  user_id: string;
  subscription_selected_at: string;
  selected_subscription_id: string;
  pending_order_id: string;

  // Optional subscription fields
  razorpay_subscription_id?: string;
  subscription_status?: string;
  plan_category?: string; // "free" | "starter" | "pro" | "business" | "enterprise"
  billing_cycle?: string; // "monthly" | "yearly"
  subscription_quantity?: number;
  subscription_created_at?: string;
  subscription_verified_at?: string;
  entitlement_end?: string; // Subscription end date
}

UserFeatures Interface:

interface UserFeatures {
  user_id: string;
  subscription_id: string;
  baseFeatureID: string;
  featureIDs: string[];
  no_of_chatbots: number;
  no_of_chat_sessions: number;
  no_of_linkcrawls: number;
  no_of_users: number;
  grace_period: string;
  subscription_details: {
    pricing: any;
    offers: any;
  };
  base_feature_details: {
    no_of_chatbots: number;
    no_of_chat_sessions: string;
    no_of_users: string;
    no_of_linkcrawls: string;
    grace_period: string;
  };
  features: Array<{
    featureID: string;
    feature: string;
    feature_value: string;
  }>;
}

API Integration (3 Endpoints)

1. Get User Data:

const fetchUserData = async (userId: string) => {
  const response = await fetch(
    `${process.env.NEXT_PUBLIC_API_BASE_URL}/v2/get-user-data/${userId}`,
    { method: "GET", headers: { "Content-Type": "application/json" } }
  );

  const data: ApiResponse = await response.json();
  setUserData(data.user_data);

  // Fetch user features after getting user data
  await fetchUserFeatures(userId);
};

2. Get User Features:

const fetchUserFeatures = async (userId: string) => {
  const response = await fetch(
    `${process.env.NEXT_PUBLIC_API_BASE_URL}/v2/get-user-features/${userId}`,
    { method: "GET", headers: { "Content-Type": "application/json" } }
  );

  const data: UserFeaturesResponse = await response.json();
  setUserFeatures(data.user_features);
};

3. Get Plan Details:

const fetchPlanDetails = async (planCategory: string) => {
  const response = await fetch(
    `${process.env.NEXT_PUBLIC_API_BASE_URL}/v2/subscriptions/plans`,
    { method: "GET", headers: { "Content-Type": "application/json" } }
  );

  const data = await response.json();
  const plan = data.plans.find((p) => p.category === planCategory);
  setPlanDetails(plan);
};

Subscription Overview Section

4 Info Cards:

  1. Subscription Plan Card:

  2. Plan name (capitalized): "Free Plan" / "Starter Plan" / "Pro Plan" etc.

  3. Billing cycle: from userData.billing_cycle
  4. Icon: Document icon
  5. Color: Orange theme

  6. Subscription Date Card:

  7. Start date: from userData.subscription_created_at or user_created_at(DATE)

  8. Format: "DD Month YYYY" (e.g., "23 December 2024")
  9. End date: from userData.entitlement_end (if available)
  10. Icon: Calendar icon
  11. Color: Blue theme

  12. Payment Status Card:

  13. Status: from userData.payment_status ("Success" | "Pending")

  14. Selected date: from userData.subscription_selected_at
  15. Icon: Credit card icon
  16. Color: Green for success, Yellow for pending
  17. Dynamic text color based on status

  18. Account Status Card:

  19. Status: from userData.account_status ("Active" | "Inactive")
  20. Icon: User icon
  21. Color: Purple theme
  22. Dynamic text color: Green for active, Red for inactive

Usage Overview Table

Desktop Table View:

Features Included In Plan Used Remaining
Chatbots {limit} {used} {remaining}
Link Crawl {limit} {used} {remaining}
Chat Sessions {limit} {used} {remaining}

Hover Effects:

  • Row background changes to orange-50 on hover
  • Alternating row colors (white / gray-50)

Mobile Cards View

3 Separate Cards:

  1. Chatbots Card:

  2. Icon: Chat bubble

  3. 3-column grid: Included | Used | Remaining
  4. Color-coded backgrounds (orange-50, blue-50, green-50)

  5. Link Crawl Card:

  6. Icon: Link icon

  7. Same 3-column grid layout

  8. Chat Sessions Card:

  9. Icon: Chat bubble
  10. Same 3-column grid layout

Usage Calculation Logic

Plan Limits (from userFeatures):

const getPlanLimits = (userFeatures: UserFeatures | null) => {
  if (!userFeatures) {
    return { chatbots: 1, chatSessions: 50, linkCrawl: 10 }; // Free plan defaults
  }

  return {
    chatbots: userFeatures.no_of_chatbots || 1,
    chatSessions: userFeatures.no_of_chat_sessions || 50,
    linkCrawl: userFeatures.no_of_linkcrawls || 10,
  };
};

Usage Data (Mock - TODO: Real API):

const getUsageData = (userFeatures: UserFeatures | null) => {
  if (!userFeatures) return defaultUsage;

  const limits = getPlanLimits(userFeatures);

  // Mock usage percentages
  const mockUsage = {
    chatbots: {
      used: Math.floor(limits.chatbots * 0.1),
      remaining: limits.chatbots - Math.floor(limits.chatbots * 0.1),
    },
    chatSessions: {
      used: Math.floor(limits.chatSessions * 0.15),
      remaining: limits.chatSessions - Math.floor(limits.chatSessions * 0.15),
    },
    linkCrawl: {
      used: Math.floor(limits.linkCrawl * 0.2),
      remaining: limits.linkCrawl - Math.floor(limits.linkCrawl * 0.2),
    },
  };

  return mockUsage;
};

Desktop Sidebar (Black Background):

Dashboard Link:

  • /chatbots route
  • Orange border when active

Billing Details Dropdown:

  • Expandable/collapsible
  • 3 sub-items:
  • Subscription Plan (current - orange background)
  • Payment Mode - Link to /Billing_details_paymentmode
  • Invoice Center - Link to /Billing_details_invoicecenter

Action Button

"Upgrade Plan" Button:

  • Orange background (bg-orange-500)
  • Hover effect (hover:bg-orange-600)
  • Top-right corner
  • Presumably links to pricing page (not implemented in visible code)

Loading State

{
  loading ? (
    <div className="flex items-center justify-center min-h-96">
      <div className="animate-spin rounded-full h-32 w-32 border-b-2 border-orange-500"></div>
      <p className="mt-4 text-gray-600">Loading subscription details...</p>
    </div>
  ) : (
    <SubscriptionPlanContent />
  );
}

Responsive Design

Desktop (md:):

  • Sidebar + content layout
  • 4-column grid for info cards (lg:grid-cols-4)
  • Full table view

Mobile:

  • No sidebar
  • 2-column grid for info cards (sm:grid-cols-2)
  • Card-based usage display
  • Stacked layout

Session Storage

Authentication Check:

const token = sessionStorage.getItem("authToken");
const userId = sessionStorage.getItem("user_id");

if (!token || !userId) {
  router.push("/login");
  return;
}

2. Payment Mode

File: src/app/Billing_details_paymentmode/page.tsx
Route: /Billing_details_paymentmode
Type: Protected
Purpose: Manage payment methods

Features:

  • Current payment method display
  • Add new card/payment method
  • Update payment method
  • Remove payment method
  • Default payment method selection

Estimated Lines: ~400

API Integration:

  • GET /v2/payment-methods?user_id={id} - List methods
  • POST /v2/payment-methods - Add method
  • PUT /v2/payment-methods/{id} - Update method
  • DELETE /v2/payment-methods/{id} - Remove method

3. Invoice Center

File: src/app/Billing_details_invoicecenter/page.tsx
Route: /Billing_details_invoicecenter
Type: Protected
Purpose: View and download invoices

Features:

  • List of all invoices
  • Invoice details (date, amount, status)
  • Download PDF button
  • Pagination
  • Filter by date range
  • Search by invoice number

Estimated Lines: ~350

API Integration:

  • GET /v2/invoices?user_id={id} - List invoices
  • GET /v2/invoice/{id}/download - Download PDF

Summary

Page Lines Key Feature Complexity
Subscription Plan 586 Usage tracking ⭐⭐⭐⭐⭐
Payment Mode ~400 Card management ⭐⭐⭐
Invoice Center ~350 Invoice downloads ⭐⭐⭐

Total: ~1,336 lines of billing management code


Common Patterns

  1. Protected routes - Auth required
  2. Sidebar navigation - Consistent across billing pages
  3. API integration - RESTful endpoints
  4. Loading states - Orange spinner
  5. Responsive design - Desktop sidebar, mobile cards
  6. Toast notifications - Error/success feedback
  7. Session storage - User authentication

"Every subscription tracked, every invoice accessible."