@burdenoff/microfe-subscriberbot 2026.624.1 → 2026.626.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 (104) hide show
  1. package/dist/subscriberbot/components/EmptyState.js +17 -10
  2. package/dist/subscriberbot/components/EmptyState.js.map +1 -1
  3. package/dist/subscriberbot/components/InvestmentCard.js +23 -22
  4. package/dist/subscriberbot/components/InvestmentCard.js.map +1 -1
  5. package/dist/subscriberbot/components/MetricsCard.js +15 -12
  6. package/dist/subscriberbot/components/MetricsCard.js.map +1 -1
  7. package/dist/subscriberbot/components/PageLayout.js +27 -15
  8. package/dist/subscriberbot/components/PageLayout.js.map +1 -1
  9. package/dist/subscriberbot/components/RatingDisplay.js +3 -3
  10. package/dist/subscriberbot/components/RatingDisplay.js.map +1 -1
  11. package/dist/subscriberbot/components/StatusBadge.js +25 -13
  12. package/dist/subscriberbot/components/StatusBadge.js.map +1 -1
  13. package/dist/subscriberbot/context/SubscriberBotContext.js.map +1 -1
  14. package/dist/subscriberbot/pages/HomePage.js +72 -63
  15. package/dist/subscriberbot/pages/HomePage.js.map +1 -1
  16. package/dist/subscriberbot/pages/admin/AdminAnalyticsPage.js +106 -100
  17. package/dist/subscriberbot/pages/admin/AdminAnalyticsPage.js.map +1 -1
  18. package/dist/subscriberbot/pages/admin/AdminDashboard.js +125 -85
  19. package/dist/subscriberbot/pages/admin/AdminDashboard.js.map +1 -1
  20. package/dist/subscriberbot/pages/admin/AdminFinancialPage.js +51 -45
  21. package/dist/subscriberbot/pages/admin/AdminFinancialPage.js.map +1 -1
  22. package/dist/subscriberbot/pages/admin/AdminOrdersPage.js +246 -241
  23. package/dist/subscriberbot/pages/admin/AdminOrdersPage.js.map +1 -1
  24. package/dist/subscriberbot/pages/admin/AdminProfilePage.js +131 -129
  25. package/dist/subscriberbot/pages/admin/AdminProfilePage.js.map +1 -1
  26. package/dist/subscriberbot/pages/admin/AdminSettingsPage.js +247 -242
  27. package/dist/subscriberbot/pages/admin/AdminSettingsPage.js.map +1 -1
  28. package/dist/subscriberbot/pages/admin/CartManagementPage.js +307 -302
  29. package/dist/subscriberbot/pages/admin/CartManagementPage.js.map +1 -1
  30. package/dist/subscriberbot/pages/admin/UserManagementPage.js +308 -303
  31. package/dist/subscriberbot/pages/admin/UserManagementPage.js.map +1 -1
  32. package/dist/subscriberbot/pages/cart-owner/AnalyticsDashboard.js +89 -84
  33. package/dist/subscriberbot/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
  34. package/dist/subscriberbot/pages/cart-owner/BusinessSettingsPage.js +269 -264
  35. package/dist/subscriberbot/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
  36. package/dist/subscriberbot/pages/cart-owner/CartOwnerDashboard.js +269 -227
  37. package/dist/subscriberbot/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
  38. package/dist/subscriberbot/pages/cart-owner/CartOwnerProfilePage.js +191 -186
  39. package/dist/subscriberbot/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
  40. package/dist/subscriberbot/pages/cart-owner/CartServiceConfigPage.js +168 -166
  41. package/dist/subscriberbot/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
  42. package/dist/subscriberbot/pages/cart-owner/InventoryManagementPage.js +344 -347
  43. package/dist/subscriberbot/pages/cart-owner/InventoryManagementPage.js.map +1 -1
  44. package/dist/subscriberbot/pages/cart-owner/OrderManagementPage.js +270 -272
  45. package/dist/subscriberbot/pages/cart-owner/OrderManagementPage.js.map +1 -1
  46. package/dist/subscriberbot/pages/cart-owner/StaffManagementPage.js +294 -289
  47. package/dist/subscriberbot/pages/cart-owner/StaffManagementPage.js.map +1 -1
  48. package/dist/subscriberbot/pages/common/HelpSupportPage.js +156 -158
  49. package/dist/subscriberbot/pages/common/HelpSupportPage.js.map +1 -1
  50. package/dist/subscriberbot/pages/common/NotificationCenterPage.js +94 -87
  51. package/dist/subscriberbot/pages/common/NotificationCenterPage.js.map +1 -1
  52. package/dist/subscriberbot/pages/common/SettingsPage.js +749 -740
  53. package/dist/subscriberbot/pages/common/SettingsPage.js.map +1 -1
  54. package/dist/subscriberbot/pages/customer/BookingDetailsPage.js +357 -324
  55. package/dist/subscriberbot/pages/customer/BookingDetailsPage.js.map +1 -1
  56. package/dist/subscriberbot/pages/customer/CartDetailPage.js +281 -247
  57. package/dist/subscriberbot/pages/customer/CartDetailPage.js.map +1 -1
  58. package/dist/subscriberbot/pages/customer/CartDiscoveryPage.js +106 -98
  59. package/dist/subscriberbot/pages/customer/CartDiscoveryPage.js.map +1 -1
  60. package/dist/subscriberbot/pages/customer/CheckoutPage.js +235 -238
  61. package/dist/subscriberbot/pages/customer/CheckoutPage.js.map +1 -1
  62. package/dist/subscriberbot/pages/customer/CustomerDashboard.js +426 -390
  63. package/dist/subscriberbot/pages/customer/CustomerDashboard.js.map +1 -1
  64. package/dist/subscriberbot/pages/customer/CustomerProfilePage.js +488 -479
  65. package/dist/subscriberbot/pages/customer/CustomerProfilePage.js.map +1 -1
  66. package/dist/subscriberbot/pages/customer/DirectServiceBookingPage.js +522 -512
  67. package/dist/subscriberbot/pages/customer/DirectServiceBookingPage.js.map +1 -1
  68. package/dist/subscriberbot/pages/customer/FavoritesPage.js +73 -66
  69. package/dist/subscriberbot/pages/customer/FavoritesPage.js.map +1 -1
  70. package/dist/subscriberbot/pages/customer/OrderHistoryPage.js +75 -67
  71. package/dist/subscriberbot/pages/customer/OrderHistoryPage.js.map +1 -1
  72. package/dist/subscriberbot/pages/customer/OrderTrackingPage.js +82 -76
  73. package/dist/subscriberbot/pages/customer/OrderTrackingPage.js.map +1 -1
  74. package/dist/subscriberbot/pages/customer/PaymentMethodsPage.js +100 -93
  75. package/dist/subscriberbot/pages/customer/PaymentMethodsPage.js.map +1 -1
  76. package/dist/subscriberbot/pages/customer/ReviewsPage.js +97 -90
  77. package/dist/subscriberbot/pages/customer/ReviewsPage.js.map +1 -1
  78. package/dist/subscriberbot/pages/customer/SavedAddressesPage.js +86 -79
  79. package/dist/subscriberbot/pages/customer/SavedAddressesPage.js.map +1 -1
  80. package/dist/subscriberbot/pages/investor/InvestmentDetailsPage.js +330 -293
  81. package/dist/subscriberbot/pages/investor/InvestmentDetailsPage.js.map +1 -1
  82. package/dist/subscriberbot/pages/investor/InvestmentOpportunitiesPage.js +269 -261
  83. package/dist/subscriberbot/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
  84. package/dist/subscriberbot/pages/investor/InvestorAnalyticsPage.js +97 -91
  85. package/dist/subscriberbot/pages/investor/InvestorAnalyticsPage.js.map +1 -1
  86. package/dist/subscriberbot/pages/investor/InvestorDashboard.js +354 -322
  87. package/dist/subscriberbot/pages/investor/InvestorDashboard.js.map +1 -1
  88. package/dist/subscriberbot/pages/investor/InvestorInvestmentsPage.js +118 -111
  89. package/dist/subscriberbot/pages/investor/InvestorInvestmentsPage.js.map +1 -1
  90. package/dist/subscriberbot/pages/investor/InvestorPortfolioPage.js +75 -69
  91. package/dist/subscriberbot/pages/investor/InvestorPortfolioPage.js.map +1 -1
  92. package/dist/subscriberbot/pages/investor/InvestorProfilePage.js +435 -430
  93. package/dist/subscriberbot/pages/investor/InvestorProfilePage.js.map +1 -1
  94. package/dist/subscriberbot/pages/worker/TaskDetailsPage.js +328 -289
  95. package/dist/subscriberbot/pages/worker/TaskDetailsPage.js.map +1 -1
  96. package/dist/subscriberbot/pages/worker/WorkerDashboard.js +135 -103
  97. package/dist/subscriberbot/pages/worker/WorkerDashboard.js.map +1 -1
  98. package/dist/subscriberbot/pages/worker/WorkerOrdersPage.js +120 -114
  99. package/dist/subscriberbot/pages/worker/WorkerOrdersPage.js.map +1 -1
  100. package/dist/subscriberbot/pages/worker/WorkerProfilePage.js +125 -120
  101. package/dist/subscriberbot/pages/worker/WorkerProfilePage.js.map +1 -1
  102. package/dist/subscriberbot/pages/worker/WorkerSchedulePage.js +354 -344
  103. package/dist/subscriberbot/pages/worker/WorkerSchedulePage.js.map +1 -1
  104. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"InvestorInvestmentsPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/investor/InvestorInvestmentsPage.tsx"],"sourcesContent":["/**\n * Investor Investments Page\n * @module subscriberbot/pages/investor\n *\n * MetricsGrid summary cards, filter tabs (all/active/pending/matured) with counts,\n * responsive mobile/desktop layouts, P&L display, ROI display, status icons,\n * empty state.\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport {\n TrendingUp,\n TrendingDown,\n Briefcase,\n Eye,\n BarChart3,\n AlertCircle,\n CheckCircle2,\n Clock,\n Wallet,\n IndianRupee,\n Plus,\n Target,\n} from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatDate } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Investment {\n id: string;\n cartName: string;\n cartOwner: string;\n investmentAmount: number;\n currentValue: number;\n profitLoss: number;\n profitLossPercentage: number;\n investmentDate: string;\n status: 'active' | 'pending' | 'matured' | 'withdrawn';\n roiAnnual: number;\n duration: string;\n nextPayout: string;\n totalReturns: number;\n}\n\ninterface InvestmentSummary {\n totalInvested: number;\n currentValue: number;\n totalReturns: number;\n activeInvestments: number;\n averageRoi: number;\n profitLoss: number;\n profitLossPercentage: number;\n}\n\ntype FilterKey = 'all' | 'active' | 'pending' | 'matured';\n\n// ---------------------------------------------------------------------------\n// Mock data\n// ---------------------------------------------------------------------------\n\nconst mockInvestments: Investment[] = [\n {\n id: 'inv-001',\n cartName: 'South Indian Express',\n cartOwner: 'Raj Kumar',\n investmentAmount: 50000,\n currentValue: 58500,\n profitLoss: 8500,\n profitLossPercentage: 17.0,\n investmentDate: '2024-01-15',\n status: 'active',\n roiAnnual: 22.5,\n duration: '18 months',\n nextPayout: '2024-12-15',\n totalReturns: 8500,\n },\n {\n id: 'inv-002',\n cartName: 'Pizza Corner',\n cartOwner: 'Priya Singh',\n investmentAmount: 75000,\n currentValue: 82000,\n profitLoss: 7000,\n profitLossPercentage: 9.3,\n investmentDate: '2024-03-10',\n status: 'active',\n roiAnnual: 18.0,\n duration: '24 months',\n nextPayout: '2024-12-10',\n totalReturns: 7000,\n },\n {\n id: 'inv-003',\n cartName: 'Healthy Bites',\n cartOwner: 'Amit Patel',\n investmentAmount: 30000,\n currentValue: 31200,\n profitLoss: 1200,\n profitLossPercentage: 4.0,\n investmentDate: '2024-06-01',\n status: 'active',\n roiAnnual: 15.0,\n duration: '12 months',\n nextPayout: '2024-12-01',\n totalReturns: 1200,\n },\n {\n id: 'inv-004',\n cartName: 'Street Food Junction',\n cartOwner: 'Neha Sharma',\n investmentAmount: 40000,\n currentValue: 40000,\n profitLoss: 0,\n profitLossPercentage: 0,\n investmentDate: '2024-08-15',\n status: 'pending',\n roiAnnual: 20.0,\n duration: '15 months',\n nextPayout: '2025-01-15',\n totalReturns: 0,\n },\n {\n id: 'inv-005',\n cartName: 'Biryani House',\n cartOwner: 'Suresh Reddy',\n investmentAmount: 60000,\n currentValue: 72000,\n profitLoss: 12000,\n profitLossPercentage: 20.0,\n investmentDate: '2023-12-01',\n status: 'matured',\n roiAnnual: 25.0,\n duration: '12 months',\n nextPayout: '-',\n totalReturns: 12000,\n },\n];\n\nconst mockSummary: InvestmentSummary = {\n totalInvested: 255000,\n currentValue: 283700,\n totalReturns: 28700,\n activeInvestments: 3,\n averageRoi: 19.6,\n profitLoss: 28700,\n profitLossPercentage: 11.3,\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getStatusColor(status: string): string {\n switch (status) {\n case 'active':\n return 'bg-green-500/20 text-green-600 dark:text-green-400';\n case 'pending':\n return 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400';\n case 'matured':\n return 'bg-blue-500/20 text-blue-600 dark:text-blue-400';\n case 'withdrawn':\n return 'bg-secondary text-secondary-foreground';\n default:\n return 'bg-secondary text-secondary-foreground';\n }\n}\n\nfunction getStatusIcon(status: string) {\n switch (status) {\n case 'active':\n return <CheckCircle2 className=\"h-4 w-4\" />;\n case 'pending':\n return <Clock className=\"h-4 w-4\" />;\n case 'matured':\n return <CheckCircle2 className=\"h-4 w-4\" />;\n default:\n return <AlertCircle className=\"h-4 w-4\" />;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorInvestmentsPage() {\n const { navigateTo } = useSubscriberBot();\n const [isLoading, setIsLoading] = useState(true);\n const [filter, setFilter] = useState<FilterKey>('all');\n\n useEffect(() => {\n const timer = setTimeout(() => setIsLoading(false), 600);\n return () => clearTimeout(timer);\n }, []);\n\n const filteredInvestments = useMemo(() => {\n if (filter === 'all') return mockInvestments;\n return mockInvestments.filter((inv) => inv.status === filter);\n }, [filter]);\n\n const filterTabs: Array<{ key: FilterKey; label: string }> = [\n { key: 'all', label: 'All Investments' },\n { key: 'active', label: 'Active' },\n { key: 'pending', label: 'Pending' },\n { key: 'matured', label: 'Matured' },\n ];\n\n function getCount(key: FilterKey): number {\n if (key === 'all') return mockInvestments.length;\n return mockInvestments.filter((inv) => inv.status === key).length;\n }\n\n if (isLoading) {\n return (\n <PageLayout title=\"My Investments\" description=\"Loading your investments...\">\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 investments...</p>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"My Investments\"\n description=\"Track and manage your investment portfolio\"\n actions={\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 New Investment\n </button>\n }\n >\n {/* Investment Summary */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"up\"\n trendValue=\"Total amount invested\"\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend={mockSummary.profitLoss > 0 ? 'up' : 'down'}\n trendValue={`${mockSummary.profitLossPercentage > 0 ? '+' : ''}${mockSummary.profitLossPercentage}% total returns`}\n />\n <MetricsCard\n icon={<TrendingUp className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.totalReturns, { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n trend=\"up\"\n trendValue=\"Total profit earned\"\n />\n <MetricsCard\n icon={<CheckCircle2 className=\"h-5 w-5\" />}\n value={String(mockSummary.activeInvestments)}\n label=\"Active Investments\"\n trend=\"neutral\"\n trendValue={`${mockSummary.averageRoi}% avg ROI`}\n />\n </div>\n\n {/* Filter Tabs */}\n <div className=\"mt-6 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex flex-wrap gap-2\">\n {filterTabs.map((tab) => (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => setFilter(tab.key)}\n className={cn(\n 'flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors',\n filter === tab.key\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary hover:bg-bg-sunken/80'\n )}\n >\n {tab.label}\n <span\n className={cn(\n 'rounded-full px-2 py-0.5 text-xs',\n filter === tab.key\n ? 'bg-primary-foreground/20 text-action-primary-text'\n : 'bg-action-primary-bg/10 text-primary'\n )}\n >\n {getCount(tab.key)}\n </span>\n </button>\n ))}\n </div>\n </div>\n\n {/* Investments List */}\n <div className=\"mt-6 space-y-4\">\n {filteredInvestments.length > 0 ? (\n filteredInvestments.map((investment) => (\n <div key={investment.id} className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6\">\n {/* Mobile Layout */}\n <div className=\"block space-y-4 lg:hidden\">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">{investment.cartName}</h3>\n <p className=\"text-sm text-text-secondary\">by {investment.cartOwner}</p>\n </div>\n <span\n className={cn(\n 'flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium',\n getStatusColor(investment.status)\n )}\n >\n {getStatusIcon(investment.status)}\n <span className=\"capitalize\">{investment.status}</span>\n </span>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invested</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.investmentAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Current Value</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">P&L</p>\n <p\n className={cn(\n 'font-semibold',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n {investment.profitLoss >= 0 ? '+' : ''}\n {formatCurrency(investment.profitLoss, { minimumFractionDigits: 0 })} (\n {investment.profitLossPercentage >= 0 ? '+' : ''}\n {investment.profitLossPercentage}%)\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">ROI</p>\n <p className=\"font-semibold text-text-primary\">{investment.roiAnnual}% p.a.</p>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between border-t border-border-subtle pt-2\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested on</p>\n <p className=\"text-sm font-medium text-text-primary\">\n {formatDate(investment.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\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 </div>\n\n {/* Desktop Layout */}\n <div className=\"hidden lg:flex lg:items-center lg:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"mb-2 flex items-center justify-between\">\n <h3 className=\"text-lg font-semibold text-text-primary\">{investment.cartName}</h3>\n <span\n className={cn(\n 'flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium',\n getStatusColor(investment.status)\n )}\n >\n {getStatusIcon(investment.status)}\n <span className=\"capitalize\">{investment.status}</span>\n </span>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">by {investment.cartOwner}</p>\n\n <div className=\"grid grid-cols-5 gap-6\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invested</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.investmentAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Current Value</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">P&L</p>\n <p\n className={cn(\n 'font-semibold',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n {investment.profitLoss >= 0 ? '+' : ''}\n {formatCurrency(investment.profitLoss, { minimumFractionDigits: 0 })}\n </p>\n <p\n className={cn(\n 'text-xs',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n ({investment.profitLossPercentage >= 0 ? '+' : ''}\n {investment.profitLossPercentage}%)\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">ROI</p>\n <p className=\"font-semibold text-text-primary\">{investment.roiAnnual}% p.a.</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Invested on</p>\n <p className=\"font-semibold text-text-primary\">\n {formatDate(investment.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\n </div>\n </div>\n </div>\n\n <div className=\"ml-6\">\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 </div>\n </div>\n ))\n ) : (\n <EmptyState\n icon={<TrendingDown className=\"h-12 w-12\" />}\n title={`No ${filter !== 'all' ? filter : ''} investments found`}\n description={\n filter === 'all'\n ? \"You haven't made any investments yet. Start exploring opportunities to grow your wealth.\"\n : `You don't have any ${filter} investments at the moment.`\n }\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n 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\"\n >\n Explore Investment Opportunities\n </button>\n }\n />\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"InvestorInvestmentsPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/investor/InvestorInvestmentsPage.tsx"],"sourcesContent":["/**\n * Investor Investments Page\n * @module subscriberbot/pages/investor\n *\n * MetricsGrid summary cards, filter tabs (all/active/pending/matured) with counts,\n * responsive mobile/desktop layouts, P&L display, ROI display, status icons,\n * empty state.\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport {\n TrendingUp,\n TrendingDown,\n Briefcase,\n Eye,\n BarChart3,\n AlertCircle,\n CheckCircle2,\n Clock,\n Wallet,\n IndianRupee,\n Plus,\n Target,\n} from 'lucide-react';\nimport { PagePurpose, EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatDate } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Investment {\n id: string;\n cartName: string;\n cartOwner: string;\n investmentAmount: number;\n currentValue: number;\n profitLoss: number;\n profitLossPercentage: number;\n investmentDate: string;\n status: 'active' | 'pending' | 'matured' | 'withdrawn';\n roiAnnual: number;\n duration: string;\n nextPayout: string;\n totalReturns: number;\n}\n\ninterface InvestmentSummary {\n totalInvested: number;\n currentValue: number;\n totalReturns: number;\n activeInvestments: number;\n averageRoi: number;\n profitLoss: number;\n profitLossPercentage: number;\n}\n\ntype FilterKey = 'all' | 'active' | 'pending' | 'matured';\n\n// ---------------------------------------------------------------------------\n// Mock data\n// ---------------------------------------------------------------------------\n\nconst mockInvestments: Investment[] = [\n {\n id: 'inv-001',\n cartName: 'South Indian Express',\n cartOwner: 'Raj Kumar',\n investmentAmount: 50000,\n currentValue: 58500,\n profitLoss: 8500,\n profitLossPercentage: 17.0,\n investmentDate: '2024-01-15',\n status: 'active',\n roiAnnual: 22.5,\n duration: '18 months',\n nextPayout: '2024-12-15',\n totalReturns: 8500,\n },\n {\n id: 'inv-002',\n cartName: 'Pizza Corner',\n cartOwner: 'Priya Singh',\n investmentAmount: 75000,\n currentValue: 82000,\n profitLoss: 7000,\n profitLossPercentage: 9.3,\n investmentDate: '2024-03-10',\n status: 'active',\n roiAnnual: 18.0,\n duration: '24 months',\n nextPayout: '2024-12-10',\n totalReturns: 7000,\n },\n {\n id: 'inv-003',\n cartName: 'Healthy Bites',\n cartOwner: 'Amit Patel',\n investmentAmount: 30000,\n currentValue: 31200,\n profitLoss: 1200,\n profitLossPercentage: 4.0,\n investmentDate: '2024-06-01',\n status: 'active',\n roiAnnual: 15.0,\n duration: '12 months',\n nextPayout: '2024-12-01',\n totalReturns: 1200,\n },\n {\n id: 'inv-004',\n cartName: 'Street Food Junction',\n cartOwner: 'Neha Sharma',\n investmentAmount: 40000,\n currentValue: 40000,\n profitLoss: 0,\n profitLossPercentage: 0,\n investmentDate: '2024-08-15',\n status: 'pending',\n roiAnnual: 20.0,\n duration: '15 months',\n nextPayout: '2025-01-15',\n totalReturns: 0,\n },\n {\n id: 'inv-005',\n cartName: 'Biryani House',\n cartOwner: 'Suresh Reddy',\n investmentAmount: 60000,\n currentValue: 72000,\n profitLoss: 12000,\n profitLossPercentage: 20.0,\n investmentDate: '2023-12-01',\n status: 'matured',\n roiAnnual: 25.0,\n duration: '12 months',\n nextPayout: '-',\n totalReturns: 12000,\n },\n];\n\nconst mockSummary: InvestmentSummary = {\n totalInvested: 255000,\n currentValue: 283700,\n totalReturns: 28700,\n activeInvestments: 3,\n averageRoi: 19.6,\n profitLoss: 28700,\n profitLossPercentage: 11.3,\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getStatusColor(status: string): string {\n switch (status) {\n case 'active':\n return 'bg-status-success-bg/20 text-status-success-text';\n case 'pending':\n return 'bg-status-warning-bg/20 text-status-warning-text';\n case 'matured':\n return 'bg-status-info-bg/20 text-status-info-text';\n case 'withdrawn':\n return 'bg-secondary text-secondary-foreground';\n default:\n return 'bg-secondary text-secondary-foreground';\n }\n}\n\nfunction getStatusIcon(status: string) {\n switch (status) {\n case 'active':\n return <CheckCircle2 className=\"h-4 w-4\" />;\n case 'pending':\n return <Clock className=\"h-4 w-4\" />;\n case 'matured':\n return <CheckCircle2 className=\"h-4 w-4\" />;\n default:\n return <AlertCircle className=\"h-4 w-4\" />;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorInvestmentsPage() {\n const { navigateTo } = useSubscriberBot();\n const [isLoading, setIsLoading] = useState(true);\n const [filter, setFilter] = useState<FilterKey>('all');\n\n useEffect(() => {\n const timer = setTimeout(() => setIsLoading(false), 600);\n return () => clearTimeout(timer);\n }, []);\n\n const filteredInvestments = useMemo(() => {\n if (filter === 'all') return mockInvestments;\n return mockInvestments.filter((inv) => inv.status === filter);\n }, [filter]);\n\n const filterTabs: Array<{ key: FilterKey; label: string }> = [\n { key: 'all', label: 'All Investments' },\n { key: 'active', label: 'Active' },\n { key: 'pending', label: 'Pending' },\n { key: 'matured', label: 'Matured' },\n ];\n\n function getCount(key: FilterKey): number {\n if (key === 'all') return mockInvestments.length;\n return mockInvestments.filter((inv) => inv.status === key).length;\n }\n\n if (isLoading) {\n return (\n <PageLayout title=\"My Investments\" description=\"Loading your investments...\">\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 investments...</p>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"My Investments\"\n description=\"Track and manage your investment portfolio\"\n actions={\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 New Investment\n </button>\n }\n >\n <PagePurpose icon={<Briefcase className=\"h-4 w-4\" />} className=\"mb-6\">\n The working list of every investment you hold. Filter by status to focus on\n active, pending or exited positions, and tap any investment to review its\n performance in detail. Use it to keep your portfolio tidy and decide where to add,\n hold or move on.\n </PagePurpose>\n\n {/* Investment Summary — the ONE emphasis zone */}\n <EmphasisPanel className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"up\"\n trendValue=\"Total amount invested\"\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend={mockSummary.profitLoss > 0 ? 'up' : 'down'}\n trendValue={`${mockSummary.profitLossPercentage > 0 ? '+' : ''}${mockSummary.profitLossPercentage}% total returns`}\n />\n <MetricsCard\n icon={<TrendingUp className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.totalReturns, { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n trend=\"up\"\n trendValue=\"Total profit earned\"\n />\n <MetricsCard\n icon={<CheckCircle2 className=\"h-5 w-5\" />}\n value={String(mockSummary.activeInvestments)}\n label=\"Active Investments\"\n trend=\"neutral\"\n trendValue={`${mockSummary.averageRoi}% avg ROI`}\n />\n </EmphasisPanel>\n\n {/* Filter Tabs */}\n <div className=\"mt-6 rounded-lg border border-border-seam bg-bg-surface p-4\">\n <div className=\"flex flex-wrap gap-2\">\n {filterTabs.map((tab) => (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => setFilter(tab.key)}\n className={cn(\n 'flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors',\n filter === tab.key\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary hover:bg-bg-sunken/80'\n )}\n >\n {tab.label}\n <span\n className={cn(\n 'rounded-full px-2 py-0.5 text-xs',\n filter === tab.key\n ? 'bg-primary-foreground/20 text-action-primary-text'\n : 'bg-action-primary-bg/10 text-primary'\n )}\n >\n {getCount(tab.key)}\n </span>\n </button>\n ))}\n </div>\n </div>\n\n {/* Investments List */}\n <div className=\"mt-6 space-y-4\">\n {filteredInvestments.length > 0 ? (\n filteredInvestments.map((investment) => (\n <div\n key={investment.id}\n className=\"rounded-lg border border-border-seam bg-bg-surface p-4 sm:p-6\"\n >\n {/* Mobile Layout */}\n <div className=\"block space-y-4 lg:hidden\">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {investment.cartName}\n </h3>\n <p className=\"text-sm text-text-secondary\">by {investment.cartOwner}</p>\n </div>\n <span\n className={cn(\n 'flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium',\n getStatusColor(investment.status)\n )}\n >\n {getStatusIcon(investment.status)}\n <span className=\"capitalize\">{investment.status}</span>\n </span>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invested</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.investmentAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Current Value</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">P&L</p>\n <p\n className={cn(\n 'font-semibold',\n investment.profitLoss >= 0\n ? 'text-status-success-text'\n : 'text-status-error-text'\n )}\n >\n {investment.profitLoss >= 0 ? '+' : ''}\n {formatCurrency(investment.profitLoss, { minimumFractionDigits: 0 })} (\n {investment.profitLossPercentage >= 0 ? '+' : ''}\n {investment.profitLossPercentage}%)\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">ROI</p>\n <p className=\"font-semibold text-text-primary\">{investment.roiAnnual}% p.a.</p>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between border-t border-border-seam pt-2\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested on</p>\n <p className=\"text-sm font-medium text-text-primary\">\n {formatDate(investment.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\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-seam 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 </div>\n\n {/* Desktop Layout */}\n <div className=\"hidden lg:flex lg:items-center lg:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"mb-2 flex items-center justify-between\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {investment.cartName}\n </h3>\n <span\n className={cn(\n 'flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium',\n getStatusColor(investment.status)\n )}\n >\n {getStatusIcon(investment.status)}\n <span className=\"capitalize\">{investment.status}</span>\n </span>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">by {investment.cartOwner}</p>\n\n <div className=\"grid grid-cols-5 gap-6\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invested</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.investmentAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Current Value</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">P&L</p>\n <p\n className={cn(\n 'font-semibold',\n investment.profitLoss >= 0\n ? 'text-status-success-text'\n : 'text-status-error-text'\n )}\n >\n {investment.profitLoss >= 0 ? '+' : ''}\n {formatCurrency(investment.profitLoss, { minimumFractionDigits: 0 })}\n </p>\n <p\n className={cn(\n 'text-xs',\n investment.profitLoss >= 0\n ? 'text-status-success-text'\n : 'text-status-error-text'\n )}\n >\n ({investment.profitLossPercentage >= 0 ? '+' : ''}\n {investment.profitLossPercentage}%)\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">ROI</p>\n <p className=\"font-semibold text-text-primary\">\n {investment.roiAnnual}% p.a.\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Invested on</p>\n <p className=\"font-semibold text-text-primary\">\n {formatDate(investment.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\n </div>\n </div>\n </div>\n\n <div className=\"ml-6\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-seam 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 </div>\n </div>\n ))\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<TrendingDown className=\"h-12 w-12\" />}\n title={`No ${filter !== 'all' ? filter : ''} investments found`}\n description={\n filter === 'all'\n ? \"You haven't made any investments yet. Start exploring opportunities to grow your wealth.\"\n : `You don't have any ${filter} investments at the moment.`\n }\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n 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\"\n >\n Explore Investment Opportunities\n </button>\n }\n />\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;AAoEA,IAAM,IAAgC;CACpC;EACE,IAAI;EACJ,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,YAAY;EACZ,sBAAsB;EACtB,gBAAgB;EAChB,QAAQ;EACR,WAAW;EACX,UAAU;EACV,YAAY;EACZ,cAAc;EACf;CACD;EACE,IAAI;EACJ,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,YAAY;EACZ,sBAAsB;EACtB,gBAAgB;EAChB,QAAQ;EACR,WAAW;EACX,UAAU;EACV,YAAY;EACZ,cAAc;EACf;CACD;EACE,IAAI;EACJ,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,YAAY;EACZ,sBAAsB;EACtB,gBAAgB;EAChB,QAAQ;EACR,WAAW;EACX,UAAU;EACV,YAAY;EACZ,cAAc;EACf;CACD;EACE,IAAI;EACJ,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,YAAY;EACZ,sBAAsB;EACtB,gBAAgB;EAChB,QAAQ;EACR,WAAW;EACX,UAAU;EACV,YAAY;EACZ,cAAc;EACf;CACD;EACE,IAAI;EACJ,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,YAAY;EACZ,sBAAsB;EACtB,gBAAgB;EAChB,QAAQ;EACR,WAAW;EACX,UAAU;EACV,YAAY;EACZ,cAAc;EACf;CACF,EAEK,IAAiC;CACrC,eAAe;CACf,cAAc;CACd,cAAc;CACd,mBAAmB;CACnB,YAAY;CACZ,YAAY;CACZ,sBAAsB;CACvB;AAMD,SAAS,EAAe,GAAwB;AAC9C,SAAQ,GAAR;EACE,KAAK,SACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,QACE,QAAO;;;AAIb,SAAS,EAAc,GAAgB;AACrC,SAAQ,GAAR;EACE,KAAK,SACH,QAAO,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA;EAC7C,KAAK,UACH,QAAO,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;EACtC,KAAK,UACH,QAAO,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA;EAC7C,QACE,QAAO,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA;;;AAQhD,SAAgB,IAA0B;CACxC,IAAM,EAAE,kBAAe,GAAkB,EACnC,CAAC,GAAW,KAAgB,EAAS,GAAK,EAC1C,CAAC,GAAQ,KAAa,EAAoB,MAAM;AAEtD,SAAgB;EACd,IAAM,IAAQ,iBAAiB,EAAa,GAAM,EAAE,IAAI;AACxD,eAAa,aAAa,EAAM;IAC/B,EAAE,CAAC;CAEN,IAAM,IAAsB,QACtB,MAAW,QAAc,IACtB,EAAgB,QAAQ,MAAQ,EAAI,WAAW,EAAO,EAC5D,CAAC,EAAO,CAAC,EAEN,IAAuD;EAC3D;GAAE,KAAK;GAAO,OAAO;GAAmB;EACxC;GAAE,KAAK;GAAU,OAAO;GAAU;EAClC;GAAE,KAAK;GAAW,OAAO;GAAW;EACpC;GAAE,KAAK;GAAW,OAAO;GAAW;EACrC;CAED,SAAS,EAAS,GAAwB;AAExC,SADI,MAAQ,QAAc,EAAgB,SACnC,EAAgB,QAAQ,MAAQ,EAAI,WAAW,EAAI,CAAC;;AAgB7D,QAbI,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAiB,aAAY;YAC7C,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAK,WAAU,8EAA+E,CAAA,EAC9F,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAA+B,CAAA,CACtE;;GACF,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,0BAA0B;GACpD,WAAU;aAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,iBAErB;;YAXb;GAcE,kBAAC,GAAD;IAAa,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;IAAE,WAAU;cAAO;IAKzD,CAAA;GAGd,kBAAC,GAAD;IAAe,WAAU;cAAzB;KACE,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;MACpC,OAAO,EAAe,EAAY,eAAe,EAAE,uBAAuB,GAAG,CAAC;MAC9E,OAAM;MACN,OAAM;MACN,YAAW;MACX,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA;MACzC,OAAO,EAAe,EAAY,cAAc,EAAE,uBAAuB,GAAG,CAAC;MAC7E,OAAM;MACN,OAAO,EAAY,aAAa,IAAI,OAAO;MAC3C,YAAY,GAAG,EAAY,uBAAuB,IAAI,MAAM,KAAK,EAAY,qBAAqB;MAClG,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA;MACxC,OAAO,EAAe,EAAY,cAAc,EAAE,uBAAuB,GAAG,CAAC;MAC7E,OAAM;MACN,OAAM;MACN,YAAW;MACX,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA;MAC1C,OAAO,OAAO,EAAY,kBAAkB;MAC5C,OAAM;MACN,OAAM;MACN,YAAY,GAAG,EAAY,WAAW;MACtC,CAAA;KACY;;GAGhB,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAW,KAAK,MACf,kBAAC,UAAD;MAEE,MAAK;MACL,eAAe,EAAU,EAAI,IAAI;MACjC,WAAW,EACT,sFACA,MAAW,EAAI,MACX,kDACA,uDACL;gBATH,CAWG,EAAI,OACL,kBAAC,QAAD;OACE,WAAW,EACT,oCACA,MAAW,EAAI,MACX,sDACA,uCACL;iBAEA,EAAS,EAAI,IAAI;OACb,CAAA,CACA;QArBF,EAAI,IAqBF,CACT;KACE,CAAA;IACF,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAoB,SAAS,IAC5B,EAAoB,KAAK,MACvB,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAKE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAW;SACT,CAAA,EACL,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAA2C,OAAI,EAAW,UAAc;WACpE,EAAA,CAAA,EACN,kBAAC,QAAD;SACE,WAAW,EACT,sEACA,EAAe,EAAW,OAAO,CAClC;mBAJH,CAMG,EAAc,EAAW,OAAO,EACjC,kBAAC,QAAD;UAAM,WAAU;oBAAc,EAAW;UAAc,CAAA,CAClD;WACH;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;UAAG,WAAU;oBAA8B;UAAY,CAAA,EACvD,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAe,EAAW,kBAAkB,EAAE,uBAAuB,GAAG,CAAC;UACxE,CAAA,CACA,EAAA,CAAA;SACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;UAAG,WAAU;oBAA8B;UAAiB,CAAA,EAC5D,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAe,EAAW,cAAc,EAAE,uBAAuB,GAAG,CAAC;UACpE,CAAA,CACA,EAAA,CAAA;SACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;UAAG,WAAU;oBAA8B;UAAO,CAAA,EAClD,kBAAC,KAAD;UACE,WAAW,EACT,iBACA,EAAW,cAAc,IACrB,6BACA,yBACL;oBANH;WAQG,EAAW,cAAc,IAAI,MAAM;WACnC,EAAe,EAAW,YAAY,EAAE,uBAAuB,GAAG,CAAC;WAAC;WACpE,EAAW,wBAAwB,IAAI,MAAM;WAC7C,EAAW;WAAqB;WAC/B;YACA,EAAA,CAAA;SACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;UAAG,WAAU;oBAA8B;UAAO,CAAA,EAClD,kBAAC,KAAD;UAAG,WAAU;oBAAb,CAAgD,EAAW,WAAU,SAAU;YAC3E,EAAA,CAAA;SACF;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAe,CAAA,EAC1D,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAW,EAAW,gBAAgB;UACrC,MAAM,KAAA;UACN,QAAQ,KAAA;UACT,CAAC;SACA,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAW,yBAAyB,EAAW,KAAK;SACnE,WAAU;mBAHZ,CAKE,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA,EAAA,eAEpB;WACL;;OACF;SAGN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAW;UACT,CAAA,EACL,kBAAC,QAAD;UACE,WAAW,EACT,sEACA,EAAe,EAAW,OAAO,CAClC;oBAJH,CAMG,EAAc,EAAW,OAAO,EACjC,kBAAC,QAAD;WAAM,WAAU;qBAAc,EAAW;WAAc,CAAA,CAClD;YACH;;QACN,kBAAC,KAAD;SAAG,WAAU;mBAAb,CAAgD,OAAI,EAAW,UAAc;;QAE7E,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;WAAG,WAAU;qBAA8B;WAAY,CAAA,EACvD,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAe,EAAW,kBAAkB,EAAE,uBAAuB,GAAG,CAAC;WACxE,CAAA,CACA,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;WAAG,WAAU;qBAA8B;WAAiB,CAAA,EAC5D,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAe,EAAW,cAAc,EAAE,uBAAuB,GAAG,CAAC;WACpE,CAAA,CACA,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA;WACE,kBAAC,KAAD;YAAG,WAAU;sBAA8B;YAAO,CAAA;WAClD,kBAAC,KAAD;YACE,WAAW,EACT,iBACA,EAAW,cAAc,IACrB,6BACA,yBACL;sBANH,CAQG,EAAW,cAAc,IAAI,MAAM,IACnC,EAAe,EAAW,YAAY,EAAE,uBAAuB,GAAG,CAAC,CAClE;;WACJ,kBAAC,KAAD;YACE,WAAW,EACT,WACA,EAAW,cAAc,IACrB,6BACA,yBACL;sBANH;aAOC;aACG,EAAW,wBAAwB,IAAI,MAAM;aAC9C,EAAW;aAAqB;aAC/B;;WACA,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;WAAG,WAAU;qBAA8B;WAAO,CAAA,EAClD,kBAAC,KAAD;WAAG,WAAU;qBAAb,CACG,EAAW,WAAU,SACpB;aACA,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;WAAG,WAAU;qBAA8B;WAAe,CAAA,EAC1D,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAW,EAAW,gBAAgB;YACrC,MAAM,KAAA;YACN,QAAQ,KAAA;YACT,CAAC;WACA,CAAA,CACA,EAAA,CAAA;UACF;;QACF;UAEN,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAW,yBAAyB,EAAW,KAAK;QACnE,WAAU;kBAHZ,CAKE,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA,EAAA,eAEpB;;OACL,CAAA,CACF;QACF;OArKC,EAAW,GAqKZ,CACN,GAEF,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAc,WAAU,aAAc,CAAA;KAC5C,OAAO,MAAM,MAAW,QAAiB,KAAT,EAAY;KAC5C,aACE,MAAW,QACP,6FACA,sBAAsB,EAAO;KAEnC,QACE,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAW,0BAA0B;MACpD,WAAU;gBACX;MAEQ,CAAA;KAEX,CAAA;IAEA,CAAA;GACK"}
@@ -6,8 +6,9 @@ import { formatCurrency as i, formatDate as a } from "../../utils/formatters.js"
6
6
  import { useCallback as o, useMemo as s, useState as c } from "react";
7
7
  import { ArrowDownCircle as l, BarChart3 as u, Briefcase as d, CreditCard as f, Eye as p, IndianRupee as m, Star as h, TrendingDown as g, TrendingUp as _, Wallet as v } from "lucide-react";
8
8
  import { jsx as y, jsxs as b } from "react/jsx-runtime";
9
+ import { EmphasisPanel as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
9
10
  //#region src/subscriberbot/pages/investor/InvestorPortfolioPage.tsx
10
- var x = [
11
+ var C = [
11
12
  {
12
13
  id: "inv-001",
13
14
  cartId: "SERV-001",
@@ -104,7 +105,7 @@ var x = [
104
105
  growthRate: 5
105
106
  }
106
107
  }
107
- ], S = [
108
+ ], w = [
108
109
  {
109
110
  id: "txn-001",
110
111
  type: "investment",
@@ -145,25 +146,25 @@ var x = [
145
146
  date: "2024-06-01",
146
147
  status: "pending"
147
148
  }
148
- ], C = [
149
+ ], T = [
149
150
  "",
150
151
  "Personal Care & Beauty",
151
152
  "Repair & Maintenance",
152
153
  "Home Services",
153
154
  "Food & Beverage"
154
155
  ];
155
- function w(e) {
156
+ function E(e) {
156
157
  let { color: n, label: r } = {
157
158
  low: {
158
- color: "bg-green-500/20 text-green-600 dark:text-green-400",
159
+ color: "bg-status-success-bg/20 text-status-success-text",
159
160
  label: "Low Risk"
160
161
  },
161
162
  medium: {
162
- color: "bg-yellow-500/20 text-yellow-600 dark:text-yellow-400",
163
+ color: "bg-status-warning-bg/20 text-status-warning-text",
163
164
  label: "Medium Risk"
164
165
  },
165
166
  high: {
166
- color: "bg-red-500/20 text-red-600 dark:text-red-400",
167
+ color: "bg-status-error-bg/20 text-status-error-text",
167
168
  label: "High Risk"
168
169
  }
169
170
  }[e];
@@ -172,51 +173,56 @@ function w(e) {
172
173
  children: r
173
174
  });
174
175
  }
175
- function T(e) {
176
+ function D(e) {
176
177
  return `${e > 0 ? "+" : ""}${e.toFixed(1)}%`;
177
178
  }
178
- function E() {
179
- let { navigateTo: E } = e(), [D, O] = c("overview"), [k, A] = c(""), j = s(() => k ? x.filter((e) => e.category === k) : x, [k]), M = j.reduce((e, t) => e + t.amount, 0), N = j.reduce((e, t) => e + t.currentValue, 0), P = N - M, F = M > 0 ? P / M * 100 : 0, I = j.reduce((e, t) => e + t.monthlyDividend, 0), L = j.filter((e) => e.status === "active").length, R = {
179
+ function O() {
180
+ let { navigateTo: O } = e(), [k, A] = c("overview"), [j, M] = c(""), N = s(() => j ? C.filter((e) => e.category === j) : C, [j]), P = N.reduce((e, t) => e + t.amount, 0), F = N.reduce((e, t) => e + t.currentValue, 0), I = F - P, L = P > 0 ? I / P * 100 : 0, R = N.reduce((e, t) => e + t.monthlyDividend, 0), z = N.filter((e) => e.status === "active").length, B = {
180
181
  low: 1,
181
182
  medium: 2,
182
183
  high: 3
183
- }, z = j.length > 0 ? j.reduce((e, t) => e + R[t.riskLevel], 0) / j.length : 0, B = j.reduce((e, t) => t.returnsPercentage > e.returnsPercentage ? t : e, j[0] || {
184
+ }, V = N.length > 0 ? N.reduce((e, t) => e + B[t.riskLevel], 0) / N.length : 0, H = N.reduce((e, t) => t.returnsPercentage > e.returnsPercentage ? t : e, N[0] || {
184
185
  cartName: "",
185
186
  returnsPercentage: 0
186
- }), V = o((e) => {
187
+ }), U = o((e) => {
187
188
  alert(`Withdrawal request submitted for ${e}`);
188
- }, []), H = j.reduce((e, t) => (e[t.category] = (e[t.category] || 0) + t.currentValue, e), {});
189
+ }, []), W = N.reduce((e, t) => (e[t.category] = (e[t.category] || 0) + t.currentValue, e), {});
189
190
  return /* @__PURE__ */ b(n, {
190
191
  title: "My Portfolio",
191
192
  description: "Track your investment performance and holdings",
192
193
  children: [
193
- /* @__PURE__ */ b("div", {
194
+ /* @__PURE__ */ y(S, {
195
+ icon: /* @__PURE__ */ y(d, { className: "h-4 w-4" }),
196
+ className: "mb-6",
197
+ children: "The full picture of everything you've invested in. See how much you've put in, what it's worth now, the returns you've earned, and your monthly dividend income. Drill into any holding to review its performance, and use these numbers to decide whether to top up, hold or diversify."
198
+ }),
199
+ /* @__PURE__ */ b(x, {
194
200
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
195
201
  children: [
196
202
  /* @__PURE__ */ y(r, {
197
203
  icon: /* @__PURE__ */ y(v, { className: "h-5 w-5" }),
198
- value: i(M, { minimumFractionDigits: 0 }),
204
+ value: i(P, { minimumFractionDigits: 0 }),
199
205
  label: "Total Invested",
200
206
  trend: "up",
201
- trendValue: `${L} active`
207
+ trendValue: `${z} active`
202
208
  }),
203
209
  /* @__PURE__ */ y(r, {
204
210
  icon: /* @__PURE__ */ y(m, { className: "h-5 w-5" }),
205
- value: i(N, { minimumFractionDigits: 0 }),
211
+ value: i(F, { minimumFractionDigits: 0 }),
206
212
  label: "Current Value",
207
- trend: F > 0 ? "up" : "down",
208
- trendValue: T(F)
213
+ trend: L > 0 ? "up" : "down",
214
+ trendValue: D(L)
209
215
  }),
210
216
  /* @__PURE__ */ y(r, {
211
217
  icon: /* @__PURE__ */ y(_, { className: "h-5 w-5" }),
212
- value: i(Math.abs(P), { minimumFractionDigits: 0 }),
218
+ value: i(Math.abs(I), { minimumFractionDigits: 0 }),
213
219
  label: "Total Returns",
214
- trend: P >= 0 ? "up" : "down",
215
- trendValue: T(F)
220
+ trend: I >= 0 ? "up" : "down",
221
+ trendValue: D(L)
216
222
  }),
217
223
  /* @__PURE__ */ y(r, {
218
224
  icon: /* @__PURE__ */ y(d, { className: "h-5 w-5" }),
219
- value: i(I, { minimumFractionDigits: 0 }),
225
+ value: i(R, { minimumFractionDigits: 0 }),
220
226
  label: "Monthly Dividend",
221
227
  trend: "up",
222
228
  trendValue: "Next: July 1"
@@ -227,17 +233,17 @@ function E() {
227
233
  className: "mt-4 grid grid-cols-2 gap-3 lg:grid-cols-4",
228
234
  children: [
229
235
  /* @__PURE__ */ b("div", {
230
- className: "rounded-lg border border-border-subtle bg-bg-surface p-3",
236
+ className: "rounded-lg border border-border-seam bg-bg-surface p-3",
231
237
  children: [/* @__PURE__ */ y("p", {
232
238
  className: "text-xs text-text-secondary",
233
239
  children: "Active Investments"
234
240
  }), /* @__PURE__ */ y("p", {
235
241
  className: "text-xl font-bold text-text-primary",
236
- children: L
242
+ children: z
237
243
  })]
238
244
  }),
239
245
  /* @__PURE__ */ b("div", {
240
- className: "rounded-lg border border-border-subtle bg-bg-surface p-3",
246
+ className: "rounded-lg border border-border-seam bg-bg-surface p-3",
241
247
  children: [/* @__PURE__ */ y("p", {
242
248
  className: "text-xs text-text-secondary",
243
249
  children: "Avg Risk Score"
@@ -246,17 +252,17 @@ function E() {
246
252
  children: [/* @__PURE__ */ y("div", {
247
253
  className: "h-2 flex-1 rounded-full bg-bg-sunken overflow-hidden",
248
254
  children: /* @__PURE__ */ y("div", {
249
- className: t("h-full rounded-full", z <= 1.5 ? "bg-green-500" : z <= 2.5 ? "bg-yellow-500" : "bg-red-500"),
250
- style: { width: `${z / 3 * 100}%` }
255
+ className: t("h-full rounded-full", V <= 1.5 ? "bg-status-success-text" : V <= 2.5 ? "bg-status-warning-text" : "bg-status-error-text"),
256
+ style: { width: `${V / 3 * 100}%` }
251
257
  })
252
258
  }), /* @__PURE__ */ b("span", {
253
259
  className: "text-sm font-medium text-text-primary",
254
- children: [z.toFixed(1), "/3"]
260
+ children: [V.toFixed(1), "/3"]
255
261
  })]
256
262
  })]
257
263
  }),
258
264
  /* @__PURE__ */ b("div", {
259
- className: "rounded-lg border border-border-subtle bg-bg-surface p-3",
265
+ className: "rounded-lg border border-border-seam bg-bg-surface p-3",
260
266
  children: [
261
267
  /* @__PURE__ */ y("p", {
262
268
  className: "text-xs text-text-secondary",
@@ -264,16 +270,16 @@ function E() {
264
270
  }),
265
271
  /* @__PURE__ */ y("p", {
266
272
  className: "truncate text-sm font-bold text-text-primary",
267
- children: B.cartName
273
+ children: H.cartName
268
274
  }),
269
275
  /* @__PURE__ */ y("p", {
270
- className: "text-xs text-green-600 dark:text-green-400",
271
- children: T(B.returnsPercentage)
276
+ className: "text-xs text-status-success-text",
277
+ children: D(H.returnsPercentage)
272
278
  })
273
279
  ]
274
280
  }),
275
281
  /* @__PURE__ */ b("div", {
276
- className: "rounded-lg border border-border-subtle bg-bg-surface p-3",
282
+ className: "rounded-lg border border-border-seam bg-bg-surface p-3",
277
283
  children: [
278
284
  /* @__PURE__ */ y("p", {
279
285
  className: "text-xs text-text-secondary",
@@ -292,9 +298,9 @@ function E() {
292
298
  ]
293
299
  }),
294
300
  /* @__PURE__ */ b("div", {
295
- className: "mt-6 rounded-lg border border-border-subtle bg-bg-surface shadow-sm",
301
+ className: "mt-6 rounded-lg border border-border-seam bg-bg-surface shadow-sm",
296
302
  children: [/* @__PURE__ */ y("div", {
297
- className: "flex border-b border-border-subtle overflow-x-auto",
303
+ className: "flex border-b border-border-seam overflow-x-auto",
298
304
  children: [
299
305
  {
300
306
  key: "overview",
@@ -303,7 +309,7 @@ function E() {
303
309
  },
304
310
  {
305
311
  key: "investments",
306
- label: `Investments (${j.length})`,
312
+ label: `Investments (${N.length})`,
307
313
  Icon: d
308
314
  },
309
315
  {
@@ -313,20 +319,20 @@ function E() {
313
319
  }
314
320
  ].map(({ key: e, label: n, Icon: r }) => /* @__PURE__ */ b("button", {
315
321
  type: "button",
316
- onClick: () => O(e),
317
- className: t("flex items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium transition-colors", D === e ? "border-b-2 border-primary text-text-primary" : "text-text-secondary hover:text-text-primary"),
322
+ onClick: () => A(e),
323
+ className: t("flex items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium transition-colors", k === e ? "border-b-2 border-primary text-text-primary" : "text-text-secondary hover:text-text-primary"),
318
324
  children: [/* @__PURE__ */ y(r, { className: "h-4 w-4" }), n]
319
325
  }, e))
320
326
  }), /* @__PURE__ */ b("div", {
321
327
  className: "p-4",
322
328
  children: [
323
- D === "overview" && /* @__PURE__ */ b("div", {
329
+ k === "overview" && /* @__PURE__ */ b("div", {
324
330
  className: "space-y-6",
325
331
  children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("h3", {
326
332
  className: "mb-4 text-base font-semibold text-text-primary",
327
333
  children: "Portfolio Performance"
328
334
  }), /* @__PURE__ */ b("div", {
329
- className: "rounded-lg border border-border-subtle bg-bg-sunken/50 p-8 text-center",
335
+ className: "rounded-lg border border-border-seam bg-bg-sunken/50 p-8 text-center",
330
336
  children: [
331
337
  /* @__PURE__ */ y(u, { className: "mx-auto mb-2 h-8 w-8 text-text-secondary/50" }),
332
338
  /* @__PURE__ */ y("p", {
@@ -343,7 +349,7 @@ function E() {
343
349
  children: "Asset Allocation"
344
350
  }), /* @__PURE__ */ y("div", {
345
351
  className: "space-y-3",
346
- children: Object.entries(H).map(([e, t]) => /* @__PURE__ */ b("div", {
352
+ children: Object.entries(W).map(([e, t]) => /* @__PURE__ */ b("div", {
347
353
  className: "flex items-center",
348
354
  children: [
349
355
  /* @__PURE__ */ y("span", {
@@ -354,10 +360,10 @@ function E() {
354
360
  className: "mx-3 h-6 flex-1 rounded-full bg-bg-sunken overflow-hidden",
355
361
  children: /* @__PURE__ */ y("div", {
356
362
  className: "flex h-6 items-center justify-end rounded-full bg-action-primary-bg pr-2",
357
- style: { width: `${N > 0 ? t / N * 100 : 0}%` },
363
+ style: { width: `${F > 0 ? t / F * 100 : 0}%` },
358
364
  children: /* @__PURE__ */ b("span", {
359
365
  className: "text-xs font-medium text-action-primary-text",
360
- children: [N > 0 ? (t / N * 100).toFixed(1) : 0, "%"]
366
+ children: [F > 0 ? (t / F * 100).toFixed(1) : 0, "%"]
361
367
  })
362
368
  })
363
369
  }),
@@ -369,24 +375,24 @@ function E() {
369
375
  }, e))
370
376
  })] })]
371
377
  }),
372
- D === "investments" && /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("div", {
378
+ k === "investments" && /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("div", {
373
379
  className: "mb-4",
374
380
  children: /* @__PURE__ */ b("select", {
375
- value: k,
376
- onChange: (e) => A(e.target.value),
377
- className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
381
+ value: j,
382
+ onChange: (e) => M(e.target.value),
383
+ className: "rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
378
384
  children: [/* @__PURE__ */ y("option", {
379
385
  value: "",
380
386
  children: "All Categories"
381
- }), C.filter(Boolean).map((e) => /* @__PURE__ */ y("option", {
387
+ }), T.filter(Boolean).map((e) => /* @__PURE__ */ y("option", {
382
388
  value: e,
383
389
  children: e
384
390
  }, e))]
385
391
  })
386
392
  }), /* @__PURE__ */ y("div", {
387
393
  className: "space-y-4",
388
- children: j.map((e) => /* @__PURE__ */ b("div", {
389
- className: "rounded-lg border border-border-subtle p-4 hover:bg-accent/50 transition-colors",
394
+ children: N.map((e) => /* @__PURE__ */ b("div", {
395
+ className: "rounded-lg border border-border-seam p-4 hover:bg-accent/50 transition-colors",
390
396
  children: [
391
397
  /* @__PURE__ */ b("div", {
392
398
  className: "mb-4 flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",
@@ -411,7 +417,7 @@ function E() {
411
417
  children: [/* @__PURE__ */ y("span", {
412
418
  className: "text-sm text-text-secondary",
413
419
  children: e.category
414
- }), w(e.riskLevel)]
420
+ }), E(e.riskLevel)]
415
421
  })
416
422
  ]
417
423
  }), /* @__PURE__ */ b("div", {
@@ -420,11 +426,11 @@ function E() {
420
426
  className: "text-xl font-bold text-text-primary",
421
427
  children: i(e.currentValue, { minimumFractionDigits: 0 })
422
428
  }), /* @__PURE__ */ b("p", {
423
- className: t("text-sm", e.returns > 0 ? "text-green-600 dark:text-green-400" : "text-red-600 dark:text-red-400"),
429
+ className: t("text-sm", e.returns > 0 ? "text-status-success-text" : "text-status-error-text"),
424
430
  children: [
425
431
  i(Math.abs(e.returns), { minimumFractionDigits: 0 }),
426
432
  " (",
427
- T(e.returnsPercentage),
433
+ D(e.returnsPercentage),
428
434
  ")"
429
435
  ]
430
436
  })]
@@ -467,7 +473,7 @@ function E() {
467
473
  ]
468
474
  }),
469
475
  /* @__PURE__ */ b("div", {
470
- className: "border-t border-border-subtle pt-4",
476
+ className: "border-t border-border-seam pt-4",
471
477
  children: [/* @__PURE__ */ y("p", {
472
478
  className: "mb-2 text-sm font-medium text-text-secondary",
473
479
  children: "Performance Metrics"
@@ -483,7 +489,7 @@ function E() {
483
489
  })] }),
484
490
  /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ b("div", {
485
491
  className: "flex items-center justify-center gap-1",
486
- children: [/* @__PURE__ */ y(h, { className: "h-4 w-4 fill-yellow-400 text-yellow-400" }), /* @__PURE__ */ y("p", {
492
+ children: [/* @__PURE__ */ y(h, { className: "h-4 w-4 fill-status-warning-text text-status-warning-text" }), /* @__PURE__ */ y("p", {
487
493
  className: "text-lg font-bold text-text-primary",
488
494
  children: e.performanceMetrics.averageRating
489
495
  })]
@@ -492,7 +498,7 @@ function E() {
492
498
  children: "Rating"
493
499
  })] }),
494
500
  /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ b("p", {
495
- className: "text-lg font-bold text-green-600 dark:text-green-400",
501
+ className: "text-lg font-bold text-status-success-text",
496
502
  children: [
497
503
  "+",
498
504
  e.performanceMetrics.growthRate,
@@ -509,28 +515,28 @@ function E() {
509
515
  className: "mt-4 flex flex-wrap gap-2",
510
516
  children: [/* @__PURE__ */ b("button", {
511
517
  type: "button",
512
- onClick: () => E(`/investor/investments/${e.id}`),
513
- 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",
518
+ onClick: () => O(`/investor/investments/${e.id}`),
519
+ className: "flex items-center gap-2 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors",
514
520
  children: [/* @__PURE__ */ y(p, { className: "h-4 w-4" }), "View Details"]
515
521
  }), e.status === "active" && /* @__PURE__ */ b("button", {
516
522
  type: "button",
517
- onClick: () => V(e.id),
518
- 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",
523
+ onClick: () => U(e.id),
524
+ className: "flex items-center gap-2 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors",
519
525
  children: [/* @__PURE__ */ y(l, { className: "h-4 w-4" }), "Withdraw"]
520
526
  })]
521
527
  })
522
528
  ]
523
529
  }, e.id))
524
530
  })] }),
525
- D === "transactions" && /* @__PURE__ */ y("div", {
531
+ k === "transactions" && /* @__PURE__ */ y("div", {
526
532
  className: "space-y-3",
527
- children: S.map((e) => /* @__PURE__ */ b("div", {
528
- className: "flex flex-col gap-3 rounded-lg border border-border-subtle p-4 hover:bg-accent/50 transition-colors sm:flex-row sm:items-center sm:justify-between",
533
+ children: w.map((e) => /* @__PURE__ */ b("div", {
534
+ className: "flex flex-col gap-3 rounded-lg border border-border-seam p-4 hover:bg-accent/50 transition-colors sm:flex-row sm:items-center sm:justify-between",
529
535
  children: [/* @__PURE__ */ b("div", {
530
536
  className: "flex items-center gap-3",
531
537
  children: [/* @__PURE__ */ y("div", {
532
- className: t("flex h-10 w-10 shrink-0 items-center justify-center rounded-full", e.type === "investment" ? "bg-blue-500/10" : e.type === "dividend" ? "bg-green-500/10" : "bg-red-500/10"),
533
- children: e.type === "investment" ? /* @__PURE__ */ y(v, { className: "h-5 w-5 text-blue-600 dark:text-blue-400" }) : e.type === "dividend" ? /* @__PURE__ */ y(_, { className: "h-5 w-5 text-green-600 dark:text-green-400" }) : /* @__PURE__ */ y(g, { className: "h-5 w-5 text-red-600 dark:text-red-400" })
538
+ className: t("flex h-10 w-10 shrink-0 items-center justify-center rounded-full", e.type === "investment" ? "bg-status-info-bg/10" : e.type === "dividend" ? "bg-status-success-bg/10" : "bg-status-error-bg/10"),
539
+ children: e.type === "investment" ? /* @__PURE__ */ y(v, { className: "h-5 w-5 text-status-info-text" }) : e.type === "dividend" ? /* @__PURE__ */ y(_, { className: "h-5 w-5 text-status-success-text" }) : /* @__PURE__ */ y(g, { className: "h-5 w-5 text-status-error-text" })
534
540
  }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ b("p", {
535
541
  className: "text-sm font-medium text-text-primary",
536
542
  children: [
@@ -548,10 +554,10 @@ function E() {
548
554
  }), /* @__PURE__ */ b("div", {
549
555
  className: "flex items-center justify-between sm:gap-4",
550
556
  children: [/* @__PURE__ */ b("p", {
551
- className: t("text-sm font-bold", e.type === "dividend" ? "text-green-600 dark:text-green-400" : "text-text-primary"),
557
+ className: t("text-sm font-bold", e.type === "dividend" ? "text-status-success-text" : "text-text-primary"),
552
558
  children: [e.type === "dividend" ? "+" : "-", i(e.amount, { minimumFractionDigits: 0 })]
553
559
  }), /* @__PURE__ */ y("span", {
554
- className: t("rounded-full px-2.5 py-0.5 text-xs font-medium", e.status === "completed" ? "bg-green-500/20 text-green-600 dark:text-green-400" : e.status === "pending" ? "bg-yellow-500/20 text-yellow-600 dark:text-yellow-400" : "bg-red-500/20 text-red-600 dark:text-red-400"),
560
+ className: t("rounded-full px-2.5 py-0.5 text-xs font-medium", e.status === "completed" ? "bg-status-success-bg/20 text-status-success-text" : e.status === "pending" ? "bg-status-warning-bg/20 text-status-warning-text" : "bg-status-error-bg/20 text-status-error-text"),
555
561
  children: e.status
556
562
  })]
557
563
  })]
@@ -564,6 +570,6 @@ function E() {
564
570
  });
565
571
  }
566
572
  //#endregion
567
- export { E as InvestorPortfolioPage };
573
+ export { O as InvestorPortfolioPage };
568
574
 
569
575
  //# sourceMappingURL=InvestorPortfolioPage.js.map