@burdenoff/microfe-kadaikodi 2026.704.2 → 2026.704.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"AdminDashboard.js","names":[],"sources":["../../../../src/kadaikodi/pages/admin/AdminDashboard.tsx"],"sourcesContent":["/**\n * Admin Dashboard Page\n * @module kadaikodi/pages/admin\n *\n * Platform control room wired to the live Kadaikodi backend. Every stat,\n * activity row and breakdown is derived from real hook data\n * (useDashboardStats + useProviders + useOrders + useAdminAnalytics).\n * Where a metric has no honest backend source it is omitted rather than faked.\n */\n\nimport { useMemo } from 'react';\nimport {\n Users,\n Store,\n ShoppingBag,\n IndianRupee,\n Activity,\n ArrowRight,\n Star,\n Settings,\n BarChart3,\n Award,\n FileText,\n AlertTriangle,\n Loader2,\n} from 'lucide-react';\nimport { CTAOverflowMenu, EmphasisPanel, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport {\n useDashboardStats,\n useProviders,\n useOrders,\n useAdminAnalytics,\n} from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatRelativeTime } from '../../utils/formatters';\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function AdminDashboard() {\n const { navigateTo, currentUser } = useKadaikodi();\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'Admin';\n\n const { data: stats, isLoading: statsLoading } = useDashboardStats();\n const { data: providers = [], isLoading: providersLoading } = useProviders();\n const { data: orders = [], isLoading: ordersLoading } = useOrders({});\n const { data: analytics } = useAdminAnalytics();\n\n const isLoading = statsLoading || providersLoading || ordersLoading;\n\n const fmtCur = (amount: number) => formatCurrency(amount, { minimumFractionDigits: 0 });\n\n // Carts awaiting activation/verification — real derivation from provider status.\n const pendingCarts = useMemo(() => providers.filter((p) => !p.isOpen).length, [providers]);\n\n // Most recent orders across the platform → honest \"recent activity\" feed.\n const recentOrders = useMemo(\n () =>\n [...orders]\n .sort((a, b) => new Date(b.orderDate).getTime() - new Date(a.orderDate).getTime())\n .slice(0, 6),\n [orders]\n );\n\n const orderStatusBadge = (status: string) => {\n if (status === 'delivered') return 'bg-status-success-bg-subtle text-status-success-text';\n if (status === 'cancelled') return 'bg-status-error-bg-subtle text-status-error-text';\n return 'bg-status-warning-bg-subtle text-status-warning-text';\n };\n\n /* ---- Loading state ---- */\n if (isLoading) {\n return (\n <PageLayout title=\"Admin Dashboard\" description=\"Loading...\">\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 className=\"h-10 w-10 animate-spin text-text-secondary mb-4\" />\n <p className=\"text-text-secondary\">Loading admin dashboard...</p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Admin Dashboard\"\n description={`Welcome, ${firstName}! Monitor and manage the platform.`}\n actions={\n pendingCarts > 0 ? (\n <div className=\"flex items-center gap-2 rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-3 py-2\">\n <AlertTriangle className=\"h-4 w-4 text-status-error-text\" />\n <span className=\"text-sm font-medium text-status-error-text\">\n {pendingCarts} carts awaiting review\n </span>\n </div>\n ) : undefined\n }\n >\n <PagePurpose className=\"mb-6\">\n The control room for the whole Kadaikodi marketplace — approve new carts, keep an eye on\n users, orders and platform revenue, and act on anything that needs attention. Clear pending\n approvals first, then review platform health below.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"kadaikodi-admin-dashboard\"\n className=\"mb-6\"\n steps={[\n {\n id: 'approvals',\n label: 'Review pending cart approvals',\n description: 'Vet and approve new carts waiting to go live.',\n onClick: () => navigateTo('/admin/carts'),\n done: pendingCarts === 0,\n },\n {\n id: 'users',\n label: 'Manage users',\n description: 'Review accounts, roles and access across the platform.',\n onClick: () => navigateTo('/admin/users'),\n },\n {\n id: 'financial',\n label: 'Check financial health',\n description: 'Track revenue, commission and payouts.',\n onClick: () => navigateTo('/admin/financial'),\n },\n ]}\n />\n\n {/* Hero — the one emphasis zone: pending approvals + primary action + overflow */}\n <EmphasisPanel className=\"mb-8\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Quick Actions</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {pendingCarts > 0\n ? `${pendingCarts} carts awaiting your review.`\n : 'All caught up — nothing pending review.'}\n </p>\n </div>\n <CTAOverflowMenu\n primary={{\n label: `Review Carts${pendingCarts > 0 ? ` (${pendingCarts})` : ''}`,\n icon: <Store className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/carts'),\n }}\n actions={[\n {\n label: 'Manage Carts',\n icon: <Store className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/carts'),\n },\n {\n label: 'User Management',\n icon: <Users className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/users'),\n },\n {\n label: 'Order Management',\n icon: <ShoppingBag className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/orders'),\n },\n {\n label: 'Financial Analytics',\n icon: <IndianRupee className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/financial'),\n },\n {\n label: 'Analytics',\n icon: <BarChart3 className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/analytics'),\n },\n {\n label: 'Settings',\n icon: <Settings className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/settings'),\n },\n {\n label: 'Reports',\n icon: <FileText className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/analytics'),\n },\n ]}\n />\n </div>\n </EmphasisPanel>\n\n {/* Platform Overview — real dashboard stats */}\n {stats && (\n <div className=\"mb-8\">\n <h2 className=\"text-lg font-semibold text-text-primary mb-4\">Platform Overview</h2>\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-4\">\n <MetricsCard\n icon={<Users className=\"h-5 w-5\" />}\n value={stats.activeCustomers.toLocaleString('en-IN')}\n label=\"Active Customers\"\n />\n <MetricsCard\n icon={<Store className=\"h-5 w-5\" />}\n value={stats.activeProviders.toLocaleString('en-IN')}\n label=\"Active Carts\"\n />\n <MetricsCard\n icon={<ShoppingBag className=\"h-5 w-5\" />}\n value={stats.totalOrders.toLocaleString('en-IN')}\n label=\"Total Orders\"\n />\n <MetricsCard\n featured\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={fmtCur(stats.totalRevenue)}\n label=\"Total Revenue\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-4 mt-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Total Carts</p>\n <p className=\"text-xl font-bold text-text-primary\">\n {providers.length.toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Pending Cart Approvals</p>\n <p className=\"text-xl font-bold text-status-error-text\">\n {pendingCarts.toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Pending Orders</p>\n <p className=\"text-xl font-bold text-status-warning-text\">\n {stats.pendingOrders.toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Average Rating</p>\n <p className=\"text-xl font-bold text-text-primary flex items-center gap-1\">\n <Star className=\"h-4 w-4 fill-status-warning-text text-status-warning-text\" />\n {stats.avgRating > 0 ? stats.avgRating.toFixed(1) : '—'}\n </p>\n </div>\n </div>\n </div>\n )}\n\n {/* Recent Activity — real recent orders */}\n <div className=\"mb-8\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent Orders</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/admin/orders')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-secondary hover:text-text-primary transition-colors\"\n >\n View all orders\n <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n {recentOrders.length > 0 ? (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface divide-y divide-border\">\n {recentOrders.map((order) => (\n <div key={order.id} className=\"flex items-start gap-3 px-4 py-3\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-bg-sunken mt-0.5 text-text-secondary\">\n <ShoppingBag className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-col sm:flex-row sm:items-center justify-between gap-2\">\n <p className=\"text-sm font-medium text-text-primary\">\n Order from {order.cartName}\n </p>\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium capitalize w-fit',\n orderStatusBadge(order.status)\n )}\n >\n {order.status.replace(/_/g, ' ')}\n </span>\n </div>\n <div className=\"flex flex-wrap items-center mt-1 text-xs text-text-secondary gap-3\">\n <span>{formatRelativeTime(order.orderDate)}</span>\n <span className=\"flex items-center gap-1\">\n <IndianRupee className=\"h-3 w-3\" />\n {order.total.toLocaleString('en-IN')}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No orders yet\"\n description=\"Orders placed across the platform will appear here as they come in.\"\n />\n )}\n </div>\n\n {/* Revenue by Category & Top Carts — real admin analytics */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-4\">\n <BarChart3 className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-lg font-semibold text-text-primary\">Revenue by Category</h3>\n </div>\n {analytics && analytics.revenueByCategory.length > 0 ? (\n <div className=\"space-y-3\">\n {analytics.revenueByCategory.map((row) => (\n <div\n key={row.category}\n className=\"flex items-center justify-between rounded-lg bg-bg-sunken/50 p-3\"\n >\n <div>\n <p className=\"text-sm font-medium text-text-primary capitalize\">\n {row.category}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {row.orders.toLocaleString('en-IN')} orders\n </p>\n </div>\n <p className=\"text-sm font-semibold text-text-primary\">{fmtCur(row.revenue)}</p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Category revenue will appear here once orders are recorded.\n </p>\n )}\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-4\">\n <Award className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-lg font-semibold text-text-primary\">Top Carts</h3>\n </div>\n {analytics && analytics.topProviders.length > 0 ? (\n <div className=\"space-y-3\">\n {analytics.topProviders.map((cart) => (\n <div\n key={cart.id}\n className=\"flex items-center justify-between rounded-lg bg-bg-sunken/50 p-3\"\n >\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{cart.name}</p>\n <p className=\"text-xs text-text-secondary flex items-center gap-1\">\n <Star className=\"h-3 w-3 fill-status-warning-text text-status-warning-text\" />\n {cart.rating.toFixed(1)} · {cart.orders.toLocaleString('en-IN')} orders\n </p>\n </div>\n <p className=\"text-sm font-semibold text-text-primary\">{fmtCur(cart.revenue)}</p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Top-performing carts will be ranked here once orders start flowing.\n </p>\n )}\n </div>\n </div>\n\n {/* Management Links */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[\n {\n icon: Store,\n label: 'Cart Management',\n desc: 'Approve, manage, and monitor carts',\n path: '/admin/carts',\n },\n {\n icon: Users,\n label: 'User Management',\n desc: 'Manage users and permissions',\n path: '/admin/users',\n },\n {\n icon: BarChart3,\n label: 'Analytics & Reports',\n desc: 'View detailed platform analytics',\n path: '/admin/analytics',\n },\n {\n icon: IndianRupee,\n label: 'Financial Analytics',\n desc: 'View revenue, investments, and financial metrics',\n path: '/admin/financial',\n },\n {\n icon: Activity,\n label: 'Order Management',\n desc: 'Handle orders and customer issues',\n path: '/admin/orders',\n },\n {\n icon: Settings,\n label: 'Platform Settings',\n desc: 'Configure platform-wide settings',\n path: '/admin/settings',\n },\n ].map((link) => {\n const LinkIcon = link.icon;\n return (\n <button\n key={link.label}\n type=\"button\"\n onClick={() => navigateTo(link.path)}\n className={cn(\n 'flex items-center gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6 text-left shadow-sm transition-all',\n 'hover:bg-accent hover:shadow-md'\n )}\n >\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <LinkIcon className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"font-semibold text-text-primary text-sm sm:text-base\">\n {link.label}\n </h3>\n <p className=\"text-xs sm:text-sm text-text-secondary\">{link.desc}</p>\n </div>\n </button>\n );\n })}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminDashboard.js","names":[],"sources":["../../../../src/kadaikodi/pages/admin/AdminDashboard.tsx"],"sourcesContent":["/**\n * Admin Dashboard Page\n * @module kadaikodi/pages/admin\n *\n * Platform control room wired to the live Kadaikodi backend. Every stat,\n * activity row and breakdown is derived from real hook data\n * (useDashboardStats + useProviders + useOrders + useAdminAnalytics).\n * Where a metric has no honest backend source it is omitted rather than faked.\n */\n\nimport { useMemo } from 'react';\nimport {\n Users,\n Store,\n ShoppingBag,\n IndianRupee,\n Activity,\n ArrowRight,\n Star,\n Settings,\n BarChart3,\n Award,\n FileText,\n AlertTriangle,\n Loader2,\n} from 'lucide-react';\nimport { CTAOverflowMenu, EmphasisPanel, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport {\n useDashboardStats,\n useProviders,\n useOrders,\n useAdminAnalytics,\n} from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatRelativeTime } from '../../utils/formatters';\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function AdminDashboard() {\n const { navigateTo, currentUser } = useKadaikodi();\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'Admin';\n\n const { data: stats, isLoading: statsLoading } = useDashboardStats();\n const { data: providers = [], isLoading: providersLoading } = useProviders();\n const { data: orders = [], isLoading: ordersLoading } = useOrders({});\n const { data: analytics } = useAdminAnalytics();\n\n const isLoading = statsLoading || providersLoading || ordersLoading;\n\n const fmtCur = (amount: number) => formatCurrency(amount, { minimumFractionDigits: 0 });\n\n // Carts awaiting activation/verification — real derivation from provider status.\n const pendingCarts = useMemo(() => providers.filter((p) => !p.isOpen).length, [providers]);\n\n // Most recent orders across the platform → honest \"recent activity\" feed.\n const recentOrders = useMemo(\n () =>\n [...orders]\n .sort((a, b) => new Date(b.orderDate).getTime() - new Date(a.orderDate).getTime())\n .slice(0, 6),\n [orders]\n );\n\n // Admin analytics — only fields the backend actually returns.\n const prettyCategory = (c: string) => c.replace(/_/g, ' ').toLowerCase();\n const topProviders = analytics?.topProviders ?? [];\n const categoryRows = Object.entries(analytics?.categoryDistribution ?? {}).sort(\n (a, b) => b[1] - a[1]\n );\n\n const orderStatusBadge = (status: string) => {\n if (status === 'delivered') return 'bg-status-success-bg-subtle text-status-success-text';\n if (status === 'cancelled') return 'bg-status-error-bg-subtle text-status-error-text';\n return 'bg-status-warning-bg-subtle text-status-warning-text';\n };\n\n /* ---- Loading state ---- */\n if (isLoading) {\n return (\n <PageLayout title=\"Admin Dashboard\" description=\"Loading...\">\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 className=\"h-10 w-10 animate-spin text-text-secondary mb-4\" />\n <p className=\"text-text-secondary\">Loading admin dashboard...</p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Admin Dashboard\"\n description={`Welcome, ${firstName}! Monitor and manage the platform.`}\n actions={\n pendingCarts > 0 ? (\n <div className=\"flex items-center gap-2 rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-3 py-2\">\n <AlertTriangle className=\"h-4 w-4 text-status-error-text\" />\n <span className=\"text-sm font-medium text-status-error-text\">\n {pendingCarts} carts awaiting review\n </span>\n </div>\n ) : undefined\n }\n >\n <PagePurpose className=\"mb-6\">\n The control room for the whole Kadaikodi marketplace — approve new carts, keep an eye on\n users, orders and platform revenue, and act on anything that needs attention. Clear pending\n approvals first, then review platform health below.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"kadaikodi-admin-dashboard\"\n className=\"mb-6\"\n steps={[\n {\n id: 'approvals',\n label: 'Review pending cart approvals',\n description: 'Vet and approve new carts waiting to go live.',\n onClick: () => navigateTo('/admin/carts'),\n done: pendingCarts === 0,\n },\n {\n id: 'users',\n label: 'Manage users',\n description: 'Review accounts, roles and access across the platform.',\n onClick: () => navigateTo('/admin/users'),\n },\n {\n id: 'financial',\n label: 'Check financial health',\n description: 'Track revenue, commission and payouts.',\n onClick: () => navigateTo('/admin/financial'),\n },\n ]}\n />\n\n {/* Hero — the one emphasis zone: pending approvals + primary action + overflow */}\n <EmphasisPanel className=\"mb-8\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Quick Actions</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {pendingCarts > 0\n ? `${pendingCarts} carts awaiting your review.`\n : 'All caught up — nothing pending review.'}\n </p>\n </div>\n <CTAOverflowMenu\n primary={{\n label: `Review Carts${pendingCarts > 0 ? ` (${pendingCarts})` : ''}`,\n icon: <Store className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/carts'),\n }}\n actions={[\n {\n label: 'Manage Carts',\n icon: <Store className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/carts'),\n },\n {\n label: 'User Management',\n icon: <Users className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/users'),\n },\n {\n label: 'Order Management',\n icon: <ShoppingBag className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/orders'),\n },\n {\n label: 'Financial Analytics',\n icon: <IndianRupee className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/financial'),\n },\n {\n label: 'Analytics',\n icon: <BarChart3 className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/analytics'),\n },\n {\n label: 'Settings',\n icon: <Settings className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/settings'),\n },\n {\n label: 'Reports',\n icon: <FileText className=\"h-4 w-4\" />,\n onSelect: () => navigateTo('/admin/analytics'),\n },\n ]}\n />\n </div>\n </EmphasisPanel>\n\n {/* Platform Overview — real dashboard stats */}\n {stats && (\n <div className=\"mb-8\">\n <h2 className=\"text-lg font-semibold text-text-primary mb-4\">Platform Overview</h2>\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-4\">\n <MetricsCard\n icon={<Users className=\"h-5 w-5\" />}\n value={(stats.activeCustomers ?? 0).toLocaleString('en-IN')}\n label=\"Active Customers\"\n />\n <MetricsCard\n icon={<Store className=\"h-5 w-5\" />}\n value={(stats.activeProviders ?? 0).toLocaleString('en-IN')}\n label=\"Active Carts\"\n />\n <MetricsCard\n icon={<ShoppingBag className=\"h-5 w-5\" />}\n value={(stats.totalOrders ?? 0).toLocaleString('en-IN')}\n label=\"Total Orders\"\n />\n <MetricsCard\n featured\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={fmtCur(stats.totalRevenue)}\n label=\"Total Revenue\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-4 mt-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Total Carts</p>\n <p className=\"text-xl font-bold text-text-primary\">\n {providers.length.toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Pending Cart Approvals</p>\n <p className=\"text-xl font-bold text-status-error-text\">\n {pendingCarts.toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Pending Orders</p>\n <p className=\"text-xl font-bold text-status-warning-text\">\n {(stats.pendingOrders ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Average Rating</p>\n <p className=\"text-xl font-bold text-text-primary flex items-center gap-1\">\n <Star className=\"h-4 w-4 fill-status-warning-text text-status-warning-text\" />\n {stats.avgRating > 0 ? stats.avgRating.toFixed(1) : '—'}\n </p>\n </div>\n </div>\n </div>\n )}\n\n {/* Recent Activity — real recent orders */}\n <div className=\"mb-8\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent Orders</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/admin/orders')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-secondary hover:text-text-primary transition-colors\"\n >\n View all orders\n <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n {recentOrders.length > 0 ? (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface divide-y divide-border\">\n {recentOrders.map((order) => (\n <div key={order.id} className=\"flex items-start gap-3 px-4 py-3\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-bg-sunken mt-0.5 text-text-secondary\">\n <ShoppingBag className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-col sm:flex-row sm:items-center justify-between gap-2\">\n <p className=\"text-sm font-medium text-text-primary\">\n Order from {order.cartName}\n </p>\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium capitalize w-fit',\n orderStatusBadge(order.status)\n )}\n >\n {order.status.replace(/_/g, ' ')}\n </span>\n </div>\n <div className=\"flex flex-wrap items-center mt-1 text-xs text-text-secondary gap-3\">\n <span>{formatRelativeTime(order.orderDate)}</span>\n <span className=\"flex items-center gap-1\">\n <IndianRupee className=\"h-3 w-3\" />\n {(order.total ?? 0).toLocaleString('en-IN')}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No orders yet\"\n description=\"Orders placed across the platform will appear here as they come in.\"\n />\n )}\n </div>\n\n {/* Carts by Category & Top Carts — real admin analytics */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-4\">\n <BarChart3 className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-lg font-semibold text-text-primary\">Carts by Category</h3>\n </div>\n {categoryRows.length > 0 ? (\n <div className=\"space-y-3\">\n {categoryRows.map(([category, count]) => (\n <div\n key={category}\n className=\"flex items-center justify-between rounded-lg bg-bg-sunken/50 p-3\"\n >\n <p className=\"text-sm font-medium text-text-primary capitalize\">\n {prettyCategory(category)}\n </p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {(count ?? 0).toLocaleString('en-IN')}{' '}\n <span className=\"text-xs font-normal text-text-secondary\">\n {count === 1 ? 'cart' : 'carts'}\n </span>\n </p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Cart categories will appear here as carts are onboarded.\n </p>\n )}\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-4\">\n <Award className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-lg font-semibold text-text-primary\">Top Carts</h3>\n </div>\n {topProviders.length > 0 ? (\n <div className=\"space-y-3\">\n {topProviders.map((cart) => (\n <div\n key={cart.id}\n className=\"flex items-center justify-between rounded-lg bg-bg-sunken/50 p-3\"\n >\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{cart.name}</p>\n <p className=\"text-xs text-text-secondary capitalize\">\n {prettyCategory(cart.category)}\n </p>\n </div>\n <p className=\"text-sm font-semibold text-text-primary flex items-center gap-1\">\n <Star className=\"h-3.5 w-3.5 fill-status-warning-text text-status-warning-text\" />\n {(cart.rating ?? 0).toFixed(1)}\n </p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Top-performing carts will be ranked here once orders start flowing.\n </p>\n )}\n </div>\n </div>\n\n {/* Management Links */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[\n {\n icon: Store,\n label: 'Cart Management',\n desc: 'Approve, manage, and monitor carts',\n path: '/admin/carts',\n },\n {\n icon: Users,\n label: 'User Management',\n desc: 'Manage users and permissions',\n path: '/admin/users',\n },\n {\n icon: BarChart3,\n label: 'Analytics & Reports',\n desc: 'View detailed platform analytics',\n path: '/admin/analytics',\n },\n {\n icon: IndianRupee,\n label: 'Financial Analytics',\n desc: 'View revenue, investments, and financial metrics',\n path: '/admin/financial',\n },\n {\n icon: Activity,\n label: 'Order Management',\n desc: 'Handle orders and customer issues',\n path: '/admin/orders',\n },\n {\n icon: Settings,\n label: 'Platform Settings',\n desc: 'Configure platform-wide settings',\n path: '/admin/settings',\n },\n ].map((link) => {\n const LinkIcon = link.icon;\n return (\n <button\n key={link.label}\n type=\"button\"\n onClick={() => navigateTo(link.path)}\n className={cn(\n 'flex items-center gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6 text-left shadow-sm transition-all',\n 'hover:bg-accent hover:shadow-md'\n )}\n >\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <LinkIcon className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"font-semibold text-text-primary text-sm sm:text-base\">\n {link.label}\n </h3>\n <p className=\"text-xs sm:text-sm text-text-secondary\">{link.desc}</p>\n </div>\n </button>\n );\n })}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -5,271 +5,288 @@ import { EmptyState as r } from "../../components/EmptyState.js";
5
5
  import { useAdminAnalytics as i, useDashboardStats as a } from "../../hooks/useKadaikodiApi.js";
6
6
  import { formatCurrency as o } from "../../utils/formatters.js";
7
7
  import { useMemo as s } from "react";
8
- import { ArrowLeft as c, Award as l, BarChart3 as u, Calendar as d, Clock as f, Download as p, IndianRupee as m, Loader2 as h, ShoppingBag as g, ShoppingCart as _, Store as v, TrendingUp as y } from "lucide-react";
9
- import { jsx as b, jsxs as x } from "react/jsx-runtime";
10
- import { EmphasisPanel as S, PagePurpose as C } from "@burdenoff/fe-libs/ui";
8
+ import { ArrowLeft as c, Award as l, BarChart3 as u, Calendar as d, Clock as f, Download as p, IndianRupee as m, Loader2 as h, ShoppingBag as g, ShoppingCart as _, Star as v, Store as y, TrendingUp as b } from "lucide-react";
9
+ import { jsx as x, jsxs as S } from "react/jsx-runtime";
10
+ import { EmphasisPanel as C, PagePurpose as w } from "@burdenoff/fe-libs/ui";
11
11
  //#region src/kadaikodi/pages/admin/AdminFinancialPage.tsx
12
- function w() {
13
- let { navigateTo: w } = e(), { data: T, isLoading: E } = a(), { data: D, isLoading: O } = i(), k = E || O, A = (e) => o(e, { minimumFractionDigits: 0 }), j = s(() => T && T.totalOrders > 0 ? T.totalRevenue / T.totalOrders : 0, [T]), M = s(() => {
14
- let e = D?.revenueByCategory ?? [], t = e.reduce((e, t) => e + t.revenue, 0);
15
- return e.map((e) => ({
16
- ...e,
17
- percentage: t > 0 ? e.revenue / t * 100 : 0
18
- }));
19
- }, [D]), N = D?.topProviders ?? [], P = D?.orderTrends ?? [], F = () => {
12
+ function T() {
13
+ let { navigateTo: T } = e(), { data: E, isLoading: D } = a(), { data: O, isLoading: k } = i(), A = D || k, j = (e) => o(e, { minimumFractionDigits: 0 }), M = s(() => E && E.totalOrders > 0 ? E.totalRevenue / E.totalOrders : 0, [E]), N = s(() => {
14
+ let e = Object.entries(O?.categoryDistribution ?? {}), t = e.reduce((e, [, t]) => e + t, 0);
15
+ return e.map(([e, n]) => ({
16
+ category: e,
17
+ count: n,
18
+ percentage: t > 0 ? n / t * 100 : 0
19
+ })).sort((e, t) => t.count - e.count);
20
+ }, [O]), P = O?.topProviders ?? [], F = O?.orderTrends ?? [], I = (e) => e.replace(/_/g, " ").toLowerCase(), L = (e) => e === "delivered" ? "bg-status-success-bg-subtle text-status-success-text" : e === "cancelled" ? "bg-status-error-bg-subtle text-status-error-text" : "bg-status-warning-bg-subtle text-status-warning-text", R = () => {
20
21
  let e = [];
21
- e.push("Kadaikodi Financial Report"), e.push(""), e.push("Metric,Value"), e.push(`Total Revenue,${T?.totalRevenue ?? 0}`), e.push(`Total Orders,${T?.totalOrders ?? 0}`), e.push(`Average Order Value,${Math.round(j)}`), e.push(`Pending Orders,${T?.pendingOrders ?? 0}`), e.push(""), e.push("Revenue by Category"), e.push("Category,Revenue,Orders,Share %"), M.forEach((t) => {
22
- e.push(`${t.category},${t.revenue},${t.orders},${t.percentage.toFixed(1)}`);
23
- }), e.push(""), e.push("Top Performing Carts"), e.push("Cart,Revenue,Orders,Rating"), N.forEach((t) => {
24
- e.push(`${t.name},${t.revenue},${t.orders},${t.rating}`);
22
+ e.push("Kadaikodi Financial Report"), e.push(""), e.push("Metric,Value"), e.push(`Total Revenue,${E?.totalRevenue ?? 0}`), e.push(`Total Orders,${E?.totalOrders ?? 0}`), e.push(`Average Order Value,${Math.round(M)}`), e.push(`Pending Orders,${E?.pendingOrders ?? 0}`), e.push(""), e.push("Cart Category Distribution"), e.push("Category,Carts,Share %"), N.forEach((t) => {
23
+ e.push(`${t.category},${t.count},${(t.percentage ?? 0).toFixed(1)}`);
24
+ }), e.push(""), e.push("Top Performing Carts"), e.push("Cart,Category,Rating"), P.forEach((t) => {
25
+ e.push(`${t.name},${t.category},${t.rating ?? 0}`);
26
+ }), e.push(""), e.push("Recent Orders"), e.push("Date,Status,Amount"), F.forEach((t) => {
27
+ e.push(`${new Date(t.createdAt).toISOString().slice(0, 10)},${t.status},${t.total ?? 0}`);
25
28
  });
26
29
  let t = new Blob([e.join("\n")], { type: "text/csv;charset=utf-8;" }), n = URL.createObjectURL(t), r = document.createElement("a");
27
30
  r.href = n, r.download = `kadaikodi-financial-report-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.csv`, r.click(), URL.revokeObjectURL(n);
28
- }, I = (e) => e < 3 ? /* @__PURE__ */ b(l, { className: "h-5 w-5 text-status-warning-text" }) : /* @__PURE__ */ b("span", {
31
+ }, z = (e) => e < 3 ? /* @__PURE__ */ x(l, { className: "h-5 w-5 text-status-warning-text" }) : /* @__PURE__ */ x("span", {
29
32
  className: "flex h-5 w-5 items-center justify-center rounded-full bg-bg-sunken text-xs font-bold text-text-secondary",
30
33
  children: e + 1
31
34
  });
32
- return k ? /* @__PURE__ */ b(t, {
35
+ return A ? /* @__PURE__ */ x(t, {
33
36
  title: "Financial Reports",
34
37
  description: "Loading financial data...",
35
- children: /* @__PURE__ */ x("div", {
38
+ children: /* @__PURE__ */ S("div", {
36
39
  className: "flex flex-col items-center justify-center py-20",
37
- children: [/* @__PURE__ */ b(h, { className: "h-10 w-10 animate-spin text-text-secondary mb-4" }), /* @__PURE__ */ b("p", {
40
+ children: [/* @__PURE__ */ x(h, { className: "h-10 w-10 animate-spin text-text-secondary mb-4" }), /* @__PURE__ */ x("p", {
38
41
  className: "text-text-secondary",
39
42
  children: "Loading financial data..."
40
43
  })]
41
44
  })
42
- }) : T ? /* @__PURE__ */ x(t, {
45
+ }) : E ? /* @__PURE__ */ S(t, {
43
46
  title: "Financial Reports",
44
47
  description: "Revenue, top carts and financial trends",
45
- actions: /* @__PURE__ */ x("div", {
48
+ actions: /* @__PURE__ */ S("div", {
46
49
  className: "flex flex-col sm:flex-row items-stretch sm:items-center gap-3",
47
- children: [/* @__PURE__ */ x("button", {
50
+ children: [/* @__PURE__ */ S("button", {
48
51
  type: "button",
49
- onClick: () => w("/admin"),
52
+ onClick: () => T("/admin"),
50
53
  className: "flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors",
51
- children: [/* @__PURE__ */ b(c, { className: "h-4 w-4" }), " Back"]
52
- }), /* @__PURE__ */ x("button", {
54
+ children: [/* @__PURE__ */ x(c, { className: "h-4 w-4" }), " Back"]
55
+ }), /* @__PURE__ */ S("button", {
53
56
  type: "button",
54
- onClick: F,
57
+ onClick: R,
55
58
  className: "flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors",
56
- children: [/* @__PURE__ */ b(p, { className: "h-4 w-4" }), " Export Report"]
59
+ children: [/* @__PURE__ */ x(p, { className: "h-4 w-4" }), " Export Report"]
57
60
  })]
58
61
  }),
59
62
  children: [
60
- /* @__PURE__ */ b(C, {
63
+ /* @__PURE__ */ x(w, {
61
64
  className: "mb-6",
62
65
  children: "The money view of Kadaikodi. Track total revenue and order volume, see which carts and categories drive the most business, and watch how orders trend over time — then export a CSV for accounting or investor updates."
63
66
  }),
64
- /* @__PURE__ */ x(S, {
67
+ /* @__PURE__ */ S(C, {
65
68
  className: "mb-8",
66
- children: [/* @__PURE__ */ b("h2", {
69
+ children: [/* @__PURE__ */ x("h2", {
67
70
  className: "mb-4 text-lg font-semibold text-text-primary",
68
71
  children: "Financial Summary"
69
- }), /* @__PURE__ */ x("div", {
72
+ }), /* @__PURE__ */ S("div", {
70
73
  className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",
71
74
  children: [
72
- /* @__PURE__ */ b(n, {
75
+ /* @__PURE__ */ x(n, {
73
76
  featured: !0,
74
- icon: /* @__PURE__ */ b(m, { className: "h-5 w-5" }),
75
- value: A(T.totalRevenue),
77
+ icon: /* @__PURE__ */ x(m, { className: "h-5 w-5" }),
78
+ value: j(E.totalRevenue),
76
79
  label: "Total Revenue"
77
80
  }),
78
- /* @__PURE__ */ b(n, {
79
- icon: /* @__PURE__ */ b(g, { className: "h-5 w-5" }),
80
- value: T.totalOrders.toLocaleString("en-IN"),
81
+ /* @__PURE__ */ x(n, {
82
+ icon: /* @__PURE__ */ x(g, { className: "h-5 w-5" }),
83
+ value: (E.totalOrders ?? 0).toLocaleString("en-IN"),
81
84
  label: "Total Orders"
82
85
  }),
83
- /* @__PURE__ */ b(n, {
84
- icon: /* @__PURE__ */ b(y, { className: "h-5 w-5" }),
85
- value: A(j),
86
+ /* @__PURE__ */ x(n, {
87
+ icon: /* @__PURE__ */ x(b, { className: "h-5 w-5" }),
88
+ value: j(M),
86
89
  label: "Avg Order Value"
87
90
  }),
88
- /* @__PURE__ */ b(n, {
89
- icon: /* @__PURE__ */ b(f, { className: "h-5 w-5" }),
90
- value: T.pendingOrders.toLocaleString("en-IN"),
91
+ /* @__PURE__ */ x(n, {
92
+ icon: /* @__PURE__ */ x(f, { className: "h-5 w-5" }),
93
+ value: (E.pendingOrders ?? 0).toLocaleString("en-IN"),
91
94
  label: "Pending Orders"
92
95
  })
93
96
  ]
94
97
  })]
95
98
  }),
96
- /* @__PURE__ */ x("div", {
99
+ /* @__PURE__ */ S("div", {
97
100
  className: "grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8",
98
- children: [/* @__PURE__ */ x("div", {
101
+ children: [/* @__PURE__ */ S("div", {
99
102
  className: "rounded-lg border border-border-subtle bg-bg-surface p-6",
100
- children: [/* @__PURE__ */ x("div", {
103
+ children: [/* @__PURE__ */ S("div", {
101
104
  className: "flex items-center gap-2 mb-4",
102
- children: [/* @__PURE__ */ b(_, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ b("h3", {
105
+ children: [/* @__PURE__ */ x(_, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ x("h3", {
103
106
  className: "text-lg font-semibold text-text-primary",
104
107
  children: "Top Performing Carts"
105
108
  })]
106
- }), N.length > 0 ? /* @__PURE__ */ b("div", {
109
+ }), P.length > 0 ? /* @__PURE__ */ x("div", {
107
110
  className: "space-y-3",
108
- children: N.map((e, t) => /* @__PURE__ */ x("div", {
111
+ children: P.map((e, t) => /* @__PURE__ */ S("div", {
109
112
  className: "flex items-center justify-between rounded-lg bg-bg-sunken/50 p-3",
110
- children: [/* @__PURE__ */ x("div", {
113
+ children: [/* @__PURE__ */ S("div", {
111
114
  className: "flex items-center gap-3",
112
- children: [I(t), /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
115
+ children: [z(t), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("p", {
113
116
  className: "text-sm font-medium text-text-primary",
114
117
  children: e.name
115
118
  }), /* @__PURE__ */ x("p", {
116
- className: "text-xs text-text-secondary",
117
- children: [e.orders.toLocaleString("en-IN"), " orders"]
119
+ className: "text-xs text-text-secondary capitalize",
120
+ children: I(e.category)
118
121
  })] })]
119
- }), /* @__PURE__ */ b("p", {
120
- className: "text-sm font-semibold text-text-primary",
121
- children: A(e.revenue)
122
+ }), /* @__PURE__ */ S("p", {
123
+ className: "text-sm font-semibold text-text-primary flex items-center gap-1",
124
+ children: [/* @__PURE__ */ x(v, { className: "h-3.5 w-3.5 fill-status-warning-text text-status-warning-text" }), (e.rating ?? 0).toFixed(1)]
122
125
  })]
123
126
  }, e.id))
124
- }) : /* @__PURE__ */ b("p", {
127
+ }) : /* @__PURE__ */ x("p", {
125
128
  className: "text-sm text-text-secondary",
126
129
  children: "Top-performing carts will be ranked here once orders start flowing."
127
130
  })]
128
- }), /* @__PURE__ */ x("div", {
131
+ }), /* @__PURE__ */ S("div", {
129
132
  className: "rounded-lg border border-border-subtle bg-bg-surface p-6",
130
- children: [/* @__PURE__ */ x("div", {
133
+ children: [/* @__PURE__ */ S("div", {
131
134
  className: "flex items-center gap-2 mb-4",
132
- children: [/* @__PURE__ */ b(u, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ b("h3", {
135
+ children: [/* @__PURE__ */ x(u, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ x("h3", {
133
136
  className: "text-lg font-semibold text-text-primary",
134
- children: "Revenue by Category"
137
+ children: "Cart Category Distribution"
135
138
  })]
136
- }), M.length > 0 ? /* @__PURE__ */ b("div", {
139
+ }), N.length > 0 ? /* @__PURE__ */ x("div", {
137
140
  className: "space-y-3",
138
- children: M.map((e) => /* @__PURE__ */ x("div", { children: [
139
- /* @__PURE__ */ x("div", {
141
+ children: N.map((e) => /* @__PURE__ */ S("div", { children: [
142
+ /* @__PURE__ */ S("div", {
140
143
  className: "flex items-center justify-between mb-1",
141
- children: [/* @__PURE__ */ b("span", {
144
+ children: [/* @__PURE__ */ x("span", {
142
145
  className: "text-sm font-medium text-text-primary capitalize",
143
- children: e.category
144
- }), /* @__PURE__ */ x("span", {
146
+ children: I(e.category)
147
+ }), /* @__PURE__ */ S("span", {
145
148
  className: "text-sm text-text-secondary",
146
- children: [e.percentage.toFixed(1), "%"]
149
+ children: [(e.percentage ?? 0).toFixed(1), "%"]
147
150
  })]
148
151
  }),
149
- /* @__PURE__ */ b("div", {
152
+ /* @__PURE__ */ x("div", {
150
153
  className: "w-full bg-bg-sunken rounded-full h-2",
151
- children: /* @__PURE__ */ b("div", {
154
+ children: /* @__PURE__ */ x("div", {
152
155
  className: "bg-action-primary-bg h-2 rounded-full transition-all duration-300",
153
156
  style: { width: `${e.percentage}%` }
154
157
  })
155
158
  }),
156
- /* @__PURE__ */ b("div", {
159
+ /* @__PURE__ */ x("div", {
157
160
  className: "text-right mt-1",
158
- children: /* @__PURE__ */ b("span", {
161
+ children: /* @__PURE__ */ S("span", {
159
162
  className: "text-sm font-semibold text-text-primary",
160
- children: A(e.revenue)
163
+ children: [
164
+ (e.count ?? 0).toLocaleString("en-IN"),
165
+ " ",
166
+ /* @__PURE__ */ x("span", {
167
+ className: "text-xs font-normal text-text-secondary",
168
+ children: e.count === 1 ? "cart" : "carts"
169
+ })
170
+ ]
161
171
  })
162
172
  })
163
173
  ] }, e.category))
164
- }) : /* @__PURE__ */ b("p", {
174
+ }) : /* @__PURE__ */ x("p", {
165
175
  className: "text-sm text-text-secondary",
166
- children: "Category revenue will appear here once orders are recorded."
176
+ children: "Cart categories will appear here as carts are onboarded."
167
177
  })]
168
178
  })]
169
179
  }),
170
- P.length > 0 && /* @__PURE__ */ x("div", {
180
+ F.length > 0 && /* @__PURE__ */ S("div", {
171
181
  className: "rounded-lg border border-border-subtle bg-bg-surface p-6 mb-8",
172
- children: [/* @__PURE__ */ x("div", {
182
+ children: [/* @__PURE__ */ S("div", {
173
183
  className: "flex items-center gap-2 mb-4",
174
- children: [/* @__PURE__ */ b(d, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ b("h3", {
184
+ children: [/* @__PURE__ */ x(d, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ x("h3", {
175
185
  className: "text-lg font-semibold text-text-primary",
176
- children: "Order Trends"
186
+ children: "Recent Orders"
177
187
  })]
178
- }), /* @__PURE__ */ b("div", {
188
+ }), /* @__PURE__ */ x("div", {
179
189
  className: "overflow-x-auto",
180
- children: /* @__PURE__ */ x("table", {
190
+ children: /* @__PURE__ */ S("table", {
181
191
  className: "w-full",
182
- children: [/* @__PURE__ */ b("thead", { children: /* @__PURE__ */ x("tr", {
192
+ children: [/* @__PURE__ */ x("thead", { children: /* @__PURE__ */ S("tr", {
183
193
  className: "border-b border-border-subtle bg-bg-sunken/50",
184
194
  children: [
185
- /* @__PURE__ */ b("th", {
195
+ /* @__PURE__ */ x("th", {
186
196
  className: "px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider",
187
197
  children: "Date"
188
198
  }),
189
- /* @__PURE__ */ b("th", {
190
- className: "px-4 py-3 text-right text-xs font-medium text-text-secondary uppercase tracking-wider",
191
- children: "Orders"
199
+ /* @__PURE__ */ x("th", {
200
+ className: "px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider",
201
+ children: "Status"
192
202
  }),
193
- /* @__PURE__ */ b("th", {
203
+ /* @__PURE__ */ x("th", {
194
204
  className: "px-4 py-3 text-right text-xs font-medium text-text-secondary uppercase tracking-wider",
195
- children: "Revenue"
205
+ children: "Amount"
196
206
  })
197
207
  ]
198
- }) }), /* @__PURE__ */ b("tbody", {
208
+ }) }), /* @__PURE__ */ x("tbody", {
199
209
  className: "divide-y divide-border",
200
- children: P.map((e) => /* @__PURE__ */ x("tr", {
210
+ children: F.map((e) => /* @__PURE__ */ S("tr", {
201
211
  className: "hover:bg-accent/50 transition-colors",
202
212
  children: [
203
- /* @__PURE__ */ b("td", {
213
+ /* @__PURE__ */ x("td", {
204
214
  className: "px-4 py-3 text-sm font-medium text-text-primary",
205
- children: e.date
215
+ children: new Date(e.createdAt).toLocaleDateString("en-IN", {
216
+ day: "2-digit",
217
+ month: "short",
218
+ year: "numeric"
219
+ })
206
220
  }),
207
- /* @__PURE__ */ b("td", {
208
- className: "px-4 py-3 text-sm text-right text-text-primary",
209
- children: e.orders.toLocaleString("en-IN")
221
+ /* @__PURE__ */ x("td", {
222
+ className: "px-4 py-3 text-sm",
223
+ children: /* @__PURE__ */ x("span", {
224
+ className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium capitalize ${L(e.status)}`,
225
+ children: e.status.replace(/_/g, " ")
226
+ })
210
227
  }),
211
- /* @__PURE__ */ b("td", {
228
+ /* @__PURE__ */ x("td", {
212
229
  className: "px-4 py-3 text-sm text-right text-text-primary",
213
- children: A(e.revenue)
230
+ children: j(e.total ?? 0)
214
231
  })
215
232
  ]
216
- }, e.date))
233
+ }, e.id))
217
234
  })]
218
235
  })
219
236
  })]
220
237
  }),
221
- /* @__PURE__ */ x("div", {
238
+ /* @__PURE__ */ S("div", {
222
239
  className: "grid grid-cols-1 md:grid-cols-3 gap-6",
223
240
  children: [
224
- /* @__PURE__ */ x("div", {
241
+ /* @__PURE__ */ S("div", {
225
242
  className: "rounded-lg border border-border-subtle bg-bg-surface p-6 text-center",
226
243
  children: [
227
- /* @__PURE__ */ b(g, { className: "h-8 w-8 text-primary mx-auto mb-3" }),
228
- /* @__PURE__ */ b("h4", {
244
+ /* @__PURE__ */ x(g, { className: "h-8 w-8 text-primary mx-auto mb-3" }),
245
+ /* @__PURE__ */ x("h4", {
229
246
  className: "text-lg font-semibold text-text-primary mb-2",
230
247
  children: "Total Orders"
231
248
  }),
232
- /* @__PURE__ */ b("p", {
249
+ /* @__PURE__ */ x("p", {
233
250
  className: "text-2xl font-bold text-primary",
234
- children: T.totalOrders.toLocaleString("en-IN")
251
+ children: (E.totalOrders ?? 0).toLocaleString("en-IN")
235
252
  }),
236
- /* @__PURE__ */ b("p", {
253
+ /* @__PURE__ */ x("p", {
237
254
  className: "text-sm text-text-secondary mt-1",
238
255
  children: "All-time orders"
239
256
  })
240
257
  ]
241
258
  }),
242
- /* @__PURE__ */ x("div", {
259
+ /* @__PURE__ */ S("div", {
243
260
  className: "rounded-lg border border-border-subtle bg-bg-surface p-6 text-center",
244
261
  children: [
245
- /* @__PURE__ */ b(u, { className: "h-8 w-8 text-status-success-text mx-auto mb-3" }),
246
- /* @__PURE__ */ b("h4", {
262
+ /* @__PURE__ */ x(u, { className: "h-8 w-8 text-status-success-text mx-auto mb-3" }),
263
+ /* @__PURE__ */ x("h4", {
247
264
  className: "text-lg font-semibold text-text-primary mb-2",
248
265
  children: "Average Order Value"
249
266
  }),
250
- /* @__PURE__ */ b("p", {
267
+ /* @__PURE__ */ x("p", {
251
268
  className: "text-2xl font-bold text-status-success-text",
252
- children: A(j)
269
+ children: j(M)
253
270
  }),
254
- /* @__PURE__ */ b("p", {
271
+ /* @__PURE__ */ x("p", {
255
272
  className: "text-sm text-text-secondary mt-1",
256
273
  children: "Per order average"
257
274
  })
258
275
  ]
259
276
  }),
260
- /* @__PURE__ */ x("div", {
277
+ /* @__PURE__ */ S("div", {
261
278
  className: "rounded-lg border border-border-subtle bg-bg-surface p-6 text-center",
262
279
  children: [
263
- /* @__PURE__ */ b(v, { className: "h-8 w-8 text-text-primary mx-auto mb-3" }),
264
- /* @__PURE__ */ b("h4", {
280
+ /* @__PURE__ */ x(y, { className: "h-8 w-8 text-text-primary mx-auto mb-3" }),
281
+ /* @__PURE__ */ x("h4", {
265
282
  className: "text-lg font-semibold text-text-primary mb-2",
266
283
  children: "Active Carts"
267
284
  }),
268
- /* @__PURE__ */ b("p", {
285
+ /* @__PURE__ */ x("p", {
269
286
  className: "text-2xl font-bold text-text-primary",
270
- children: T.activeProviders.toLocaleString("en-IN")
287
+ children: (E.activeProviders ?? 0).toLocaleString("en-IN")
271
288
  }),
272
- /* @__PURE__ */ b("p", {
289
+ /* @__PURE__ */ x("p", {
273
290
  className: "text-sm text-text-secondary mt-1",
274
291
  children: "Currently live on the platform"
275
292
  })
@@ -278,10 +295,10 @@ function w() {
278
295
  ]
279
296
  })
280
297
  ]
281
- }) : /* @__PURE__ */ b(t, {
298
+ }) : /* @__PURE__ */ x(t, {
282
299
  title: "Financial Reports",
283
300
  description: "Unable to load financial data",
284
- children: /* @__PURE__ */ b(r, {
301
+ children: /* @__PURE__ */ x(r, {
285
302
  illustration: "empty-data",
286
303
  title: "No financial data available",
287
304
  description: "We couldn't load the financial figures right now. Please check back shortly."
@@ -289,6 +306,6 @@ function w() {
289
306
  });
290
307
  }
291
308
  //#endregion
292
- export { w as AdminFinancialPage };
309
+ export { T as AdminFinancialPage };
293
310
 
294
311
  //# sourceMappingURL=AdminFinancialPage.js.map