import { useState, useEffect } from 'react'; import PageMeta from '../../components/common/PageMeta'; import { useToast } from '../../components/ui/toast/ToastContainer'; import { fetchCreditUsage, CreditUsageLog, fetchUsageLimits, LimitCard } from '../../services/api'; import { Card } from '../../components/ui/card'; import Badge from '../../components/ui/badge/Badge'; export default function Usage() { const toast = useToast(); const [usageLogs, setUsageLogs] = useState([]); const [limits, setLimits] = useState([]); const [loading, setLoading] = useState(true); const [limitsLoading, setLimitsLoading] = useState(true); useEffect(() => { loadUsage(); loadLimits(); }, []); const loadUsage = async () => { try { setLoading(true); const response = await fetchCreditUsage({ page: 1 }); setUsageLogs(response.results || []); } catch (error: any) { toast.error(`Failed to load usage logs: ${error.message}`); } finally { setLoading(false); } }; const loadLimits = async () => { try { setLimitsLoading(true); const response = await fetchUsageLimits(); console.log('Usage limits response:', response); setLimits(response.limits || []); if (!response.limits || response.limits.length === 0) { console.warn('No limits data received from API'); } } catch (error: any) { console.error('Error loading usage limits:', error); toast.error(`Failed to load usage limits: ${error.message}`); setLimits([]); } finally { setLimitsLoading(false); } }; const groupedLimits = { planner: limits.filter(l => l.category === 'planner'), writer: limits.filter(l => l.category === 'writer'), images: limits.filter(l => l.category === 'images'), ai: limits.filter(l => l.category === 'ai'), general: limits.filter(l => l.category === 'general'), }; // Debug info console.log('[Usage Component] Render state:', { limitsLoading, limitsCount: limits.length, groupedLimits, plannerCount: groupedLimits.planner.length, writerCount: groupedLimits.writer.length, imagesCount: groupedLimits.images.length, aiCount: groupedLimits.ai.length, generalCount: groupedLimits.general.length, }); return (

Acoount Limits Usage 2

Monitor your plan limits and usage statistics

{/* Debug Info - Remove in production */} {import.meta.env.DEV && (
Debug: Loading={limitsLoading ? 'Yes' : 'No'}, Limits={limits.length}, Planner={groupedLimits.planner.length}, Writer={groupedLimits.writer.length}, Images={groupedLimits.images.length}, AI={groupedLimits.ai.length}, General={groupedLimits.general.length}
)} {/* Limit Cards by Category */} {limitsLoading ? (
Loading limits...
) : limits.length === 0 ? (

No usage limits data available.

The API endpoint may not be responding or your account may not have a plan configured.

Check browser console for errors. Endpoint: /v1/billing/credits/usage/limits/

) : (
{/* Planner Limits */} {groupedLimits.planner.length > 0 && (

Planner Limits

{groupedLimits.planner.map((limit, idx) => ( ))}
)} {/* Writer Limits */} {groupedLimits.writer.length > 0 && (

Writer Limits

{groupedLimits.writer.map((limit, idx) => ( ))}
)} {/* Image Limits */} {groupedLimits.images.length > 0 && (

Image Generation Limits

{groupedLimits.images.map((limit, idx) => ( ))}
)} {/* AI Credits */} {groupedLimits.ai.length > 0 && (

AI Credits

{groupedLimits.ai.map((limit, idx) => ( ))}
)} {/* General Limits */} {groupedLimits.general.length > 0 && (

General Limits

{groupedLimits.general.map((limit, idx) => ( ))}
)}
)} {/* Usage Logs Table */}

Usage Logs

{loading ? (
Loading...
) : (
{usageLogs.map((log) => ( ))}
Date Operation Credits Used Model Cost (USD)
{new Date(log.created_at).toLocaleString()} {log.operation_type_display} {log.credits_used} {log.model_used || 'N/A'} {log.cost_usd ? `$${parseFloat(log.cost_usd).toFixed(4)}` : 'N/A'}
)}
); } // Limit Card Component function LimitCardComponent({ limit }: { limit: LimitCard }) { const getCategoryColor = (category: string) => { switch (category) { case 'planner': return 'blue'; case 'writer': return 'green'; case 'images': return 'purple'; case 'ai': return 'orange'; case 'general': return 'gray'; default: return 'gray'; } }; const getUsageStatus = (percentage: number) => { if (percentage >= 90) return 'danger'; if (percentage >= 75) return 'warning'; return 'success'; }; const percentage = Math.min(limit.percentage, 100); const status = getUsageStatus(percentage); const color = getCategoryColor(limit.category); const statusColorClass = status === 'danger' ? 'bg-red-500' : status === 'warning' ? 'bg-yellow-500' : 'bg-green-500'; const statusTextColor = status === 'danger' ? 'text-red-600 dark:text-red-400' : status === 'warning' ? 'text-yellow-600 dark:text-yellow-400' : 'text-green-600 dark:text-green-400'; return (

{limit.title}

{limit.category}
{limit.used.toLocaleString()} / {limit.limit.toLocaleString()} {limit.unit}
{limit.available.toLocaleString()} available {percentage.toFixed(1)}% used
); }