@burdenoff/microfe-kadaikodi 2026.710.1 → 2026.716.1

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.
Files changed (60) hide show
  1. package/dist/kadaikodi/pages/HomePage.d.ts.map +1 -1
  2. package/dist/kadaikodi/pages/HomePage.js.map +1 -1
  3. package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.d.ts.map +1 -1
  4. package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js.map +1 -1
  5. package/dist/kadaikodi/pages/admin/AdminDashboard.d.ts.map +1 -1
  6. package/dist/kadaikodi/pages/admin/AdminDashboard.js.map +1 -1
  7. package/dist/kadaikodi/pages/admin/AdminFinancialPage.d.ts.map +1 -1
  8. package/dist/kadaikodi/pages/admin/AdminFinancialPage.js.map +1 -1
  9. package/dist/kadaikodi/pages/admin/AdminOrdersPage.d.ts.map +1 -1
  10. package/dist/kadaikodi/pages/admin/AdminOrdersPage.js.map +1 -1
  11. package/dist/kadaikodi/pages/admin/CartManagementPage.d.ts.map +1 -1
  12. package/dist/kadaikodi/pages/admin/CartManagementPage.js.map +1 -1
  13. package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.d.ts.map +1 -1
  14. package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
  15. package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.d.ts.map +1 -1
  16. package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js.map +1 -1
  17. package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js.map +1 -1
  18. package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.d.ts.map +1 -1
  19. package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js.map +1 -1
  20. package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.d.ts.map +1 -1
  21. package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js.map +1 -1
  22. package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.d.ts.map +1 -1
  23. package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js.map +1 -1
  24. package/dist/kadaikodi/pages/customer/BookingDetailsPage.d.ts.map +1 -1
  25. package/dist/kadaikodi/pages/customer/BookingDetailsPage.js.map +1 -1
  26. package/dist/kadaikodi/pages/customer/CartDetailPage.d.ts.map +1 -1
  27. package/dist/kadaikodi/pages/customer/CartDetailPage.js.map +1 -1
  28. package/dist/kadaikodi/pages/customer/CheckoutPage.js.map +1 -1
  29. package/dist/kadaikodi/pages/customer/FavoritesPage.d.ts.map +1 -1
  30. package/dist/kadaikodi/pages/customer/FavoritesPage.js.map +1 -1
  31. package/dist/kadaikodi/pages/customer/OrderTrackingPage.d.ts.map +1 -1
  32. package/dist/kadaikodi/pages/customer/OrderTrackingPage.js.map +1 -1
  33. package/dist/kadaikodi/pages/customer/ReviewsPage.d.ts.map +1 -1
  34. package/dist/kadaikodi/pages/customer/ReviewsPage.js.map +1 -1
  35. package/dist/kadaikodi/pages/customer/shared.d.ts.map +1 -1
  36. package/dist/kadaikodi/pages/customer/shared.js.map +1 -1
  37. package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.d.ts.map +1 -1
  38. package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js +3 -3
  39. package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js.map +1 -1
  40. package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.d.ts.map +1 -1
  41. package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
  42. package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.d.ts.map +1 -1
  43. package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js.map +1 -1
  44. package/dist/kadaikodi/pages/worker/TaskDetailsPage.d.ts.map +1 -1
  45. package/dist/kadaikodi/pages/worker/TaskDetailsPage.js.map +1 -1
  46. package/dist/kadaikodi/pages/worker/WorkerDashboard.d.ts.map +1 -1
  47. package/dist/kadaikodi/pages/worker/WorkerDashboard.js.map +1 -1
  48. package/dist/kadaikodi/pages/worker/WorkerSchedulePage.d.ts.map +1 -1
  49. package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js.map +1 -1
  50. package/dist/services/createSandboxAssistantTransport.d.ts +8 -27
  51. package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -1
  52. package/dist/services/createSandboxAssistantTransport.js +7 -10
  53. package/dist/services/createSandboxAssistantTransport.js.map +1 -1
  54. package/dist/stories/EmptyState.stories.d.ts +10 -0
  55. package/dist/stories/EmptyState.stories.d.ts.map +1 -0
  56. package/dist/stories/MetricsCard.stories.d.ts +10 -0
  57. package/dist/stories/MetricsCard.stories.d.ts.map +1 -0
  58. package/dist/stories/StatusBadge.stories.d.ts +12 -0
  59. package/dist/stories/StatusBadge.stories.d.ts.map +1 -0
  60. package/package.json +15 -3
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage.d.ts","sourceRoot":"","sources":["../../../src/kadaikodi/pages/HomePage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAiSH,wBAAgB,QAAQ,gCAyiBvB"}
1
+ {"version":3,"file":"HomePage.d.ts","sourceRoot":"","sources":["../../../src/kadaikodi/pages/HomePage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAiSH,wBAAgB,QAAQ,gCAgjBvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/kadaikodi/pages/HomePage.tsx"],"sourcesContent":["/**\n * Home Page\n * @module kadaikodi/pages\n *\n * The role-aware launch pad — \"one account, every role\". The hero is a set of\n * role cards (Customer / My Cart-Merchant / Work / Invest / Admin), each with an\n * icon, a one-line description, a LIVE stat pulled from the real backend hooks\n * where it is cheap, and a chevron that jumps to that role's home. The Admin\n * card is gated for operators. Below the role cards, a compact current-role\n * surface keeps the day-to-day essentials (quick actions, what's open nearby,\n * recent orders, categories) — all wired to real data, no fabricated values.\n */\n\nimport { useState, useMemo, useCallback } from 'react';\nimport type { ReactNode } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n Search,\n ShoppingBag,\n ShoppingCart,\n Store,\n ClipboardList,\n TrendingUp,\n LayoutDashboard,\n Users,\n IndianRupee,\n ArrowRight,\n ChevronRight,\n Star,\n MapPin,\n Clock,\n ChefHat,\n Scissors,\n Wrench,\n Home,\n Shirt,\n Heart,\n GraduationCap,\n Package,\n BarChart3,\n Sparkles,\n HandCoins,\n UserCheck,\n Truck,\n BadgeCheck,\n Shield,\n Lock,\n Settings,\n Loader2,\n AlertCircle,\n} from 'lucide-react';\nimport { PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { EmptyState } from '../components/EmptyState';\nimport { useKadaikodi } from '../context/KadaikodiContext';\nimport { useKadaikodiApi } from '../hooks/useKadaikodiApi';\nimport { cn } from '../utils/cn';\nimport { formatCurrency, formatRelativeTime, formatDistance } from '../utils/formatters';\nimport type { UserRole } from '../types';\n\n// ---------------------------------------------------------------------------\n// Role-based Quick Action configs (valid, real routes only)\n// ---------------------------------------------------------------------------\n\ninterface QuickAction {\n label: string;\n description: string;\n icon: ReactNode;\n path: string;\n color: string;\n}\n\nconst quickActionsByRole: Record<UserRole, QuickAction[]> = {\n customer: [\n {\n label: 'Discover',\n description: 'Browse carts near you',\n icon: <Search className=\"h-5 w-5\" />,\n path: '/customer/discover',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'My Orders',\n description: 'Track your orders',\n icon: <ShoppingBag className=\"h-5 w-5\" />,\n path: '/customer/orders',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Favorites',\n description: 'Your saved carts',\n icon: <Heart className=\"h-5 w-5\" />,\n path: '/customer/favorites',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Settings',\n description: 'Manage preferences',\n icon: <Settings className=\"h-5 w-5\" />,\n path: '/settings',\n color: 'bg-bg-sunken text-text-secondary',\n },\n ],\n cart_owner: [\n {\n label: 'Dashboard',\n description: 'Run your cart',\n icon: <Store className=\"h-5 w-5\" />,\n path: '/cart-owner/dashboard',\n color: 'bg-accent-primary/10 text-accent-primary',\n },\n {\n label: 'Orders',\n description: 'Incoming orders',\n icon: <ShoppingBag className=\"h-5 w-5\" />,\n path: '/cart-owner/orders',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Analytics',\n description: 'Revenue & insights',\n icon: <BarChart3 className=\"h-5 w-5\" />,\n path: '/cart-owner/analytics',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Staff',\n description: 'Manage workers',\n icon: <Users className=\"h-5 w-5\" />,\n path: '/cart-owner/staff',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n ],\n worker: [\n {\n label: 'My Tasks',\n description: 'Assigned work',\n icon: <ClipboardList className=\"h-5 w-5\" />,\n path: '/worker/dashboard',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n label: 'Schedule',\n description: 'View shifts',\n icon: <Clock className=\"h-5 w-5\" />,\n path: '/worker/schedule',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Deliveries',\n description: 'Active runs',\n icon: <Package className=\"h-5 w-5\" />,\n path: '/worker/orders',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Profile',\n description: 'Your details',\n icon: <UserCheck className=\"h-5 w-5\" />,\n path: '/worker/profile',\n color: 'bg-bg-sunken text-text-secondary',\n },\n ],\n investor: [\n {\n label: 'Portfolio',\n description: 'Your investments',\n icon: <TrendingUp className=\"h-5 w-5\" />,\n path: '/investor/portfolio',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Opportunities',\n description: 'New investments',\n icon: <HandCoins className=\"h-5 w-5\" />,\n path: '/investor/opportunities',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Investments',\n description: 'Active positions',\n icon: <IndianRupee className=\"h-5 w-5\" />,\n path: '/investor/investments',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Analytics',\n description: 'Performance',\n icon: <BarChart3 className=\"h-5 w-5\" />,\n path: '/investor/analytics',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n ],\n admin: [\n {\n label: 'Dashboard',\n description: 'Platform overview',\n icon: <LayoutDashboard className=\"h-5 w-5\" />,\n path: '/admin/dashboard',\n color: 'bg-status-error-bg-subtle text-status-error-text',\n },\n {\n label: 'Users',\n description: 'Manage accounts',\n icon: <Users className=\"h-5 w-5\" />,\n path: '/admin/users',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Carts',\n description: 'Approve & manage',\n icon: <Store className=\"h-5 w-5\" />,\n path: '/admin/carts',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Analytics',\n description: 'Revenue reports',\n icon: <BarChart3 className=\"h-5 w-5\" />,\n path: '/admin/analytics',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n ],\n};\n\n// ---------------------------------------------------------------------------\n// Category data (real navigation into discovery, filtered by category)\n// ---------------------------------------------------------------------------\n\nconst categories = [\n {\n label: 'Food & Beverage',\n icon: <ChefHat className=\"h-6 w-6\" />,\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n label: 'Personal Care & Beauty',\n icon: <Scissors className=\"h-6 w-6\" />,\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Repair & Maintenance',\n icon: <Wrench className=\"h-6 w-6\" />,\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Home Services',\n icon: <Home className=\"h-6 w-6\" />,\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Clothing & Fashion',\n icon: <Shirt className=\"h-6 w-6\" />,\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Health & Wellness',\n icon: <Heart className=\"h-6 w-6\" />,\n color: 'bg-status-error-bg-subtle text-status-error-text',\n },\n {\n label: 'Education & Skills',\n icon: <GraduationCap className=\"h-6 w-6\" />,\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n label: 'Retail & Merchandise',\n icon: <Package className=\"h-6 w-6\" />,\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Grocery & Essentials',\n icon: <ShoppingCart className=\"h-6 w-6\" />,\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n];\n\n// ---------------------------------------------------------------------------\n// Role card definitions (the hero of the page)\n// ---------------------------------------------------------------------------\n\ninterface RoleCardDef {\n role: UserRole;\n title: string;\n description: string;\n icon: ReactNode;\n path: string;\n iconClass: string;\n}\n\ninterface RoleStat {\n value: string;\n label: string;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function HomePage() {\n const { navigateTo, currentUser } = useKadaikodi();\n const { t: translate } = useI18n();\n const [searchQuery, setSearchQuery] = useState('');\n\n const { providers, orders, dashboardStats, investments } = useKadaikodiApi();\n\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'there';\n const userRole: UserRole = (currentUser?.role as UserRole) ?? 'customer';\n const isOperator = userRole === 'admin';\n\n const quickActions = quickActionsByRole[userRole] ?? quickActionsByRole.customer;\n\n // --- Real, cheap live metrics (derived only from already-fetched data) ---\n const myProvider = useMemo(\n () => (providers.data ?? []).find((p) => p.ownerId === currentUser?.id),\n [providers.data, currentUser?.id]\n );\n const customerOrderCount = (orders.data ?? []).length;\n const portfolioValue = useMemo(\n () => (investments.data ?? []).reduce((sum, inv) => sum + inv.currentValue, 0),\n [investments.data]\n );\n\n const roleStat = useCallback(\n (role: UserRole): RoleStat | null => {\n switch (role) {\n case 'customer':\n return {\n value: customerOrderCount.toString(),\n label: customerOrderCount === 1 ? t('kadaikodi.home.order', 'order') : t('kadaikodi.home.orders', 'orders'),\n };\n case 'cart_owner':\n return myProvider\n ? { value: `★ ${myProvider.rating.toFixed(1)}`, label: t('kadaikodi.home.rating', 'rating') }\n : null;\n case 'investor':\n return portfolioValue > 0\n ? {\n value: formatCurrency(portfolioValue, { minimumFractionDigits: 0 }),\n label: t('kadaikodi.home.portfolio', 'portfolio'),\n }\n : null;\n case 'admin':\n return isOperator\n ? {\n value: (dashboardStats.data?.activeProviders ?? 0).toString(),\n label: t('kadaikodi.home.providers', 'providers'),\n }\n : null;\n case 'worker':\n default:\n // Worker stats need a worker-scoped query we intentionally keep off the\n // launch pad to stay cheap — the card shows its description only.\n return null;\n }\n },\n [customerOrderCount, myProvider, portfolioValue, isOperator, dashboardStats.data, t]\n );\n\n const roleCards: RoleCardDef[] = [\n {\n role: 'customer',\n title: t('kadaikodi.home.roleCard.customer.title', 'Shop as Customer'),\n description: t('kadaikodi.home.roleCard.customer.desc', 'Discover carts & order'),\n icon: <ShoppingCart className=\"h-6 w-6\" />,\n path: '/customer/dashboard',\n iconClass: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n role: 'cart_owner',\n title: t('kadaikodi.home.roleCard.merchant.title', 'My Cart (Merchant)'),\n description: t('kadaikodi.home.roleCard.merchant.desc', 'Run your business'),\n icon: <Store className=\"h-6 w-6\" />,\n path: '/cart-owner/dashboard',\n iconClass: 'bg-accent-primary/10 text-accent-primary',\n },\n {\n role: 'worker',\n title: t('kadaikodi.home.roleCard.worker.title', 'Work'),\n description: t('kadaikodi.home.roleCard.worker.desc', 'Deliveries & tasks'),\n icon: <Truck className=\"h-6 w-6\" />,\n path: '/worker/dashboard',\n iconClass: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n role: 'investor',\n title: t('kadaikodi.home.roleCard.investor.title', 'Invest'),\n description: t('kadaikodi.home.roleCard.investor.desc', 'Back local merchants'),\n icon: <HandCoins className=\"h-6 w-6\" />,\n path: '/investor/dashboard',\n iconClass: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n role: 'admin',\n title: t('kadaikodi.home.roleCard.admin.title', 'Admin'),\n description: t('kadaikodi.home.roleCard.admin.desc', 'Platform operations'),\n icon: <Shield className=\"h-6 w-6\" />,\n path: '/admin/dashboard',\n iconClass: 'bg-bg-sunken text-text-secondary',\n },\n ];\n\n // Featured carts (top-rated, open) — real providers\n const featuredCarts = useMemo(() => {\n let carts = (providers.data ?? []).filter((c) => c.isOpen);\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n carts = carts.filter(\n (c) => c.name.toLowerCase().includes(q) || c.category.toLowerCase().includes(q)\n );\n }\n return carts.sort((a, b) => b.rating - a.rating).slice(0, 6);\n }, [providers.data, searchQuery]);\n\n // Recent orders — real\n const recentOrders = useMemo(() => {\n return [...(orders.data ?? [])]\n .sort((a, b) => new Date(b.orderDate).getTime() - new Date(a.orderDate).getTime())\n .slice(0, 3);\n }, [orders.data]);\n\n const isNewUser = (orders.data ?? []).length === 0 && !orders.isLoading;\n const isLoading = providers.isLoading || orders.isLoading || dashboardStats.isLoading;\n const isError = providers.isError || orders.isError || dashboardStats.isError;\n\n if (isLoading) {\n return (\n <PageLayout title={t('kadaikodi.common.loading', 'Loading...')}>\n <div className=\"flex h-[60vh] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-accent-primary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title={t('kadaikodi.common.error', 'Error')}>\n <div className=\"flex h-[60vh] flex-col items-center justify-center gap-4\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <h2 className=\"text-xl font-semibold text-text-primary\">\n {t('kadaikodi.common.errorLoading', 'Error loading data')}\n </h2>\n <p className=\"text-text-secondary\">\n {t('kadaikodi.common.tryAgain', 'Please try again later.')}\n </p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`${t('kadaikodi.home.hi', 'Hi')}, ${firstName}`}\n description={t('kadaikodi.home.everyRole', 'One account, every role')}\n >\n <PagePurpose className=\"mb-6\">\n {t(\n 'kadaikodi.home.purpose',\n 'Kadaikodi gives you one account for every side of local commerce. Jump into the role you need — shop as a customer, run your cart as a merchant, pick up delivery work, or back local businesses — and pick up right where you left off.'\n )}\n </PagePurpose>\n\n {/* Welcome Banner for New Users (real: gated on empty order history) */}\n {isNewUser && (\n <section className=\"mb-8 overflow-hidden rounded-xl border border-border-subtle bg-accent-primary/5 p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-accent-primary/10 text-accent-primary\">\n <Sparkles className=\"h-6 w-6\" />\n </div>\n <div className=\"flex-1\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.welcomeTitle', 'Welcome to Kadaikodi!')}\n </h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {t(\n 'kadaikodi.home.welcomeDescription',\n 'Your local commerce hub. Start by exploring service providers near you, or pick a role above to get going.'\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => navigateTo('/customer/discover')}\n className=\"mt-3 inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n <Search className=\"h-4 w-4\" />\n {t('kadaikodi.home.exploreServices', 'Explore Services')}\n </button>\n </div>\n </div>\n </section>\n )}\n\n {/* ── ROLE CARDS — the hero: one account, every role ─────────── */}\n <section className=\"mb-10\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.chooseRole', 'Choose how you want to show up')}\n </h2>\n <span className=\"hidden items-center gap-1 text-xs font-medium text-text-muted sm:inline-flex\">\n <Shield className=\"h-3.5 w-3.5\" />\n {t('kadaikodi.home.rbac', 'RBAC & multi-tenant')}\n </span>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3\">\n {roleCards.map((card) => {\n const isCurrent = card.role === userRole;\n const gated = card.role === 'admin' && !isOperator;\n const stat = roleStat(card.role);\n\n return (\n <button\n key={card.role}\n type=\"button\"\n disabled={gated}\n onClick={() => {\n if (!gated) navigateTo(card.path);\n }}\n aria-label={card.title}\n className={cn(\n 'group relative flex items-center gap-4 rounded-xl border p-4 text-left transition-all sm:p-5',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n isCurrent\n ? 'border-accent-primary/40 bg-accent-primary/5 shadow-[var(--shadow-glow)]'\n : 'border-border-subtle bg-bg-surface hover:border-border-strong hover:shadow-md',\n gated && 'cursor-not-allowed opacity-70 hover:border-border-subtle hover:shadow-none'\n )}\n >\n <div\n className={cn(\n 'flex h-12 w-12 shrink-0 items-center justify-center rounded-xl',\n card.iconClass\n )}\n >\n {gated ? <Lock className=\"h-6 w-6\" /> : card.icon}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"truncate text-base font-semibold text-text-primary\">\n {card.title}\n </p>\n {isCurrent && (\n <span className=\"inline-flex items-center rounded-full bg-accent-primary/10 px-2 py-0.5 text-[11px] font-medium text-accent-primary\">\n {t('kadaikodi.home.current', 'Current')}\n </span>\n )}\n </div>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">{card.description}</p>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-3\">\n {gated ? (\n <span className=\"inline-flex items-center gap-1 whitespace-nowrap text-xs font-medium text-text-muted\">\n {t('kadaikodi.home.operatorsOnly', 'operators only')}\n <Lock className=\"h-3.5 w-3.5\" />\n </span>\n ) : (\n <>\n {stat && (\n <div className=\"hidden text-right sm:block\">\n <p className=\"text-sm font-bold tabular-nums text-text-primary\">\n {stat.value}\n </p>\n <p className=\"text-[11px] text-text-secondary\">{stat.label}</p>\n </div>\n )}\n <ChevronRight className=\"h-5 w-5 text-text-secondary transition group-hover:translate-x-0.5 group-hover:text-text-primary\" />\n </>\n )}\n </div>\n </button>\n );\n })}\n </div>\n </section>\n\n {/* ── Current-role surface ───────────────────────────────────── */}\n\n {/* Quick Actions */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.quickActions', 'Quick Actions')}\n </h2>\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n {quickActions.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n onClick={() => navigateTo(action.path)}\n className={cn(\n 'group flex items-start gap-3 rounded-lg border border-border-subtle bg-bg-surface p-4 text-left shadow-sm transition-all',\n 'hover:border-border-strong hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n <div\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-lg',\n action.color\n )}\n >\n {action.icon}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold text-text-primary\">{action.label}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">{action.description}</p>\n </div>\n <ArrowRight className=\"mt-1 h-4 w-4 shrink-0 text-text-secondary transition group-hover:translate-x-0.5\" />\n </button>\n ))}\n </div>\n </section>\n\n {/* Featured / Nearby Carts (real providers) */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {searchQuery\n ? t('kadaikodi.home.searchResults', 'Search Results')\n : t('kadaikodi.home.openNearby', \"What's open nearby\")}\n </h2>\n <div className=\"flex items-center gap-3\">\n <div className=\"relative w-full sm:w-64\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n placeholder={t('kadaikodi.home.searchPlaceholder', 'Search carts...')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo('/customer/discover')}\n className=\"hidden items-center gap-1 whitespace-nowrap text-sm font-medium text-accent-primary hover:underline sm:flex\"\n >\n {t('kadaikodi.common.viewAll', 'View All')} <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n </div>\n\n {featuredCarts.length === 0 ? (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Search className=\"h-10 w-10\" />}\n title={t('kadaikodi.home.noCartsFound', 'No carts found')}\n description={t(\n 'kadaikodi.home.noCartsDescription',\n 'Try adjusting your search or browse all categories'\n )}\n action={\n searchQuery ? (\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n {t('kadaikodi.home.clearSearch', 'Clear Search')}\n </button>\n ) : undefined\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {featuredCarts.map((cart) => (\n <div\n key={cart.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => navigateTo(`/customer/cart/${cart.id}`)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigateTo(`/customer/cart/${cart.id}`);\n }\n }}\n className=\"group cursor-pointer overflow-hidden rounded-xl border border-border-subtle bg-bg-surface shadow-sm transition-all hover:border-border-strong hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n {/* Header band — honest placeholder (no fabricated imagery). */}\n <div className=\"relative flex h-24 items-center justify-center bg-gradient-to-br from-[var(--color-accent-soft)] to-bg-sunken\">\n <Store className=\"h-8 w-8 text-text-secondary/50\" />\n <div className=\"absolute right-2 top-2\">\n <StatusBadge status={cart.isOpen ? 'open' : 'closed'} />\n </div>\n {cart.isVerified && (\n <div className=\"absolute left-2 top-2\">\n <span className=\"inline-flex items-center gap-1 rounded-full bg-bg-surface/80 px-2 py-0.5 text-xs font-medium text-accent-primary backdrop-blur-sm\">\n <BadgeCheck className=\"h-3 w-3\" />\n {t('kadaikodi.home.verified', 'Verified')}\n </span>\n </div>\n )}\n </div>\n\n <div className=\"p-4\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">\n {cart.name}\n </h3>\n <p className=\"mt-0.5 text-sm text-text-secondary\">{cart.category}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-1 rounded bg-status-success-bg-subtle px-1.5 py-0.5\">\n <Star className=\"h-3 w-3 fill-status-success-text text-status-success-text\" />\n <span className=\"text-xs font-bold text-status-success-text tabular-nums\">\n {cart.rating.toFixed(1)}\n </span>\n </div>\n </div>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary\">\n {cart.distance != null && (\n <span className=\"flex items-center gap-1\">\n <MapPin className=\"h-3 w-3\" /> {formatDistance(cart.distance)}\n </span>\n )}\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3\" /> {cart.totalRatings}{' '}\n {t('kadaikodi.home.reviews', 'reviews')}\n </span>\n {cart.averageOrderValue != null && cart.averageOrderValue > 0 && (\n <span className=\"flex items-center gap-1\">\n <IndianRupee className=\"h-3 w-3\" /> {t('kadaikodi.home.average', 'Avg.')}{' '}\n {formatCurrency(cart.averageOrderValue, { minimumFractionDigits: 0 })}\n </span>\n )}\n </div>\n\n {cart.serviceTypes && cart.serviceTypes.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {cart.serviceTypes.slice(0, 3).map((st) => (\n <span\n key={st}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {st.replace(/_/g, ' ')}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </section>\n\n {/* Recent Orders (real) */}\n {recentOrders.length > 0 && (\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.recentOrders', 'Recent Orders')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/customer/orders')}\n className=\"flex items-center gap-1 text-sm font-medium text-accent-primary hover:underline\"\n >\n {t('kadaikodi.common.viewAll', 'View All')} <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div className=\"divide-y divide-border-subtle overflow-hidden rounded-xl border border-border-subtle bg-bg-surface\">\n {recentOrders.map((order) => (\n <div\n key={order.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => navigateTo(`/customer/orders/${order.id}/track`)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigateTo(`/customer/orders/${order.id}/track`);\n }\n }}\n className=\"flex cursor-pointer items-center gap-4 px-4 py-3 transition-colors hover:bg-bg-sunken/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <ShoppingBag className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {order.cartName}\n </p>\n <StatusBadge status={order.status} />\n </div>\n <p className=\"mt-0.5 truncate text-xs text-text-secondary\">\n {order.items.map((i) => i.name).join(', ')}\n </p>\n </div>\n <div className=\"shrink-0 text-right\">\n <p className=\"text-sm font-semibold text-text-primary tabular-nums\">\n {formatCurrency(order.total, { minimumFractionDigits: 0 })}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {formatRelativeTime(order.orderDate)}\n </p>\n </div>\n </div>\n ))}\n </div>\n </section>\n )}\n\n {/* Browse by Category (real navigation) */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.browseByCategory', 'Browse by Category')}\n </h2>\n <div className=\"grid grid-cols-3 gap-3 sm:grid-cols-4 lg:grid-cols-5\">\n {categories.map((cat) => (\n <button\n key={cat.label}\n type=\"button\"\n onClick={() =>\n navigateTo(`/customer/discover?category=${encodeURIComponent(cat.label)}`)\n }\n className=\"flex flex-col items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface p-4 text-center transition-all hover:border-border-strong hover:shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <div\n className={cn('flex h-12 w-12 items-center justify-center rounded-full', cat.color)}\n >\n {cat.icon}\n </div>\n <span className=\"text-xs font-medium leading-tight text-text-primary\">\n {cat.label}\n </span>\n </button>\n ))}\n </div>\n </section>\n\n {/* Footer note */}\n <p className=\"mt-2 text-center text-xs text-text-muted\">\n {t(\n 'kadaikodi.home.footerNote',\n 'RBAC & multi-tenancy inherited from the Burdenoff platform'\n )}\n </p>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/kadaikodi/pages/HomePage.tsx"],"sourcesContent":["/**\n * Home Page\n * @module kadaikodi/pages\n *\n * The role-aware launch pad — \"one account, every role\". The hero is a set of\n * role cards (Customer / My Cart-Merchant / Work / Invest / Admin), each with an\n * icon, a one-line description, a LIVE stat pulled from the real backend hooks\n * where it is cheap, and a chevron that jumps to that role's home. The Admin\n * card is gated for operators. Below the role cards, a compact current-role\n * surface keeps the day-to-day essentials (quick actions, what's open nearby,\n * recent orders, categories) — all wired to real data, no fabricated values.\n */\n\nimport { useState, useMemo, useCallback } from 'react';\nimport type { ReactNode } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n Search,\n ShoppingBag,\n ShoppingCart,\n Store,\n ClipboardList,\n TrendingUp,\n LayoutDashboard,\n Users,\n IndianRupee,\n ArrowRight,\n ChevronRight,\n Star,\n MapPin,\n Clock,\n ChefHat,\n Scissors,\n Wrench,\n Home,\n Shirt,\n Heart,\n GraduationCap,\n Package,\n BarChart3,\n Sparkles,\n HandCoins,\n UserCheck,\n Truck,\n BadgeCheck,\n Shield,\n Lock,\n Settings,\n Loader2,\n AlertCircle,\n} from 'lucide-react';\nimport { PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { EmptyState } from '../components/EmptyState';\nimport { useKadaikodi } from '../context/KadaikodiContext';\nimport { useKadaikodiApi } from '../hooks/useKadaikodiApi';\nimport { cn } from '../utils/cn';\nimport { formatCurrency, formatRelativeTime, formatDistance } from '../utils/formatters';\nimport type { UserRole } from '../types';\n\n// ---------------------------------------------------------------------------\n// Role-based Quick Action configs (valid, real routes only)\n// ---------------------------------------------------------------------------\n\ninterface QuickAction {\n label: string;\n description: string;\n icon: ReactNode;\n path: string;\n color: string;\n}\n\nconst quickActionsByRole: Record<UserRole, QuickAction[]> = {\n customer: [\n {\n label: 'Discover',\n description: 'Browse carts near you',\n icon: <Search className=\"h-5 w-5\" />,\n path: '/customer/discover',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'My Orders',\n description: 'Track your orders',\n icon: <ShoppingBag className=\"h-5 w-5\" />,\n path: '/customer/orders',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Favorites',\n description: 'Your saved carts',\n icon: <Heart className=\"h-5 w-5\" />,\n path: '/customer/favorites',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Settings',\n description: 'Manage preferences',\n icon: <Settings className=\"h-5 w-5\" />,\n path: '/settings',\n color: 'bg-bg-sunken text-text-secondary',\n },\n ],\n cart_owner: [\n {\n label: 'Dashboard',\n description: 'Run your cart',\n icon: <Store className=\"h-5 w-5\" />,\n path: '/cart-owner/dashboard',\n color: 'bg-accent-primary/10 text-accent-primary',\n },\n {\n label: 'Orders',\n description: 'Incoming orders',\n icon: <ShoppingBag className=\"h-5 w-5\" />,\n path: '/cart-owner/orders',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Analytics',\n description: 'Revenue & insights',\n icon: <BarChart3 className=\"h-5 w-5\" />,\n path: '/cart-owner/analytics',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Staff',\n description: 'Manage workers',\n icon: <Users className=\"h-5 w-5\" />,\n path: '/cart-owner/staff',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n ],\n worker: [\n {\n label: 'My Tasks',\n description: 'Assigned work',\n icon: <ClipboardList className=\"h-5 w-5\" />,\n path: '/worker/dashboard',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n label: 'Schedule',\n description: 'View shifts',\n icon: <Clock className=\"h-5 w-5\" />,\n path: '/worker/schedule',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Deliveries',\n description: 'Active runs',\n icon: <Package className=\"h-5 w-5\" />,\n path: '/worker/orders',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Profile',\n description: 'Your details',\n icon: <UserCheck className=\"h-5 w-5\" />,\n path: '/worker/profile',\n color: 'bg-bg-sunken text-text-secondary',\n },\n ],\n investor: [\n {\n label: 'Portfolio',\n description: 'Your investments',\n icon: <TrendingUp className=\"h-5 w-5\" />,\n path: '/investor/portfolio',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Opportunities',\n description: 'New investments',\n icon: <HandCoins className=\"h-5 w-5\" />,\n path: '/investor/opportunities',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Investments',\n description: 'Active positions',\n icon: <IndianRupee className=\"h-5 w-5\" />,\n path: '/investor/investments',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Analytics',\n description: 'Performance',\n icon: <BarChart3 className=\"h-5 w-5\" />,\n path: '/investor/analytics',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n ],\n admin: [\n {\n label: 'Dashboard',\n description: 'Platform overview',\n icon: <LayoutDashboard className=\"h-5 w-5\" />,\n path: '/admin/dashboard',\n color: 'bg-status-error-bg-subtle text-status-error-text',\n },\n {\n label: 'Users',\n description: 'Manage accounts',\n icon: <Users className=\"h-5 w-5\" />,\n path: '/admin/users',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Carts',\n description: 'Approve & manage',\n icon: <Store className=\"h-5 w-5\" />,\n path: '/admin/carts',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Analytics',\n description: 'Revenue reports',\n icon: <BarChart3 className=\"h-5 w-5\" />,\n path: '/admin/analytics',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n ],\n};\n\n// ---------------------------------------------------------------------------\n// Category data (real navigation into discovery, filtered by category)\n// ---------------------------------------------------------------------------\n\nconst categories = [\n {\n label: 'Food & Beverage',\n icon: <ChefHat className=\"h-6 w-6\" />,\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n label: 'Personal Care & Beauty',\n icon: <Scissors className=\"h-6 w-6\" />,\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Repair & Maintenance',\n icon: <Wrench className=\"h-6 w-6\" />,\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Home Services',\n icon: <Home className=\"h-6 w-6\" />,\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Clothing & Fashion',\n icon: <Shirt className=\"h-6 w-6\" />,\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Health & Wellness',\n icon: <Heart className=\"h-6 w-6\" />,\n color: 'bg-status-error-bg-subtle text-status-error-text',\n },\n {\n label: 'Education & Skills',\n icon: <GraduationCap className=\"h-6 w-6\" />,\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n label: 'Retail & Merchandise',\n icon: <Package className=\"h-6 w-6\" />,\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Grocery & Essentials',\n icon: <ShoppingCart className=\"h-6 w-6\" />,\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n];\n\n// ---------------------------------------------------------------------------\n// Role card definitions (the hero of the page)\n// ---------------------------------------------------------------------------\n\ninterface RoleCardDef {\n role: UserRole;\n title: string;\n description: string;\n icon: ReactNode;\n path: string;\n iconClass: string;\n}\n\ninterface RoleStat {\n value: string;\n label: string;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function HomePage() {\n const { navigateTo, currentUser } = useKadaikodi();\n const { t: translate } = useI18n();\n const [searchQuery, setSearchQuery] = useState('');\n\n const { providers, orders, dashboardStats, investments } = useKadaikodiApi();\n\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'there';\n const userRole: UserRole = (currentUser?.role as UserRole) ?? 'customer';\n const isOperator = userRole === 'admin';\n\n const quickActions = quickActionsByRole[userRole] ?? quickActionsByRole.customer;\n\n // --- Real, cheap live metrics (derived only from already-fetched data) ---\n const myProvider = useMemo(\n () => (providers.data ?? []).find((p) => p.ownerId === currentUser?.id),\n [providers.data, currentUser?.id]\n );\n const customerOrderCount = (orders.data ?? []).length;\n const portfolioValue = useMemo(\n () => (investments.data ?? []).reduce((sum, inv) => sum + inv.currentValue, 0),\n [investments.data]\n );\n\n const roleStat = useCallback(\n (role: UserRole): RoleStat | null => {\n switch (role) {\n case 'customer':\n return {\n value: customerOrderCount.toString(),\n label:\n customerOrderCount === 1\n ? t('kadaikodi.home.order', 'order')\n : t('kadaikodi.home.orders', 'orders'),\n };\n case 'cart_owner':\n return myProvider\n ? {\n value: `★ ${myProvider.rating.toFixed(1)}`,\n label: t('kadaikodi.home.rating', 'rating'),\n }\n : null;\n case 'investor':\n return portfolioValue > 0\n ? {\n value: formatCurrency(portfolioValue, { minimumFractionDigits: 0 }),\n label: t('kadaikodi.home.portfolio', 'portfolio'),\n }\n : null;\n case 'admin':\n return isOperator\n ? {\n value: (dashboardStats.data?.activeProviders ?? 0).toString(),\n label: t('kadaikodi.home.providers', 'providers'),\n }\n : null;\n case 'worker':\n default:\n // Worker stats need a worker-scoped query we intentionally keep off the\n // launch pad to stay cheap — the card shows its description only.\n return null;\n }\n },\n [customerOrderCount, myProvider, portfolioValue, isOperator, dashboardStats.data, t]\n );\n\n const roleCards: RoleCardDef[] = [\n {\n role: 'customer',\n title: t('kadaikodi.home.roleCard.customer.title', 'Shop as Customer'),\n description: t('kadaikodi.home.roleCard.customer.desc', 'Discover carts & order'),\n icon: <ShoppingCart className=\"h-6 w-6\" />,\n path: '/customer/dashboard',\n iconClass: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n role: 'cart_owner',\n title: t('kadaikodi.home.roleCard.merchant.title', 'My Cart (Merchant)'),\n description: t('kadaikodi.home.roleCard.merchant.desc', 'Run your business'),\n icon: <Store className=\"h-6 w-6\" />,\n path: '/cart-owner/dashboard',\n iconClass: 'bg-accent-primary/10 text-accent-primary',\n },\n {\n role: 'worker',\n title: t('kadaikodi.home.roleCard.worker.title', 'Work'),\n description: t('kadaikodi.home.roleCard.worker.desc', 'Deliveries & tasks'),\n icon: <Truck className=\"h-6 w-6\" />,\n path: '/worker/dashboard',\n iconClass: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n role: 'investor',\n title: t('kadaikodi.home.roleCard.investor.title', 'Invest'),\n description: t('kadaikodi.home.roleCard.investor.desc', 'Back local merchants'),\n icon: <HandCoins className=\"h-6 w-6\" />,\n path: '/investor/dashboard',\n iconClass: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n role: 'admin',\n title: t('kadaikodi.home.roleCard.admin.title', 'Admin'),\n description: t('kadaikodi.home.roleCard.admin.desc', 'Platform operations'),\n icon: <Shield className=\"h-6 w-6\" />,\n path: '/admin/dashboard',\n iconClass: 'bg-bg-sunken text-text-secondary',\n },\n ];\n\n // Featured carts (top-rated, open) — real providers\n const featuredCarts = useMemo(() => {\n let carts = (providers.data ?? []).filter((c) => c.isOpen);\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n carts = carts.filter(\n (c) => c.name.toLowerCase().includes(q) || c.category.toLowerCase().includes(q)\n );\n }\n return carts.sort((a, b) => b.rating - a.rating).slice(0, 6);\n }, [providers.data, searchQuery]);\n\n // Recent orders — real\n const recentOrders = useMemo(() => {\n return [...(orders.data ?? [])]\n .sort((a, b) => new Date(b.orderDate).getTime() - new Date(a.orderDate).getTime())\n .slice(0, 3);\n }, [orders.data]);\n\n const isNewUser = (orders.data ?? []).length === 0 && !orders.isLoading;\n const isLoading = providers.isLoading || orders.isLoading || dashboardStats.isLoading;\n const isError = providers.isError || orders.isError || dashboardStats.isError;\n\n if (isLoading) {\n return (\n <PageLayout title={t('kadaikodi.common.loading', 'Loading...')}>\n <div className=\"flex h-[60vh] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-accent-primary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title={t('kadaikodi.common.error', 'Error')}>\n <div className=\"flex h-[60vh] flex-col items-center justify-center gap-4\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <h2 className=\"text-xl font-semibold text-text-primary\">\n {t('kadaikodi.common.errorLoading', 'Error loading data')}\n </h2>\n <p className=\"text-text-secondary\">\n {t('kadaikodi.common.tryAgain', 'Please try again later.')}\n </p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`${t('kadaikodi.home.hi', 'Hi')}, ${firstName}`}\n description={t('kadaikodi.home.everyRole', 'One account, every role')}\n >\n <PagePurpose className=\"mb-6\">\n {t(\n 'kadaikodi.home.purpose',\n 'Kadaikodi gives you one account for every side of local commerce. Jump into the role you need — shop as a customer, run your cart as a merchant, pick up delivery work, or back local businesses — and pick up right where you left off.'\n )}\n </PagePurpose>\n\n {/* Welcome Banner for New Users (real: gated on empty order history) */}\n {isNewUser && (\n <section className=\"mb-8 overflow-hidden rounded-xl border border-border-subtle bg-accent-primary/5 p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-accent-primary/10 text-accent-primary\">\n <Sparkles className=\"h-6 w-6\" />\n </div>\n <div className=\"flex-1\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.welcomeTitle', 'Welcome to Kadaikodi!')}\n </h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {t(\n 'kadaikodi.home.welcomeDescription',\n 'Your local commerce hub. Start by exploring service providers near you, or pick a role above to get going.'\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => navigateTo('/customer/discover')}\n className=\"mt-3 inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n <Search className=\"h-4 w-4\" />\n {t('kadaikodi.home.exploreServices', 'Explore Services')}\n </button>\n </div>\n </div>\n </section>\n )}\n\n {/* ── ROLE CARDS — the hero: one account, every role ─────────── */}\n <section className=\"mb-10\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.chooseRole', 'Choose how you want to show up')}\n </h2>\n <span className=\"hidden items-center gap-1 text-xs font-medium text-text-muted sm:inline-flex\">\n <Shield className=\"h-3.5 w-3.5\" />\n {t('kadaikodi.home.rbac', 'RBAC & multi-tenant')}\n </span>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3\">\n {roleCards.map((card) => {\n const isCurrent = card.role === userRole;\n const gated = card.role === 'admin' && !isOperator;\n const stat = roleStat(card.role);\n\n return (\n <button\n key={card.role}\n type=\"button\"\n disabled={gated}\n onClick={() => {\n if (!gated) navigateTo(card.path);\n }}\n aria-label={card.title}\n className={cn(\n 'group relative flex items-center gap-4 rounded-xl border p-4 text-left transition-all sm:p-5',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n isCurrent\n ? 'border-accent-primary/40 bg-accent-primary/5 shadow-[var(--shadow-glow)]'\n : 'border-border-subtle bg-bg-surface hover:border-border-strong hover:shadow-md',\n gated &&\n 'cursor-not-allowed opacity-70 hover:border-border-subtle hover:shadow-none'\n )}\n >\n <div\n className={cn(\n 'flex h-12 w-12 shrink-0 items-center justify-center rounded-xl',\n card.iconClass\n )}\n >\n {gated ? <Lock className=\"h-6 w-6\" /> : card.icon}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"truncate text-base font-semibold text-text-primary\">\n {card.title}\n </p>\n {isCurrent && (\n <span className=\"inline-flex items-center rounded-full bg-accent-primary/10 px-2 py-0.5 text-[11px] font-medium text-accent-primary\">\n {t('kadaikodi.home.current', 'Current')}\n </span>\n )}\n </div>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">{card.description}</p>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-3\">\n {gated ? (\n <span className=\"inline-flex items-center gap-1 whitespace-nowrap text-xs font-medium text-text-muted\">\n {t('kadaikodi.home.operatorsOnly', 'operators only')}\n <Lock className=\"h-3.5 w-3.5\" />\n </span>\n ) : (\n <>\n {stat && (\n <div className=\"hidden text-right sm:block\">\n <p className=\"text-sm font-bold tabular-nums text-text-primary\">\n {stat.value}\n </p>\n <p className=\"text-[11px] text-text-secondary\">{stat.label}</p>\n </div>\n )}\n <ChevronRight className=\"h-5 w-5 text-text-secondary transition group-hover:translate-x-0.5 group-hover:text-text-primary\" />\n </>\n )}\n </div>\n </button>\n );\n })}\n </div>\n </section>\n\n {/* ── Current-role surface ───────────────────────────────────── */}\n\n {/* Quick Actions */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.quickActions', 'Quick Actions')}\n </h2>\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n {quickActions.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n onClick={() => navigateTo(action.path)}\n className={cn(\n 'group flex items-start gap-3 rounded-lg border border-border-subtle bg-bg-surface p-4 text-left shadow-sm transition-all',\n 'hover:border-border-strong hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n <div\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-lg',\n action.color\n )}\n >\n {action.icon}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold text-text-primary\">{action.label}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">{action.description}</p>\n </div>\n <ArrowRight className=\"mt-1 h-4 w-4 shrink-0 text-text-secondary transition group-hover:translate-x-0.5\" />\n </button>\n ))}\n </div>\n </section>\n\n {/* Featured / Nearby Carts (real providers) */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {searchQuery\n ? t('kadaikodi.home.searchResults', 'Search Results')\n : t('kadaikodi.home.openNearby', \"What's open nearby\")}\n </h2>\n <div className=\"flex items-center gap-3\">\n <div className=\"relative w-full sm:w-64\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n placeholder={t('kadaikodi.home.searchPlaceholder', 'Search carts...')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo('/customer/discover')}\n className=\"hidden items-center gap-1 whitespace-nowrap text-sm font-medium text-accent-primary hover:underline sm:flex\"\n >\n {t('kadaikodi.common.viewAll', 'View All')} <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n </div>\n\n {featuredCarts.length === 0 ? (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Search className=\"h-10 w-10\" />}\n title={t('kadaikodi.home.noCartsFound', 'No carts found')}\n description={t(\n 'kadaikodi.home.noCartsDescription',\n 'Try adjusting your search or browse all categories'\n )}\n action={\n searchQuery ? (\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n {t('kadaikodi.home.clearSearch', 'Clear Search')}\n </button>\n ) : undefined\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {featuredCarts.map((cart) => (\n <div\n key={cart.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => navigateTo(`/customer/cart/${cart.id}`)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigateTo(`/customer/cart/${cart.id}`);\n }\n }}\n className=\"group cursor-pointer overflow-hidden rounded-xl border border-border-subtle bg-bg-surface shadow-sm transition-all hover:border-border-strong hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n {/* Header band — honest placeholder (no fabricated imagery). */}\n <div className=\"relative flex h-24 items-center justify-center bg-gradient-to-br from-[var(--color-accent-soft)] to-bg-sunken\">\n <Store className=\"h-8 w-8 text-text-secondary/50\" />\n <div className=\"absolute right-2 top-2\">\n <StatusBadge status={cart.isOpen ? 'open' : 'closed'} />\n </div>\n {cart.isVerified && (\n <div className=\"absolute left-2 top-2\">\n <span className=\"inline-flex items-center gap-1 rounded-full bg-bg-surface/80 px-2 py-0.5 text-xs font-medium text-accent-primary backdrop-blur-sm\">\n <BadgeCheck className=\"h-3 w-3\" />\n {t('kadaikodi.home.verified', 'Verified')}\n </span>\n </div>\n )}\n </div>\n\n <div className=\"p-4\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">\n {cart.name}\n </h3>\n <p className=\"mt-0.5 text-sm text-text-secondary\">{cart.category}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-1 rounded bg-status-success-bg-subtle px-1.5 py-0.5\">\n <Star className=\"h-3 w-3 fill-status-success-text text-status-success-text\" />\n <span className=\"text-xs font-bold text-status-success-text tabular-nums\">\n {cart.rating.toFixed(1)}\n </span>\n </div>\n </div>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary\">\n {cart.distance != null && (\n <span className=\"flex items-center gap-1\">\n <MapPin className=\"h-3 w-3\" /> {formatDistance(cart.distance)}\n </span>\n )}\n <span className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3\" /> {cart.totalRatings}{' '}\n {t('kadaikodi.home.reviews', 'reviews')}\n </span>\n {cart.averageOrderValue != null && cart.averageOrderValue > 0 && (\n <span className=\"flex items-center gap-1\">\n <IndianRupee className=\"h-3 w-3\" /> {t('kadaikodi.home.average', 'Avg.')}{' '}\n {formatCurrency(cart.averageOrderValue, { minimumFractionDigits: 0 })}\n </span>\n )}\n </div>\n\n {cart.serviceTypes && cart.serviceTypes.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {cart.serviceTypes.slice(0, 3).map((st) => (\n <span\n key={st}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {st.replace(/_/g, ' ')}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </section>\n\n {/* Recent Orders (real) */}\n {recentOrders.length > 0 && (\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.recentOrders', 'Recent Orders')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/customer/orders')}\n className=\"flex items-center gap-1 text-sm font-medium text-accent-primary hover:underline\"\n >\n {t('kadaikodi.common.viewAll', 'View All')} <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div className=\"divide-y divide-border-subtle overflow-hidden rounded-xl border border-border-subtle bg-bg-surface\">\n {recentOrders.map((order) => (\n <div\n key={order.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => navigateTo(`/customer/orders/${order.id}/track`)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigateTo(`/customer/orders/${order.id}/track`);\n }\n }}\n className=\"flex cursor-pointer items-center gap-4 px-4 py-3 transition-colors hover:bg-bg-sunken/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <ShoppingBag className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {order.cartName}\n </p>\n <StatusBadge status={order.status} />\n </div>\n <p className=\"mt-0.5 truncate text-xs text-text-secondary\">\n {order.items.map((i) => i.name).join(', ')}\n </p>\n </div>\n <div className=\"shrink-0 text-right\">\n <p className=\"text-sm font-semibold text-text-primary tabular-nums\">\n {formatCurrency(order.total, { minimumFractionDigits: 0 })}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {formatRelativeTime(order.orderDate)}\n </p>\n </div>\n </div>\n ))}\n </div>\n </section>\n )}\n\n {/* Browse by Category (real navigation) */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">\n {t('kadaikodi.home.browseByCategory', 'Browse by Category')}\n </h2>\n <div className=\"grid grid-cols-3 gap-3 sm:grid-cols-4 lg:grid-cols-5\">\n {categories.map((cat) => (\n <button\n key={cat.label}\n type=\"button\"\n onClick={() =>\n navigateTo(`/customer/discover?category=${encodeURIComponent(cat.label)}`)\n }\n className=\"flex flex-col items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface p-4 text-center transition-all hover:border-border-strong hover:shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <div\n className={cn('flex h-12 w-12 items-center justify-center rounded-full', cat.color)}\n >\n {cat.icon}\n </div>\n <span className=\"text-xs font-medium leading-tight text-text-primary\">\n {cat.label}\n </span>\n </button>\n ))}\n </div>\n </section>\n\n {/* Footer note */}\n <p className=\"mt-2 text-center text-xs text-text-muted\">\n {t(\n 'kadaikodi.home.footerNote',\n 'RBAC & multi-tenancy inherited from the Burdenoff platform'\n )}\n </p>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AdminAnalyticsPage.d.ts","sourceRoot":"","sources":["../../../../src/kadaikodi/pages/admin/AdminAnalyticsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAyDH,wBAAgB,kBAAkB,gCA8kBjC"}
1
+ {"version":3,"file":"AdminAnalyticsPage.d.ts","sourceRoot":"","sources":["../../../../src/kadaikodi/pages/admin/AdminAnalyticsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAyDH,wBAAgB,kBAAkB,gCAilBjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AdminAnalyticsPage.js","names":[],"sources":["../../../../src/kadaikodi/pages/admin/AdminAnalyticsPage.tsx"],"sourcesContent":["/**\n * Admin Analytics Page\n * @module kadaikodi/pages/admin\n *\n * Platform analytics wired to the live backend (useDashboardStats +\n * useAdminAnalytics + useProviders + useOrders). Every figure is real or\n * derived from real records — order-status distribution is counted from\n * loaded orders, category/growth breakdowns come from the analytics hook.\n * Metrics with no honest source (operating costs, delivery time, etc.) are\n * omitted rather than fabricated.\n */\n\nimport { useMemo, useState } from 'react';\nimport {\n Users,\n ShoppingBag,\n IndianRupee,\n BarChart3,\n Zap,\n Loader2,\n Star,\n Award,\n Store,\n TrendingUp,\n} from 'lucide-react';\nimport { EmphasisPanel, GlassCard, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { DonutChart, AreaChart, HBarFunnel } from '../../components/viz';\nimport type { LabeledValue, Segment } from '../../components/viz';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport {\n useDashboardStats,\n useAdminAnalytics,\n useProviders,\n useOrders,\n} from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\n/* ------------------------------------------------------------------ */\n/* Types + helpers */\n/* ------------------------------------------------------------------ */\n\ntype TabKey = 'overview' | 'revenue' | 'users' | 'performance';\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nconst titleCase = (s: string) =>\n s\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n\nconst dayKey = (d: Date) => {\n const x = new Date(d);\n x.setHours(0, 0, 0, 0);\n return x.getTime();\n};\n\nconst dayLabel = (t: number) =>\n new Date(t).toLocaleDateString('en-IN', { day: 'numeric', month: 'short' });\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function AdminAnalyticsPage() {\n const { navigateTo } = useKadaikodi();\n\n const { data: stats, isLoading: statsLoading } = useDashboardStats();\n const { data: analytics, isLoading: analyticsLoading } = useAdminAnalytics();\n const { data: providers = [], isLoading: providersLoading } = useProviders();\n const { data: orders = [], isLoading: ordersLoading } = useOrders({});\n\n const [activeTab, setActiveTab] = useState<TabKey>('overview');\n\n const loading = statsLoading || analyticsLoading || providersLoading || ordersLoading;\n\n const fmtCur = (amount: number) => {\n if (amount >= 10000000) return `₹${(amount / 10000000).toFixed(1)}Cr`;\n if (amount >= 100000) return `₹${(amount / 100000).toFixed(1)}L`;\n return formatCurrency(amount, { minimumFractionDigits: 0 });\n };\n\n // Order status distribution — counted from real loaded orders.\n const orderStats = useMemo(() => {\n const total = orders.length;\n const completed = orders.filter((o) => o.status === 'delivered').length;\n const cancelled = orders.filter((o) => o.status === 'cancelled').length;\n const pending = orders.filter((o) => o.status === 'pending' || o.status === 'confirmed').length;\n const startOfToday = new Date();\n startOfToday.setHours(0, 0, 0, 0);\n const ordersToday = orders.filter(\n (o) => new Date(o.orderDate).getTime() >= startOfToday.getTime()\n ).length;\n const avgOrderValue =\n stats && stats.totalOrders > 0 ? stats.totalRevenue / stats.totalOrders : 0;\n return { total, completed, cancelled, pending, ordersToday, avgOrderValue };\n }, [orders, stats]);\n\n const pendingCarts = useMemo(() => providers.filter((p) => !p.isOpen).length, [providers]);\n\n const topCarts = analytics?.topProviders ?? [];\n const customerTotal = analytics?.customerGrowth?.customers ?? 0;\n\n // Cart distribution per category with a real, derived share percentage.\n // The backend exposes counts per category, not revenue per category.\n const categoryDistRows = useMemo(() => {\n const entries = Object.entries(analytics?.categoryDistribution ?? {});\n const total = entries.reduce((sum, [, count]) => sum + count, 0);\n return entries\n .map(([category, count]) => ({\n category,\n count,\n percentage: total > 0 ? (count / total) * 100 : 0,\n }))\n .sort((a, b) => b.count - a.count);\n }, [analytics]);\n\n const prettyCategory = (c: string) => c.replace(/_/g, ' ').toLowerCase();\n\n const pct = (part: number, whole: number) => (whole > 0 ? (part / whole) * 100 : 0);\n\n // ── Category distribution donut — real cart counts per category. ───────────\n const categorySegments = useMemo<Segment[]>(\n () =>\n Object.entries(analytics?.categoryDistribution ?? {})\n .sort((a, b) => b[1] - a[1])\n .map(([c, count]) => ({ label: titleCase(c), value: count })),\n [analytics]\n );\n const totalCarts = useMemo(\n () => categorySegments.reduce((s, seg) => s + seg.value, 0),\n [categorySegments]\n );\n\n // ── GMV + order-volume over time — real per-day figures from real orders. ──\n const { gmvTrend, volumeTrend } = useMemo(() => {\n const today = dayKey(new Date());\n const start = today - 29 * DAY_MS;\n const gmv = new Map<number, number>();\n const vol = new Map<number, number>();\n for (let t = start; t <= today; t += DAY_MS) {\n gmv.set(t, 0);\n vol.set(t, 0);\n }\n for (const o of orders) {\n const t = dayKey(new Date(o.orderDate));\n if (gmv.has(t)) {\n gmv.set(t, (gmv.get(t) ?? 0) + (o.total ?? 0));\n vol.set(t, (vol.get(t) ?? 0) + 1);\n }\n }\n const g: LabeledValue[] = [...gmv.entries()].map(([t, v]) => ({ label: dayLabel(t), value: v }));\n const v: LabeledValue[] = [...vol.entries()].map(([t, val]) => ({\n label: dayLabel(t),\n value: val,\n }));\n return { gmvTrend: g, volumeTrend: v };\n }, [orders]);\n\n // ── Top categories by revenue — derived by joining real orders → provider. ─\n const topCategoryRevenue = useMemo<LabeledValue[]>(() => {\n const catOf = new Map(providers.map((p) => [p.id, p.category]));\n const byCat = new Map<string, number>();\n for (const o of orders) {\n const cat = catOf.get(o.cartId) ?? 'OTHER';\n byCat.set(cat, (byCat.get(cat) ?? 0) + (o.total ?? 0));\n }\n return [...byCat.entries()]\n .filter(([, v]) => v > 0)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 6)\n .map(([c, v]) => ({ label: titleCase(c), value: v }));\n }, [orders, providers]);\n\n const medalIcon = (index: number) => {\n if (index < 3) return <Award className=\"h-5 w-5 text-status-warning-text\" />;\n return <BarChart3 className=\"h-5 w-5 text-text-secondary\" />;\n };\n\n if (loading || !stats) {\n return (\n <PageLayout title=\"Platform Analytics\" description=\"Loading analytics...\">\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 analytics...</p>\n </div>\n </PageLayout>\n );\n }\n\n const tabs: Array<{ key: TabKey; label: string; icon: typeof BarChart3 }> = [\n { key: 'overview', label: 'Overview', icon: BarChart3 },\n { key: 'revenue', label: 'Revenue', icon: IndianRupee },\n { key: 'users', label: 'Users', icon: Users },\n { key: 'performance', label: 'Performance', icon: Zap },\n ];\n\n return (\n <PageLayout title=\"Platform Analytics\" description=\"Comprehensive platform metrics and trends\">\n <PagePurpose className=\"mb-6\">\n Your bird&apos;s-eye view of how Kadaikodi is performing. Spot revenue and order trends, see\n which carts and categories drive the most business, and understand where customers are\n growing — so you can decide where to invest and which carts to promote. Switch tabs to drill\n into revenue, users, and operational performance.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"kadaikodi-admin-analytics\"\n className=\"mb-6\"\n steps={[\n {\n id: 'review-carts',\n label: 'Review top-performing carts',\n description: 'See which carts drive the most revenue and orders.',\n onClick: () => setActiveTab('overview'),\n },\n {\n id: 'check-revenue',\n label: 'Break down revenue by category',\n description: 'Find your strongest categories in the Revenue tab.',\n onClick: () => setActiveTab('revenue'),\n },\n {\n id: 'manage-carts',\n label: 'Approve pending carts',\n description: 'Onboard the carts waiting for review.',\n onClick: () => navigateTo('/admin/carts'),\n done: pendingCarts === 0,\n },\n ]}\n />\n\n <div className=\"flex justify-end mb-6\">\n <span className=\"text-sm text-text-secondary\">\n Last updated: {new Date().toLocaleString('en-IN')}\n </span>\n </div>\n\n {/* Key Metrics — the one emphasis zone for this page */}\n <EmphasisPanel className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Key Metrics</h2>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n <MetricsCard\n featured\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={fmtCur(stats.totalRevenue)}\n label=\"Total Revenue\"\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 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 trendValue={`${pendingCarts} pending`}\n />\n </div>\n </EmphasisPanel>\n\n {/* Real-chart grid — the mockup's analytics dashboard, all live data */}\n <div className=\"mb-8 grid grid-cols-1 gap-6 lg:grid-cols-2\">\n {/* Category Distribution */}\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">Category Distribution</h3>\n {categorySegments.length > 0 ? (\n <DonutChart\n segments={categorySegments}\n centerLabel={totalCarts.toLocaleString('en-IN')}\n centerCaption=\"carts\"\n valueFormatter={(v) => v.toLocaleString('en-IN')}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Category breakdown will appear here as carts are onboarded.\n </p>\n )}\n </GlassCard>\n\n {/* GMV over time */}\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"mb-4 flex items-center justify-between gap-2\">\n <h3 className=\"text-base font-semibold text-text-primary\">GMV over time</h3>\n <span className=\"text-xs text-text-muted\">Last 30 days</span>\n </div>\n {orders.length > 0 ? (\n <AreaChart\n series={gmvTrend}\n height={200}\n valueFormatter={(v) => fmtCur(v)}\n title=\"Gross merchandise value per day over the last 30 days\"\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n GMV will chart here once orders are placed.\n </p>\n )}\n </GlassCard>\n\n {/* Order Volume over time (real substitute for un-derivable customer-growth series) */}\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"mb-4 flex items-center justify-between gap-2\">\n <h3 className=\"text-base font-semibold text-text-primary\">Order Volume</h3>\n <span className=\"text-xs text-text-muted\">Last 30 days</span>\n </div>\n {orders.length > 0 ? (\n <AreaChart\n series={volumeTrend}\n height={200}\n valueFormatter={(v) => v.toLocaleString('en-IN')}\n title=\"Order volume per day over the last 30 days\"\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Order volume will chart here once orders are placed.\n </p>\n )}\n </GlassCard>\n\n {/* Top Categories by Revenue */}\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">\n Top Categories by Revenue\n </h3>\n {topCategoryRevenue.length > 0 ? (\n <HBarFunnel\n stages={topCategoryRevenue}\n showConversion={false}\n valueFormatter={(v) => fmtCur(v)}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Category revenue will rank here as orders come in.\n </p>\n )}\n </GlassCard>\n </div>\n\n {/* Tabs */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface mb-8\">\n <div className=\"border-b border-border-subtle\">\n <nav className=\"flex -mb-px overflow-x-auto\">\n {tabs.map((tab) => {\n const TabIcon = tab.icon;\n return (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => setActiveTab(tab.key)}\n className={cn(\n 'flex items-center gap-2 py-3 px-4 sm:px-6 text-sm font-medium whitespace-nowrap border-b-2 transition-colors',\n activeTab === tab.key\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n )}\n >\n <TabIcon className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{tab.label}</span>\n </button>\n );\n })}\n </nav>\n </div>\n\n <div className=\"p-4 sm:p-6\">\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"space-y-8\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n Order Status Distribution\n </h3>\n {orderStats.total > 0 ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n <div className=\"rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-4\">\n <p className=\"text-sm text-status-success-text\">Completed Orders</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {orderStats.completed.toLocaleString('en-IN')}\n </p>\n <p className=\"text-sm text-status-success-text/80\">\n {pct(orderStats.completed, orderStats.total).toFixed(1)}% of total\n </p>\n </div>\n <div className=\"rounded-lg border border-status-warning-text/30 bg-status-warning-bg-subtle p-4\">\n <p className=\"text-sm text-status-warning-text\">Pending Orders</p>\n <p className=\"text-2xl font-bold text-status-warning-text\">\n {orderStats.pending.toLocaleString('en-IN')}\n </p>\n <p className=\"text-sm text-status-warning-text/80\">\n {pct(orderStats.pending, orderStats.total).toFixed(1)}% of total\n </p>\n </div>\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle p-4\">\n <p className=\"text-sm text-status-error-text\">Cancelled Orders</p>\n <p className=\"text-2xl font-bold text-status-error-text\">\n {orderStats.cancelled.toLocaleString('en-IN')}\n </p>\n <p className=\"text-sm text-status-error-text/80\">\n {pct(orderStats.cancelled, orderStats.total).toFixed(1)}% of total\n </p>\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Order breakdowns will appear here once orders are placed.\n </p>\n )}\n </div>\n\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n Top Performing Carts\n </h3>\n {topCarts.length > 0 ? (\n <div className=\"rounded-lg border border-border-subtle overflow-hidden\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-subtle bg-bg-sunken/50\">\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase\">\n Cart Name\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase\">\n Category\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium text-text-secondary uppercase\">\n Rating\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {topCarts.map((cart, i) => (\n <tr key={cart.id} className=\"hover:bg-accent/50 transition-colors\">\n <td className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2\">\n {medalIcon(i)}\n <span className=\"text-sm font-medium text-text-primary\">\n {cart.name}\n </span>\n </div>\n </td>\n <td className=\"px-4 py-3 text-sm text-left text-text-secondary capitalize\">\n {prettyCategory(cart.category)}\n </td>\n <td className=\"px-4 py-3 text-sm text-right text-text-primary\">\n <span className=\"flex items-center justify-end 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 </span>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\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\n {/* Revenue Tab */}\n {activeTab === 'revenue' && (\n <div className=\"space-y-8\">\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div className=\"rounded-lg border border-border-focus/30 bg-[var(--color-accent-soft)] p-6\">\n <h4 className=\"text-sm font-medium text-text-primary mb-2\">Total Revenue</h4>\n <p className=\"text-2xl font-bold text-text-primary\">\n {fmtCur(stats.totalRevenue)}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-6\">\n <h4 className=\"text-sm font-medium text-text-secondary mb-2\">Total Orders</h4>\n <p className=\"text-2xl font-bold text-text-primary\">\n {(stats.totalOrders ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-6\">\n <h4 className=\"text-sm font-medium text-status-success-text mb-2\">\n Average Order Value\n </h4>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {fmtCur(orderStats.avgOrderValue)}\n </p>\n </div>\n </div>\n\n {topCategoryRevenue.length > 0 ? (\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">\n Revenue by Category\n </h4>\n <HBarFunnel\n stages={topCategoryRevenue}\n showConversion={false}\n valueFormatter={(v) => fmtCur(v)}\n />\n <p className=\"mt-3 text-xs text-text-muted\">\n Derived by attributing each order&apos;s value to its cart&apos;s category.\n </p>\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Revenue by category will appear here as orders come in.\n </p>\n )}\n </div>\n )}\n\n {/* Users Tab */}\n {activeTab === 'users' && (\n <div className=\"space-y-8\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Users className=\"h-5 w-5 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">Active Customers</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {(stats.activeCustomers ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Store className=\"h-5 w-5 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">Active Cart Owners</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {(stats.activeProviders ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/20 p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Users className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-sm font-medium text-text-secondary\">Total Customers</h3>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {customerTotal.toLocaleString('en-IN')}\n </p>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Customers on the platform to date.\n </p>\n </div>\n\n {categoryDistRows.length > 0 && (\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n Cart Category Distribution\n </h3>\n <div className=\"space-y-3\">\n {categoryDistRows.map((row) => (\n <div key={row.category}>\n <div className=\"flex items-center justify-between mb-1\">\n <span className=\"text-sm font-medium text-text-primary capitalize\">\n {prettyCategory(row.category)}\n </span>\n <span className=\"text-sm text-text-secondary\">\n {(row.count ?? 0).toLocaleString('en-IN')} (\n {(row.percentage ?? 0).toFixed(1)}%)\n </span>\n </div>\n <div className=\"w-full bg-bg-sunken rounded-full h-2\">\n <div\n className=\"bg-action-primary-bg h-2 rounded-full transition-all duration-300\"\n style={{ width: `${row.percentage}%` }}\n />\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Performance Tab */}\n {activeTab === 'performance' && (\n <div className=\"space-y-8\">\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Star className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">\n Customer Satisfaction\n </h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary flex items-center gap-1\">\n <Star className=\"h-6 w-6 fill-status-warning-text text-status-warning-text\" />\n {stats.avgRating > 0 ? stats.avgRating.toFixed(1) : '—'}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">Average rating across carts</p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">Completion Rate</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {orderStats.total > 0\n ? `${pct(orderStats.completed, orderStats.total).toFixed(1)}%`\n : '—'}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">Orders delivered</p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">Cancellation Rate</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {orderStats.total > 0\n ? `${pct(orderStats.cancelled, orderStats.total).toFixed(1)}%`\n : '—'}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">Orders cancelled</p>\n </div>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n Today&apos;s Activity\n </h3>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <p className=\"text-sm text-text-secondary mb-2\">Orders Today</p>\n <p className=\"text-3xl font-bold text-text-primary\">\n {orderStats.ordersToday.toLocaleString('en-IN')}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary mb-2\">Pending Orders</p>\n <p className=\"text-3xl font-bold text-status-warning-text\">\n {(stats.pendingOrders ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminAnalyticsPage.js","names":[],"sources":["../../../../src/kadaikodi/pages/admin/AdminAnalyticsPage.tsx"],"sourcesContent":["/**\n * Admin Analytics Page\n * @module kadaikodi/pages/admin\n *\n * Platform analytics wired to the live backend (useDashboardStats +\n * useAdminAnalytics + useProviders + useOrders). Every figure is real or\n * derived from real records — order-status distribution is counted from\n * loaded orders, category/growth breakdowns come from the analytics hook.\n * Metrics with no honest source (operating costs, delivery time, etc.) are\n * omitted rather than fabricated.\n */\n\nimport { useMemo, useState } from 'react';\nimport {\n Users,\n ShoppingBag,\n IndianRupee,\n BarChart3,\n Zap,\n Loader2,\n Star,\n Award,\n Store,\n TrendingUp,\n} from 'lucide-react';\nimport { EmphasisPanel, GlassCard, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { DonutChart, AreaChart, HBarFunnel } from '../../components/viz';\nimport type { LabeledValue, Segment } from '../../components/viz';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport {\n useDashboardStats,\n useAdminAnalytics,\n useProviders,\n useOrders,\n} from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\n/* ------------------------------------------------------------------ */\n/* Types + helpers */\n/* ------------------------------------------------------------------ */\n\ntype TabKey = 'overview' | 'revenue' | 'users' | 'performance';\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nconst titleCase = (s: string) =>\n s\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n\nconst dayKey = (d: Date) => {\n const x = new Date(d);\n x.setHours(0, 0, 0, 0);\n return x.getTime();\n};\n\nconst dayLabel = (t: number) =>\n new Date(t).toLocaleDateString('en-IN', { day: 'numeric', month: 'short' });\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function AdminAnalyticsPage() {\n const { navigateTo } = useKadaikodi();\n\n const { data: stats, isLoading: statsLoading } = useDashboardStats();\n const { data: analytics, isLoading: analyticsLoading } = useAdminAnalytics();\n const { data: providers = [], isLoading: providersLoading } = useProviders();\n const { data: orders = [], isLoading: ordersLoading } = useOrders({});\n\n const [activeTab, setActiveTab] = useState<TabKey>('overview');\n\n const loading = statsLoading || analyticsLoading || providersLoading || ordersLoading;\n\n const fmtCur = (amount: number) => {\n if (amount >= 10000000) return `₹${(amount / 10000000).toFixed(1)}Cr`;\n if (amount >= 100000) return `₹${(amount / 100000).toFixed(1)}L`;\n return formatCurrency(amount, { minimumFractionDigits: 0 });\n };\n\n // Order status distribution — counted from real loaded orders.\n const orderStats = useMemo(() => {\n const total = orders.length;\n const completed = orders.filter((o) => o.status === 'delivered').length;\n const cancelled = orders.filter((o) => o.status === 'cancelled').length;\n const pending = orders.filter((o) => o.status === 'pending' || o.status === 'confirmed').length;\n const startOfToday = new Date();\n startOfToday.setHours(0, 0, 0, 0);\n const ordersToday = orders.filter(\n (o) => new Date(o.orderDate).getTime() >= startOfToday.getTime()\n ).length;\n const avgOrderValue =\n stats && stats.totalOrders > 0 ? stats.totalRevenue / stats.totalOrders : 0;\n return { total, completed, cancelled, pending, ordersToday, avgOrderValue };\n }, [orders, stats]);\n\n const pendingCarts = useMemo(() => providers.filter((p) => !p.isOpen).length, [providers]);\n\n const topCarts = analytics?.topProviders ?? [];\n const customerTotal = analytics?.customerGrowth?.customers ?? 0;\n\n // Cart distribution per category with a real, derived share percentage.\n // The backend exposes counts per category, not revenue per category.\n const categoryDistRows = useMemo(() => {\n const entries = Object.entries(analytics?.categoryDistribution ?? {});\n const total = entries.reduce((sum, [, count]) => sum + count, 0);\n return entries\n .map(([category, count]) => ({\n category,\n count,\n percentage: total > 0 ? (count / total) * 100 : 0,\n }))\n .sort((a, b) => b.count - a.count);\n }, [analytics]);\n\n const prettyCategory = (c: string) => c.replace(/_/g, ' ').toLowerCase();\n\n const pct = (part: number, whole: number) => (whole > 0 ? (part / whole) * 100 : 0);\n\n // ── Category distribution donut — real cart counts per category. ───────────\n const categorySegments = useMemo<Segment[]>(\n () =>\n Object.entries(analytics?.categoryDistribution ?? {})\n .sort((a, b) => b[1] - a[1])\n .map(([c, count]) => ({ label: titleCase(c), value: count })),\n [analytics]\n );\n const totalCarts = useMemo(\n () => categorySegments.reduce((s, seg) => s + seg.value, 0),\n [categorySegments]\n );\n\n // ── GMV + order-volume over time — real per-day figures from real orders. ──\n const { gmvTrend, volumeTrend } = useMemo(() => {\n const today = dayKey(new Date());\n const start = today - 29 * DAY_MS;\n const gmv = new Map<number, number>();\n const vol = new Map<number, number>();\n for (let t = start; t <= today; t += DAY_MS) {\n gmv.set(t, 0);\n vol.set(t, 0);\n }\n for (const o of orders) {\n const t = dayKey(new Date(o.orderDate));\n if (gmv.has(t)) {\n gmv.set(t, (gmv.get(t) ?? 0) + (o.total ?? 0));\n vol.set(t, (vol.get(t) ?? 0) + 1);\n }\n }\n const g: LabeledValue[] = [...gmv.entries()].map(([t, v]) => ({\n label: dayLabel(t),\n value: v,\n }));\n const v: LabeledValue[] = [...vol.entries()].map(([t, val]) => ({\n label: dayLabel(t),\n value: val,\n }));\n return { gmvTrend: g, volumeTrend: v };\n }, [orders]);\n\n // ── Top categories by revenue — derived by joining real orders → provider. ─\n const topCategoryRevenue = useMemo<LabeledValue[]>(() => {\n const catOf = new Map(providers.map((p) => [p.id, p.category]));\n const byCat = new Map<string, number>();\n for (const o of orders) {\n const cat = catOf.get(o.cartId) ?? 'OTHER';\n byCat.set(cat, (byCat.get(cat) ?? 0) + (o.total ?? 0));\n }\n return [...byCat.entries()]\n .filter(([, v]) => v > 0)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 6)\n .map(([c, v]) => ({ label: titleCase(c), value: v }));\n }, [orders, providers]);\n\n const medalIcon = (index: number) => {\n if (index < 3) return <Award className=\"h-5 w-5 text-status-warning-text\" />;\n return <BarChart3 className=\"h-5 w-5 text-text-secondary\" />;\n };\n\n if (loading || !stats) {\n return (\n <PageLayout title=\"Platform Analytics\" description=\"Loading analytics...\">\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 analytics...</p>\n </div>\n </PageLayout>\n );\n }\n\n const tabs: Array<{ key: TabKey; label: string; icon: typeof BarChart3 }> = [\n { key: 'overview', label: 'Overview', icon: BarChart3 },\n { key: 'revenue', label: 'Revenue', icon: IndianRupee },\n { key: 'users', label: 'Users', icon: Users },\n { key: 'performance', label: 'Performance', icon: Zap },\n ];\n\n return (\n <PageLayout title=\"Platform Analytics\" description=\"Comprehensive platform metrics and trends\">\n <PagePurpose className=\"mb-6\">\n Your bird&apos;s-eye view of how Kadaikodi is performing. Spot revenue and order trends, see\n which carts and categories drive the most business, and understand where customers are\n growing — so you can decide where to invest and which carts to promote. Switch tabs to drill\n into revenue, users, and operational performance.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"kadaikodi-admin-analytics\"\n className=\"mb-6\"\n steps={[\n {\n id: 'review-carts',\n label: 'Review top-performing carts',\n description: 'See which carts drive the most revenue and orders.',\n onClick: () => setActiveTab('overview'),\n },\n {\n id: 'check-revenue',\n label: 'Break down revenue by category',\n description: 'Find your strongest categories in the Revenue tab.',\n onClick: () => setActiveTab('revenue'),\n },\n {\n id: 'manage-carts',\n label: 'Approve pending carts',\n description: 'Onboard the carts waiting for review.',\n onClick: () => navigateTo('/admin/carts'),\n done: pendingCarts === 0,\n },\n ]}\n />\n\n <div className=\"flex justify-end mb-6\">\n <span className=\"text-sm text-text-secondary\">\n Last updated: {new Date().toLocaleString('en-IN')}\n </span>\n </div>\n\n {/* Key Metrics — the one emphasis zone for this page */}\n <EmphasisPanel className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Key Metrics</h2>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n <MetricsCard\n featured\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={fmtCur(stats.totalRevenue)}\n label=\"Total Revenue\"\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 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 trendValue={`${pendingCarts} pending`}\n />\n </div>\n </EmphasisPanel>\n\n {/* Real-chart grid — the mockup's analytics dashboard, all live data */}\n <div className=\"mb-8 grid grid-cols-1 gap-6 lg:grid-cols-2\">\n {/* Category Distribution */}\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">Category Distribution</h3>\n {categorySegments.length > 0 ? (\n <DonutChart\n segments={categorySegments}\n centerLabel={totalCarts.toLocaleString('en-IN')}\n centerCaption=\"carts\"\n valueFormatter={(v) => v.toLocaleString('en-IN')}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Category breakdown will appear here as carts are onboarded.\n </p>\n )}\n </GlassCard>\n\n {/* GMV over time */}\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"mb-4 flex items-center justify-between gap-2\">\n <h3 className=\"text-base font-semibold text-text-primary\">GMV over time</h3>\n <span className=\"text-xs text-text-muted\">Last 30 days</span>\n </div>\n {orders.length > 0 ? (\n <AreaChart\n series={gmvTrend}\n height={200}\n valueFormatter={(v) => fmtCur(v)}\n title=\"Gross merchandise value per day over the last 30 days\"\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n GMV will chart here once orders are placed.\n </p>\n )}\n </GlassCard>\n\n {/* Order Volume over time (real substitute for un-derivable customer-growth series) */}\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"mb-4 flex items-center justify-between gap-2\">\n <h3 className=\"text-base font-semibold text-text-primary\">Order Volume</h3>\n <span className=\"text-xs text-text-muted\">Last 30 days</span>\n </div>\n {orders.length > 0 ? (\n <AreaChart\n series={volumeTrend}\n height={200}\n valueFormatter={(v) => v.toLocaleString('en-IN')}\n title=\"Order volume per day over the last 30 days\"\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Order volume will chart here once orders are placed.\n </p>\n )}\n </GlassCard>\n\n {/* Top Categories by Revenue */}\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">\n Top Categories by Revenue\n </h3>\n {topCategoryRevenue.length > 0 ? (\n <HBarFunnel\n stages={topCategoryRevenue}\n showConversion={false}\n valueFormatter={(v) => fmtCur(v)}\n />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Category revenue will rank here as orders come in.\n </p>\n )}\n </GlassCard>\n </div>\n\n {/* Tabs */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface mb-8\">\n <div className=\"border-b border-border-subtle\">\n <nav className=\"flex -mb-px overflow-x-auto\">\n {tabs.map((tab) => {\n const TabIcon = tab.icon;\n return (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => setActiveTab(tab.key)}\n className={cn(\n 'flex items-center gap-2 py-3 px-4 sm:px-6 text-sm font-medium whitespace-nowrap border-b-2 transition-colors',\n activeTab === tab.key\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n )}\n >\n <TabIcon className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{tab.label}</span>\n </button>\n );\n })}\n </nav>\n </div>\n\n <div className=\"p-4 sm:p-6\">\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"space-y-8\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n Order Status Distribution\n </h3>\n {orderStats.total > 0 ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n <div className=\"rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-4\">\n <p className=\"text-sm text-status-success-text\">Completed Orders</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {orderStats.completed.toLocaleString('en-IN')}\n </p>\n <p className=\"text-sm text-status-success-text/80\">\n {pct(orderStats.completed, orderStats.total).toFixed(1)}% of total\n </p>\n </div>\n <div className=\"rounded-lg border border-status-warning-text/30 bg-status-warning-bg-subtle p-4\">\n <p className=\"text-sm text-status-warning-text\">Pending Orders</p>\n <p className=\"text-2xl font-bold text-status-warning-text\">\n {orderStats.pending.toLocaleString('en-IN')}\n </p>\n <p className=\"text-sm text-status-warning-text/80\">\n {pct(orderStats.pending, orderStats.total).toFixed(1)}% of total\n </p>\n </div>\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle p-4\">\n <p className=\"text-sm text-status-error-text\">Cancelled Orders</p>\n <p className=\"text-2xl font-bold text-status-error-text\">\n {orderStats.cancelled.toLocaleString('en-IN')}\n </p>\n <p className=\"text-sm text-status-error-text/80\">\n {pct(orderStats.cancelled, orderStats.total).toFixed(1)}% of total\n </p>\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Order breakdowns will appear here once orders are placed.\n </p>\n )}\n </div>\n\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n Top Performing Carts\n </h3>\n {topCarts.length > 0 ? (\n <div className=\"rounded-lg border border-border-subtle overflow-hidden\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-subtle bg-bg-sunken/50\">\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase\">\n Cart Name\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase\">\n Category\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium text-text-secondary uppercase\">\n Rating\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {topCarts.map((cart, i) => (\n <tr key={cart.id} className=\"hover:bg-accent/50 transition-colors\">\n <td className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2\">\n {medalIcon(i)}\n <span className=\"text-sm font-medium text-text-primary\">\n {cart.name}\n </span>\n </div>\n </td>\n <td className=\"px-4 py-3 text-sm text-left text-text-secondary capitalize\">\n {prettyCategory(cart.category)}\n </td>\n <td className=\"px-4 py-3 text-sm text-right text-text-primary\">\n <span className=\"flex items-center justify-end 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 </span>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\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\n {/* Revenue Tab */}\n {activeTab === 'revenue' && (\n <div className=\"space-y-8\">\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div className=\"rounded-lg border border-border-focus/30 bg-[var(--color-accent-soft)] p-6\">\n <h4 className=\"text-sm font-medium text-text-primary mb-2\">Total Revenue</h4>\n <p className=\"text-2xl font-bold text-text-primary\">\n {fmtCur(stats.totalRevenue)}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-6\">\n <h4 className=\"text-sm font-medium text-text-secondary mb-2\">Total Orders</h4>\n <p className=\"text-2xl font-bold text-text-primary\">\n {(stats.totalOrders ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-6\">\n <h4 className=\"text-sm font-medium text-status-success-text mb-2\">\n Average Order Value\n </h4>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {fmtCur(orderStats.avgOrderValue)}\n </p>\n </div>\n </div>\n\n {topCategoryRevenue.length > 0 ? (\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">\n Revenue by Category\n </h4>\n <HBarFunnel\n stages={topCategoryRevenue}\n showConversion={false}\n valueFormatter={(v) => fmtCur(v)}\n />\n <p className=\"mt-3 text-xs text-text-muted\">\n Derived by attributing each order&apos;s value to its cart&apos;s category.\n </p>\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n Revenue by category will appear here as orders come in.\n </p>\n )}\n </div>\n )}\n\n {/* Users Tab */}\n {activeTab === 'users' && (\n <div className=\"space-y-8\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Users className=\"h-5 w-5 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">Active Customers</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {(stats.activeCustomers ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Store className=\"h-5 w-5 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">Active Cart Owners</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {(stats.activeProviders ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/20 p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Users className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-sm font-medium text-text-secondary\">Total Customers</h3>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {customerTotal.toLocaleString('en-IN')}\n </p>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Customers on the platform to date.\n </p>\n </div>\n\n {categoryDistRows.length > 0 && (\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n Cart Category Distribution\n </h3>\n <div className=\"space-y-3\">\n {categoryDistRows.map((row) => (\n <div key={row.category}>\n <div className=\"flex items-center justify-between mb-1\">\n <span className=\"text-sm font-medium text-text-primary capitalize\">\n {prettyCategory(row.category)}\n </span>\n <span className=\"text-sm text-text-secondary\">\n {(row.count ?? 0).toLocaleString('en-IN')} (\n {(row.percentage ?? 0).toFixed(1)}%)\n </span>\n </div>\n <div className=\"w-full bg-bg-sunken rounded-full h-2\">\n <div\n className=\"bg-action-primary-bg h-2 rounded-full transition-all duration-300\"\n style={{ width: `${row.percentage}%` }}\n />\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Performance Tab */}\n {activeTab === 'performance' && (\n <div className=\"space-y-8\">\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Star className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">\n Customer Satisfaction\n </h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary flex items-center gap-1\">\n <Star className=\"h-6 w-6 fill-status-warning-text text-status-warning-text\" />\n {stats.avgRating > 0 ? stats.avgRating.toFixed(1) : '—'}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">Average rating across carts</p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">Completion Rate</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {orderStats.total > 0\n ? `${pct(orderStats.completed, orderStats.total).toFixed(1)}%`\n : '—'}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">Orders delivered</p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-center gap-2 mb-2\">\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-medium text-text-secondary\">Cancellation Rate</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {orderStats.total > 0\n ? `${pct(orderStats.cancelled, orderStats.total).toFixed(1)}%`\n : '—'}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">Orders cancelled</p>\n </div>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-6\">\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n Today&apos;s Activity\n </h3>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <p className=\"text-sm text-text-secondary mb-2\">Orders Today</p>\n <p className=\"text-3xl font-bold text-text-primary\">\n {orderStats.ordersToday.toLocaleString('en-IN')}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary mb-2\">Pending Orders</p>\n <p className=\"text-3xl font-bold text-status-warning-text\">\n {(stats.pendingOrders ?? 0).toLocaleString('en-IN')}\n </p>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AdminDashboard.d.ts","sourceRoot":"","sources":["../../../../src/kadaikodi/pages/admin/AdminDashboard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAwDH,wBAAgB,cAAc,gCAoZ7B"}
1
+ {"version":3,"file":"AdminDashboard.d.ts","sourceRoot":"","sources":["../../../../src/kadaikodi/pages/admin/AdminDashboard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAwDH,wBAAgB,cAAc,gCAuZ7B"}