@burdenoff/microfe-kadaikodi 2026.704.3 → 2026.704.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/kadaikodi/KadaikodiRoutes.js +34 -26
- package/dist/kadaikodi/KadaikodiRoutes.js.map +1 -1
- package/dist/kadaikodi/components/viz/AllocationBar.js +68 -0
- package/dist/kadaikodi/components/viz/AllocationBar.js.map +1 -0
- package/dist/kadaikodi/components/viz/AreaChart.js +102 -0
- package/dist/kadaikodi/components/viz/AreaChart.js.map +1 -0
- package/dist/kadaikodi/components/viz/AvatarStack.js +36 -0
- package/dist/kadaikodi/components/viz/AvatarStack.js.map +1 -0
- package/dist/kadaikodi/components/viz/BarChart.js +83 -0
- package/dist/kadaikodi/components/viz/BarChart.js.map +1 -0
- package/dist/kadaikodi/components/viz/CertificateCard.js +4 -0
- package/dist/kadaikodi/components/viz/DonutChart.js +109 -0
- package/dist/kadaikodi/components/viz/DonutChart.js.map +1 -0
- package/dist/kadaikodi/components/viz/HBarFunnel.js +54 -0
- package/dist/kadaikodi/components/viz/HBarFunnel.js.map +1 -0
- package/dist/kadaikodi/components/viz/Heatmap.js +3 -0
- package/dist/kadaikodi/components/viz/KanbanBoard.js +50 -0
- package/dist/kadaikodi/components/viz/KanbanBoard.js.map +1 -0
- package/dist/kadaikodi/components/viz/LineChart.js +4 -0
- package/dist/kadaikodi/components/viz/OrgTree.js +2 -0
- package/dist/kadaikodi/components/viz/PathSteps.js +3 -0
- package/dist/kadaikodi/components/viz/ProgressRing.js +68 -0
- package/dist/kadaikodi/components/viz/ProgressRing.js.map +1 -0
- package/dist/kadaikodi/components/viz/RatingStars.js +51 -0
- package/dist/kadaikodi/components/viz/RatingStars.js.map +1 -0
- package/dist/kadaikodi/components/viz/SegmentedTabs.js +69 -0
- package/dist/kadaikodi/components/viz/SegmentedTabs.js.map +1 -0
- package/dist/kadaikodi/components/viz/SkillBar.js +3 -0
- package/dist/kadaikodi/components/viz/Sparkline.js +74 -0
- package/dist/kadaikodi/components/viz/Sparkline.js.map +1 -0
- package/dist/kadaikodi/components/viz/StatCard.js +60 -0
- package/dist/kadaikodi/components/viz/StatCard.js.map +1 -0
- package/dist/kadaikodi/components/viz/StepProgress.js +64 -0
- package/dist/kadaikodi/components/viz/StepProgress.js.map +1 -0
- package/dist/kadaikodi/components/viz/Timeline.js +66 -0
- package/dist/kadaikodi/components/viz/Timeline.js.map +1 -0
- package/dist/kadaikodi/components/viz/index.js +23 -0
- package/dist/kadaikodi/components/viz/lib/Avatar.js +30 -0
- package/dist/kadaikodi/components/viz/lib/Avatar.js.map +1 -0
- package/dist/kadaikodi/components/viz/lib/CartesianFrame.js +119 -0
- package/dist/kadaikodi/components/viz/lib/CartesianFrame.js.map +1 -0
- package/dist/kadaikodi/components/viz/lib/ResponsiveSvg.js +35 -0
- package/dist/kadaikodi/components/viz/lib/ResponsiveSvg.js.map +1 -0
- package/dist/kadaikodi/components/viz/lib/format.js +21 -0
- package/dist/kadaikodi/components/viz/lib/format.js.map +1 -0
- package/dist/kadaikodi/components/viz/lib/geometry.js +61 -0
- package/dist/kadaikodi/components/viz/lib/geometry.js.map +1 -0
- package/dist/kadaikodi/components/viz/lib/hooks.js +39 -0
- package/dist/kadaikodi/components/viz/lib/hooks.js.map +1 -0
- package/dist/kadaikodi/components/viz/lib/palette.js +27 -0
- package/dist/kadaikodi/components/viz/lib/palette.js.map +1 -0
- package/dist/kadaikodi/hooks/useKadaikodiApi.js +84 -6
- package/dist/kadaikodi/hooks/useKadaikodiApi.js.map +1 -1
- package/dist/kadaikodi/pages/HomePage.js +373 -631
- package/dist/kadaikodi/pages/HomePage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js +304 -169
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminDashboard.js +255 -271
- package/dist/kadaikodi/pages/admin/AdminDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminFinancialPage.js +185 -125
- package/dist/kadaikodi/pages/admin/AdminFinancialPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminOrdersPage.js +141 -102
- package/dist/kadaikodi/pages/admin/AdminOrdersPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminSettingsPage.js +332 -276
- package/dist/kadaikodi/pages/admin/AdminSettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/CartManagementPage.js +564 -729
- package/dist/kadaikodi/pages/admin/CartManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/UserManagementPage.js +310 -366
- package/dist/kadaikodi/pages/admin/UserManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js +201 -120
- package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js +290 -257
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js +173 -194
- package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartOwnerProfilePage.js +270 -228
- package/dist/kadaikodi/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartServiceConfigPage.js +194 -173
- package/dist/kadaikodi/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js +428 -347
- package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js +332 -0
- package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js.map +1 -0
- package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js +373 -0
- package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js.map +1 -0
- package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js +294 -162
- package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js +180 -181
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/HelpSupportPage.js +310 -317
- package/dist/kadaikodi/pages/common/HelpSupportPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/NotificationCenterPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/SettingsPage.js +502 -586
- package/dist/kadaikodi/pages/common/SettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/BookingDetailsPage.js +239 -156
- package/dist/kadaikodi/pages/customer/BookingDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDetailPage.js +405 -248
- package/dist/kadaikodi/pages/customer/CartDetailPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js +258 -232
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CheckoutPage.js +254 -205
- package/dist/kadaikodi/pages/customer/CheckoutPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CustomerDashboard.js +5 -5
- package/dist/kadaikodi/pages/customer/CustomerDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.js +189 -199
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js +272 -230
- package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/FavoritesPage.js +150 -413
- package/dist/kadaikodi/pages/customer/FavoritesPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/OrderHistoryPage.js +173 -134
- package/dist/kadaikodi/pages/customer/OrderHistoryPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.js +411 -305
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/ReviewsPage.js +310 -406
- package/dist/kadaikodi/pages/customer/ReviewsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/SavedAddressesPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/shared.js +181 -0
- package/dist/kadaikodi/pages/customer/shared.js.map +1 -0
- package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js +438 -311
- package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js +320 -293
- package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js +159 -91
- package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorDashboard.js +137 -107
- package/dist/kadaikodi/pages/investor/InvestorDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorInvestmentsPage.js +157 -135
- package/dist/kadaikodi/pages/investor/InvestorInvestmentsPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js +280 -206
- package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorProfilePage.js +441 -514
- package/dist/kadaikodi/pages/investor/InvestorProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.js +428 -431
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerDashboard.js +328 -445
- package/dist/kadaikodi/pages/worker/WorkerDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js +141 -164
- package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerProfilePage.js +360 -288
- package/dist/kadaikodi/pages/worker/WorkerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js +303 -281
- package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js.map +1 -1
- 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's split across the carts you'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":";;;;;;;;;;;;AAgCA,SAAS,EAAO,GAAe;AAC7B,QAAO,GAAG,IAAQ,IAAI,MAAM,KAAK,EAAM,QAAQ,EAAE,CAAC;;AAOpD,SAAgB,IAAwB;CACtC,IAAM,EAAE,eAAY,mBAAgB,GAAc,EAC5C,EAAE,MAAM,IAAc,EAAE,EAAE,iBAAc,EAAe,GAAa,MAAM,GAAG,EAC7E,CAAC,GAAW,KAAgB,EAChC,WACD,EAEK,IAAgB,EAAY,QAAQ,GAAG,MAAM,IAAI,EAAE,gBAAgB,EAAE,EACrE,IAAe,EAAY,QAAQ,GAAG,MAAM,IAAI,EAAE,cAAc,EAAE,EAClE,IAAe,IAAe,GAC9B,IAAoB,IAAgB,IAAK,IAAe,IAAiB,MAAM,GAC/E,IAAc,EAAY,QAAQ,MAAM,EAAE,WAAW,SAAS,CAAC,QAG/D,IAAgB,QAElB,EAAY,QAAgC,GAAK,OAC/C,EAAI,EAAI,aAAa,EAAI,EAAI,aAAa,KAAK,EAAI,cAC5C,IACN,EAAE,CAAC,EACR,CAAC,EAAY,CACd;AAeD,QAbI,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAe,aAAY;YAC3C,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAK,WAAU,8EAA+E,CAAA,EAC9F,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAA6B,CAAA,CACpE;;GACF,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EAAY,OAAM;EAAe,aAAY;YAA7C;GACE,kBAAC,GAAD;IAAa,WAAU;cAAO;IAIhB,CAAA;GAGd,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAAiD;IAA0B,CAAA,EACzF,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;MACpC,OAAO,EAAe,GAAe,EAAE,uBAAuB,GAAG,CAAC;MAClE,OAAM;MACN,OAAM;MACN,YAAY,GAAG,EAAY;MAC3B,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA;MACzC,OAAO,EAAe,GAAc,EAAE,uBAAuB,GAAG,CAAC;MACjE,OAAM;MACN,OAAO,KAAqB,IAAI,OAAO;MACvC,YAAY,EAAO,EAAkB;MACrC,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA;MACxC,OAAO,EAAe,KAAK,IAAI,EAAa,EAAE,EAAE,uBAAuB,GAAG,CAAC;MAC3E,OAAM;MACN,OAAO,KAAgB,IAAI,OAAO;MAClC,YAAY,EAAO,EAAkB;MACrC,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;MACvC,OAAO,OAAO,EAAY,OAAO;MACjC,OAAM;MACN,CAAA;KACE;MACQ,EAAA,CAAA;GAGhB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAEX;MACE;OAAE,KAAK;OAAY,OAAO;OAAY,MAAM;OAAW;MACvD;OACE,KAAK;OACL,OAAO,gBAAgB,EAAY,OAAO;OAC1C,MAAM;OACP;MACD;OAAE,KAAK;OAAgB,OAAO;OAAgB,MAAM;OAAY;MACjE,CACD,KAAK,EAAE,QAAK,UAAO,cACnB,kBAAC,UAAD;MAEE,MAAK;MACL,eAAe,EAAa,EAAI;MAChC,WAAW,EACT,6FACA,MAAc,IACV,gDACA,8CACL;gBATH,CAWE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EACM;QAZF,EAYE,CACT;KACE,CAAA,EAEN,kBAAC,OAAD;KAAK,WAAU;eAAf;MAEG,MAAc,cACb,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAY,WAAW,IACtB,kBAAC,GAAD;QACE,cAAa;QACb,OAAM;QACN,aAAY;QACZ,QACE,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAW,0BAA0B;SACpD,WAAU;mBACX;SAEQ,CAAA;QAEX,CAAA,GAEF,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBAAiD;QAE1D,CAAA,EACL,kBAAC,OAAD;QAAK,WAAU;kBACZ,OAAO,QAAQ,EAAc,CAAC,KAAK,CAAC,GAAU,OAC7C,kBAAC,OAAD;SAAoB,WAAU;mBAA9B;UACE,kBAAC,QAAD;WAAM,WAAU;qBAA2C;WAAgB,CAAA;UAC3E,kBAAC,OAAD;WAAK,WAAU;qBACb,kBAAC,OAAD;YACE,WAAU;YACV,OAAO,EACL,OAAO,GAAG,IAAe,IAAK,IAAQ,IAAgB,MAAM,EAAE,IAC/D;sBAED,kBAAC,QAAD;aAAM,WAAU;uBAAhB,CACG,IAAe,KAAM,IAAQ,IAAgB,KAAK,QAAQ,EAAE,GAAG,GAAE,IAC7D;;YACH,CAAA;WACF,CAAA;UACN,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAe,GAAO,EAAE,uBAAuB,GAAG,CAAC;WAC/C,CAAA;UACH;WAjBI,EAiBJ,CACN;QACE,CAAA,CACF,EAAA,CAAA;OAEJ,CAAA;MAIP,MAAc,iBACb,kBAAC,OAAD,EAAA,UACG,EAAY,WAAW,IACtB,kBAAC,GAAD;OACE,cAAa;OACb,OAAM;OACN,aAAY;OACZ,QACE,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAW,0BAA0B;QACpD,WAAU;kBACX;QAEQ,CAAA;OAEX,CAAA,GAEF,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAY,KAAK,MAAQ;QACxB,IAAM,IAAK,EAAI,eAAe,EAAI,gBAC5B,IAAQ,EAAI,iBAAiB,IAAK,IAAK,EAAI,iBAAkB,MAAM;AACzE,eACE,kBAAC,OAAD;SAEE,WAAU;mBAFZ;UAIE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,MAAD;aAAI,WAAU;uBACX,EAAI;aACF,CAAA,EACL,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAI;aACH,CAAA,CACA;eACN,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAe,EAAI,cAAc,EAAE,uBAAuB,GAAG,CAAC;aAC7D,CAAA,EACJ,kBAAC,KAAD;aACE,WAAW,EACT,WACA,KAAM,IAAI,6BAA6B,yBACxC;uBAJH;cAMG,EAAe,KAAK,IAAI,EAAG,EAAE,EAAE,uBAAuB,GAAG,CAAC;cAAC;cAC3D,EAAO,EAAM;cAAC;cACb;eACA;cACF;;UAEN,kBAAC,OAAD;WAAK,WAAU;qBAAf;YACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;aAAG,WAAU;uBAA8B;aAAY,CAAA,EACvD,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAe,EAAI,gBAAgB,EAAE,uBAAuB,GAAG,CAAC;aAC/D,CAAA,CACA,EAAA,CAAA;YACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;aAAG,WAAU;uBAA8B;aAAW,CAAA,EACtD,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAe,EAAI,SAAS,EAAE,uBAAuB,GAAG,CAAC;aACxD,CAAA,CACA,EAAA,CAAA;YACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;aAAG,WAAU;uBAA8B;aAAmB,CAAA,EAC9D,kBAAC,KAAD;aAAG,WAAU;uBAAb,CACG,EAAI,mBAAkB,IACrB;eACA,EAAA,CAAA;YACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;aAAG,WAAU;uBAA8B;aAAmB,CAAA,EAC9D,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAW,EAAI,gBAAgB;cAC9B,MAAM,KAAA;cACN,QAAQ,KAAA;cACT,CAAC;aACA,CAAA,CACA,EAAA,CAAA;YACF;;UAEN,kBAAC,OAAD;WAAK,WAAU;qBACb,kBAAC,UAAD;YACE,MAAK;YACL,eAAe,EAAW,yBAAyB,EAAI,KAAK;YAC5D,WAAU;sBAHZ,CAKE,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA,EAAA,eAEpB;;WACL,CAAA;UACF;WApEC,EAAI,GAoEL;SAER;OACE,CAAA,EAEJ,CAAA;MAIP,MAAc,kBACb,kBAAC,GAAD;OACE,cAAa;OACb,OAAM;OACN,aAAY;OACZ,CAAA;MAEA;OACF;;GACK"}
|
|
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've backed more carts, how it'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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"}
|