@burdenoff/microfe-kadaikodi 2026.704.3 → 2026.704.5

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 (145) hide show
  1. package/dist/kadaikodi/KadaikodiRoutes.js +34 -26
  2. package/dist/kadaikodi/KadaikodiRoutes.js.map +1 -1
  3. package/dist/kadaikodi/components/viz/AllocationBar.js +68 -0
  4. package/dist/kadaikodi/components/viz/AllocationBar.js.map +1 -0
  5. package/dist/kadaikodi/components/viz/AreaChart.js +102 -0
  6. package/dist/kadaikodi/components/viz/AreaChart.js.map +1 -0
  7. package/dist/kadaikodi/components/viz/AvatarStack.js +36 -0
  8. package/dist/kadaikodi/components/viz/AvatarStack.js.map +1 -0
  9. package/dist/kadaikodi/components/viz/BarChart.js +83 -0
  10. package/dist/kadaikodi/components/viz/BarChart.js.map +1 -0
  11. package/dist/kadaikodi/components/viz/CertificateCard.js +4 -0
  12. package/dist/kadaikodi/components/viz/DonutChart.js +109 -0
  13. package/dist/kadaikodi/components/viz/DonutChart.js.map +1 -0
  14. package/dist/kadaikodi/components/viz/HBarFunnel.js +54 -0
  15. package/dist/kadaikodi/components/viz/HBarFunnel.js.map +1 -0
  16. package/dist/kadaikodi/components/viz/Heatmap.js +3 -0
  17. package/dist/kadaikodi/components/viz/KanbanBoard.js +50 -0
  18. package/dist/kadaikodi/components/viz/KanbanBoard.js.map +1 -0
  19. package/dist/kadaikodi/components/viz/LineChart.js +4 -0
  20. package/dist/kadaikodi/components/viz/OrgTree.js +2 -0
  21. package/dist/kadaikodi/components/viz/PathSteps.js +3 -0
  22. package/dist/kadaikodi/components/viz/ProgressRing.js +68 -0
  23. package/dist/kadaikodi/components/viz/ProgressRing.js.map +1 -0
  24. package/dist/kadaikodi/components/viz/RatingStars.js +51 -0
  25. package/dist/kadaikodi/components/viz/RatingStars.js.map +1 -0
  26. package/dist/kadaikodi/components/viz/SegmentedTabs.js +69 -0
  27. package/dist/kadaikodi/components/viz/SegmentedTabs.js.map +1 -0
  28. package/dist/kadaikodi/components/viz/SkillBar.js +3 -0
  29. package/dist/kadaikodi/components/viz/Sparkline.js +74 -0
  30. package/dist/kadaikodi/components/viz/Sparkline.js.map +1 -0
  31. package/dist/kadaikodi/components/viz/StatCard.js +60 -0
  32. package/dist/kadaikodi/components/viz/StatCard.js.map +1 -0
  33. package/dist/kadaikodi/components/viz/StepProgress.js +64 -0
  34. package/dist/kadaikodi/components/viz/StepProgress.js.map +1 -0
  35. package/dist/kadaikodi/components/viz/Timeline.js +66 -0
  36. package/dist/kadaikodi/components/viz/Timeline.js.map +1 -0
  37. package/dist/kadaikodi/components/viz/index.js +23 -0
  38. package/dist/kadaikodi/components/viz/lib/Avatar.js +30 -0
  39. package/dist/kadaikodi/components/viz/lib/Avatar.js.map +1 -0
  40. package/dist/kadaikodi/components/viz/lib/CartesianFrame.js +119 -0
  41. package/dist/kadaikodi/components/viz/lib/CartesianFrame.js.map +1 -0
  42. package/dist/kadaikodi/components/viz/lib/ResponsiveSvg.js +35 -0
  43. package/dist/kadaikodi/components/viz/lib/ResponsiveSvg.js.map +1 -0
  44. package/dist/kadaikodi/components/viz/lib/format.js +21 -0
  45. package/dist/kadaikodi/components/viz/lib/format.js.map +1 -0
  46. package/dist/kadaikodi/components/viz/lib/geometry.js +61 -0
  47. package/dist/kadaikodi/components/viz/lib/geometry.js.map +1 -0
  48. package/dist/kadaikodi/components/viz/lib/hooks.js +39 -0
  49. package/dist/kadaikodi/components/viz/lib/hooks.js.map +1 -0
  50. package/dist/kadaikodi/components/viz/lib/palette.js +27 -0
  51. package/dist/kadaikodi/components/viz/lib/palette.js.map +1 -0
  52. package/dist/kadaikodi/hooks/useKadaikodiApi.js +84 -6
  53. package/dist/kadaikodi/hooks/useKadaikodiApi.js.map +1 -1
  54. package/dist/kadaikodi/pages/HomePage.js +373 -631
  55. package/dist/kadaikodi/pages/HomePage.js.map +1 -1
  56. package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js +304 -169
  57. package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js.map +1 -1
  58. package/dist/kadaikodi/pages/admin/AdminDashboard.js +255 -271
  59. package/dist/kadaikodi/pages/admin/AdminDashboard.js.map +1 -1
  60. package/dist/kadaikodi/pages/admin/AdminFinancialPage.js +185 -125
  61. package/dist/kadaikodi/pages/admin/AdminFinancialPage.js.map +1 -1
  62. package/dist/kadaikodi/pages/admin/AdminOrdersPage.js +141 -102
  63. package/dist/kadaikodi/pages/admin/AdminOrdersPage.js.map +1 -1
  64. package/dist/kadaikodi/pages/admin/AdminProfilePage.js.map +1 -1
  65. package/dist/kadaikodi/pages/admin/AdminSettingsPage.js +332 -276
  66. package/dist/kadaikodi/pages/admin/AdminSettingsPage.js.map +1 -1
  67. package/dist/kadaikodi/pages/admin/CartManagementPage.js +564 -729
  68. package/dist/kadaikodi/pages/admin/CartManagementPage.js.map +1 -1
  69. package/dist/kadaikodi/pages/admin/UserManagementPage.js +310 -366
  70. package/dist/kadaikodi/pages/admin/UserManagementPage.js.map +1 -1
  71. package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js +201 -120
  72. package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
  73. package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js +290 -257
  74. package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
  75. package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js +173 -194
  76. package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
  77. package/dist/kadaikodi/pages/cart-owner/CartOwnerProfilePage.js +270 -228
  78. package/dist/kadaikodi/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
  79. package/dist/kadaikodi/pages/cart-owner/CartServiceConfigPage.js +194 -173
  80. package/dist/kadaikodi/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
  81. package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js +428 -347
  82. package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js.map +1 -1
  83. package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js +332 -0
  84. package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js.map +1 -0
  85. package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js +373 -0
  86. package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js.map +1 -0
  87. package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js +294 -162
  88. package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js.map +1 -1
  89. package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js +180 -181
  90. package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js.map +1 -1
  91. package/dist/kadaikodi/pages/common/HelpSupportPage.js +310 -317
  92. package/dist/kadaikodi/pages/common/HelpSupportPage.js.map +1 -1
  93. package/dist/kadaikodi/pages/common/NotificationCenterPage.js.map +1 -1
  94. package/dist/kadaikodi/pages/common/SettingsPage.js +502 -586
  95. package/dist/kadaikodi/pages/common/SettingsPage.js.map +1 -1
  96. package/dist/kadaikodi/pages/customer/BookingDetailsPage.js +239 -156
  97. package/dist/kadaikodi/pages/customer/BookingDetailsPage.js.map +1 -1
  98. package/dist/kadaikodi/pages/customer/CartDetailPage.js +405 -248
  99. package/dist/kadaikodi/pages/customer/CartDetailPage.js.map +1 -1
  100. package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js +258 -232
  101. package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js.map +1 -1
  102. package/dist/kadaikodi/pages/customer/CheckoutPage.js +254 -205
  103. package/dist/kadaikodi/pages/customer/CheckoutPage.js.map +1 -1
  104. package/dist/kadaikodi/pages/customer/CustomerDashboard.js +5 -5
  105. package/dist/kadaikodi/pages/customer/CustomerDashboard.js.map +1 -1
  106. package/dist/kadaikodi/pages/customer/CustomerProfilePage.js +189 -199
  107. package/dist/kadaikodi/pages/customer/CustomerProfilePage.js.map +1 -1
  108. package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js +272 -230
  109. package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js.map +1 -1
  110. package/dist/kadaikodi/pages/customer/FavoritesPage.js +150 -413
  111. package/dist/kadaikodi/pages/customer/FavoritesPage.js.map +1 -1
  112. package/dist/kadaikodi/pages/customer/OrderHistoryPage.js +173 -134
  113. package/dist/kadaikodi/pages/customer/OrderHistoryPage.js.map +1 -1
  114. package/dist/kadaikodi/pages/customer/OrderTrackingPage.js +411 -305
  115. package/dist/kadaikodi/pages/customer/OrderTrackingPage.js.map +1 -1
  116. package/dist/kadaikodi/pages/customer/ReviewsPage.js +310 -406
  117. package/dist/kadaikodi/pages/customer/ReviewsPage.js.map +1 -1
  118. package/dist/kadaikodi/pages/customer/SavedAddressesPage.js.map +1 -1
  119. package/dist/kadaikodi/pages/customer/shared.js +181 -0
  120. package/dist/kadaikodi/pages/customer/shared.js.map +1 -0
  121. package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js +438 -311
  122. package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js.map +1 -1
  123. package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js +320 -293
  124. package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
  125. package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js +159 -91
  126. package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js.map +1 -1
  127. package/dist/kadaikodi/pages/investor/InvestorDashboard.js +137 -107
  128. package/dist/kadaikodi/pages/investor/InvestorDashboard.js.map +1 -1
  129. package/dist/kadaikodi/pages/investor/InvestorInvestmentsPage.js +157 -135
  130. package/dist/kadaikodi/pages/investor/InvestorInvestmentsPage.js.map +1 -1
  131. package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js +280 -206
  132. package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js.map +1 -1
  133. package/dist/kadaikodi/pages/investor/InvestorProfilePage.js +441 -514
  134. package/dist/kadaikodi/pages/investor/InvestorProfilePage.js.map +1 -1
  135. package/dist/kadaikodi/pages/worker/TaskDetailsPage.js +428 -431
  136. package/dist/kadaikodi/pages/worker/TaskDetailsPage.js.map +1 -1
  137. package/dist/kadaikodi/pages/worker/WorkerDashboard.js +328 -445
  138. package/dist/kadaikodi/pages/worker/WorkerDashboard.js.map +1 -1
  139. package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js +141 -164
  140. package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js.map +1 -1
  141. package/dist/kadaikodi/pages/worker/WorkerProfilePage.js +360 -288
  142. package/dist/kadaikodi/pages/worker/WorkerProfilePage.js.map +1 -1
  143. package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js +303 -281
  144. package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js.map +1 -1
  145. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InvestorDashboard.js","names":[],"sources":["../../../../src/kadaikodi/pages/investor/InvestorDashboard.tsx"],"sourcesContent":["/**\n * Investor Dashboard Page\n * @module kadaikodi/pages/investor\n *\n * Portfolio overview with real metrics derived from the investor's holdings,\n * tab navigation (my investments / new opportunities), and quick actions.\n * All data comes from the live backend — no fabricated insights or activity.\n */\n\nimport { useState, useMemo } from 'react';\nimport {\n Wallet,\n PieChart,\n IndianRupee,\n Target,\n Award,\n Filter,\n Eye,\n Plus,\n BarChart3,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { EmptyState } from '../../components/EmptyState';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { InvestmentCard } from '../../components/InvestmentCard';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useInvestmentOpportunities, useInvestments } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getStatusBadgeColor(status: string): string {\n switch (status) {\n case 'active':\n return 'bg-status-success-bg-subtle text-status-success-text';\n case 'completed':\n return 'bg-[var(--color-accent-soft)] text-text-primary';\n case 'exited':\n return 'bg-bg-sunken text-text-secondary';\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorDashboard() {\n const { navigateTo, currentUser } = useKadaikodi();\n const [activeTab, setActiveTab] = useState<'portfolio' | 'opportunities'>('portfolio');\n\n const { data: opportunities = [], isLoading: opportunitiesLoading } =\n useInvestmentOpportunities();\n const { data: investments = [], isLoading: investmentsLoading } = useInvestments(\n currentUser?.id || ''\n );\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'Investor';\n\n const activeOpportunities = opportunities.filter((inv) => inv.status === 'active');\n\n const portfolioSummary = useMemo(() => {\n const totalInvested = investments.reduce((sum, inv) => sum + inv.investedAmount, 0);\n const currentValue = investments.reduce((sum, inv) => sum + inv.currentValue, 0);\n const totalReturns = investments.reduce((sum, inv) => sum + inv.returns, 0);\n const roi = totalInvested > 0 ? ((currentValue - totalInvested) / totalInvested) * 100 : 0;\n\n return {\n totalInvested,\n currentValue,\n totalReturns,\n roi,\n };\n }, [investments]);\n\n if (opportunitiesLoading || investmentsLoading) {\n return (\n <PageLayout title=\"Investment Dashboard\" description=\"Loading your portfolio...\">\n <div className=\"flex items-center justify-center py-20\">\n <div className=\"text-center\">\n <div className=\"mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary\" />\n <p className=\"text-sm text-text-secondary\">Loading your portfolio...</p>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`Welcome back, ${firstName}!`}\n description=\"Here's your investment portfolio overview.\"\n >\n <PagePurpose className=\"mb-6\">\n Track how your money is working across the mobile carts you've backed — see what you've\n invested, what it's worth today, and the returns flowing in. Review your active investments\n below or browse new opportunities to diversify.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"kadaikodi-investor-dashboard\"\n className=\"mb-6\"\n steps={[\n {\n id: 'opportunities',\n label: 'Explore new opportunities',\n description: 'Discover carts seeking funding and their projected returns.',\n onClick: () => navigateTo('/investor/opportunities'),\n },\n {\n id: 'portfolio',\n label: 'Review your portfolio',\n description: 'Dig into each active investment and its performance.',\n onClick: () => navigateTo('/investor/portfolio'),\n },\n {\n id: 'analytics',\n label: 'Analyse your returns',\n description: 'See trends and projections across your whole portfolio.',\n onClick: () => navigateTo('/investor/analytics'),\n },\n ]}\n />\n\n {/* Portfolio Summary Metrics — the one emphasis zone */}\n <EmphasisPanel>\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Portfolio Overview</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <MetricsCard\n featured\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"up\"\n trendValue=\"Across all businesses\"\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend={portfolioSummary.roi >= 0 ? 'up' : 'down'}\n trendValue={`${portfolioSummary.roi >= 0 ? '+' : ''}${portfolioSummary.roi.toFixed(1)}%`}\n />\n <MetricsCard\n icon={<Target className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.totalReturns, { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Main Content + Sidebar */}\n <div className=\"mt-8 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Main Content */}\n <div className=\"lg:col-span-2\">\n {/* Tab Navigation */}\n <div className=\"mb-6 flex rounded-lg bg-bg-sunken p-1\">\n <button\n type=\"button\"\n onClick={() => setActiveTab('portfolio')}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n activeTab === 'portfolio'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n My Investments\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('opportunities')}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n activeTab === 'opportunities'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n New Opportunities\n </button>\n </div>\n\n {/* Portfolio Tab */}\n {activeTab === 'portfolio' && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">Active Investments</h3>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/investments')}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Filter className=\"h-4 w-4\" />\n View all\n </button>\n </div>\n\n {investments.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No active investments yet\"\n description=\"Once you back a cart, your investments will appear here. Browse open opportunities to get started.\"\n action={\n <button\n type=\"button\"\n onClick={() => setActiveTab('opportunities')}\n className=\"rounded-lg bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n Browse opportunities\n </button>\n }\n />\n ) : (\n investments.map((investment) => (\n <div\n key={investment.id}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 shadow-sm hover:shadow-md transition-shadow\"\n >\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex-1\">\n <div className=\"mb-2 flex flex-wrap items-center gap-2\">\n <h4 className=\"text-base font-semibold text-text-primary\">\n {investment.cartName}\n </h4>\n <span\n className={cn(\n 'rounded-full px-2 py-0.5 text-xs font-medium',\n getStatusBadgeColor(investment.status)\n )}\n >\n {investment.status}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n\n <div className=\"mt-3 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(investment.investedAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Current Value</p>\n <p className=\"text-sm font-semibold text-status-success-text\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Returns</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(investment.returns, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Expected Return</p>\n <p className=\"text-sm font-semibold text-status-success-text\">\n {investment.returnsPercentage}%\n </p>\n </div>\n </div>\n </div>\n ))\n )}\n </div>\n )}\n\n {/* Opportunities Tab */}\n {activeTab === 'opportunities' && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n Investment Opportunities\n </h3>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n Browse All\n </button>\n </div>\n\n {activeOpportunities.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No open opportunities right now\"\n description=\"New carts seeking funding will show up here. Check back soon.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {activeOpportunities.slice(0, 4).map((opp) => (\n <InvestmentCard\n key={opp.id}\n id={opp.id}\n cartName={opp.cartName}\n targetAmount={opp.targetAmount}\n raisedAmount={opp.raisedAmount}\n expectedReturns={`${opp.expectedReturns}%`}\n riskLevel={opp.riskLevel}\n status={opp.status}\n onClick={(id) => navigateTo(`/investor/opportunity/${id}`)}\n />\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Quick Actions */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Quick Actions</h3>\n <div className=\"space-y-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/portfolio')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <PieChart className=\"h-4 w-4 text-text-secondary\" />\n View Full Portfolio\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Target className=\"h-4 w-4 text-text-secondary\" />\n Browse Opportunities\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/analytics')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n Investment Analytics\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/profile')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Award className=\"h-4 w-4 text-text-secondary\" />\n View Profile\n </button>\n </div>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"InvestorDashboard.js","names":[],"sources":["../../../../src/kadaikodi/pages/investor/InvestorDashboard.tsx"],"sourcesContent":["/**\n * Investor Dashboard Page\n * @module kadaikodi/pages/investor\n *\n * Portfolio overview with real metrics derived from the investor's holdings,\n * tab navigation (my investments / new opportunities), and quick actions.\n * All data comes from the live backend — no fabricated insights or activity.\n */\n\nimport { useState, useMemo } from 'react';\nimport {\n Wallet,\n PieChart,\n IndianRupee,\n Target,\n Award,\n Filter,\n Eye,\n Plus,\n BarChart3,\n} from 'lucide-react';\nimport { EmphasisPanel, GlassCard, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { EmptyState } from '../../components/EmptyState';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { InvestmentCard } from '../../components/InvestmentCard';\nimport { AreaChart } from '../../components/viz';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useInvestmentOpportunities, useInvestments } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatDate } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getStatusBadgeColor(status: string): string {\n switch (status) {\n case 'active':\n return 'bg-status-success-bg-subtle text-status-success-text';\n case 'completed':\n return 'bg-[var(--color-accent-soft)] text-text-primary';\n case 'exited':\n return 'bg-bg-sunken text-text-secondary';\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorDashboard() {\n const { navigateTo, currentUser } = useKadaikodi();\n const [activeTab, setActiveTab] = useState<'portfolio' | 'opportunities'>('portfolio');\n\n const { data: opportunities = [], isLoading: opportunitiesLoading } =\n useInvestmentOpportunities();\n const { data: investments = [], isLoading: investmentsLoading } = useInvestments(\n currentUser?.id || ''\n );\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'Investor';\n\n const activeOpportunities = opportunities.filter((inv) => inv.status === 'active');\n\n const portfolioSummary = useMemo(() => {\n const totalInvested = investments.reduce((sum, inv) => sum + inv.investedAmount, 0);\n const currentValue = investments.reduce((sum, inv) => sum + inv.currentValue, 0);\n const totalReturns = investments.reduce((sum, inv) => sum + inv.returns, 0);\n const roi = totalInvested > 0 ? ((currentValue - totalInvested) / totalInvested) * 100 : 0;\n\n return {\n totalInvested,\n currentValue,\n totalReturns,\n roi,\n };\n }, [investments]);\n\n // Portfolio value trend — running total of holding value by date (real).\n const valueTrend = useMemo(() => {\n const sorted = [...investments].sort(\n (a, b) => new Date(a.investmentDate).getTime() - new Date(b.investmentDate).getTime()\n );\n let running = 0;\n const points = sorted.map((inv) => {\n running += inv.currentValue;\n return {\n label: formatDate(inv.investmentDate, {\n day: undefined,\n hour: undefined,\n minute: undefined,\n }),\n value: running,\n };\n });\n return points.length === 1 ? [{ label: 'Start', value: 0 }, ...points] : points;\n }, [investments]);\n\n if (opportunitiesLoading || investmentsLoading) {\n return (\n <PageLayout title=\"Investment Dashboard\" description=\"Loading your portfolio...\">\n <div className=\"flex items-center justify-center py-20\">\n <div className=\"text-center\">\n <div className=\"mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary\" />\n <p className=\"text-sm text-text-secondary\">Loading your portfolio...</p>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`Welcome back, ${firstName}!`}\n description=\"Here's your investment portfolio overview.\"\n >\n <PagePurpose className=\"mb-6\">\n Track how your money is working across the mobile carts you've backed — see what you've\n invested, what it's worth today, and the returns flowing in. Review your active investments\n below or browse new opportunities to diversify.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"kadaikodi-investor-dashboard\"\n className=\"mb-6\"\n steps={[\n {\n id: 'opportunities',\n label: 'Explore new opportunities',\n description: 'Discover carts seeking funding and their projected returns.',\n onClick: () => navigateTo('/investor/opportunities'),\n },\n {\n id: 'portfolio',\n label: 'Review your portfolio',\n description: 'Dig into each active investment and its performance.',\n onClick: () => navigateTo('/investor/portfolio'),\n },\n {\n id: 'analytics',\n label: 'Analyse your returns',\n description: 'See trends and projections across your whole portfolio.',\n onClick: () => navigateTo('/investor/analytics'),\n },\n ]}\n />\n\n {/* Portfolio Summary Metrics — the one emphasis zone */}\n <EmphasisPanel>\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Portfolio Overview</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <MetricsCard\n featured\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"up\"\n trendValue=\"Across all businesses\"\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend={portfolioSummary.roi >= 0 ? 'up' : 'down'}\n trendValue={`${portfolioSummary.roi >= 0 ? '+' : ''}${portfolioSummary.roi.toFixed(1)}%`}\n />\n <MetricsCard\n icon={<Target className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.totalReturns, { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Main Content + Sidebar */}\n <div className=\"mt-8 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Main Content */}\n <div className=\"lg:col-span-2\">\n {/* Tab Navigation */}\n <div className=\"mb-6 flex rounded-lg bg-bg-sunken p-1\">\n <button\n type=\"button\"\n onClick={() => setActiveTab('portfolio')}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n activeTab === 'portfolio'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n My Investments\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('opportunities')}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n activeTab === 'opportunities'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n New Opportunities\n </button>\n </div>\n\n {/* Portfolio Tab */}\n {activeTab === 'portfolio' && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">Active Investments</h3>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/investments')}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Filter className=\"h-4 w-4\" />\n View all\n </button>\n </div>\n\n {investments.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No active investments yet\"\n description=\"Once you back a cart, your investments will appear here. Browse open opportunities to get started.\"\n action={\n <button\n type=\"button\"\n onClick={() => setActiveTab('opportunities')}\n className=\"rounded-lg bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n Browse opportunities\n </button>\n }\n />\n ) : (\n investments.map((investment) => (\n <div\n key={investment.id}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 shadow-sm hover:shadow-md transition-shadow\"\n >\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex-1\">\n <div className=\"mb-2 flex flex-wrap items-center gap-2\">\n <h4 className=\"text-base font-semibold text-text-primary\">\n {investment.cartName}\n </h4>\n <span\n className={cn(\n 'rounded-full px-2 py-0.5 text-xs font-medium',\n getStatusBadgeColor(investment.status)\n )}\n >\n {investment.status}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n\n <div className=\"mt-3 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(investment.investedAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Current Value</p>\n <p className=\"text-sm font-semibold text-status-success-text\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Returns</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(investment.returns, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Expected Return</p>\n <p className=\"text-sm font-semibold text-status-success-text\">\n {investment.returnsPercentage}%\n </p>\n </div>\n </div>\n </div>\n ))\n )}\n </div>\n )}\n\n {/* Opportunities Tab */}\n {activeTab === 'opportunities' && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n Investment Opportunities\n </h3>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n Browse All\n </button>\n </div>\n\n {activeOpportunities.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No open opportunities right now\"\n description=\"New carts seeking funding will show up here. Check back soon.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {activeOpportunities.slice(0, 4).map((opp) => (\n <InvestmentCard\n key={opp.id}\n id={opp.id}\n cartName={opp.cartName}\n targetAmount={opp.targetAmount}\n raisedAmount={opp.raisedAmount}\n expectedReturns={`${opp.expectedReturns}%`}\n riskLevel={opp.riskLevel}\n status={opp.status}\n onClick={(id) => navigateTo(`/investor/opportunity/${id}`)}\n />\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Portfolio value trend */}\n {investments.length > 0 && (\n <GlassCard treatment=\"plain\" className=\"p-4 sm:p-5\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">\n Portfolio Value Trend\n </h3>\n <AreaChart\n series={valueTrend}\n height={160}\n valueFormatter={(v) =>\n formatCurrency(v, { minimumFractionDigits: 0, notation: 'compact' })\n }\n title=\"Cumulative portfolio value by holding date\"\n />\n </GlassCard>\n )}\n\n {/* Quick Actions */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Quick Actions</h3>\n <div className=\"space-y-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/portfolio')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <PieChart className=\"h-4 w-4 text-text-secondary\" />\n View Full Portfolio\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Target className=\"h-4 w-4 text-text-secondary\" />\n Browse Opportunities\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/analytics')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n Investment Analytics\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/profile')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Award className=\"h-4 w-4 text-text-secondary\" />\n View Profile\n </button>\n </div>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1,16 +1,18 @@
1
1
  import { useKadaikodi as e } from "../../context/KadaikodiContext.js";
2
2
  import { cn as t } from "../../utils/cn.js";
3
3
  import { PageLayout as n } from "../../components/PageLayout.js";
4
- import { MetricsCard as r } from "../../components/MetricsCard.js";
5
- import { EmptyState as i } from "../../components/EmptyState.js";
6
- import { useInvestments as a } from "../../hooks/useKadaikodiApi.js";
7
- import { formatCurrency as o, formatDate as s } from "../../utils/formatters.js";
8
- import { useMemo as c, useState as l } from "react";
9
- import { CheckCircle2 as u, Clock as d, Eye as f, IndianRupee as p, Plus as m, TrendingDown as h, TrendingUp as g, Wallet as _ } from "lucide-react";
10
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
11
- import { EmphasisPanel as b, PagePurpose as x } from "@burdenoff/fe-libs/ui";
4
+ import { EmptyState as r } from "../../components/EmptyState.js";
5
+ import { useInvestments as i } from "../../hooks/useKadaikodiApi.js";
6
+ import { formatCurrency as a, formatDate as o } from "../../utils/formatters.js";
7
+ import { MetricsCard as s } from "../../components/MetricsCard.js";
8
+ import { AllocationBar as c } from "../../components/viz/AllocationBar.js";
9
+ import "../../components/viz/index.js";
10
+ import { useMemo as l, useState as u } from "react";
11
+ import { CheckCircle2 as d, Clock as f, Eye as p, IndianRupee as m, Plus as h, TrendingDown as g, TrendingUp as _, Wallet as v } from "lucide-react";
12
+ import { jsx as y, jsxs as b } from "react/jsx-runtime";
13
+ import { EmphasisPanel as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
12
14
  //#region src/kadaikodi/pages/investor/InvestorInvestmentsPage.tsx
13
- var S = [
15
+ var C = [
14
16
  {
15
17
  key: "all",
16
18
  label: "All Investments"
@@ -28,7 +30,7 @@ var S = [
28
30
  label: "Exited"
29
31
  }
30
32
  ];
31
- function C(e) {
33
+ function w(e) {
32
34
  switch (e) {
33
35
  case "active": return "bg-status-success-bg-subtle text-status-success-text";
34
36
  case "completed": return "bg-[var(--color-accent-soft)] text-text-primary";
@@ -36,231 +38,251 @@ function C(e) {
36
38
  default: return "bg-bg-sunken text-text-secondary";
37
39
  }
38
40
  }
39
- function w(e) {
41
+ function T(e) {
40
42
  switch (e) {
41
- case "active": return /* @__PURE__ */ v(u, { className: "h-4 w-4" });
42
- case "completed": return /* @__PURE__ */ v(u, { className: "h-4 w-4" });
43
- default: return /* @__PURE__ */ v(d, { className: "h-4 w-4" });
43
+ case "active": return /* @__PURE__ */ y(d, { className: "h-4 w-4" });
44
+ case "completed": return /* @__PURE__ */ y(d, { className: "h-4 w-4" });
45
+ default: return /* @__PURE__ */ y(f, { className: "h-4 w-4" });
44
46
  }
45
47
  }
46
- function T(e) {
48
+ function E(e) {
47
49
  return e.currentValue - e.investedAmount;
48
50
  }
49
- function E(e) {
50
- return e.investedAmount > 0 ? T(e) / e.investedAmount * 100 : 0;
51
+ function D(e) {
52
+ return e.investedAmount > 0 ? E(e) / e.investedAmount * 100 : 0;
51
53
  }
52
- function D() {
53
- let { navigateTo: d, currentUser: D } = e(), { data: O = [], isLoading: k } = a(D?.id || ""), [A, j] = l("all"), M = c(() => A === "all" ? O : O.filter((e) => e.status === A), [A, O]), N = c(() => {
54
- let e = O.reduce((e, t) => e + t.investedAmount, 0), t = O.reduce((e, t) => e + t.currentValue, 0), n = O.reduce((e, t) => e + t.returns, 0), r = t - e;
54
+ function O() {
55
+ let { navigateTo: f, currentUser: O } = e(), { data: k = [], isLoading: A } = i(O?.id || ""), [j, M] = u("all"), N = l(() => j === "all" ? k : k.filter((e) => e.status === j), [j, k]), P = l(() => {
56
+ let e = k.reduce((e, t) => e + t.investedAmount, 0), t = k.reduce((e, t) => e + t.currentValue, 0), n = k.reduce((e, t) => e + t.returns, 0), r = t - e;
55
57
  return {
56
58
  totalInvested: e,
57
59
  currentValue: t,
58
60
  totalReturns: n,
59
61
  pl: r,
60
62
  plPct: e > 0 ? r / e * 100 : 0,
61
- activeInvestments: O.filter((e) => e.status === "active").length
63
+ activeInvestments: k.filter((e) => e.status === "active").length
62
64
  };
63
- }, [O]);
64
- function P(e) {
65
- return e === "all" ? O.length : O.filter((t) => t.status === e).length;
65
+ }, [k]), F = l(() => {
66
+ let e = k.reduce((e, t) => (e[t.cartName] = (e[t.cartName] || 0) + t.currentValue, e), {});
67
+ return Object.entries(e).map(([e, t]) => ({
68
+ label: e,
69
+ value: t
70
+ })).sort((e, t) => t.value - e.value);
71
+ }, [k]);
72
+ function I(e) {
73
+ return e === "all" ? k.length : k.filter((t) => t.status === e).length;
66
74
  }
67
- return k ? /* @__PURE__ */ v(n, {
75
+ return A ? /* @__PURE__ */ y(n, {
68
76
  title: "My Investments",
69
77
  description: "Loading your investments...",
70
- children: /* @__PURE__ */ v("div", {
78
+ children: /* @__PURE__ */ y("div", {
71
79
  className: "flex items-center justify-center py-20",
72
- children: /* @__PURE__ */ y("div", {
80
+ children: /* @__PURE__ */ b("div", {
73
81
  className: "text-center",
74
- children: [/* @__PURE__ */ v("div", { className: "mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary" }), /* @__PURE__ */ v("p", {
82
+ children: [/* @__PURE__ */ y("div", { className: "mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary" }), /* @__PURE__ */ y("p", {
75
83
  className: "text-sm text-text-secondary",
76
84
  children: "Loading your investments..."
77
85
  })]
78
86
  })
79
87
  })
80
- }) : /* @__PURE__ */ y(n, {
88
+ }) : /* @__PURE__ */ b(n, {
81
89
  title: "My Investments",
82
90
  description: "Track and manage your investment portfolio",
83
- actions: /* @__PURE__ */ y("button", {
91
+ actions: /* @__PURE__ */ b("button", {
84
92
  type: "button",
85
- onClick: () => d("/investor/opportunities"),
93
+ onClick: () => f("/investor/opportunities"),
86
94
  className: "flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors",
87
- children: [/* @__PURE__ */ v(m, { className: "h-4 w-4" }), "New Investment"]
95
+ children: [/* @__PURE__ */ y(h, { className: "h-4 w-4" }), "New Investment"]
88
96
  }),
89
97
  children: [
90
- /* @__PURE__ */ v(x, {
98
+ /* @__PURE__ */ y(S, {
91
99
  className: "mb-6",
92
100
  children: "Your active holdings in one place. Use this page to track every cart you've backed — what you put in, what it's worth now, the returns you've earned, and which investments are still active. Filter by status to focus, open any investment for the full picture, or start a New Investment when you're ready to grow your portfolio."
93
101
  }),
94
- /* @__PURE__ */ y(b, { children: [/* @__PURE__ */ v("h2", {
95
- className: "mb-4 text-base font-semibold text-text-primary",
96
- children: "Portfolio Summary"
97
- }), /* @__PURE__ */ y("div", {
98
- className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
99
- children: [
100
- /* @__PURE__ */ v(r, {
101
- icon: /* @__PURE__ */ v(_, { className: "h-5 w-5" }),
102
- value: o(N.totalInvested, { minimumFractionDigits: 0 }),
103
- label: "Total Invested"
104
- }),
105
- /* @__PURE__ */ v(r, {
106
- icon: /* @__PURE__ */ v(p, { className: "h-5 w-5" }),
107
- value: o(N.currentValue, { minimumFractionDigits: 0 }),
108
- label: "Current Value",
109
- trend: N.pl >= 0 ? "up" : "down",
110
- trendValue: `${N.plPct >= 0 ? "+" : ""}${N.plPct.toFixed(1)}%`
111
- }),
112
- /* @__PURE__ */ v(r, {
113
- icon: /* @__PURE__ */ v(g, { className: "h-5 w-5" }),
114
- value: o(N.totalReturns, { minimumFractionDigits: 0 }),
115
- label: "Total Returns"
116
- }),
117
- /* @__PURE__ */ v(r, {
118
- icon: /* @__PURE__ */ v(u, { className: "h-5 w-5" }),
119
- value: String(N.activeInvestments),
120
- label: "Active Investments",
121
- trend: "neutral"
102
+ /* @__PURE__ */ b(x, { children: [
103
+ /* @__PURE__ */ y("h2", {
104
+ className: "mb-4 text-base font-semibold text-text-primary",
105
+ children: "Portfolio Summary"
106
+ }),
107
+ /* @__PURE__ */ b("div", {
108
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
109
+ children: [
110
+ /* @__PURE__ */ y(s, {
111
+ icon: /* @__PURE__ */ y(v, { className: "h-5 w-5" }),
112
+ value: a(P.totalInvested, { minimumFractionDigits: 0 }),
113
+ label: "Total Invested"
114
+ }),
115
+ /* @__PURE__ */ y(s, {
116
+ icon: /* @__PURE__ */ y(m, { className: "h-5 w-5" }),
117
+ value: a(P.currentValue, { minimumFractionDigits: 0 }),
118
+ label: "Current Value",
119
+ trend: P.pl >= 0 ? "up" : "down",
120
+ trendValue: `${P.plPct >= 0 ? "+" : ""}${P.plPct.toFixed(1)}%`
121
+ }),
122
+ /* @__PURE__ */ y(s, {
123
+ icon: /* @__PURE__ */ y(_, { className: "h-5 w-5" }),
124
+ value: a(P.totalReturns, { minimumFractionDigits: 0 }),
125
+ label: "Total Returns"
126
+ }),
127
+ /* @__PURE__ */ y(s, {
128
+ icon: /* @__PURE__ */ y(d, { className: "h-5 w-5" }),
129
+ value: String(P.activeInvestments),
130
+ label: "Active Investments",
131
+ trend: "neutral"
132
+ })
133
+ ]
134
+ }),
135
+ F.length > 1 && /* @__PURE__ */ y("div", {
136
+ className: "mt-4 rounded-lg border border-border-subtle bg-bg-surface p-4",
137
+ children: /* @__PURE__ */ y(c, {
138
+ segments: F,
139
+ label: "Allocation by cart",
140
+ rightLabel: a(P.currentValue, {
141
+ minimumFractionDigits: 0,
142
+ notation: "compact"
143
+ })
122
144
  })
123
- ]
124
- })] }),
125
- /* @__PURE__ */ v("div", {
145
+ })
146
+ ] }),
147
+ /* @__PURE__ */ y("div", {
126
148
  className: "mt-6 rounded-lg border border-border-subtle bg-bg-surface p-4",
127
- children: /* @__PURE__ */ v("div", {
149
+ children: /* @__PURE__ */ y("div", {
128
150
  className: "flex flex-wrap gap-2",
129
- children: S.map((e) => /* @__PURE__ */ y("button", {
151
+ children: C.map((e) => /* @__PURE__ */ b("button", {
130
152
  type: "button",
131
- onClick: () => j(e.key),
132
- className: t("flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors", A === e.key ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-primary hover:bg-bg-sunken/80"),
133
- children: [e.label, /* @__PURE__ */ v("span", {
134
- className: t("rounded-full px-2 py-0.5 text-xs", A === e.key ? "bg-primary-foreground/20 text-action-primary-text" : "bg-action-primary-bg/10 text-primary"),
135
- children: P(e.key)
153
+ onClick: () => M(e.key),
154
+ className: t("flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors", j === e.key ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-primary hover:bg-bg-sunken/80"),
155
+ children: [e.label, /* @__PURE__ */ y("span", {
156
+ className: t("rounded-full px-2 py-0.5 text-xs", j === e.key ? "bg-primary-foreground/20 text-action-primary-text" : "bg-action-primary-bg/10 text-primary"),
157
+ children: I(e.key)
136
158
  })]
137
159
  }, e.key))
138
160
  })
139
161
  }),
140
- /* @__PURE__ */ v("div", {
162
+ /* @__PURE__ */ y("div", {
141
163
  className: "mt-6 space-y-4",
142
- children: M.length > 0 ? M.map((e) => {
143
- let n = T(e), r = E(e);
144
- return /* @__PURE__ */ y("div", {
164
+ children: N.length > 0 ? N.map((e) => {
165
+ let n = E(e), r = D(e);
166
+ return /* @__PURE__ */ b("div", {
145
167
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6",
146
- children: [/* @__PURE__ */ y("div", {
168
+ children: [/* @__PURE__ */ b("div", {
147
169
  className: "block space-y-4 lg:hidden",
148
170
  children: [
149
- /* @__PURE__ */ y("div", {
171
+ /* @__PURE__ */ b("div", {
150
172
  className: "flex items-start justify-between",
151
- children: [/* @__PURE__ */ v("h3", {
173
+ children: [/* @__PURE__ */ y("h3", {
152
174
  className: "text-lg font-semibold text-text-primary",
153
175
  children: e.cartName
154
- }), /* @__PURE__ */ y("span", {
155
- className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium", C(e.status)),
156
- children: [w(e.status), /* @__PURE__ */ v("span", {
176
+ }), /* @__PURE__ */ b("span", {
177
+ className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium", w(e.status)),
178
+ children: [T(e.status), /* @__PURE__ */ y("span", {
157
179
  className: "capitalize",
158
180
  children: e.status
159
181
  })]
160
182
  })]
161
183
  }),
162
- /* @__PURE__ */ y("div", {
184
+ /* @__PURE__ */ b("div", {
163
185
  className: "grid grid-cols-2 gap-4",
164
186
  children: [
165
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
187
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
166
188
  className: "text-sm text-text-secondary",
167
189
  children: "Invested"
168
- }), /* @__PURE__ */ v("p", {
190
+ }), /* @__PURE__ */ y("p", {
169
191
  className: "font-semibold text-text-primary",
170
- children: o(e.investedAmount, { minimumFractionDigits: 0 })
192
+ children: a(e.investedAmount, { minimumFractionDigits: 0 })
171
193
  })] }),
172
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
194
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
173
195
  className: "text-sm text-text-secondary",
174
196
  children: "Current Value"
175
- }), /* @__PURE__ */ v("p", {
197
+ }), /* @__PURE__ */ y("p", {
176
198
  className: "font-semibold text-text-primary",
177
- children: o(e.currentValue, { minimumFractionDigits: 0 })
199
+ children: a(e.currentValue, { minimumFractionDigits: 0 })
178
200
  })] }),
179
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
201
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
180
202
  className: "text-sm text-text-secondary",
181
203
  children: "P&L"
182
- }), /* @__PURE__ */ y("p", {
204
+ }), /* @__PURE__ */ b("p", {
183
205
  className: t("font-semibold", n >= 0 ? "text-status-success-text" : "text-status-error-text"),
184
206
  children: [
185
207
  n >= 0 ? "+" : "",
186
- o(n, { minimumFractionDigits: 0 }),
208
+ a(n, { minimumFractionDigits: 0 }),
187
209
  " (",
188
210
  r >= 0 ? "+" : "",
189
211
  r.toFixed(1),
190
212
  "%)"
191
213
  ]
192
214
  })] }),
193
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
215
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
194
216
  className: "text-sm text-text-secondary",
195
217
  children: "Expected Return"
196
- }), /* @__PURE__ */ y("p", {
218
+ }), /* @__PURE__ */ b("p", {
197
219
  className: "font-semibold text-text-primary",
198
220
  children: [e.returnsPercentage, "%"]
199
221
  })] })
200
222
  ]
201
223
  }),
202
- /* @__PURE__ */ y("div", {
224
+ /* @__PURE__ */ b("div", {
203
225
  className: "flex items-center justify-between border-t border-border-subtle pt-2",
204
- children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
226
+ children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
205
227
  className: "text-xs text-text-secondary",
206
228
  children: "Invested on"
207
- }), /* @__PURE__ */ v("p", {
229
+ }), /* @__PURE__ */ y("p", {
208
230
  className: "text-sm font-medium text-text-primary",
209
- children: s(e.investmentDate, {
231
+ children: o(e.investmentDate, {
210
232
  hour: void 0,
211
233
  minute: void 0
212
234
  })
213
- })] }), /* @__PURE__ */ y("button", {
235
+ })] }), /* @__PURE__ */ b("button", {
214
236
  type: "button",
215
- onClick: () => d(`/investor/investments/${e.id}`),
237
+ onClick: () => f(`/investor/investments/${e.id}`),
216
238
  className: "flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors",
217
- children: [/* @__PURE__ */ v(f, { className: "h-4 w-4" }), "View Details"]
239
+ children: [/* @__PURE__ */ y(p, { className: "h-4 w-4" }), "View Details"]
218
240
  })]
219
241
  })
220
242
  ]
221
- }), /* @__PURE__ */ y("div", {
243
+ }), /* @__PURE__ */ b("div", {
222
244
  className: "hidden lg:flex lg:items-center lg:justify-between",
223
- children: [/* @__PURE__ */ y("div", {
245
+ children: [/* @__PURE__ */ b("div", {
224
246
  className: "min-w-0 flex-1",
225
- children: [/* @__PURE__ */ y("div", {
247
+ children: [/* @__PURE__ */ b("div", {
226
248
  className: "mb-4 flex items-center justify-between",
227
- children: [/* @__PURE__ */ v("h3", {
249
+ children: [/* @__PURE__ */ y("h3", {
228
250
  className: "text-lg font-semibold text-text-primary",
229
251
  children: e.cartName
230
- }), /* @__PURE__ */ y("span", {
231
- className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium", C(e.status)),
232
- children: [w(e.status), /* @__PURE__ */ v("span", {
252
+ }), /* @__PURE__ */ b("span", {
253
+ className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium", w(e.status)),
254
+ children: [T(e.status), /* @__PURE__ */ y("span", {
233
255
  className: "capitalize",
234
256
  children: e.status
235
257
  })]
236
258
  })]
237
- }), /* @__PURE__ */ y("div", {
259
+ }), /* @__PURE__ */ b("div", {
238
260
  className: "grid grid-cols-5 gap-6",
239
261
  children: [
240
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
262
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
241
263
  className: "text-sm text-text-secondary",
242
264
  children: "Invested"
243
- }), /* @__PURE__ */ v("p", {
265
+ }), /* @__PURE__ */ y("p", {
244
266
  className: "font-semibold text-text-primary",
245
- children: o(e.investedAmount, { minimumFractionDigits: 0 })
267
+ children: a(e.investedAmount, { minimumFractionDigits: 0 })
246
268
  })] }),
247
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
269
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
248
270
  className: "text-sm text-text-secondary",
249
271
  children: "Current Value"
250
- }), /* @__PURE__ */ v("p", {
272
+ }), /* @__PURE__ */ y("p", {
251
273
  className: "font-semibold text-text-primary",
252
- children: o(e.currentValue, { minimumFractionDigits: 0 })
274
+ children: a(e.currentValue, { minimumFractionDigits: 0 })
253
275
  })] }),
254
- /* @__PURE__ */ y("div", { children: [
255
- /* @__PURE__ */ v("p", {
276
+ /* @__PURE__ */ b("div", { children: [
277
+ /* @__PURE__ */ y("p", {
256
278
  className: "text-sm text-text-secondary",
257
279
  children: "P&L"
258
280
  }),
259
- /* @__PURE__ */ y("p", {
281
+ /* @__PURE__ */ b("p", {
260
282
  className: t("font-semibold", n >= 0 ? "text-status-success-text" : "text-status-error-text"),
261
- children: [n >= 0 ? "+" : "", o(n, { minimumFractionDigits: 0 })]
283
+ children: [n >= 0 ? "+" : "", a(n, { minimumFractionDigits: 0 })]
262
284
  }),
263
- /* @__PURE__ */ y("p", {
285
+ /* @__PURE__ */ b("p", {
264
286
  className: t("text-xs", n >= 0 ? "text-status-success-text" : "text-status-error-text"),
265
287
  children: [
266
288
  "(",
@@ -270,43 +292,43 @@ function D() {
270
292
  ]
271
293
  })
272
294
  ] }),
273
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
295
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
274
296
  className: "text-sm text-text-secondary",
275
297
  children: "Expected Return"
276
- }), /* @__PURE__ */ y("p", {
298
+ }), /* @__PURE__ */ b("p", {
277
299
  className: "font-semibold text-text-primary",
278
300
  children: [e.returnsPercentage, "%"]
279
301
  })] }),
280
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
302
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
281
303
  className: "text-sm text-text-secondary",
282
304
  children: "Invested on"
283
- }), /* @__PURE__ */ v("p", {
305
+ }), /* @__PURE__ */ y("p", {
284
306
  className: "font-semibold text-text-primary",
285
- children: s(e.investmentDate, {
307
+ children: o(e.investmentDate, {
286
308
  hour: void 0,
287
309
  minute: void 0
288
310
  })
289
311
  })] })
290
312
  ]
291
313
  })]
292
- }), /* @__PURE__ */ v("div", {
314
+ }), /* @__PURE__ */ y("div", {
293
315
  className: "ml-6",
294
- children: /* @__PURE__ */ y("button", {
316
+ children: /* @__PURE__ */ b("button", {
295
317
  type: "button",
296
- onClick: () => d(`/investor/investments/${e.id}`),
318
+ onClick: () => f(`/investor/investments/${e.id}`),
297
319
  className: "flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors",
298
- children: [/* @__PURE__ */ v(f, { className: "h-4 w-4" }), "View Details"]
320
+ children: [/* @__PURE__ */ y(p, { className: "h-4 w-4" }), "View Details"]
299
321
  })
300
322
  })]
301
323
  })]
302
324
  }, e.id);
303
- }) : /* @__PURE__ */ v(i, {
304
- icon: /* @__PURE__ */ v(h, { className: "h-12 w-12" }),
305
- title: `No ${A === "all" ? "" : A} investments found`,
306
- description: A === "all" ? "You haven't made any investments yet. Start exploring opportunities to grow your wealth." : `You don't have any ${A} investments at the moment.`,
307
- action: /* @__PURE__ */ v("button", {
325
+ }) : /* @__PURE__ */ y(r, {
326
+ icon: /* @__PURE__ */ y(g, { className: "h-12 w-12" }),
327
+ title: `No ${j === "all" ? "" : j} investments found`,
328
+ description: j === "all" ? "You haven't made any investments yet. Start exploring opportunities to grow your wealth." : `You don't have any ${j} investments at the moment.`,
329
+ action: /* @__PURE__ */ y("button", {
308
330
  type: "button",
309
- onClick: () => d("/investor/opportunities"),
331
+ onClick: () => f("/investor/opportunities"),
310
332
  className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors",
311
333
  children: "Explore Investment Opportunities"
312
334
  })
@@ -316,6 +338,6 @@ function D() {
316
338
  });
317
339
  }
318
340
  //#endregion
319
- export { D as InvestorInvestmentsPage };
341
+ export { O as InvestorInvestmentsPage };
320
342
 
321
343
  //# sourceMappingURL=InvestorInvestmentsPage.js.map