This commit is contained in:
IGNY8 VPS (Salman)
2025-12-12 14:08:27 +00:00
parent 6e2101d019
commit f163a2e07d
14 changed files with 1324 additions and 677 deletions

View File

@@ -86,7 +86,7 @@ export default function AccountSettingsPage() {
if (loading) {
return (
<div className="flex items-center justify-center min-h-screen">
<Loader2 className="w-8 h-8 animate-spin text-blue-600" />
<Loader2 className="w-8 h-8 animate-spin text-[var(--color-brand-500)]" />
</div>
);
}
@@ -261,7 +261,7 @@ export default function AccountSettingsPage() {
<button
type="submit"
disabled={saving}
className="flex items-center gap-2 px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
className="flex items-center gap-2 px-6 py-2 bg-[var(--color-brand-500)] text-white rounded-lg hover:bg-[var(--color-brand-600)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
{saving ? (
<>

View File

@@ -13,6 +13,8 @@ import Badge from '../../components/ui/badge/Badge';
import Button from '../../components/ui/button/Button';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { PricingTable, PricingPlan } from '../../components/ui/pricing-table';
import CreditCostBreakdownPanel from '../../components/billing/CreditCostBreakdownPanel';
import CreditCostsPanel from '../../components/billing/CreditCostsPanel';
import {
getCreditBalance,
getCreditPackages,
@@ -39,7 +41,7 @@ import {
} from '../../services/billing.api';
import { useAuthStore } from '../../store/authStore';
type TabType = 'plan' | 'credits' | 'invoices';
type TabType = 'plan' | 'credits' | 'purchase' | 'invoices';
export default function PlansAndBillingPage() {
const [activeTab, setActiveTab] = useState<TabType>('plan');
@@ -322,7 +324,7 @@ export default function PlansAndBillingPage() {
if (loading) {
return (
<div className="flex items-center justify-center min-h-screen">
<Loader2 className="w-8 h-8 animate-spin text-blue-600" />
<Loader2 className="w-8 h-8 animate-spin text-[var(--color-brand-500)]" />
</div>
);
}
@@ -341,6 +343,7 @@ export default function PlansAndBillingPage() {
const tabs = [
{ id: 'plan' as TabType, label: 'Current Plan', icon: <Package className="w-4 h-4" /> },
{ id: 'credits' as TabType, label: 'Credits Overview', icon: <TrendingUp className="w-4 h-4" /> },
{ id: 'purchase' as TabType, label: 'Purchase Credits', icon: <Wallet className="w-4 h-4" /> },
{ id: 'invoices' as TabType, label: 'Billing History', icon: <FileText className="w-4 h-4" /> },
];
@@ -360,7 +363,7 @@ export default function PlansAndBillingPage() {
</div>
)}
{hasPendingManualPayment && (
<div className="mb-4 p-4 rounded-lg border border-blue-200 bg-blue-50 text-blue-800 dark:border-blue-800 dark:bg-blue-900/20 dark:text-blue-100">
<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.
</div>
)}
@@ -383,7 +386,7 @@ export default function PlansAndBillingPage() {
className={`
flex items-center gap-2 py-4 px-1 border-b-2 font-medium text-sm whitespace-nowrap
${activeTab === tab.id
? 'border-blue-500 text-blue-600 dark:text-blue-400'
? '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'
}
`}
@@ -447,7 +450,7 @@ export default function PlansAndBillingPage() {
</div>
</div>
<div className="mt-6 flex gap-3">
<Button variant="outline" tone="neutral" onClick={() => setActiveTab('credits')}>
<Button variant="outline" tone="neutral" onClick={() => setActiveTab('purchase')}>
Purchase Credits
</Button>
{hasActivePlan && (
@@ -471,7 +474,7 @@ export default function PlansAndBillingPage() {
{(currentPlan?.features && currentPlan.features.length > 0
? currentPlan.features
: ['ai_writer', 'image_gen', 'auto_publish', 'custom_prompts', 'email_support', 'api_access'])
.map((feature) => (
.map((feature: string) => (
<div key={feature} className="flex items-start gap-2 text-sm">
<CheckCircle className="w-4 h-4 text-green-600 mt-0.5 flex-shrink-0" />
<span className="text-gray-700 dark:text-gray-300">{feature}</span>
@@ -519,9 +522,9 @@ export default function PlansAndBillingPage() {
/>
</div>
<Card className="p-6 bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 mt-6">
<h3 className="font-semibold text-blue-900 dark:text-blue-100 mb-2">Plan Change Policy</h3>
<ul className="space-y-2 text-sm text-blue-800 dark:text-blue-200">
<Card className="p-6 bg-[var(--color-brand-50)] dark:bg-[var(--color-brand-900)]/20 border-[var(--color-brand-200)] dark:border-[var(--color-brand-800)] mt-6">
<h3 className="font-semibold text-[var(--color-brand-900)] dark:text-[var(--color-brand-100)] mb-2">Plan Change Policy</h3>
<ul className="space-y-2 text-sm text-[var(--color-brand-800)] dark:text-[var(--color-brand-200)]">
<li> Upgrades take effect immediately and you'll be charged a prorated amount</li>
<li>• Downgrades take effect at the end of your current billing period</li>
<li>• Unused credits from your current plan will carry over</li>
@@ -538,7 +541,7 @@ export default function PlansAndBillingPage() {
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="p-6">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">Current Balance</div>
<div className="text-3xl font-bold text-blue-600 dark:text-blue-400">
<div className="text-3xl font-bold text-[var(--color-brand-500)]">
{creditBalance?.credits.toLocaleString() || 0}
</div>
<div className="text-sm text-gray-500 mt-2">credits available</div>
@@ -568,7 +571,7 @@ export default function PlansAndBillingPage() {
</div>
<div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div
className="bg-blue-600 h-2 rounded-full"
className="bg-[var(--color-brand-500)] h-2 rounded-full"
style={{
width: creditBalance?.credits
? `${Math.min((creditBalance.credits / (creditBalance.plan_credits_per_month || 1)) * 100, 100)}%`
@@ -579,40 +582,57 @@ export default function PlansAndBillingPage() {
</div>
</Card>
{/* Purchase Credits Section - Single Row */}
{/* Credit Cost Breakdown */}
<div className="mt-8 pt-8 border-t border-gray-200 dark:border-gray-700">
<div className="mb-6">
<h2 className="text-xl font-semibold mb-2">Purchase Additional Credits</h2>
<p className="text-gray-600 dark:text-gray-400">Top up your credit balance with our packages</p>
<h2 className="text-xl font-semibold">Credit Cost Analytics</h2>
<p className="text-gray-600 dark:text-gray-400">Cost breakdown by operation type</p>
</div>
<CreditCostBreakdownPanel />
</div>
<div className="overflow-x-auto">
<div className="flex gap-4 pb-4">
{packages.map((pkg) => (
<article key={pkg.id} className="rounded-2xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/3 hover:border-blue-500 dark:hover:border-blue-500 transition-colors flex-shrink-0" style={{ minWidth: '280px' }}>
<div className="relative p-5 pb-6">
<div className="mb-3 inline-flex h-10 w-10 items-center justify-center rounded-lg bg-blue-50 dark:bg-blue-500/10">
<svg className="w-6 h-6 text-blue-600 dark:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<h3 className="mb-2 text-lg font-semibold text-gray-800 dark:text-white/90">
{pkg.name}
</h3>
<div className="flex items-baseline gap-2 mb-1">
<span className="text-3xl font-bold text-blue-600 dark:text-blue-400">{pkg.credits.toLocaleString()}</span>
<span className="text-sm text-gray-500 dark:text-gray-400">credits</span>
</div>
<div className="text-2xl font-semibold text-gray-900 dark:text-white mb-2">
${pkg.price}
</div>
{pkg.description && (
<p className="text-sm text-gray-500 dark:text-gray-400">
{pkg.description}
</p>
)}
{/* Credit Costs Reference */}
<div className="mt-8 pt-8 border-t border-gray-200 dark:border-gray-700">
<CreditCostsPanel />
</div>
</div>
)}
{/* Purchase Credits Tab */}
{activeTab === 'purchase' && (
<div className="space-y-6">
<div className="mb-6">
<h2 className="text-xl font-semibold mb-2">Purchase Additional Credits</h2>
<p className="text-gray-600 dark:text-gray-400">Top up your credit balance with our packages</p>
</div>
<div className="overflow-x-auto">
<div className="flex gap-4 pb-4">
{packages.map((pkg) => (
<article key={pkg.id} className="rounded-2xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/3 hover:border-[var(--color-brand-500)] dark:hover:border-[var(--color-brand-500)] transition-colors flex-shrink-0" style={{ minWidth: '280px' }}>
<div className="relative p-5 pb-6">
<div className="mb-3 inline-flex h-10 w-10 items-center justify-center rounded-lg bg-[var(--color-brand-50)] dark:bg-[var(--color-brand-500)]/10">
<svg className="w-6 h-6 text-[var(--color-brand-500)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div className="border-t border-gray-200 p-4 dark:border-gray-800">
<h3 className="mb-2 text-lg font-semibold text-gray-800 dark:text-white/90">
{pkg.name}
</h3>
<div className="flex items-baseline gap-2 mb-1">
<span className="text-3xl font-bold text-[var(--color-brand-500)]">{pkg.credits.toLocaleString()}</span>
<span className="text-sm text-gray-500 dark:text-gray-400">credits</span>
</div>
<div className="text-2xl font-semibold text-gray-900 dark:text-white mb-2">
${pkg.price}
</div>
{pkg.description && (
<p className="text-sm text-gray-500 dark:text-gray-400">
{pkg.description}
</p>
)}
</div>
<div className="border-t border-gray-200 p-4 dark:border-gray-800">
<Button
variant="primary"
tone="brand"
@@ -633,7 +653,23 @@ export default function PlansAndBillingPage() {
)}
</div>
</div>
</div>
{/* Payment Methods Info */}
{!hasPaymentMethods && paymentMethods.length === 0 && (
<Card className="p-6 bg-[var(--color-warning-50)] dark:bg-[var(--color-warning-900)]/20 border-[var(--color-warning-200)] dark:border-[var(--color-warning-700)]">
<div className="flex items-start gap-3">
<AlertCircle className="w-5 h-5 text-[var(--color-warning-600)] mt-0.5" />
<div>
<h3 className="font-semibold text-[var(--color-warning-900)] dark:text-[var(--color-warning-100)] mb-1">
Payment Method Required
</h3>
<p className="text-sm text-[var(--color-warning-800)] dark:text-[var(--color-warning-200)]">
Please contact support to set up a payment method before purchasing credits.
</p>
</div>
</div>
</Card>
)}
</div>
)}

View File

@@ -143,7 +143,7 @@ export default function PurchaseCreditsPage() {
if (loading) {
return (
<div className="flex items-center justify-center min-h-screen">
<Loader2 className="w-8 h-8 animate-spin text-blue-600" />
<Loader2 className="w-8 h-8 animate-spin text-[var(--color-brand-500)]" />
</div>
);
}
@@ -179,9 +179,9 @@ export default function PurchaseCreditsPage() {
</div>
{/* Payment Instructions */}
<div className="bg-blue-50 border border-blue-200 rounded-lg p-6 mb-6">
<h3 className="font-semibold mb-3 text-blue-900">Payment Instructions</h3>
<p className="text-blue-800 mb-4">{selectedMethod?.instructions}</p>
<div className="bg-[var(--color-info-50)] border border-[var(--color-info-200)] dark:bg-[var(--color-info-900)]/20 dark:border-[var(--color-info-700)] rounded-lg p-6 mb-6">
<h3 className="font-semibold mb-3 text-[var(--color-info-900)] dark:text-[var(--color-info-100)]">Payment Instructions</h3>
<p className="text-[var(--color-info-800)] dark:text-[var(--color-info-200)] mb-4">{selectedMethod?.instructions}</p>
{selectedMethod?.bank_details && (
<div className="bg-white rounded p-4 space-y-2">
@@ -240,7 +240,7 @@ export default function PurchaseCreditsPage() {
setManualPaymentData({ ...manualPaymentData, transaction_reference: e.target.value })
}
placeholder="Enter transaction ID or reference number"
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[var(--color-brand-500)] focus:border-[var(--color-brand-500)]"
/>
</div>
@@ -255,7 +255,7 @@ export default function PurchaseCreditsPage() {
}
placeholder="Any additional information..."
rows={3}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[var(--color-brand-500)] focus:border-[var(--color-brand-500)]"
/>
</div>
@@ -314,8 +314,8 @@ export default function PurchaseCreditsPage() {
onClick={() => setSelectedPackage(pkg)}
className={`relative cursor-pointer rounded-lg border-2 p-6 transition-all ${
selectedPackage?.id === pkg.id
? 'border-blue-600 bg-blue-50'
: 'border-gray-200 hover:border-blue-300 bg-white'
? 'border-[var(--color-brand-500)] bg-[var(--color-brand-50)]'
: 'border-gray-200 hover:border-[var(--color-brand-300)] bg-white'
} ${pkg.is_featured ? 'ring-2 ring-yellow-400' : ''}`}
>
{pkg.is_featured && (
@@ -326,7 +326,7 @@ export default function PurchaseCreditsPage() {
<div className="text-center">
<h3 className="text-lg font-bold mb-2">{pkg.name}</h3>
<div className="text-3xl font-bold text-blue-600 mb-1">
<div className="text-3xl font-bold text-[var(--color-brand-500)] mb-1">
{pkg.credits.toLocaleString()}
</div>
<div className="text-sm text-gray-600 mb-3">credits</div>
@@ -343,7 +343,7 @@ export default function PurchaseCreditsPage() {
{selectedPackage?.id === pkg.id && (
<div className="absolute top-3 right-3">
<div className="w-6 h-6 bg-blue-600 rounded-full flex items-center justify-center">
<div className="w-6 h-6 bg-[var(--color-brand-500)] rounded-full flex items-center justify-center">
<Check className="w-4 h-4 text-white" />
</div>
</div>
@@ -364,15 +364,15 @@ export default function PurchaseCreditsPage() {
onClick={() => setSelectedPaymentMethod(method.type)}
className={`cursor-pointer rounded-lg border-2 p-4 transition-all ${
selectedPaymentMethod === method.type
? 'border-blue-600 bg-blue-50'
: 'border-gray-200 hover:border-blue-300 bg-white'
? 'border-[var(--color-brand-500)] bg-[var(--color-brand-50)]'
: 'border-gray-200 hover:border-[var(--color-brand-300)] bg-white'
}`}
>
<div className="flex items-start gap-3">
<div
className={`p-2 rounded-lg ${
selectedPaymentMethod === method.type
? 'bg-blue-600 text-white'
? 'bg-[var(--color-brand-500)] text-white'
: 'bg-gray-100 text-gray-600'
}`}
>
@@ -383,7 +383,7 @@ export default function PurchaseCreditsPage() {
<p className="text-sm text-gray-600">{method.instructions}</p>
</div>
{selectedPaymentMethod === method.type && (
<Check className="w-5 h-5 text-blue-600 flex-shrink-0" />
<Check className="w-5 h-5 text-[var(--color-brand-500)] flex-shrink-0" />
)}
</div>
</div>
@@ -405,7 +405,7 @@ export default function PurchaseCreditsPage() {
</div>
<div className="text-right">
<div className="text-sm text-gray-600">Total:</div>
<div className="text-3xl font-bold text-blue-600">
<div className="text-3xl font-bold text-[var(--color-brand-500)]">
${selectedPackage.price}
</div>
</div>

View File

@@ -116,7 +116,7 @@ export default function TeamManagementPage() {
className={`
flex items-center gap-2 py-4 px-1 border-b-2 font-medium text-sm
${activeTab === tab.id
? 'border-blue-500 text-blue-600 dark:text-blue-400'
? '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'
}
`}

View File

@@ -1,6 +1,6 @@
/**
* Usage & Analytics Page
* Tabs: Plan Limits, Credit Usage, API Usage, Cost Breakdown
* Tabs: Limits & Usage, API Usage
*/
import { useState, useEffect } from 'react';
@@ -15,7 +15,7 @@ import BillingBalancePanel from '../../components/billing/BillingBalancePanel';
import UsageLimitsPanel from '../../components/billing/UsageLimitsPanel';
import Button from '../../components/ui/button/Button';
type TabType = 'limits' | 'credits' | 'balance' | 'api' | 'costs';
type TabType = 'limits' | 'api' | 'activity';
export default function UsageAnalyticsPage() {
const toast = useToast();
@@ -52,11 +52,9 @@ export default function UsageAnalyticsPage() {
}
const tabs = [
{ id: 'limits' as TabType, label: 'Plan Limits', icon: <BarChart3 className="w-4 h-4" /> },
{ id: 'credits' as TabType, label: 'Credit Usage', icon: <TrendingUp className="w-4 h-4" /> },
{ id: 'balance' as TabType, label: 'Credit Balance', icon: <DollarSign className="w-4 h-4" /> },
{ id: 'limits' as TabType, label: 'Limits & Usage', icon: <BarChart3 className="w-4 h-4" /> },
{ id: 'activity' as TabType, label: 'Activity', icon: <TrendingUp className="w-4 h-4" /> },
{ id: 'api' as TabType, label: 'API Usage', icon: <Activity className="w-4 h-4" /> },
{ id: 'costs' as TabType, label: 'Cost Breakdown', icon: <DollarSign className="w-4 h-4" /> },
];
return (
@@ -67,7 +65,7 @@ export default function UsageAnalyticsPage() {
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Usage & Analytics</h1>
<p className="text-gray-600 dark:text-gray-400 mt-1">
Monitor plan limits, credit usage, API calls, and cost breakdown
</p>
</p>and API calls
</div>
<div className="mb-6 flex items-center justify-between">
@@ -81,7 +79,7 @@ export default function UsageAnalyticsPage() {
className={`
flex items-center gap-2 py-4 px-1 border-b-2 font-medium text-sm
${activeTab === tab.id
? 'border-blue-500 text-blue-600 dark:text-blue-400'
? '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'
}
`}
@@ -114,79 +112,17 @@ export default function UsageAnalyticsPage() {
{/* Tab Content */}
<div className="mt-6">
{/* Plan Limits Tab */}
{/* Limits & Usage Tab */}
{activeTab === 'limits' && (
<UsageLimitsPanel />
)}
{/* Credit Usage Tab */}
{activeTab === 'credits' && (
<div className="space-y-6">
{/* Summary Cards */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="p-6">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">Total Credits Used</div>
<div className="text-3xl font-bold text-red-600 dark:text-red-400">
{analytics?.total_usage.toLocaleString() || 0}
</div>
</Card>
<Card className="p-6">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">Total Purchases</div>
<div className="text-3xl font-bold text-green-600 dark:text-green-400">
{analytics?.total_purchases.toLocaleString() || 0}
</div>
</Card>
<Card className="p-6">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">Current Balance</div>
<div className="text-3xl font-bold text-gray-900 dark:text-white">
{analytics?.current_balance.toLocaleString() || 0}
</div>
</Card>
</div>
{/* Usage by Type */}
<Card className="p-6">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white mb-4">
Usage by Operation Type
</h2>
<div className="space-y-3">
{analytics?.usage_by_type.map((item, idx) => (
<div key={idx} className="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-lg">
<div className="flex-1">
<Badge variant="light" color="error">
{item.transaction_type}
</Badge>
<div className="text-xs text-gray-500 dark:text-gray-400 mt-1">
{item.count} operations
</div>
</div>
<div className="text-right">
<div className="text-lg font-bold text-red-600 dark:text-red-400">
{item.total.toLocaleString()} credits
</div>
</div>
</div>
))}
{(!analytics?.usage_by_type || analytics.usage_by_type.length === 0) && (
<div className="text-center py-8 text-gray-500 dark:text-gray-400">
No usage in this period
</div>
)}
</div>
</Card>
{/* Insert Billing usage panel below current credit-analytics content */}
<div className="mt-6">
<BillingUsagePanel />
</div>
<UsageLimitsPanel />
</div>
)}
{/* Credit Balance Tab (billing/credits moved here) */}
{activeTab === 'balance' && (
{/* Activity Tab */}
{activeTab === 'activity' && (
<div className="space-y-6">
<BillingBalancePanel />
<BillingUsagePanel showOnlyActivity={true} />
</div>
)}
@@ -196,7 +132,7 @@ export default function UsageAnalyticsPage() {
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="p-6">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">Total API Calls</div>
<div className="text-3xl font-bold text-blue-600 dark:text-blue-400">
<div className="text-3xl font-bold text-[var(--color-brand-500)]">
{analytics?.usage_by_type.reduce((sum, item) => sum + item.count, 0).toLocaleString() || 0}
</div>
</Card>
@@ -245,64 +181,6 @@ export default function UsageAnalyticsPage() {
</Card>
</div>
)}
{/* Cost Breakdown Tab */}
{activeTab === 'costs' && (
<div className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="p-6">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">Total Cost</div>
<div className="text-3xl font-bold text-gray-900 dark:text-white">
${((analytics?.total_usage || 0) * 0.01).toFixed(2)}
</div>
<div className="text-xs text-gray-500 mt-1">Estimated USD</div>
</Card>
<Card className="p-6">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">Avg Cost/Day</div>
<div className="text-3xl font-bold text-gray-900 dark:text-white">
${(((analytics?.total_usage || 0) * 0.01) / period).toFixed(2)}
</div>
<div className="text-xs text-gray-500 mt-1">Estimated USD</div>
</Card>
<Card className="p-6">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">Cost per Credit</div>
<div className="text-3xl font-bold text-gray-900 dark:text-white">
$0.01
</div>
<div className="text-xs text-gray-500 mt-1">Average rate</div>
</Card>
</div>
<Card className="p-6">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white mb-4">
Cost by Operation
</h2>
<div className="space-y-3">
{analytics?.usage_by_type.map((item, idx) => (
<div key={idx} className="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-lg">
<div className="flex-1">
<div className="font-medium">{item.transaction_type}</div>
<div className="text-xs text-gray-500 dark:text-gray-400 mt-1">
{item.total.toLocaleString()} credits used
</div>
</div>
<div className="text-right">
<div className="text-lg font-bold">${(item.total * 0.01).toFixed(2)}</div>
<div className="text-xs text-gray-500">USD</div>
</div>
</div>
))}
{(!analytics?.usage_by_type || analytics.usage_by_type.length === 0) && (
<div className="text-center py-8 text-gray-500 dark:text-gray-400">
No cost data available
</div>
)}
</div>
</Card>
</div>
)}
</div>
{/* Summary Cards */}