@burdenoff/microfe-kadaikodi 2026.704.4 → 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 (126) hide show
  1. package/dist/kadaikodi/KadaikodiRoutes.js +30 -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 +18 -10
  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/CartManagementPage.js +558 -718
  65. package/dist/kadaikodi/pages/admin/CartManagementPage.js.map +1 -1
  66. package/dist/kadaikodi/pages/admin/UserManagementPage.js.map +1 -1
  67. package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js +142 -55
  68. package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
  69. package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js +129 -164
  70. package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
  71. package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js +379 -361
  72. package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js.map +1 -1
  73. package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js +266 -166
  74. package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js.map +1 -1
  75. package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js +373 -0
  76. package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js.map +1 -0
  77. package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js +288 -161
  78. package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js.map +1 -1
  79. package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js +180 -181
  80. package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js.map +1 -1
  81. package/dist/kadaikodi/pages/common/HelpSupportPage.js.map +1 -1
  82. package/dist/kadaikodi/pages/common/SettingsPage.js.map +1 -1
  83. package/dist/kadaikodi/pages/customer/BookingDetailsPage.js +17 -34
  84. package/dist/kadaikodi/pages/customer/BookingDetailsPage.js.map +1 -1
  85. package/dist/kadaikodi/pages/customer/CartDetailPage.js +405 -248
  86. package/dist/kadaikodi/pages/customer/CartDetailPage.js.map +1 -1
  87. package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js +258 -232
  88. package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js.map +1 -1
  89. package/dist/kadaikodi/pages/customer/CheckoutPage.js +254 -205
  90. package/dist/kadaikodi/pages/customer/CheckoutPage.js.map +1 -1
  91. package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js +270 -230
  92. package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js.map +1 -1
  93. package/dist/kadaikodi/pages/customer/FavoritesPage.js +149 -412
  94. package/dist/kadaikodi/pages/customer/FavoritesPage.js.map +1 -1
  95. package/dist/kadaikodi/pages/customer/OrderHistoryPage.js +173 -134
  96. package/dist/kadaikodi/pages/customer/OrderHistoryPage.js.map +1 -1
  97. package/dist/kadaikodi/pages/customer/OrderTrackingPage.js +176 -175
  98. package/dist/kadaikodi/pages/customer/OrderTrackingPage.js.map +1 -1
  99. package/dist/kadaikodi/pages/customer/ReviewsPage.js +295 -438
  100. package/dist/kadaikodi/pages/customer/ReviewsPage.js.map +1 -1
  101. package/dist/kadaikodi/pages/customer/shared.js +181 -0
  102. package/dist/kadaikodi/pages/customer/shared.js.map +1 -0
  103. package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js +438 -311
  104. package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js.map +1 -1
  105. package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js +320 -293
  106. package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
  107. package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js +159 -91
  108. package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js.map +1 -1
  109. package/dist/kadaikodi/pages/investor/InvestorDashboard.js +137 -107
  110. package/dist/kadaikodi/pages/investor/InvestorDashboard.js.map +1 -1
  111. package/dist/kadaikodi/pages/investor/InvestorInvestmentsPage.js +157 -135
  112. package/dist/kadaikodi/pages/investor/InvestorInvestmentsPage.js.map +1 -1
  113. package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js +280 -206
  114. package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js.map +1 -1
  115. package/dist/kadaikodi/pages/investor/InvestorProfilePage.js.map +1 -1
  116. package/dist/kadaikodi/pages/worker/TaskDetailsPage.js +424 -448
  117. package/dist/kadaikodi/pages/worker/TaskDetailsPage.js.map +1 -1
  118. package/dist/kadaikodi/pages/worker/WorkerDashboard.js +328 -445
  119. package/dist/kadaikodi/pages/worker/WorkerDashboard.js.map +1 -1
  120. package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js +141 -164
  121. package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js.map +1 -1
  122. package/dist/kadaikodi/pages/worker/WorkerProfilePage.js +300 -296
  123. package/dist/kadaikodi/pages/worker/WorkerProfilePage.js.map +1 -1
  124. package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js +284 -309
  125. package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js.map +1 -1
  126. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InvestorPortfolioPage.js","names":[],"sources":["../../../../src/kadaikodi/pages/investor/InvestorPortfolioPage.tsx"],"sourcesContent":["/**\n * Investor Portfolio Page\n * @module kadaikodi/pages/investor\n *\n * Portfolio summary cards, 3-tab UI (overview / investments / transactions),\n * per-cart allocation bars and holdings list. All figures are derived from the\n * investor's real holdings (useInvestments) — no fabricated data.\n */\n\nimport { useMemo, useState } from 'react';\nimport {\n Wallet,\n TrendingUp,\n Briefcase,\n IndianRupee,\n Eye,\n BarChart3,\n CreditCard,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useInvestments } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatDate } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction fmtPct(value: number) {\n return `${value > 0 ? '+' : ''}${value.toFixed(1)}%`;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorPortfolioPage() {\n const { navigateTo, currentUser } = useKadaikodi();\n const { data: investments = [], isLoading } = useInvestments(currentUser?.id || '');\n const [activeTab, setActiveTab] = useState<'overview' | 'investments' | 'transactions'>(\n 'overview'\n );\n\n const totalInvested = investments.reduce((s, i) => s + i.investedAmount, 0);\n const currentValue = investments.reduce((s, i) => s + i.currentValue, 0);\n const totalReturns = currentValue - totalInvested;\n const returnsPercentage = totalInvested > 0 ? (totalReturns / totalInvested) * 100 : 0;\n const activeCount = investments.filter((i) => i.status === 'active').length;\n\n // Allocation by cart — derived purely from the real holdings' current value.\n const allocationMap = useMemo(\n () =>\n investments.reduce<Record<string, number>>((acc, inv) => {\n acc[inv.cartName] = (acc[inv.cartName] || 0) + inv.currentValue;\n return acc;\n }, {}),\n [investments]\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"My Portfolio\" 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 title=\"My Portfolio\" description=\"Track your investment performance and holdings\">\n <PagePurpose className=\"mb-6\">\n The complete picture of your money on Kadaikodi. Use this page to see how your portfolio is\n performing overall, how it&apos;s split across the carts you&apos;ve backed, and the details\n of each holding. Switch tabs to drill into your holdings, and open any holding to review it.\n </PagePurpose>\n\n {/* Summary Cards — the one emphasis zone for this page */}\n <EmphasisPanel>\n <h2 className=\"mb-4 text-base font-semibold text-text-primary\">Portfolio at a Glance</h2>\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(totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"neutral\"\n trendValue={`${activeCount} active`}\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend={returnsPercentage >= 0 ? 'up' : 'down'}\n trendValue={fmtPct(returnsPercentage)}\n />\n <MetricsCard\n icon={<TrendingUp className=\"h-5 w-5\" />}\n value={formatCurrency(Math.abs(totalReturns), { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n trend={totalReturns >= 0 ? 'up' : 'down'}\n trendValue={fmtPct(returnsPercentage)}\n />\n <MetricsCard\n icon={<Briefcase className=\"h-5 w-5\" />}\n value={String(investments.length)}\n label=\"Holdings\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Tabs */}\n <div className=\"mt-6 rounded-lg border border-border-subtle bg-bg-surface shadow-sm\">\n <div className=\"flex border-b border-border-subtle overflow-x-auto\">\n {(\n [\n { key: 'overview', label: 'Overview', Icon: BarChart3 },\n {\n key: 'investments',\n label: `Investments (${investments.length})`,\n Icon: Briefcase,\n },\n { key: 'transactions', label: 'Transactions', Icon: CreditCard },\n ] as const\n ).map(({ key, label, Icon }) => (\n <button\n key={key}\n type=\"button\"\n onClick={() => setActiveTab(key)}\n className={cn(\n 'flex items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium transition-colors',\n activeTab === key\n ? 'border-b-2 border-primary text-text-primary'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n <Icon className=\"h-4 w-4\" />\n {label}\n </button>\n ))}\n </div>\n\n <div className=\"p-4\">\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"space-y-6\">\n {investments.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No holdings yet\"\n description=\"Once you back a cart, your portfolio allocation will appear here.\"\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 Browse Opportunities\n </button>\n }\n />\n ) : (\n <div>\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">\n Allocation by Cart\n </h3>\n <div className=\"space-y-3\">\n {Object.entries(allocationMap).map(([cartName, value]) => (\n <div key={cartName} className=\"flex items-center\">\n <span className=\"w-40 truncate text-sm text-text-primary\">{cartName}</span>\n <div className=\"mx-3 h-6 flex-1 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className=\"flex h-6 items-center justify-end rounded-full bg-action-primary-bg pr-2\"\n style={{\n width: `${currentValue > 0 ? (value / currentValue) * 100 : 0}%`,\n }}\n >\n <span className=\"text-xs font-medium text-action-primary-text\">\n {currentValue > 0 ? ((value / currentValue) * 100).toFixed(1) : 0}%\n </span>\n </div>\n </div>\n <span className=\"ml-2 text-sm font-medium text-text-primary\">\n {formatCurrency(value, { minimumFractionDigits: 0 })}\n </span>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Investments Tab */}\n {activeTab === 'investments' && (\n <div>\n {investments.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No holdings to show\"\n description=\"You don't hold any investments yet. Explore opportunities to start building your portfolio.\"\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 Browse Opportunities\n </button>\n }\n />\n ) : (\n <div className=\"space-y-4\">\n {investments.map((inv) => {\n const pl = inv.currentValue - inv.investedAmount;\n const plPct = inv.investedAmount > 0 ? (pl / inv.investedAmount) * 100 : 0;\n return (\n <div\n key={inv.id}\n className=\"rounded-lg border border-border-subtle p-4 hover:bg-accent/50 transition-colors\"\n >\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex-1\">\n <h4 className=\"text-base font-semibold text-text-primary\">\n {inv.cartName}\n </h4>\n <p className=\"mt-1 text-sm capitalize text-text-secondary\">\n {inv.status}\n </p>\n </div>\n <div className=\"text-left sm:text-right\">\n <p className=\"text-xl font-bold text-text-primary\">\n {formatCurrency(inv.currentValue, { minimumFractionDigits: 0 })}\n </p>\n <p\n className={cn(\n 'text-sm',\n pl >= 0 ? 'text-status-success-text' : 'text-status-error-text'\n )}\n >\n {formatCurrency(Math.abs(pl), { minimumFractionDigits: 0 })} (\n {fmtPct(plPct)})\n </p>\n </div>\n </div>\n\n <div className=\"mb-4 grid grid-cols-2 gap-3 lg:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested</p>\n <p className=\"text-sm font-medium text-text-primary\">\n {formatCurrency(inv.investedAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Returns</p>\n <p className=\"text-sm font-medium text-text-primary\">\n {formatCurrency(inv.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-medium text-text-primary\">\n {inv.returnsPercentage}%\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Investment Date</p>\n <p className=\"text-sm font-medium text-text-primary\">\n {formatDate(inv.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\n </div>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${inv.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 })}\n </div>\n )}\n </div>\n )}\n\n {/* Transactions Tab */}\n {activeTab === 'transactions' && (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No transaction history yet\"\n description=\"A detailed ledger of your investments, dividends and withdrawals will appear here as your activity builds up.\"\n />\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"InvestorPortfolioPage.js","names":[],"sources":["../../../../src/kadaikodi/pages/investor/InvestorPortfolioPage.tsx"],"sourcesContent":["/**\n * Investor Portfolio Page\n * @module kadaikodi/pages/investor\n *\n * A portfolio dashboard: headline KPI cards, a portfolio-value trend chart, an\n * allocation donut, the full holdings table, and a recent-activity feed. Every\n * figure — including the value trend and the activity feed — is derived from the\n * investor's real holdings (useInvestments). No fabricated series or ledger.\n */\n\nimport { useMemo } from 'react';\nimport {\n Wallet,\n TrendingUp,\n Briefcase,\n IndianRupee,\n Eye,\n Download,\n CheckCircle2,\n} from 'lucide-react';\nimport { EmphasisPanel, GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { AreaChart, DonutChart } from '../../components/viz';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useInvestments } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatDate } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction fmtPct(value: number) {\n return `${value > 0 ? '+' : ''}${value.toFixed(1)}%`;\n}\n\n/** Compact rupee formatter for chart axes. */\nfunction formatRupeeCompact(value: number): string {\n return formatCurrency(value, { minimumFractionDigits: 0, notation: 'compact' });\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorPortfolioPage() {\n const { navigateTo, currentUser } = useKadaikodi();\n const { data: investments = [], isLoading } = useInvestments(currentUser?.id || '');\n\n const totalInvested = investments.reduce((s, i) => s + i.investedAmount, 0);\n const currentValue = investments.reduce((s, i) => s + i.currentValue, 0);\n const totalReturns = currentValue - totalInvested;\n const returnsPercentage = totalInvested > 0 ? (totalReturns / totalInvested) * 100 : 0;\n const activeCount = investments.filter((i) => i.status === 'active').length;\n\n // Allocation by cart — derived purely from the real holdings' current value.\n const allocation = useMemo(() => {\n const map = investments.reduce<Record<string, number>>((acc, inv) => {\n acc[inv.cartName] = (acc[inv.cartName] || 0) + inv.currentValue;\n return acc;\n }, {});\n return Object.entries(map)\n .map(([label, value]) => ({ label, value }))\n .sort((a, b) => b.value - a.value);\n }, [investments]);\n\n // Portfolio value trend — the running total of holding value as each stake was\n // added, in date order. Real, derived from the holdings' own dates/values.\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 // Recent activity — each holding is a real \"Buy\" event with its date/amount.\n const activity = useMemo(\n () =>\n [...investments]\n .sort(\n (a, b) => new Date(b.investmentDate).getTime() - new Date(a.investmentDate).getTime()\n )\n .slice(0, 6),\n [investments]\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"My Portfolio\" description=\"Loading your portfolio...\">\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div\n key={i}\n className=\"h-28 animate-pulse rounded-[var(--radius-card)] bg-bg-sunken\"\n />\n ))}\n </div>\n <div className=\"h-72 animate-pulse rounded-[var(--radius-card)] bg-bg-sunken\" />\n </div>\n </PageLayout>\n );\n }\n\n const isEmpty = investments.length === 0;\n\n return (\n <PageLayout\n title=\"My Portfolio\"\n description=\"View and manage your investments\"\n actions={\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-semibold text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n Add Funds\n </button>\n }\n >\n <PagePurpose className=\"mb-6\">\n The complete picture of your money on Kadaikodi. See how your portfolio is performing\n overall, how its value has grown as you&apos;ve backed more carts, how it&apos;s split across\n holdings, and the detail of every position.\n </PagePurpose>\n\n {/* Summary Cards — the one emphasis zone for this page */}\n <EmphasisPanel>\n <h2 className=\"mb-4 text-base font-semibold text-text-primary\">Portfolio at a Glance</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n featured\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"neutral\"\n trendValue={`${activeCount} active`}\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend={returnsPercentage >= 0 ? 'up' : 'down'}\n trendValue={fmtPct(returnsPercentage)}\n />\n <MetricsCard\n icon={<TrendingUp className=\"h-5 w-5\" />}\n value={fmtPct(returnsPercentage)}\n label=\"Overall Returns\"\n trend={totalReturns >= 0 ? 'up' : 'down'}\n trendValue={formatCurrency(Math.abs(totalReturns), { minimumFractionDigits: 0 })}\n />\n <MetricsCard\n icon={<Briefcase className=\"h-5 w-5\" />}\n value={String(activeCount)}\n label=\"Active Investments\"\n />\n </div>\n </EmphasisPanel>\n\n {isEmpty ? (\n <div className=\"mt-6\">\n <EmptyState\n illustration=\"empty-data\"\n title=\"No holdings yet\"\n description=\"Once you back a cart, your portfolio value, allocation and holdings will appear here.\"\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-hover transition-colors\"\n >\n Browse Opportunities\n </button>\n }\n />\n </div>\n ) : (\n <>\n {/* Trend + Allocation */}\n <div className=\"mt-6 grid gap-6 lg:grid-cols-3\">\n <GlassCard treatment=\"plain\" className=\"p-5 sm:p-6 lg:col-span-2\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Portfolio Value Trend</h2>\n <span className=\"text-xs text-text-secondary\">by holding date</span>\n </div>\n <AreaChart\n series={valueTrend}\n height={240}\n valueFormatter={formatRupeeCompact}\n title=\"Cumulative portfolio value by holding date\"\n />\n </GlassCard>\n\n <GlassCard treatment=\"plain\" className=\"p-5 sm:p-6\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Allocation</h2>\n <div className=\"flex flex-col items-center gap-4\">\n <DonutChart\n segments={allocation}\n size={180}\n centerLabel={formatRupeeCompact(currentValue)}\n centerCaption=\"total value\"\n valueFormatter={formatRupeeCompact}\n />\n </div>\n </GlassCard>\n </div>\n\n {/* Holdings + Recent Activity */}\n <div className=\"mt-6 grid gap-6 lg:grid-cols-3\">\n {/* Holdings table (desktop) / cards (mobile) */}\n <GlassCard treatment=\"plain\" className=\"p-5 sm:p-6 lg:col-span-2\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Your Holdings</h2>\n\n {/* Desktop table */}\n <div className=\"hidden overflow-x-auto md:block\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-subtle text-left text-xs text-text-secondary\">\n <th className=\"pb-3 pr-4 font-medium\">Merchant</th>\n <th className=\"pb-3 pr-4 text-right font-medium\">Invested</th>\n <th className=\"pb-3 pr-4 text-right font-medium\">Current Value</th>\n <th className=\"pb-3 pr-4 text-right font-medium\">Returns</th>\n <th className=\"pb-3 pr-4 font-medium\">Status</th>\n <th className=\"pb-3 font-medium\" aria-label=\"actions\" />\n </tr>\n </thead>\n <tbody>\n {investments.map((inv) => {\n const pl = inv.currentValue - inv.investedAmount;\n const plPct = inv.investedAmount > 0 ? (pl / inv.investedAmount) * 100 : 0;\n return (\n <tr\n key={inv.id}\n className=\"border-b border-border-subtle/60 last:border-0\"\n >\n <td className=\"py-3 pr-4 font-medium text-text-primary\">{inv.cartName}</td>\n <td className=\"py-3 pr-4 text-right tabular-nums text-text-primary\">\n {formatCurrency(inv.investedAmount, { minimumFractionDigits: 0 })}\n </td>\n <td className=\"py-3 pr-4 text-right tabular-nums text-text-primary\">\n {formatCurrency(inv.currentValue, { minimumFractionDigits: 0 })}\n </td>\n <td\n className={cn(\n 'py-3 pr-4 text-right font-medium tabular-nums',\n pl >= 0 ? 'text-status-success-text' : 'text-status-error-text'\n )}\n >\n {fmtPct(plPct)}\n </td>\n <td className=\"py-3 pr-4\">\n <span className=\"inline-flex items-center gap-1.5 rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-xs font-medium capitalize text-status-success-text\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-status-success-text\" />\n {inv.status}\n </span>\n </td>\n <td className=\"py-3 text-right\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${inv.id}`)}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-subtle px-2.5 py-1.5 text-xs font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-3.5 w-3.5\" />\n View\n </button>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {/* Mobile cards */}\n <div className=\"space-y-3 md:hidden\">\n {investments.map((inv) => {\n const pl = inv.currentValue - inv.investedAmount;\n const plPct = inv.investedAmount > 0 ? (pl / inv.investedAmount) * 100 : 0;\n return (\n <button\n key={inv.id}\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${inv.id}`)}\n className=\"w-full rounded-lg border border-border-subtle p-4 text-left transition-colors hover:bg-accent/50\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <span className=\"font-medium text-text-primary\">{inv.cartName}</span>\n <span\n className={cn(\n 'text-sm font-semibold tabular-nums',\n pl >= 0 ? 'text-status-success-text' : 'text-status-error-text'\n )}\n >\n {fmtPct(plPct)}\n </span>\n </div>\n <div className=\"mt-3 grid grid-cols-2 gap-3 text-sm\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested</p>\n <p className=\"font-medium text-text-primary\">\n {formatCurrency(inv.investedAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Current Value</p>\n <p className=\"font-medium text-text-primary\">\n {formatCurrency(inv.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n </div>\n </button>\n );\n })}\n </div>\n </GlassCard>\n\n {/* Recent activity — derived from real investment events */}\n <GlassCard treatment=\"plain\" className=\"p-5 sm:p-6\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Recent Activity</h2>\n <ul className=\"space-y-4\">\n {activity.map((inv) => (\n <li key={inv.id} className=\"flex items-start gap-3\">\n <span className=\"mt-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[var(--color-accent-soft)]\">\n <Download className=\"h-4 w-4 text-text-primary\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n Invested · {inv.cartName}\n </p>\n <span className=\"shrink-0 text-sm font-semibold tabular-nums text-text-primary\">\n {formatCurrency(inv.investedAmount, {\n minimumFractionDigits: 0,\n notation: 'compact',\n })}\n </span>\n </div>\n <div className=\"mt-0.5 flex items-center gap-2 text-xs text-text-secondary\">\n <span>\n {formatDate(inv.investmentDate, { hour: undefined, minute: undefined })}\n </span>\n <span className=\"inline-flex items-center gap-1 capitalize text-status-success-text\">\n <CheckCircle2 className=\"h-3 w-3\" />\n {inv.status}\n </span>\n </div>\n </div>\n </li>\n ))}\n </ul>\n </GlassCard>\n </div>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"InvestorProfilePage.js","names":[],"sources":["../../../../src/kadaikodi/pages/investor/InvestorProfilePage.tsx"],"sourcesContent":["/**\n * Investor Profile Page\n * @module kadaikodi/pages/investor\n *\n * 6-tab profile (personal / investment / portfolio / documents / security /\n * notifications).\n *\n * Wiring rules (no fake success anywhere):\n * - IDENTITY (name, email, phone, photo) and AUTH (password, 2FA, sessions) are\n * platform-owned (Burdenoff account). They are shown DISPLAY-ONLY from\n * `currentUser` and the user is routed to Account Security to change them.\n * - APP-OWNED PROFILE + PREFERENCE fields (company / address / investor type /\n * sectors / risk) have no server of their own, so they are edited and\n * genuinely persisted client-side (localStorage, per user) — a real save that\n * survives reload, not a mutation no-op.\n * - KYC/documents and notification delivery have no backend yet, so they are\n * rendered honestly disabled (\"coming soon\") rather than faking success.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport {\n User,\n Mail,\n Phone,\n Save,\n X,\n Shield,\n ShieldCheck,\n Bell,\n TrendingUp,\n FileText,\n PieChart,\n Briefcase,\n DollarSign,\n Lock,\n Smartphone,\n Monitor,\n Edit3,\n Globe,\n Linkedin,\n Building2,\n ExternalLink,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useInvestments } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * App-owned profile fields the investor authors themselves. These are NOT\n * platform identity (name/email/phone live on the Burdenoff account) — there is\n * no kadaikodi investor-profile service, so they are persisted client-side.\n */\ninterface ProfilePreferences {\n // Investment Profile\n investorType: string;\n investmentRange: string;\n preferredSectors: string[];\n investmentHorizon: string;\n riskProfile: string;\n\n // Company/Organization Details\n companyName: string;\n designation: string;\n companyWebsite: string;\n linkedinProfile: string;\n\n // Address\n address: string;\n city: string;\n state: string;\n country: string;\n pincode: string;\n}\n\ninterface NotificationPreference {\n id: string;\n label: string;\n description: string;\n enabled: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Tab definition\n// ---------------------------------------------------------------------------\n\nconst tabs = [\n { id: 'personal', label: 'Personal Info', Icon: User },\n { id: 'investment', label: 'Investment Profile', Icon: TrendingUp },\n { id: 'portfolio', label: 'Portfolio', Icon: PieChart },\n { id: 'documents', label: 'Documents', Icon: FileText },\n { id: 'security', label: 'Security', Icon: Shield },\n { id: 'notifications', label: 'Notifications', Icon: Bell },\n] as const;\n\ntype TabId = (typeof tabs)[number]['id'];\n\n// ---------------------------------------------------------------------------\n// Static option lists (preference selectors — local UI state, not fabricated data)\n// ---------------------------------------------------------------------------\n\nconst sectorOptions = [\n 'Food & Beverage',\n 'Quick Commerce',\n 'Cloud Kitchen',\n 'Retail',\n 'Technology',\n 'Healthcare',\n 'Education',\n 'Logistics',\n 'FinTech',\n];\n\n// ---------------------------------------------------------------------------\n// Client-side persistence (real — survives reload, scoped per user)\n// ---------------------------------------------------------------------------\n\nconst EMPTY_PREFERENCES: ProfilePreferences = {\n investorType: '',\n investmentRange: '',\n preferredSectors: [],\n investmentHorizon: '',\n riskProfile: '',\n companyName: '',\n designation: '',\n companyWebsite: '',\n linkedinProfile: '',\n address: '',\n city: '',\n state: '',\n country: '',\n pincode: '',\n};\n\nfunction preferencesStorageKey(userId: string): string {\n return `kadaikodi:investor-profile:${userId}`;\n}\n\nfunction loadPreferences(userId: string): ProfilePreferences {\n if (!userId || typeof window === 'undefined') return EMPTY_PREFERENCES;\n try {\n const raw = window.localStorage.getItem(preferencesStorageKey(userId));\n if (!raw) return EMPTY_PREFERENCES;\n const parsed = JSON.parse(raw) as Partial<ProfilePreferences>;\n return {\n ...EMPTY_PREFERENCES,\n ...parsed,\n preferredSectors: Array.isArray(parsed.preferredSectors) ? parsed.preferredSectors : [],\n };\n } catch {\n return EMPTY_PREFERENCES;\n }\n}\n\nfunction savePreferences(userId: string, prefs: ProfilePreferences): void {\n if (!userId || typeof window === 'undefined') return;\n window.localStorage.setItem(preferencesStorageKey(userId), JSON.stringify(prefs));\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorProfilePage() {\n const { currentUser, navigateTo } = useKadaikodi();\n const { data: investments = [] } = useInvestments(currentUser?.id || '');\n\n const [activeTab, setActiveTab] = useState<TabId>('personal');\n const [isEditing, setIsEditing] = useState(false);\n const [saveMessage, setSaveMessage] = useState('');\n\n // Identity is display-only, sourced from the signed-in account — never edited here.\n const identity = useMemo(\n () => ({\n firstName: currentUser?.firstName ?? currentUser?.name?.split(' ')[0] ?? '',\n lastName: currentUser?.lastName ?? currentUser?.name?.split(' ').slice(1).join(' ') ?? '',\n email: currentUser?.email ?? '',\n phone: currentUser?.phone ?? '',\n profileImage: currentUser?.avatar ?? currentUser?.profilePicture ?? '',\n }),\n [currentUser]\n );\n\n // App-owned preferences: editable, genuinely persisted client-side.\n const [preferences, setPreferences] = useState<ProfilePreferences>(() =>\n loadPreferences(currentUser?.id ?? '')\n );\n\n const portfolioStats = useMemo(() => {\n const totalInvested = investments.reduce((sum, inv) => sum + inv.investedAmount, 0);\n const portfolioValue = investments.reduce((sum, inv) => sum + inv.currentValue, 0);\n const totalReturns = investments.reduce((sum, inv) => sum + inv.returns, 0);\n\n return {\n totalInvested,\n portfolioValue,\n totalReturns,\n activeInvestments: investments.length,\n };\n }, [investments]);\n\n // Notification delivery is not wired to any backend yet — shown as an honest,\n // disabled preview so we never imply we can turn real emails on/off.\n const notifications: NotificationPreference[] = [\n {\n id: 'opportunities',\n label: 'New Investment Opportunities',\n description: 'Get notified about new investment opportunities matching your profile',\n enabled: true,\n },\n {\n id: 'updates',\n label: 'Portfolio Updates',\n description: 'Regular updates on your portfolio performance',\n enabled: true,\n },\n {\n id: 'reports',\n label: 'Monthly Reports',\n description: 'Detailed monthly investment reports',\n enabled: true,\n },\n {\n id: 'events',\n label: 'Investor Events',\n description: 'Invitations to investor meetups and events',\n enabled: false,\n },\n {\n id: 'news',\n label: 'Market News',\n description: 'Important market news and updates',\n enabled: true,\n },\n {\n id: 'dividends',\n label: 'Dividend Alerts',\n description: 'Notifications when dividends are credited to your account',\n enabled: true,\n },\n ];\n\n const handlePreferenceChange = useCallback(\n (field: keyof ProfilePreferences, value: string | string[]) => {\n setPreferences((prev) => ({ ...prev, [field]: value }));\n },\n []\n );\n\n const handleSave = useCallback(() => {\n // Real persistence: writes to localStorage synchronously and survives reload.\n savePreferences(currentUser?.id ?? '', preferences);\n setIsEditing(false);\n setSaveMessage('Saved on this device');\n // Only clears the confirmation banner — the save itself already happened above.\n window.setTimeout(() => setSaveMessage(''), 3000);\n }, [currentUser?.id, preferences]);\n\n const handleCancel = useCallback(() => {\n setIsEditing(false);\n setPreferences(loadPreferences(currentUser?.id ?? ''));\n }, [currentUser?.id]);\n\n const goToAccountSecurity = useCallback(\n () => navigateTo('/auth/security'),\n [navigateTo]\n );\n\n const displayName = [identity.firstName, identity.lastName].filter(Boolean).join(' ') || 'Investor';\n\n return (\n <PageLayout\n title=\"Investor Profile\"\n description=\"Manage your investment profile and preferences\"\n actions={\n <div className=\"flex items-center gap-2\">\n {saveMessage && (\n <span className=\"text-sm font-medium text-status-success-text\">{saveMessage}</span>\n )}\n {!isEditing ? (\n <>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <ShieldCheck className=\"h-4 w-4\" />\n Account Security\n </button>\n <button\n type=\"button\"\n onClick={() => setIsEditing(true)}\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 <Edit3 className=\"h-4 w-4\" />\n Edit Profile\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <X className=\"h-4 w-4\" />\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\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 <Save className=\"h-4 w-4\" />\n Save Changes\n </button>\n </>\n )}\n </div>\n }\n >\n <PagePurpose className=\"mb-6\">\n Your investor identity and how the platform tailors deals to you. Your name, email, phone and\n photo come from your Burdenoff account and are managed in Account Security; here you set your\n investment profile (preferred sectors, ticket size and risk tolerance) so you see the right\n opportunities, and review your portfolio at a glance.\n </PagePurpose>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-4\">\n {/* Sidebar */}\n <div className=\"lg:col-span-1\">\n {/* Profile Card — the one emphasis zone for this page */}\n <EmphasisPanel className=\"p-4 sm:p-6\">\n <div className=\"text-center\">\n <div className=\"relative mx-auto inline-block\">\n <div className=\"h-20 w-20 overflow-hidden rounded-full bg-bg-sunken sm:h-24 sm:w-24\">\n {identity.profileImage ? (\n <img\n src={identity.profileImage}\n alt=\"Profile\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"flex h-full w-full items-center justify-center\">\n <User className=\"h-10 w-10 text-text-secondary\" />\n </div>\n )}\n </div>\n </div>\n <h3 className=\"mt-3 text-base font-semibold text-text-primary sm:text-lg\">\n {displayName}\n </h3>\n {preferences.investorType && (\n <p className=\"text-sm text-text-secondary\">{preferences.investorType}</p>\n )}\n {preferences.companyName && (\n <p className=\"mt-1 truncate text-xs text-text-secondary\">\n {preferences.companyName}\n </p>\n )}\n </div>\n\n {/* Quick Stats */}\n <div className=\"mt-5 space-y-3 border-t border-border-subtle pt-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary sm:text-sm\">Portfolio Value</span>\n <span className=\"text-xs font-semibold text-primary sm:text-sm\">\n {formatCurrency(portfolioStats.portfolioValue, { minimumFractionDigits: 0 })}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary sm:text-sm\">Active Investments</span>\n <span className=\"text-xs font-semibold text-text-primary sm:text-sm\">\n {portfolioStats.activeInvestments}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary sm:text-sm\">Total Returns</span>\n <span className=\"text-xs font-semibold text-status-success-text sm:text-sm\">\n +{formatCurrency(portfolioStats.totalReturns, { minimumFractionDigits: 0 })}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary sm:text-sm\">Total Invested</span>\n <span className=\"text-xs font-semibold text-text-primary sm:text-sm\">\n {formatCurrency(portfolioStats.totalInvested, { minimumFractionDigits: 0 })}\n </span>\n </div>\n </div>\n </EmphasisPanel>\n\n {/* Mobile: Horizontal scrolling tabs */}\n <div className=\"mt-4 flex gap-2 overflow-x-auto pb-2 lg:hidden\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex shrink-0 items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors',\n activeTab === tab.id\n ? 'bg-action-primary-bg text-action-primary-text shadow-sm'\n : 'bg-bg-surface text-text-primary hover:bg-accent'\n )}\n >\n <tab.Icon className=\"h-4 w-4 shrink-0\" />\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Desktop: Vertical tabs */}\n <div className=\"mt-4 hidden space-y-2 lg:block\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm font-medium transition-colors',\n activeTab === tab.id\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary hover:bg-accent'\n )}\n >\n <tab.Icon className=\"h-4 w-4\" />\n {tab.label}\n </button>\n ))}\n </div>\n </div>\n\n {/* Content Area */}\n <div className=\"lg:col-span-3\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6 lg:p-8\">\n {/* ==================== Personal Info Tab ==================== */}\n {activeTab === 'personal' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Personal Information\n </h2>\n\n <div className=\"space-y-6\">\n {/* Identity is account-owned — display only, managed in Account Security. */}\n <div className=\"flex flex-col gap-3 rounded-lg border border-border-subtle bg-bg-sunken/40 p-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-start gap-3\">\n <ShieldCheck className=\"mt-0.5 h-5 w-5 shrink-0 text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">\n Your name, email, phone and photo come from your Burdenoff account. To change\n them, open Account Security.\n </p>\n </div>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex shrink-0 items-center gap-1.5 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Account Security\n <ExternalLink className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n\n {/* Name & Contact — display only (identity) */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n First Name\n </label>\n <input\n type=\"text\"\n value={identity.firstName}\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2 text-sm text-text-secondary focus:outline-none\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={identity.lastName}\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2 text-sm text-text-secondary focus:outline-none\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Email Address\n </label>\n <div className=\"relative\">\n <Mail className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"email\"\n value={identity.email}\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken py-2 pl-10 pr-3 text-sm text-text-secondary focus:outline-none\"\n />\n </div>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Phone Number\n </label>\n <div className=\"relative\">\n <Phone className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"tel\"\n value={identity.phone}\n readOnly\n placeholder=\"Add in Account Security\"\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken py-2 pl-10 pr-3 text-sm text-text-secondary placeholder:text-text-secondary focus:outline-none\"\n />\n </div>\n </div>\n </div>\n\n {/* Professional Details — app-owned, editable + saved on this device */}\n <div className=\"border-t border-border-subtle pt-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary sm:text-base\">\n Professional Details\n </h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Company/Organization\n </label>\n <div className=\"relative\">\n <Building2 className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n value={preferences.companyName}\n onChange={(e) => handlePreferenceChange('companyName', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-3 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Designation\n </label>\n <input\n type=\"text\"\n value={preferences.designation}\n onChange={(e) => handlePreferenceChange('designation', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Company Website\n </label>\n <div className=\"relative\">\n <Globe className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n value={preferences.companyWebsite}\n onChange={(e) =>\n handlePreferenceChange('companyWebsite', e.target.value)\n }\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-3 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n LinkedIn Profile\n </label>\n <div className=\"relative\">\n <Linkedin className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n value={preferences.linkedinProfile}\n onChange={(e) =>\n handlePreferenceChange('linkedinProfile', e.target.value)\n }\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-3 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n </div>\n </div>\n\n {/* Address — app-owned, editable + saved on this device */}\n <div className=\"border-t border-border-subtle pt-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary sm:text-base\">\n Address\n </h3>\n <div className=\"space-y-4\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Street Address\n </label>\n <textarea\n rows={2}\n value={preferences.address}\n onChange={(e) => handlePreferenceChange('address', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n City\n </label>\n <input\n type=\"text\"\n value={preferences.city}\n onChange={(e) => handlePreferenceChange('city', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n State\n </label>\n <input\n type=\"text\"\n value={preferences.state}\n onChange={(e) => handlePreferenceChange('state', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Country\n </label>\n <input\n type=\"text\"\n value={preferences.country}\n onChange={(e) => handlePreferenceChange('country', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Pincode\n </label>\n <input\n type=\"text\"\n value={preferences.pincode}\n onChange={(e) => handlePreferenceChange('pincode', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* ==================== Investment Profile Tab ==================== */}\n {activeTab === 'investment' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Investment Profile\n </h2>\n\n <div className=\"space-y-6\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Investor Type\n </label>\n <select\n value={preferences.investorType}\n onChange={(e) => handlePreferenceChange('investorType', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select investor type</option>\n <option>Angel Investor</option>\n <option>Venture Capitalist</option>\n <option>Private Equity</option>\n <option>Strategic Investor</option>\n </select>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Investment Range\n </label>\n <select\n value={preferences.investmentRange}\n onChange={(e) => handlePreferenceChange('investmentRange', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select range</option>\n <option>1L - 5L</option>\n <option>5L - 25L</option>\n <option>25L - 1Cr</option>\n <option>1Cr+</option>\n </select>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Investment Horizon\n </label>\n <select\n value={preferences.investmentHorizon}\n onChange={(e) =>\n handlePreferenceChange('investmentHorizon', e.target.value)\n }\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select horizon</option>\n <option>1-2 years</option>\n <option>3-5 years</option>\n <option>5-7 years</option>\n <option>7+ years</option>\n </select>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Risk Profile\n </label>\n <select\n value={preferences.riskProfile}\n onChange={(e) => handlePreferenceChange('riskProfile', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select risk profile</option>\n <option>Conservative</option>\n <option>Moderate</option>\n <option>Aggressive</option>\n </select>\n </div>\n </div>\n\n {/* Preferred Sectors */}\n <div>\n <label className=\"mb-3 block text-sm font-medium text-text-primary\">\n Preferred Sectors\n </label>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {sectorOptions.map((sector) => (\n <label key={sector} className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n checked={preferences.preferredSectors.includes(sector)}\n onChange={(e) => {\n if (e.target.checked) {\n handlePreferenceChange('preferredSectors', [\n ...preferences.preferredSectors,\n sector,\n ]);\n } else {\n handlePreferenceChange(\n 'preferredSectors',\n preferences.preferredSectors.filter((s) => s !== sector)\n );\n }\n }}\n disabled={!isEditing}\n className=\"h-4 w-4 rounded border-border-subtle text-primary focus:ring-[var(--color-focus-ring)]\"\n />\n <span className=\"text-sm text-text-primary\">{sector}</span>\n </label>\n ))}\n </div>\n </div>\n\n {/* Risk Tolerance Visual */}\n <div className=\"rounded-lg border border-border-subtle p-4\">\n <div className=\"mb-2 flex items-center justify-between\">\n <p className=\"text-sm font-medium text-text-primary\">Risk Tolerance</p>\n <span\n className={cn(\n 'text-sm font-semibold',\n preferences.riskProfile === 'Conservative'\n ? 'text-status-success-text'\n : preferences.riskProfile === 'Moderate'\n ? 'text-status-warning-text'\n : 'text-status-error-text'\n )}\n >\n {preferences.riskProfile}\n </span>\n </div>\n <div className=\"flex gap-1\">\n {(['Conservative', 'Moderate', 'Aggressive'] as const).map((level) => (\n <div\n key={level}\n className={cn(\n 'h-2.5 flex-1 rounded-full',\n level === 'Conservative' && 'bg-status-success-bg-subtle',\n level === 'Moderate' && 'bg-status-warning-bg-subtle',\n level === 'Aggressive' && 'bg-status-error-bg-subtle',\n level === preferences.riskProfile &&\n level === 'Conservative' &&\n 'bg-status-success-text',\n level === preferences.riskProfile &&\n level === 'Moderate' &&\n 'bg-status-warning-text',\n level === preferences.riskProfile &&\n level === 'Aggressive' &&\n 'bg-status-error-text'\n )}\n />\n ))}\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* ==================== Portfolio Tab ==================== */}\n {activeTab === 'portfolio' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Investment Portfolio\n </h2>\n\n {/* Portfolio Summary */}\n <div className=\"mb-8 grid grid-cols-2 gap-4 sm:grid-cols-4 sm:gap-6\">\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <DollarSign className=\"mb-2 h-7 w-7 text-primary sm:h-8 sm:w-8\" />\n <div className=\"text-lg font-bold text-text-primary sm:text-2xl\">\n {formatCurrency(portfolioStats.totalInvested, {\n minimumFractionDigits: 0,\n notation: 'compact',\n })}\n </div>\n <div className=\"text-xs text-text-secondary sm:text-sm\">Total Invested</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <Briefcase className=\"mb-2 h-7 w-7 text-text-primary sm:h-8 sm:w-8\" />\n <div className=\"text-lg font-bold text-text-primary sm:text-2xl\">\n {portfolioStats.activeInvestments}\n </div>\n <div className=\"text-xs text-text-secondary sm:text-sm\">Active Investments</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <TrendingUp className=\"mb-2 h-7 w-7 text-status-success-text sm:h-8 sm:w-8\" />\n <div className=\"text-lg font-bold text-text-primary sm:text-2xl\">\n {formatCurrency(portfolioStats.totalReturns, {\n minimumFractionDigits: 0,\n notation: 'compact',\n })}\n </div>\n <div className=\"text-xs text-text-secondary sm:text-sm\">Total Returns</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <PieChart className=\"mb-2 h-7 w-7 text-text-primary sm:h-8 sm:w-8\" />\n <div className=\"text-lg font-bold text-text-primary sm:text-2xl\">\n {formatCurrency(portfolioStats.portfolioValue, {\n minimumFractionDigits: 0,\n notation: 'compact',\n })}\n </div>\n <div className=\"text-xs text-text-secondary sm:text-sm\">Portfolio Value</div>\n </div>\n </div>\n\n {/* Active Investments List */}\n <div>\n <div className=\"mb-4 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/portfolio')}\n className=\"text-sm font-medium text-primary hover:underline\"\n >\n View full portfolio\n </button>\n </div>\n {investments.length === 0 ? (\n <p className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-4 text-sm text-text-secondary\">\n You don&apos;t have any active investments yet. Explore opportunities to start\n building your portfolio.\n </p>\n ) : (\n <div className=\"space-y-3\">\n {investments.map((investment) => (\n <button\n key={investment.id}\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"block w-full rounded-lg border border-border-subtle bg-bg-sunken/30 p-4 text-left hover:bg-accent/40 transition-colors\"\n >\n <div className=\"mb-3 flex items-start justify-between\">\n <h4 className=\"text-sm font-medium text-text-primary sm:text-base\">\n {investment.cartName}\n </h4>\n <span\n className={cn(\n 'text-sm font-semibold',\n investment.returnsPercentage >= 0\n ? 'text-status-success-text'\n : 'text-status-error-text'\n )}\n >\n {investment.returnsPercentage >= 0 ? '+' : ''}\n {investment.returnsPercentage}%\n </span>\n </div>\n <div className=\"grid grid-cols-1 gap-3 text-sm sm:grid-cols-3\">\n <div>\n <span className=\"text-text-secondary\">Invested: </span>\n <span className=\"font-medium text-text-primary\">\n {formatCurrency(investment.investedAmount, {\n minimumFractionDigits: 0,\n })}\n </span>\n </div>\n <div>\n <span className=\"text-text-secondary\">Current Value: </span>\n <span className=\"font-medium text-text-primary\">\n {formatCurrency(investment.currentValue, {\n minimumFractionDigits: 0,\n })}\n </span>\n </div>\n <div>\n <span className=\"text-text-secondary\">Returns: </span>\n <span className=\"font-medium text-status-success-text\">\n {formatCurrency(\n investment.currentValue - investment.investedAmount,\n {\n minimumFractionDigits: 0,\n }\n )}\n </span>\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* ==================== Documents Tab ==================== */}\n {activeTab === 'documents' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Documents & KYC\n </h2>\n\n <div className=\"space-y-6\">\n {/* No KYC/documents backend yet — honest empty state rather than fabricated records. */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-6 text-center\">\n <FileText className=\"mx-auto mb-3 h-10 w-10 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">\n No documents on file yet\n </h3>\n <p className=\"mx-auto mt-1 max-w-md text-sm text-text-secondary\">\n Your KYC and investment documents will appear here once uploaded. Complete\n verification to unlock more opportunities.\n </p>\n </div>\n\n {/* Upload is not wired to a backend yet — honestly disabled, never a fake success. */}\n <div className=\"rounded-lg border-2 border-dashed border-border-subtle p-6 text-center opacity-70\">\n <FileText className=\"mx-auto mb-2 h-8 w-8 text-text-secondary\" />\n <p className=\"text-sm font-medium text-text-primary\">Upload New Document</p>\n <p className=\"mt-1 text-xs text-text-secondary\">PDF, JPG, or PNG up to 10MB</p>\n <button\n type=\"button\"\n disabled\n title=\"Document upload is coming soon\"\n className=\"mt-3 inline-flex cursor-not-allowed items-center gap-2 rounded-lg bg-bg-sunken px-4 py-2 text-sm font-medium text-text-secondary\"\n >\n Choose File\n <span className=\"rounded-full bg-bg-surface px-2 py-0.5 text-xs\">\n Coming soon\n </span>\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* ==================== Security Tab ==================== */}\n {activeTab === 'security' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Security Settings\n </h2>\n\n <div className=\"space-y-6\">\n {/* Password, 2FA and session management are platform-owned — route to Account Security. */}\n <div className=\"rounded-lg border border-border-subtle p-4 sm:p-6\">\n <div className=\"flex items-center gap-3 mb-3\">\n <Lock className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">Change Password</h3>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n Your password is managed by your Burdenoff account. Update it securely in\n Account Security.\n </p>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Manage in Account Security\n <ExternalLink className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle p-4 sm:p-6\">\n <div className=\"flex items-center gap-3 mb-3\">\n <Smartphone className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">\n Two-Factor Authentication\n </h3>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n Add an extra layer of security to your account. Two-factor authentication is\n configured in Account Security.\n </p>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Manage in Account Security\n <ExternalLink className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle p-4 sm:p-6\">\n <div className=\"flex items-center gap-3 mb-3\">\n <Monitor className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">Login Activity</h3>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n Review recent sign-ins and active sessions for your account in Account\n Security.\n </p>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Manage in Account Security\n <ExternalLink className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* ==================== Notifications Tab ==================== */}\n {activeTab === 'notifications' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Notification Preferences\n </h2>\n\n {/* Notification delivery has no investor backend yet — honest, disabled preview. */}\n <div className=\"mb-4 flex items-start gap-3 rounded-lg border border-border-subtle bg-bg-sunken/40 p-4\">\n <Bell className=\"mt-0.5 h-5 w-5 shrink-0 text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">\n Notification controls are coming soon. This is a preview of the alerts\n you&apos;ll be able to manage here — the switches are not active yet.\n </p>\n </div>\n\n <div className=\"space-y-4\">\n {notifications.map((item) => (\n <div\n key={item.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle bg-bg-sunken/30 p-4\"\n >\n <div className=\"flex-1 pr-4\">\n <h4 className=\"text-sm font-medium text-text-primary\">{item.label}</h4>\n <p className=\"mt-0.5 text-xs text-text-secondary sm:text-sm\">\n {item.description}\n </p>\n </div>\n <span\n aria-disabled=\"true\"\n title=\"Coming soon\"\n className={cn(\n 'relative inline-flex h-6 w-11 shrink-0 cursor-not-allowed rounded-full opacity-50 transition-colors duration-200',\n item.enabled ? 'bg-action-primary-bg' : 'bg-bg-sunken'\n )}\n >\n <span\n className={cn(\n 'pointer-events-none inline-block h-5 w-5 translate-y-0.5 rounded-full bg-white shadow ring-0 transition-transform duration-200',\n item.enabled ? 'translate-x-5' : 'translate-x-0.5'\n )}\n />\n </span>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;AA4FA,IAAM,IAAO;CACX;EAAE,IAAI;EAAY,OAAO;EAAiB,MAAM;EAAM;CACtD;EAAE,IAAI;EAAc,OAAO;EAAsB,MAAM;EAAY;CACnE;EAAE,IAAI;EAAa,OAAO;EAAa,MAAM;EAAU;CACvD;EAAE,IAAI;EAAa,OAAO;EAAa,MAAM;EAAU;CACvD;EAAE,IAAI;EAAY,OAAO;EAAY,MAAM;EAAQ;CACnD;EAAE,IAAI;EAAiB,OAAO;EAAiB,MAAM;EAAM;CAC5D,EAQK,IAAgB;CACpB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,EAMK,IAAwC;CAC5C,cAAc;CACd,iBAAiB;CACjB,kBAAkB,EAAE;CACpB,mBAAmB;CACnB,aAAa;CACb,aAAa;CACb,aAAa;CACb,gBAAgB;CAChB,iBAAiB;CACjB,SAAS;CACT,MAAM;CACN,OAAO;CACP,SAAS;CACT,SAAS;CACV;AAED,SAAS,EAAsB,GAAwB;AACrD,QAAO,8BAA8B;;AAGvC,SAAS,EAAgB,GAAoC;AAC3D,KAAI,CAAC,KAAU,OAAO,SAAW,IAAa,QAAO;AACrD,KAAI;EACF,IAAM,IAAM,OAAO,aAAa,QAAQ,EAAsB,EAAO,CAAC;AACtE,MAAI,CAAC,EAAK,QAAO;EACjB,IAAM,IAAS,KAAK,MAAM,EAAI;AAC9B,SAAO;GACL,GAAG;GACH,GAAG;GACH,kBAAkB,MAAM,QAAQ,EAAO,iBAAiB,GAAG,EAAO,mBAAmB,EAAE;GACxF;SACK;AACN,SAAO;;;AAIX,SAAS,EAAgB,GAAgB,GAAiC;AACpE,EAAC,KAAU,OAAO,SAAW,OACjC,OAAO,aAAa,QAAQ,EAAsB,EAAO,EAAE,KAAK,UAAU,EAAM,CAAC;;AAOnF,SAAgB,IAAsB;CACpC,IAAM,EAAE,gBAAa,kBAAe,GAAc,EAC5C,EAAE,MAAM,IAAc,EAAE,KAAK,EAAe,GAAa,MAAM,GAAG,EAElE,CAAC,GAAW,KAAgB,EAAgB,WAAW,EACvD,CAAC,GAAW,KAAgB,EAAS,GAAM,EAC3C,CAAC,GAAa,KAAkB,EAAS,GAAG,EAG5C,IAAW,SACR;EACL,WAAW,GAAa,aAAa,GAAa,MAAM,MAAM,IAAI,CAAC,MAAM;EACzE,UAAU,GAAa,YAAY,GAAa,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,IAAI;EACvF,OAAO,GAAa,SAAS;EAC7B,OAAO,GAAa,SAAS;EAC7B,cAAc,GAAa,UAAU,GAAa,kBAAkB;EACrE,GACD,CAAC,EAAY,CACd,EAGK,CAAC,GAAa,KAAkB,QACpC,EAAgB,GAAa,MAAM,GAAG,CACvC,EAEK,IAAiB,SAKd;EACL,eALoB,EAAY,QAAQ,GAAK,MAAQ,IAAM,EAAI,gBAAgB,EAAE;EAMjF,gBALqB,EAAY,QAAQ,GAAK,MAAQ,IAAM,EAAI,cAAc,EAAE;EAMhF,cALmB,EAAY,QAAQ,GAAK,MAAQ,IAAM,EAAI,SAAS,EAAE;EAMzE,mBAAmB,EAAY;EAChC,GACA,CAAC,EAAY,CAAC,EAIX,IAA0C;EAC9C;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,SAAS;GACV;EACD;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,SAAS;GACV;EACD;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,SAAS;GACV;EACD;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,SAAS;GACV;EACD;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,SAAS;GACV;EACD;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,SAAS;GACV;EACF,EAEK,IAAyB,GAC5B,GAAiC,MAA6B;AAC7D,KAAgB,OAAU;GAAE,GAAG;IAAO,IAAQ;GAAO,EAAE;IAEzD,EAAE,CACH,EAEK,IAAa,QAAkB;AAMnC,EAJA,EAAgB,GAAa,MAAM,IAAI,EAAY,EACnD,EAAa,GAAM,EACnB,EAAe,uBAAuB,EAEtC,OAAO,iBAAiB,EAAe,GAAG,EAAE,IAAK;IAChD,CAAC,GAAa,IAAI,EAAY,CAAC,EAE5B,IAAe,QAAkB;AAErC,EADA,EAAa,GAAM,EACnB,EAAe,EAAgB,GAAa,MAAM,GAAG,CAAC;IACrD,CAAC,GAAa,GAAG,CAAC,EAEf,IAAsB,QACpB,EAAW,iBAAiB,EAClC,CAAC,EAAW,CACb,EAEK,KAAc,CAAC,EAAS,WAAW,EAAS,SAAS,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI;AAEzF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,KACC,kBAAC,QAAD;IAAM,WAAU;cAAgD;IAAmB,CAAA,EAEnF,IAoBA,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAG,WAAU,WAAY,CAAA,EAAA,SAElB;OACT,kBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,WAAU;cAHZ,CAKE,kBAAC,IAAD,EAAM,WAAU,WAAY,CAAA,EAAA,eAErB;MACR,EAAA,CAAA,GApCH,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA,EAAA,mBAE5B;OACT,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAa,GAAK;IACjC,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAAA,eAEtB;MACR,EAAA,CAAA,CAqBD;;YA/CV,CAkDE,kBAAC,GAAD;GAAa,WAAU;aAAO;GAKhB,CAAA,EAEd,kBAAC,OAAD;GAAK,WAAU;aAAf,CAEE,kBAAC,OAAD;IAAK,WAAU;cAAf;KAEE,kBAAC,GAAD;MAAe,WAAU;gBAAzB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UAAK,WAAU;oBACZ,EAAS,eACR,kBAAC,OAAD;WACE,KAAK,EAAS;WACd,KAAI;WACJ,WAAU;WACV,CAAA,GAEF,kBAAC,OAAD;WAAK,WAAU;qBACb,kBAAC,GAAD,EAAM,WAAU,iCAAkC,CAAA;WAC9C,CAAA;UAEJ,CAAA;SACF,CAAA;QACN,kBAAC,MAAD;SAAI,WAAU;mBACX;SACE,CAAA;QACJ,EAAY,gBACX,kBAAC,KAAD;SAAG,WAAU;mBAA+B,EAAY;SAAiB,CAAA;QAE1E,EAAY,eACX,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAY;SACX,CAAA;QAEF;UAGN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBAAyC;UAAsB,CAAA,EAC/E,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAe,EAAe,gBAAgB,EAAE,uBAAuB,GAAG,CAAC;UACvE,CAAA,CACH;;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBAAyC;UAAyB,CAAA,EAClF,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAe;UACX,CAAA,CACH;;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBAAyC;UAAoB,CAAA,EAC7E,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CAA4E,KACxE,EAAe,EAAe,cAAc,EAAE,uBAAuB,GAAG,CAAC,CACtE;YACH;;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBAAyC;UAAqB,CAAA,EAC9E,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAe,EAAe,eAAe,EAAE,uBAAuB,GAAG,CAAC;UACtE,CAAA,CACH;;QACF;SACQ;;KAGhB,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAK,KAAK,MACT,kBAAC,UAAD;OAEE,MAAK;OACL,eAAe,EAAa,EAAI,GAAG;OACnC,WAAW,EACT,+FACA,MAAc,EAAI,KACd,4DACA,kDACL;iBATH,CAWE,kBAAC,EAAI,MAAL,EAAU,WAAU,oBAAqB,CAAA,EACxC,EAAI,MACE;SAZF,EAAI,GAYF,CACT;MACE,CAAA;KAGN,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAK,KAAK,MACT,kBAAC,UAAD;OAEE,MAAK;OACL,eAAe,EAAa,EAAI,GAAG;OACnC,WAAW,EACT,6FACA,MAAc,EAAI,KACd,kDACA,kDACL;iBATH,CAWE,kBAAC,EAAI,MAAL,EAAU,WAAU,WAAY,CAAA,EAC/B,EAAI,MACE;SAZF,EAAI,GAYF,CACT;MACE,CAAA;KACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf;MAEG,MAAc,cACb,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA0D;OAEnE,CAAA,EAEL,kBAAC,OAAD;OAAK,WAAU;iBAAf;QAEE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,GAAD,EAAa,WAAU,+CAAgD,CAAA,EACvE,kBAAC,KAAD;WAAG,WAAU;qBAA8B;WAGvC,CAAA,CACA;aACN,kBAAC,UAAD;UACE,MAAK;UACL,SAAS;UACT,WAAU;oBAHZ,CAIC,oBAEC,kBAAC,GAAD,EAAc,WAAU,eAAgB,CAAA,CACjC;YACL;;QAGN,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,SAAD;WACE,MAAK;WACL,OAAO,EAAS;WAChB,UAAA;WACA,WAAU;WACV,CAAA,CACE,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,SAAD;WACE,MAAK;WACL,OAAO,EAAS;WAChB,UAAA;WACA,WAAU;WACV,CAAA,CACE,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,wEAAyE,CAAA,EACzF,kBAAC,SAAD;YACE,MAAK;YACL,OAAO,EAAS;YAChB,UAAA;YACA,WAAU;YACV,CAAA,CACE;aACF,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,wEAAyE,CAAA,EAC1F,kBAAC,SAAD;YACE,MAAK;YACL,OAAO,EAAS;YAChB,UAAA;YACA,aAAY;YACZ,WAAU;YACV,CAAA,CACE;aACF,EAAA,CAAA;UACF;;QAGN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,MAAD;UAAI,WAAU;oBAA4D;UAErE,CAAA,EACL,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;YAAO,WAAU;sBAAmD;YAE5D,CAAA,EACR,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,GAAD,EAAW,WAAU,wEAAyE,CAAA,EAC9F,kBAAC,SAAD;aACE,MAAK;aACL,OAAO,EAAY;aACnB,WAAW,MAAM,EAAuB,eAAe,EAAE,OAAO,MAAM;aACtE,UAAU,CAAC;aACX,WAAU;aACV,CAAA,CACE;cACF,EAAA,CAAA;WACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;YAAO,WAAU;sBAAmD;YAE5D,CAAA,EACR,kBAAC,SAAD;YACE,MAAK;YACL,OAAO,EAAY;YACnB,WAAW,MAAM,EAAuB,eAAe,EAAE,OAAO,MAAM;YACtE,UAAU,CAAC;YACX,WAAU;YACV,CAAA,CACE,EAAA,CAAA;WACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;YAAO,WAAU;sBAAmD;YAE5D,CAAA,EACR,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,wEAAyE,CAAA,EAC1F,kBAAC,SAAD;aACE,MAAK;aACL,OAAO,EAAY;aACnB,WAAW,MACT,EAAuB,kBAAkB,EAAE,OAAO,MAAM;aAE1D,UAAU,CAAC;aACX,WAAU;aACV,CAAA,CACE;cACF,EAAA,CAAA;WACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;YAAO,WAAU;sBAAmD;YAE5D,CAAA,EACR,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,wEAAyE,CAAA,EAC7F,kBAAC,SAAD;aACE,MAAK;aACL,OAAO,EAAY;aACnB,WAAW,MACT,EAAuB,mBAAmB,EAAE,OAAO,MAAM;aAE3D,UAAU,CAAC;aACX,WAAU;aACV,CAAA,CACE;cACF,EAAA,CAAA;WACF;YACF;;QAGN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,MAAD;UAAI,WAAU;oBAA4D;UAErE,CAAA,EACL,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,YAAD;WACE,MAAM;WACN,OAAO,EAAY;WACnB,WAAW,MAAM,EAAuB,WAAW,EAAE,OAAO,MAAM;WAClE,UAAU,CAAC;WACX,WAAU;WACV,CAAA,CACE,EAAA,CAAA,EACN,kBAAC,OAAD;WAAK,WAAU;qBAAf;YACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;aAAO,WAAU;uBAAmD;aAE5D,CAAA,EACR,kBAAC,SAAD;aACE,MAAK;aACL,OAAO,EAAY;aACnB,WAAW,MAAM,EAAuB,QAAQ,EAAE,OAAO,MAAM;aAC/D,UAAU,CAAC;aACX,WAAU;aACV,CAAA,CACE,EAAA,CAAA;YACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;aAAO,WAAU;uBAAmD;aAE5D,CAAA,EACR,kBAAC,SAAD;aACE,MAAK;aACL,OAAO,EAAY;aACnB,WAAW,MAAM,EAAuB,SAAS,EAAE,OAAO,MAAM;aAChE,UAAU,CAAC;aACX,WAAU;aACV,CAAA,CACE,EAAA,CAAA;YACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;aAAO,WAAU;uBAAmD;aAE5D,CAAA,EACR,kBAAC,SAAD;aACE,MAAK;aACL,OAAO,EAAY;aACnB,WAAW,MAAM,EAAuB,WAAW,EAAE,OAAO,MAAM;aAClE,UAAU,CAAC;aACX,WAAU;aACV,CAAA,CACE,EAAA,CAAA;YACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;aAAO,WAAU;uBAAmD;aAE5D,CAAA,EACR,kBAAC,SAAD;aACE,MAAK;aACL,OAAO,EAAY;aACnB,WAAW,MAAM,EAAuB,WAAW,EAAE,OAAO,MAAM;aAClE,UAAU,CAAC;aACX,WAAU;aACV,CAAA,CACE,EAAA,CAAA;YACF;aACF;YACF;;QACF;SACF,EAAA,CAAA;MAIP,MAAc,gBACb,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA0D;OAEnE,CAAA,EAEL,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,UAAD;WACE,OAAO,EAAY;WACnB,WAAW,MAAM,EAAuB,gBAAgB,EAAE,OAAO,MAAM;WACvE,UAAU,CAAC;WACX,WAAU;qBAJZ;YAME,kBAAC,UAAD;aAAQ,OAAM;uBAAG;aAA6B,CAAA;YAC9C,kBAAC,UAAD,EAAA,UAAQ,kBAAuB,CAAA;YAC/B,kBAAC,UAAD,EAAA,UAAQ,sBAA2B,CAAA;YACnC,kBAAC,UAAD,EAAA,UAAQ,kBAAuB,CAAA;YAC/B,kBAAC,UAAD,EAAA,UAAQ,sBAA2B,CAAA;YAC5B;aACL,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,UAAD;WACE,OAAO,EAAY;WACnB,WAAW,MAAM,EAAuB,mBAAmB,EAAE,OAAO,MAAM;WAC1E,UAAU,CAAC;WACX,WAAU;qBAJZ;YAME,kBAAC,UAAD;aAAQ,OAAM;uBAAG;aAAqB,CAAA;YACtC,kBAAC,UAAD,EAAA,UAAQ,WAAgB,CAAA;YACxB,kBAAC,UAAD,EAAA,UAAQ,YAAiB,CAAA;YACzB,kBAAC,UAAD,EAAA,UAAQ,aAAkB,CAAA;YAC1B,kBAAC,UAAD,EAAA,UAAQ,QAAa,CAAA;YACd;aACL,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,UAAD;WACE,OAAO,EAAY;WACnB,WAAW,MACT,EAAuB,qBAAqB,EAAE,OAAO,MAAM;WAE7D,UAAU,CAAC;WACX,WAAU;qBANZ;YAQE,kBAAC,UAAD;aAAQ,OAAM;uBAAG;aAAuB,CAAA;YACxC,kBAAC,UAAD,EAAA,UAAQ,aAAkB,CAAA;YAC1B,kBAAC,UAAD,EAAA,UAAQ,aAAkB,CAAA;YAC1B,kBAAC,UAAD,EAAA,UAAQ,aAAkB,CAAA;YAC1B,kBAAC,UAAD,EAAA,UAAQ,YAAiB,CAAA;YAClB;aACL,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAmD;WAE5D,CAAA,EACR,kBAAC,UAAD;WACE,OAAO,EAAY;WACnB,WAAW,MAAM,EAAuB,eAAe,EAAE,OAAO,MAAM;WACtE,UAAU,CAAC;WACX,WAAU;qBAJZ;YAME,kBAAC,UAAD;aAAQ,OAAM;uBAAG;aAA4B,CAAA;YAC7C,kBAAC,UAAD,EAAA,UAAQ,gBAAqB,CAAA;YAC7B,kBAAC,UAAD,EAAA,UAAQ,YAAiB,CAAA;YACzB,kBAAC,UAAD,EAAA,UAAQ,cAAmB,CAAA;YACpB;aACL,EAAA,CAAA;UACF;;QAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,WAAU;mBAAmD;SAE5D,CAAA,EACR,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAc,KAAK,MAClB,kBAAC,SAAD;UAAoB,WAAU;oBAA9B,CACE,kBAAC,SAAD;WACE,MAAK;WACL,SAAS,EAAY,iBAAiB,SAAS,EAAO;WACtD,WAAW,MAAM;AACf,YAAI,EAAE,OAAO,UACX,EAAuB,oBAAoB,CACzC,GAAG,EAAY,kBACf,EACD,CAAC,GAEF,EACE,oBACA,EAAY,iBAAiB,QAAQ,MAAM,MAAM,EAAO,CACzD;;WAGL,UAAU,CAAC;WACX,WAAU;WACV,CAAA,EACF,kBAAC,QAAD;WAAM,WAAU;qBAA6B;WAAc,CAAA,CACrD;YArBI,EAqBJ,CACR;SACE,CAAA,CACF,EAAA,CAAA;QAGN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,KAAD;WAAG,WAAU;qBAAwC;WAAkB,CAAA,EACvE,kBAAC,QAAD;WACE,WAAW,EACT,yBACA,EAAY,gBAAgB,iBACxB,6BACA,EAAY,gBAAgB,aAC1B,6BACA,yBACP;qBAEA,EAAY;WACR,CAAA,CACH;aACN,kBAAC,OAAD;UAAK,WAAU;oBACX;WAAC;WAAgB;WAAY;WAAa,CAAW,KAAK,MAC1D,kBAAC,OAAD,EAEE,WAAW,EACT,6BACA,MAAU,kBAAkB,+BAC5B,MAAU,cAAc,+BACxB,MAAU,gBAAgB,6BAC1B,MAAU,EAAY,eACpB,MAAU,kBACV,0BACF,MAAU,EAAY,eACpB,MAAU,cACV,0BACF,MAAU,EAAY,eACpB,MAAU,gBACV,uBACH,EACD,EAhBK,EAgBL,CACF;UACE,CAAA,CACF;;QACF;SACF,EAAA,CAAA;MAIP,MAAc,eACb,kBAAC,OAAD,EAAA,UAAA;OACE,kBAAC,MAAD;QAAI,WAAU;kBAA0D;QAEnE,CAAA;OAGL,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,GAAD,EAAY,WAAU,2CAA4C,CAAA;WAClE,kBAAC,OAAD;YAAK,WAAU;sBACZ,EAAe,EAAe,eAAe;aAC5C,uBAAuB;aACvB,UAAU;aACX,CAAC;YACE,CAAA;WACN,kBAAC,OAAD;YAAK,WAAU;sBAAyC;YAAoB,CAAA;WACxE;;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,GAAD,EAAW,WAAU,gDAAiD,CAAA;WACtE,kBAAC,OAAD;YAAK,WAAU;sBACZ,EAAe;YACZ,CAAA;WACN,kBAAC,OAAD;YAAK,WAAU;sBAAyC;YAAwB,CAAA;WAC5E;;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,GAAD,EAAY,WAAU,uDAAwD,CAAA;WAC9E,kBAAC,OAAD;YAAK,WAAU;sBACZ,EAAe,EAAe,cAAc;aAC3C,uBAAuB;aACvB,UAAU;aACX,CAAC;YACE,CAAA;WACN,kBAAC,OAAD;YAAK,WAAU;sBAAyC;YAAmB,CAAA;WACvE;;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,GAAD,EAAU,WAAU,gDAAiD,CAAA;WACrE,kBAAC,OAAD;YAAK,WAAU;sBACZ,EAAe,EAAe,gBAAgB;aAC7C,uBAAuB;aACvB,UAAU;aACX,CAAC;YACE,CAAA;WACN,kBAAC,OAAD;YAAK,WAAU;sBAAyC;YAAqB,CAAA;WACzE;;SACF;;OAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBAA4C;SAAuB,CAAA,EACjF,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAW,sBAAsB;SAChD,WAAU;mBACX;SAEQ,CAAA,CACL;WACL,EAAY,WAAW,IACtB,kBAAC,KAAD;QAAG,WAAU;kBAAyF;QAGlG,CAAA,GAEJ,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAY,KAAK,MAChB,kBAAC,UAAD;SAEE,MAAK;SACL,eAAe,EAAW,yBAAyB,EAAW,KAAK;SACnE,WAAU;mBAJZ,CAME,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAW;WACT,CAAA,EACL,kBAAC,QAAD;WACE,WAAW,EACT,yBACA,EAAW,qBAAqB,IAC5B,6BACA,yBACL;qBANH;YAQG,EAAW,qBAAqB,IAAI,MAAM;YAC1C,EAAW;YAAkB;YACzB;aACH;aACN,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;YAAM,WAAU;sBAAsB;YAAiB,CAAA,EACvD,kBAAC,QAAD;YAAM,WAAU;sBACb,EAAe,EAAW,gBAAgB,EACzC,uBAAuB,GACxB,CAAC;YACG,CAAA,CACH,EAAA,CAAA;WACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;YAAM,WAAU;sBAAsB;YAAsB,CAAA,EAC5D,kBAAC,QAAD;YAAM,WAAU;sBACb,EAAe,EAAW,cAAc,EACvC,uBAAuB,GACxB,CAAC;YACG,CAAA,CACH,EAAA,CAAA;WACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;YAAM,WAAU;sBAAsB;YAAgB,CAAA,EACtD,kBAAC,QAAD;YAAM,WAAU;sBACb,EACC,EAAW,eAAe,EAAW,gBACrC,EACE,uBAAuB,GACxB,CACF;YACI,CAAA,CACH,EAAA,CAAA;WACF;YACC;WAlDF,EAAW,GAkDT,CACT;QACE,CAAA,CAEJ,EAAA,CAAA;OACF,EAAA,CAAA;MAIP,MAAc,eACb,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA0D;OAEnE,CAAA,EAEL,kBAAC,OAAD;OAAK,WAAU;iBAAf,CAEE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,GAAD,EAAU,WAAU,8CAA+C,CAAA;SACnE,kBAAC,MAAD;UAAI,WAAU;oBAA4C;UAErD,CAAA;SACL,kBAAC,KAAD;UAAG,WAAU;oBAAoD;UAG7D,CAAA;SACA;WAGN,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,GAAD,EAAU,WAAU,4CAA6C,CAAA;SACjE,kBAAC,KAAD;UAAG,WAAU;oBAAwC;UAAuB,CAAA;SAC5E,kBAAC,KAAD;UAAG,WAAU;oBAAmC;UAA+B,CAAA;SAC/E,kBAAC,UAAD;UACE,MAAK;UACL,UAAA;UACA,OAAM;UACN,WAAU;oBAJZ,CAKC,eAEC,kBAAC,QAAD;WAAM,WAAU;qBAAiD;WAE1D,CAAA,CACA;;SACL;UACF;SACF,EAAA,CAAA;MAIP,MAAc,cACb,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA0D;OAEnE,CAAA,EAEL,kBAAC,OAAD;OAAK,WAAU;iBAAf;QAEE,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,+BAAgC,CAAA,EAChD,kBAAC,MAAD;YAAI,WAAU;sBAA4C;YAAoB,CAAA,CAC1E;;UACN,kBAAC,KAAD;WAAG,WAAU;qBAAmC;WAG5C,CAAA;UACJ,kBAAC,UAAD;WACE,MAAK;WACL,SAAS;WACT,WAAU;qBAHZ,CAIC,8BAEC,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA,CAC7B;;UACL;;QAEN,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAY,WAAU,+BAAgC,CAAA,EACtD,kBAAC,MAAD;YAAI,WAAU;sBAA4C;YAErD,CAAA,CACD;;UACN,kBAAC,KAAD;WAAG,WAAU;qBAAmC;WAG5C,CAAA;UACJ,kBAAC,UAAD;WACE,MAAK;WACL,SAAS;WACT,WAAU;qBAHZ,CAIC,8BAEC,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA,CAC7B;;UACL;;QAEN,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAS,WAAU,+BAAgC,CAAA,EACnD,kBAAC,MAAD;YAAI,WAAU;sBAA4C;YAAmB,CAAA,CACzE;;UACN,kBAAC,KAAD;WAAG,WAAU;qBAAmC;WAG5C,CAAA;UACJ,kBAAC,UAAD;WACE,MAAK;WACL,SAAS;WACT,WAAU;qBAHZ,CAIC,8BAEC,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA,CAC7B;;UACL;;QACF;SACF,EAAA,CAAA;MAIP,MAAc,mBACb,kBAAC,OAAD,EAAA,UAAA;OACE,kBAAC,MAAD;QAAI,WAAU;kBAA0D;QAEnE,CAAA;OAGL,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,+CAAgD,CAAA,EAChE,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAGvC,CAAA,CACA;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAc,KAAK,MAClB,kBAAC,OAAD;SAEE,WAAU;mBAFZ,CAIE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,MAAD;WAAI,WAAU;qBAAyC,EAAK;WAAW,CAAA,EACvE,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAK;WACJ,CAAA,CACA;aACN,kBAAC,QAAD;UACE,iBAAc;UACd,OAAM;UACN,WAAW,EACT,oHACA,EAAK,UAAU,yBAAyB,eACzC;oBAED,kBAAC,QAAD,EACE,WAAW,EACT,kIACA,EAAK,UAAU,kBAAkB,kBAClC,EACD,CAAA;UACG,CAAA,CACH;WAxBC,EAAK,GAwBN,CACN;QACE,CAAA;OACF,EAAA,CAAA;MAEJ;;IACF,CAAA,CACF;KACK"}
1
+ {"version":3,"file":"InvestorProfilePage.js","names":[],"sources":["../../../../src/kadaikodi/pages/investor/InvestorProfilePage.tsx"],"sourcesContent":["/**\n * Investor Profile Page\n * @module kadaikodi/pages/investor\n *\n * 6-tab profile (personal / investment / portfolio / documents / security /\n * notifications).\n *\n * Wiring rules (no fake success anywhere):\n * - IDENTITY (name, email, phone, photo) and AUTH (password, 2FA, sessions) are\n * platform-owned (Burdenoff account). They are shown DISPLAY-ONLY from\n * `currentUser` and the user is routed to Account Security to change them.\n * - APP-OWNED PROFILE + PREFERENCE fields (company / address / investor type /\n * sectors / risk) have no server of their own, so they are edited and\n * genuinely persisted client-side (localStorage, per user) — a real save that\n * survives reload, not a mutation no-op.\n * - KYC/documents and notification delivery have no backend yet, so they are\n * rendered honestly disabled (\"coming soon\") rather than faking success.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport {\n User,\n Mail,\n Phone,\n Save,\n X,\n Shield,\n ShieldCheck,\n Bell,\n TrendingUp,\n FileText,\n PieChart,\n Briefcase,\n DollarSign,\n Lock,\n Smartphone,\n Monitor,\n Edit3,\n Globe,\n Linkedin,\n Building2,\n ExternalLink,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useInvestments } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * App-owned profile fields the investor authors themselves. These are NOT\n * platform identity (name/email/phone live on the Burdenoff account) — there is\n * no kadaikodi investor-profile service, so they are persisted client-side.\n */\ninterface ProfilePreferences {\n // Investment Profile\n investorType: string;\n investmentRange: string;\n preferredSectors: string[];\n investmentHorizon: string;\n riskProfile: string;\n\n // Company/Organization Details\n companyName: string;\n designation: string;\n companyWebsite: string;\n linkedinProfile: string;\n\n // Address\n address: string;\n city: string;\n state: string;\n country: string;\n pincode: string;\n}\n\ninterface NotificationPreference {\n id: string;\n label: string;\n description: string;\n enabled: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Tab definition\n// ---------------------------------------------------------------------------\n\nconst tabs = [\n { id: 'personal', label: 'Personal Info', Icon: User },\n { id: 'investment', label: 'Investment Profile', Icon: TrendingUp },\n { id: 'portfolio', label: 'Portfolio', Icon: PieChart },\n { id: 'documents', label: 'Documents', Icon: FileText },\n { id: 'security', label: 'Security', Icon: Shield },\n { id: 'notifications', label: 'Notifications', Icon: Bell },\n] as const;\n\ntype TabId = (typeof tabs)[number]['id'];\n\n// ---------------------------------------------------------------------------\n// Static option lists (preference selectors — local UI state, not fabricated data)\n// ---------------------------------------------------------------------------\n\nconst sectorOptions = [\n 'Food & Beverage',\n 'Quick Commerce',\n 'Cloud Kitchen',\n 'Retail',\n 'Technology',\n 'Healthcare',\n 'Education',\n 'Logistics',\n 'FinTech',\n];\n\n// ---------------------------------------------------------------------------\n// Client-side persistence (real — survives reload, scoped per user)\n// ---------------------------------------------------------------------------\n\nconst EMPTY_PREFERENCES: ProfilePreferences = {\n investorType: '',\n investmentRange: '',\n preferredSectors: [],\n investmentHorizon: '',\n riskProfile: '',\n companyName: '',\n designation: '',\n companyWebsite: '',\n linkedinProfile: '',\n address: '',\n city: '',\n state: '',\n country: '',\n pincode: '',\n};\n\nfunction preferencesStorageKey(userId: string): string {\n return `kadaikodi:investor-profile:${userId}`;\n}\n\nfunction loadPreferences(userId: string): ProfilePreferences {\n if (!userId || typeof window === 'undefined') return EMPTY_PREFERENCES;\n try {\n const raw = window.localStorage.getItem(preferencesStorageKey(userId));\n if (!raw) return EMPTY_PREFERENCES;\n const parsed = JSON.parse(raw) as Partial<ProfilePreferences>;\n return {\n ...EMPTY_PREFERENCES,\n ...parsed,\n preferredSectors: Array.isArray(parsed.preferredSectors) ? parsed.preferredSectors : [],\n };\n } catch {\n return EMPTY_PREFERENCES;\n }\n}\n\nfunction savePreferences(userId: string, prefs: ProfilePreferences): void {\n if (!userId || typeof window === 'undefined') return;\n window.localStorage.setItem(preferencesStorageKey(userId), JSON.stringify(prefs));\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorProfilePage() {\n const { currentUser, navigateTo } = useKadaikodi();\n const { data: investments = [] } = useInvestments(currentUser?.id || '');\n\n const [activeTab, setActiveTab] = useState<TabId>('personal');\n const [isEditing, setIsEditing] = useState(false);\n const [saveMessage, setSaveMessage] = useState('');\n\n // Identity is display-only, sourced from the signed-in account — never edited here.\n const identity = useMemo(\n () => ({\n firstName: currentUser?.firstName ?? currentUser?.name?.split(' ')[0] ?? '',\n lastName: currentUser?.lastName ?? currentUser?.name?.split(' ').slice(1).join(' ') ?? '',\n email: currentUser?.email ?? '',\n phone: currentUser?.phone ?? '',\n profileImage: currentUser?.avatar ?? currentUser?.profilePicture ?? '',\n }),\n [currentUser]\n );\n\n // App-owned preferences: editable, genuinely persisted client-side.\n const [preferences, setPreferences] = useState<ProfilePreferences>(() =>\n loadPreferences(currentUser?.id ?? '')\n );\n\n const portfolioStats = useMemo(() => {\n const totalInvested = investments.reduce((sum, inv) => sum + inv.investedAmount, 0);\n const portfolioValue = investments.reduce((sum, inv) => sum + inv.currentValue, 0);\n const totalReturns = investments.reduce((sum, inv) => sum + inv.returns, 0);\n\n return {\n totalInvested,\n portfolioValue,\n totalReturns,\n activeInvestments: investments.length,\n };\n }, [investments]);\n\n // Notification delivery is not wired to any backend yet — shown as an honest,\n // disabled preview so we never imply we can turn real emails on/off.\n const notifications: NotificationPreference[] = [\n {\n id: 'opportunities',\n label: 'New Investment Opportunities',\n description: 'Get notified about new investment opportunities matching your profile',\n enabled: true,\n },\n {\n id: 'updates',\n label: 'Portfolio Updates',\n description: 'Regular updates on your portfolio performance',\n enabled: true,\n },\n {\n id: 'reports',\n label: 'Monthly Reports',\n description: 'Detailed monthly investment reports',\n enabled: true,\n },\n {\n id: 'events',\n label: 'Investor Events',\n description: 'Invitations to investor meetups and events',\n enabled: false,\n },\n {\n id: 'news',\n label: 'Market News',\n description: 'Important market news and updates',\n enabled: true,\n },\n {\n id: 'dividends',\n label: 'Dividend Alerts',\n description: 'Notifications when dividends are credited to your account',\n enabled: true,\n },\n ];\n\n const handlePreferenceChange = useCallback(\n (field: keyof ProfilePreferences, value: string | string[]) => {\n setPreferences((prev) => ({ ...prev, [field]: value }));\n },\n []\n );\n\n const handleSave = useCallback(() => {\n // Real persistence: writes to localStorage synchronously and survives reload.\n savePreferences(currentUser?.id ?? '', preferences);\n setIsEditing(false);\n setSaveMessage('Saved on this device');\n // Only clears the confirmation banner — the save itself already happened above.\n window.setTimeout(() => setSaveMessage(''), 3000);\n }, [currentUser?.id, preferences]);\n\n const handleCancel = useCallback(() => {\n setIsEditing(false);\n setPreferences(loadPreferences(currentUser?.id ?? ''));\n }, [currentUser?.id]);\n\n const goToAccountSecurity = useCallback(() => navigateTo('/auth/security'), [navigateTo]);\n\n const displayName =\n [identity.firstName, identity.lastName].filter(Boolean).join(' ') || 'Investor';\n\n return (\n <PageLayout\n title=\"Investor Profile\"\n description=\"Manage your investment profile and preferences\"\n actions={\n <div className=\"flex items-center gap-2\">\n {saveMessage && (\n <span className=\"text-sm font-medium text-status-success-text\">{saveMessage}</span>\n )}\n {!isEditing ? (\n <>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <ShieldCheck className=\"h-4 w-4\" />\n Account Security\n </button>\n <button\n type=\"button\"\n onClick={() => setIsEditing(true)}\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 <Edit3 className=\"h-4 w-4\" />\n Edit Profile\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <X className=\"h-4 w-4\" />\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\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 <Save className=\"h-4 w-4\" />\n Save Changes\n </button>\n </>\n )}\n </div>\n }\n >\n <PagePurpose className=\"mb-6\">\n Your investor identity and how the platform tailors deals to you. Your name, email, phone\n and photo come from your Burdenoff account and are managed in Account Security; here you set\n your investment profile (preferred sectors, ticket size and risk tolerance) so you see the\n right opportunities, and review your portfolio at a glance.\n </PagePurpose>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-4\">\n {/* Sidebar */}\n <div className=\"lg:col-span-1\">\n {/* Profile Card — the one emphasis zone for this page */}\n <EmphasisPanel className=\"p-4 sm:p-6\">\n <div className=\"text-center\">\n <div className=\"relative mx-auto inline-block\">\n <div className=\"h-20 w-20 overflow-hidden rounded-full bg-bg-sunken sm:h-24 sm:w-24\">\n {identity.profileImage ? (\n <img\n src={identity.profileImage}\n alt=\"Profile\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"flex h-full w-full items-center justify-center\">\n <User className=\"h-10 w-10 text-text-secondary\" />\n </div>\n )}\n </div>\n </div>\n <h3 className=\"mt-3 text-base font-semibold text-text-primary sm:text-lg\">\n {displayName}\n </h3>\n {preferences.investorType && (\n <p className=\"text-sm text-text-secondary\">{preferences.investorType}</p>\n )}\n {preferences.companyName && (\n <p className=\"mt-1 truncate text-xs text-text-secondary\">\n {preferences.companyName}\n </p>\n )}\n </div>\n\n {/* Quick Stats */}\n <div className=\"mt-5 space-y-3 border-t border-border-subtle pt-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary sm:text-sm\">Portfolio Value</span>\n <span className=\"text-xs font-semibold text-primary sm:text-sm\">\n {formatCurrency(portfolioStats.portfolioValue, { minimumFractionDigits: 0 })}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary sm:text-sm\">Active Investments</span>\n <span className=\"text-xs font-semibold text-text-primary sm:text-sm\">\n {portfolioStats.activeInvestments}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary sm:text-sm\">Total Returns</span>\n <span className=\"text-xs font-semibold text-status-success-text sm:text-sm\">\n +{formatCurrency(portfolioStats.totalReturns, { minimumFractionDigits: 0 })}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary sm:text-sm\">Total Invested</span>\n <span className=\"text-xs font-semibold text-text-primary sm:text-sm\">\n {formatCurrency(portfolioStats.totalInvested, { minimumFractionDigits: 0 })}\n </span>\n </div>\n </div>\n </EmphasisPanel>\n\n {/* Mobile: Horizontal scrolling tabs */}\n <div className=\"mt-4 flex gap-2 overflow-x-auto pb-2 lg:hidden\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex shrink-0 items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors',\n activeTab === tab.id\n ? 'bg-action-primary-bg text-action-primary-text shadow-sm'\n : 'bg-bg-surface text-text-primary hover:bg-accent'\n )}\n >\n <tab.Icon className=\"h-4 w-4 shrink-0\" />\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Desktop: Vertical tabs */}\n <div className=\"mt-4 hidden space-y-2 lg:block\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm font-medium transition-colors',\n activeTab === tab.id\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary hover:bg-accent'\n )}\n >\n <tab.Icon className=\"h-4 w-4\" />\n {tab.label}\n </button>\n ))}\n </div>\n </div>\n\n {/* Content Area */}\n <div className=\"lg:col-span-3\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6 lg:p-8\">\n {/* ==================== Personal Info Tab ==================== */}\n {activeTab === 'personal' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Personal Information\n </h2>\n\n <div className=\"space-y-6\">\n {/* Identity is account-owned — display only, managed in Account Security. */}\n <div className=\"flex flex-col gap-3 rounded-lg border border-border-subtle bg-bg-sunken/40 p-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-start gap-3\">\n <ShieldCheck className=\"mt-0.5 h-5 w-5 shrink-0 text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">\n Your name, email, phone and photo come from your Burdenoff account. To\n change them, open Account Security.\n </p>\n </div>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex shrink-0 items-center gap-1.5 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Account Security\n <ExternalLink className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n\n {/* Name & Contact — display only (identity) */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n First Name\n </label>\n <input\n type=\"text\"\n value={identity.firstName}\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2 text-sm text-text-secondary focus:outline-none\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={identity.lastName}\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2 text-sm text-text-secondary focus:outline-none\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Email Address\n </label>\n <div className=\"relative\">\n <Mail className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"email\"\n value={identity.email}\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken py-2 pl-10 pr-3 text-sm text-text-secondary focus:outline-none\"\n />\n </div>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Phone Number\n </label>\n <div className=\"relative\">\n <Phone className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"tel\"\n value={identity.phone}\n readOnly\n placeholder=\"Add in Account Security\"\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken py-2 pl-10 pr-3 text-sm text-text-secondary placeholder:text-text-secondary focus:outline-none\"\n />\n </div>\n </div>\n </div>\n\n {/* Professional Details — app-owned, editable + saved on this device */}\n <div className=\"border-t border-border-subtle pt-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary sm:text-base\">\n Professional Details\n </h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Company/Organization\n </label>\n <div className=\"relative\">\n <Building2 className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n value={preferences.companyName}\n onChange={(e) => handlePreferenceChange('companyName', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-3 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Designation\n </label>\n <input\n type=\"text\"\n value={preferences.designation}\n onChange={(e) => handlePreferenceChange('designation', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Company Website\n </label>\n <div className=\"relative\">\n <Globe className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n value={preferences.companyWebsite}\n onChange={(e) =>\n handlePreferenceChange('companyWebsite', e.target.value)\n }\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-3 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n LinkedIn Profile\n </label>\n <div className=\"relative\">\n <Linkedin className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n value={preferences.linkedinProfile}\n onChange={(e) =>\n handlePreferenceChange('linkedinProfile', e.target.value)\n }\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-3 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n </div>\n </div>\n\n {/* Address — app-owned, editable + saved on this device */}\n <div className=\"border-t border-border-subtle pt-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary sm:text-base\">\n Address\n </h3>\n <div className=\"space-y-4\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Street Address\n </label>\n <textarea\n rows={2}\n value={preferences.address}\n onChange={(e) => handlePreferenceChange('address', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n City\n </label>\n <input\n type=\"text\"\n value={preferences.city}\n onChange={(e) => handlePreferenceChange('city', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n State\n </label>\n <input\n type=\"text\"\n value={preferences.state}\n onChange={(e) => handlePreferenceChange('state', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Country\n </label>\n <input\n type=\"text\"\n value={preferences.country}\n onChange={(e) => handlePreferenceChange('country', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Pincode\n </label>\n <input\n type=\"text\"\n value={preferences.pincode}\n onChange={(e) => handlePreferenceChange('pincode', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* ==================== Investment Profile Tab ==================== */}\n {activeTab === 'investment' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Investment Profile\n </h2>\n\n <div className=\"space-y-6\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6\">\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Investor Type\n </label>\n <select\n value={preferences.investorType}\n onChange={(e) => handlePreferenceChange('investorType', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select investor type</option>\n <option>Angel Investor</option>\n <option>Venture Capitalist</option>\n <option>Private Equity</option>\n <option>Strategic Investor</option>\n </select>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Investment Range\n </label>\n <select\n value={preferences.investmentRange}\n onChange={(e) => handlePreferenceChange('investmentRange', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select range</option>\n <option>1L - 5L</option>\n <option>5L - 25L</option>\n <option>25L - 1Cr</option>\n <option>1Cr+</option>\n </select>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Investment Horizon\n </label>\n <select\n value={preferences.investmentHorizon}\n onChange={(e) =>\n handlePreferenceChange('investmentHorizon', e.target.value)\n }\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select horizon</option>\n <option>1-2 years</option>\n <option>3-5 years</option>\n <option>5-7 years</option>\n <option>7+ years</option>\n </select>\n </div>\n <div>\n <label className=\"mb-1 block text-sm font-medium text-text-primary\">\n Risk Profile\n </label>\n <select\n value={preferences.riskProfile}\n onChange={(e) => handlePreferenceChange('riskProfile', e.target.value)}\n disabled={!isEditing}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary disabled:bg-bg-sunken disabled:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select risk profile</option>\n <option>Conservative</option>\n <option>Moderate</option>\n <option>Aggressive</option>\n </select>\n </div>\n </div>\n\n {/* Preferred Sectors */}\n <div>\n <label className=\"mb-3 block text-sm font-medium text-text-primary\">\n Preferred Sectors\n </label>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {sectorOptions.map((sector) => (\n <label key={sector} className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n checked={preferences.preferredSectors.includes(sector)}\n onChange={(e) => {\n if (e.target.checked) {\n handlePreferenceChange('preferredSectors', [\n ...preferences.preferredSectors,\n sector,\n ]);\n } else {\n handlePreferenceChange(\n 'preferredSectors',\n preferences.preferredSectors.filter((s) => s !== sector)\n );\n }\n }}\n disabled={!isEditing}\n className=\"h-4 w-4 rounded border-border-subtle text-primary focus:ring-[var(--color-focus-ring)]\"\n />\n <span className=\"text-sm text-text-primary\">{sector}</span>\n </label>\n ))}\n </div>\n </div>\n\n {/* Risk Tolerance Visual */}\n <div className=\"rounded-lg border border-border-subtle p-4\">\n <div className=\"mb-2 flex items-center justify-between\">\n <p className=\"text-sm font-medium text-text-primary\">Risk Tolerance</p>\n <span\n className={cn(\n 'text-sm font-semibold',\n preferences.riskProfile === 'Conservative'\n ? 'text-status-success-text'\n : preferences.riskProfile === 'Moderate'\n ? 'text-status-warning-text'\n : 'text-status-error-text'\n )}\n >\n {preferences.riskProfile}\n </span>\n </div>\n <div className=\"flex gap-1\">\n {(['Conservative', 'Moderate', 'Aggressive'] as const).map((level) => (\n <div\n key={level}\n className={cn(\n 'h-2.5 flex-1 rounded-full',\n level === 'Conservative' && 'bg-status-success-bg-subtle',\n level === 'Moderate' && 'bg-status-warning-bg-subtle',\n level === 'Aggressive' && 'bg-status-error-bg-subtle',\n level === preferences.riskProfile &&\n level === 'Conservative' &&\n 'bg-status-success-text',\n level === preferences.riskProfile &&\n level === 'Moderate' &&\n 'bg-status-warning-text',\n level === preferences.riskProfile &&\n level === 'Aggressive' &&\n 'bg-status-error-text'\n )}\n />\n ))}\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* ==================== Portfolio Tab ==================== */}\n {activeTab === 'portfolio' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Investment Portfolio\n </h2>\n\n {/* Portfolio Summary */}\n <div className=\"mb-8 grid grid-cols-2 gap-4 sm:grid-cols-4 sm:gap-6\">\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <DollarSign className=\"mb-2 h-7 w-7 text-primary sm:h-8 sm:w-8\" />\n <div className=\"text-lg font-bold text-text-primary sm:text-2xl\">\n {formatCurrency(portfolioStats.totalInvested, {\n minimumFractionDigits: 0,\n notation: 'compact',\n })}\n </div>\n <div className=\"text-xs text-text-secondary sm:text-sm\">Total Invested</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <Briefcase className=\"mb-2 h-7 w-7 text-text-primary sm:h-8 sm:w-8\" />\n <div className=\"text-lg font-bold text-text-primary sm:text-2xl\">\n {portfolioStats.activeInvestments}\n </div>\n <div className=\"text-xs text-text-secondary sm:text-sm\">Active Investments</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <TrendingUp className=\"mb-2 h-7 w-7 text-status-success-text sm:h-8 sm:w-8\" />\n <div className=\"text-lg font-bold text-text-primary sm:text-2xl\">\n {formatCurrency(portfolioStats.totalReturns, {\n minimumFractionDigits: 0,\n notation: 'compact',\n })}\n </div>\n <div className=\"text-xs text-text-secondary sm:text-sm\">Total Returns</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <PieChart className=\"mb-2 h-7 w-7 text-text-primary sm:h-8 sm:w-8\" />\n <div className=\"text-lg font-bold text-text-primary sm:text-2xl\">\n {formatCurrency(portfolioStats.portfolioValue, {\n minimumFractionDigits: 0,\n notation: 'compact',\n })}\n </div>\n <div className=\"text-xs text-text-secondary sm:text-sm\">Portfolio Value</div>\n </div>\n </div>\n\n {/* Active Investments List */}\n <div>\n <div className=\"mb-4 flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n Active Investments\n </h3>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/portfolio')}\n className=\"text-sm font-medium text-primary hover:underline\"\n >\n View full portfolio\n </button>\n </div>\n {investments.length === 0 ? (\n <p className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-4 text-sm text-text-secondary\">\n You don&apos;t have any active investments yet. Explore opportunities to start\n building your portfolio.\n </p>\n ) : (\n <div className=\"space-y-3\">\n {investments.map((investment) => (\n <button\n key={investment.id}\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"block w-full rounded-lg border border-border-subtle bg-bg-sunken/30 p-4 text-left hover:bg-accent/40 transition-colors\"\n >\n <div className=\"mb-3 flex items-start justify-between\">\n <h4 className=\"text-sm font-medium text-text-primary sm:text-base\">\n {investment.cartName}\n </h4>\n <span\n className={cn(\n 'text-sm font-semibold',\n investment.returnsPercentage >= 0\n ? 'text-status-success-text'\n : 'text-status-error-text'\n )}\n >\n {investment.returnsPercentage >= 0 ? '+' : ''}\n {investment.returnsPercentage}%\n </span>\n </div>\n <div className=\"grid grid-cols-1 gap-3 text-sm sm:grid-cols-3\">\n <div>\n <span className=\"text-text-secondary\">Invested: </span>\n <span className=\"font-medium text-text-primary\">\n {formatCurrency(investment.investedAmount, {\n minimumFractionDigits: 0,\n })}\n </span>\n </div>\n <div>\n <span className=\"text-text-secondary\">Current Value: </span>\n <span className=\"font-medium text-text-primary\">\n {formatCurrency(investment.currentValue, {\n minimumFractionDigits: 0,\n })}\n </span>\n </div>\n <div>\n <span className=\"text-text-secondary\">Returns: </span>\n <span className=\"font-medium text-status-success-text\">\n {formatCurrency(\n investment.currentValue - investment.investedAmount,\n {\n minimumFractionDigits: 0,\n }\n )}\n </span>\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* ==================== Documents Tab ==================== */}\n {activeTab === 'documents' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Documents & KYC\n </h2>\n\n <div className=\"space-y-6\">\n {/* No KYC/documents backend yet — honest empty state rather than fabricated records. */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-6 text-center\">\n <FileText className=\"mx-auto mb-3 h-10 w-10 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">\n No documents on file yet\n </h3>\n <p className=\"mx-auto mt-1 max-w-md text-sm text-text-secondary\">\n Your KYC and investment documents will appear here once uploaded. Complete\n verification to unlock more opportunities.\n </p>\n </div>\n\n {/* Upload is not wired to a backend yet — honestly disabled, never a fake success. */}\n <div className=\"rounded-lg border-2 border-dashed border-border-subtle p-6 text-center opacity-70\">\n <FileText className=\"mx-auto mb-2 h-8 w-8 text-text-secondary\" />\n <p className=\"text-sm font-medium text-text-primary\">Upload New Document</p>\n <p className=\"mt-1 text-xs text-text-secondary\">PDF, JPG, or PNG up to 10MB</p>\n <button\n type=\"button\"\n disabled\n title=\"Document upload is coming soon\"\n className=\"mt-3 inline-flex cursor-not-allowed items-center gap-2 rounded-lg bg-bg-sunken px-4 py-2 text-sm font-medium text-text-secondary\"\n >\n Choose File\n <span className=\"rounded-full bg-bg-surface px-2 py-0.5 text-xs\">\n Coming soon\n </span>\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* ==================== Security Tab ==================== */}\n {activeTab === 'security' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Security Settings\n </h2>\n\n <div className=\"space-y-6\">\n {/* Password, 2FA and session management are platform-owned — route to Account Security. */}\n <div className=\"rounded-lg border border-border-subtle p-4 sm:p-6\">\n <div className=\"flex items-center gap-3 mb-3\">\n <Lock className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">Change Password</h3>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n Your password is managed by your Burdenoff account. Update it securely in\n Account Security.\n </p>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Manage in Account Security\n <ExternalLink className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle p-4 sm:p-6\">\n <div className=\"flex items-center gap-3 mb-3\">\n <Smartphone className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">\n Two-Factor Authentication\n </h3>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n Add an extra layer of security to your account. Two-factor authentication is\n configured in Account Security.\n </p>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Manage in Account Security\n <ExternalLink className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle p-4 sm:p-6\">\n <div className=\"flex items-center gap-3 mb-3\">\n <Monitor className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">Login Activity</h3>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">\n Review recent sign-ins and active sessions for your account in Account\n Security.\n </p>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Manage in Account Security\n <ExternalLink className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* ==================== Notifications Tab ==================== */}\n {activeTab === 'notifications' && (\n <div>\n <h2 className=\"mb-6 text-lg font-semibold text-text-primary sm:text-xl\">\n Notification Preferences\n </h2>\n\n {/* Notification delivery has no investor backend yet — honest, disabled preview. */}\n <div className=\"mb-4 flex items-start gap-3 rounded-lg border border-border-subtle bg-bg-sunken/40 p-4\">\n <Bell className=\"mt-0.5 h-5 w-5 shrink-0 text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">\n Notification controls are coming soon. This is a preview of the alerts\n you&apos;ll be able to manage here — the switches are not active yet.\n </p>\n </div>\n\n <div className=\"space-y-4\">\n {notifications.map((item) => (\n <div\n key={item.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle bg-bg-sunken/30 p-4\"\n >\n <div className=\"flex-1 pr-4\">\n <h4 className=\"text-sm font-medium text-text-primary\">{item.label}</h4>\n <p className=\"mt-0.5 text-xs text-text-secondary sm:text-sm\">\n {item.description}\n </p>\n </div>\n <span\n aria-disabled=\"true\"\n title=\"Coming soon\"\n className={cn(\n 'relative inline-flex h-6 w-11 shrink-0 cursor-not-allowed rounded-full opacity-50 transition-colors duration-200',\n item.enabled ? 'bg-action-primary-bg' : 'bg-bg-sunken'\n )}\n >\n <span\n className={cn(\n 'pointer-events-none inline-block h-5 w-5 translate-y-0.5 rounded-full bg-white shadow ring-0 transition-transform duration-200',\n item.enabled ? 'translate-x-5' : 'translate-x-0.5'\n )}\n />\n </span>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}