import { useMemo, useCallback } from 'react'; import { useScenarios } from '@/hooks/useScenarios'; import { Activity, DollarSign, Server, AlertTriangle, TrendingUp } from 'lucide-react'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { CostBreakdownChart } from '@/components/charts'; import { formatCurrency, formatNumber } from '@/components/charts/chart-utils'; import { Skeleton } from '@/components/ui/skeleton'; import { Link } from 'react-router-dom'; import { analytics, useFeatureTracking } from '@/components/analytics/analytics-service'; import { useTranslation } from 'react-i18next'; interface StatCardProps { title: string; value: string | number; description?: string; icon: React.ElementType; trend?: 'up' | 'down' | 'neutral'; href?: string; } const StatCard = ({ title, value, description, icon: Icon, trend, href, }: StatCardProps) => { const content = ( {title}
{value}
{trend && (
)} {description && (

{description}

)}
); if (href) { return ( {content} ); } return content; }; export function Dashboard() { const { t } = useTranslation(); const { data: scenarios, isLoading: scenariosLoading } = useScenarios(1, 100); const trackFeature = useFeatureTracking(); // Track dashboard view const trackDashboardClick = useCallback((feature: string) => { trackFeature(feature); analytics.trackFeatureUsage(`dashboard_click_${feature}`); }, [trackFeature]); // Aggregate metrics from all scenarios const totalScenarios = scenarios?.total || 0; const runningScenarios = useMemo( () => scenarios?.items.filter(s => s.status === 'running').length || 0, [scenarios?.items] ); const totalCost = useMemo( () => scenarios?.items.reduce((sum, s) => sum + s.total_cost_estimate, 0) || 0, [scenarios?.items] ); // Calculate cost breakdown const costBreakdown = useMemo(() => [ { service: 'SQS', cost_usd: totalCost * 0.35, percentage: 35 }, { service: 'Lambda', cost_usd: totalCost * 0.25, percentage: 25 }, { service: 'Bedrock', cost_usd: totalCost * 0.40, percentage: 40 }, ].filter(item => item.cost_usd > 0), [totalCost]); if (scenariosLoading) { return (
{[...Array(4)].map((_, i) => ( ))}
); } return (

{t('dashboard.title')}

{t('dashboard.subtitle')}

trackDashboardClick('scenarios')}>
0 ? 'up' : 'neutral'} />
{/* Charts Section */}
{costBreakdown.length > 0 && ( )} {t('dashboard.recent_activity')} Latest scenario executions
{scenarios?.items.slice(0, 5).map((scenario) => ( trackDashboardClick('recent_scenario')} >

{scenario.name}

{scenario.region}

{formatCurrency(scenario.total_cost_estimate)}

{formatNumber(scenario.total_requests)} requests

))} {(!scenarios?.items || scenarios.items.length === 0) && (

No scenarios yet. Create one to get started.

)}
{/* Quick Actions */} {t('dashboard.quick_actions')}
trackDashboardClick('view_all')}> trackDashboardClick('analytics')}>
); }