@burdenoff/microfe-kadaikodi 2026.626.2 → 2026.704.2
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/hooks/useKadaikodiApi.js +260 -105
- package/dist/kadaikodi/hooks/useKadaikodiApi.js.map +1 -1
- package/dist/kadaikodi/pages/HomePage.js +4 -4
- package/dist/kadaikodi/pages/HomePage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js +341 -461
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminDashboard.js +115 -399
- package/dist/kadaikodi/pages/admin/AdminDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminFinancialPage.js +140 -283
- package/dist/kadaikodi/pages/admin/AdminFinancialPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminOrdersPage.js +282 -453
- package/dist/kadaikodi/pages/admin/AdminOrdersPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminProfilePage.js +115 -242
- package/dist/kadaikodi/pages/admin/AdminProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminSettingsPage.js +2 -2
- package/dist/kadaikodi/pages/admin/AdminSettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/CartManagementPage.js +279 -333
- package/dist/kadaikodi/pages/admin/CartManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/UserManagementPage.js +299 -372
- package/dist/kadaikodi/pages/admin/UserManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js +503 -627
- package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js +339 -282
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js +329 -432
- package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartOwnerProfilePage.js +374 -384
- package/dist/kadaikodi/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartServiceConfigPage.js +249 -208
- package/dist/kadaikodi/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js +276 -279
- package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js +229 -447
- package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js +171 -627
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/HelpSupportPage.js +331 -415
- package/dist/kadaikodi/pages/common/HelpSupportPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/NotificationCenterPage.js +18 -670
- package/dist/kadaikodi/pages/common/NotificationCenterPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/SettingsPage.js +34 -46
- package/dist/kadaikodi/pages/common/SettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/BookingDetailsPage.js +193 -447
- package/dist/kadaikodi/pages/customer/BookingDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDetailPage.js +6 -6
- package/dist/kadaikodi/pages/customer/CartDetailPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js +2 -2
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CheckoutPage.js +4 -2
- package/dist/kadaikodi/pages/customer/CheckoutPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CustomerDashboard.js +191 -369
- package/dist/kadaikodi/pages/customer/CustomerDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.js +233 -389
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js +255 -215
- package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/FavoritesPage.js +141 -178
- package/dist/kadaikodi/pages/customer/FavoritesPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/OrderHistoryPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.js +155 -161
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/PaymentMethodsPage.js +76 -118
- package/dist/kadaikodi/pages/customer/PaymentMethodsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/ReviewsPage.js +14 -140
- package/dist/kadaikodi/pages/customer/ReviewsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/SavedAddressesPage.js +135 -213
- package/dist/kadaikodi/pages/customer/SavedAddressesPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js +272 -774
- package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js +258 -523
- package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js +112 -600
- package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorDashboard.js +128 -295
- package/dist/kadaikodi/pages/investor/InvestorDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorInvestmentsPage.js +205 -291
- package/dist/kadaikodi/pages/investor/InvestorInvestmentsPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js +159 -500
- package/dist/kadaikodi/pages/investor/InvestorPortfolioPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorProfilePage.js +426 -514
- package/dist/kadaikodi/pages/investor/InvestorProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.js +231 -225
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerDashboard.js +197 -301
- package/dist/kadaikodi/pages/worker/WorkerDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js +247 -399
- package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerProfilePage.js +294 -327
- package/dist/kadaikodi/pages/worker/WorkerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js +179 -397
- package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js.map +1 -1
- package/package.json +1 -1
- package/dist/kadaikodi/mocks/data.js +0 -1517
- package/dist/kadaikodi/mocks/data.js.map +0 -1
- package/dist/kadaikodi/mocks/users.js +0 -34
- package/dist/kadaikodi/mocks/users.js.map +0 -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 * asset allocation bars, category filter, transactions list, withdrawal action,\n * and performance metrics per investment.\n */\n\nimport { useState, useCallback, useMemo } from 'react';\nimport {\n Wallet,\n TrendingUp,\n TrendingDown,\n Briefcase,\n IndianRupee,\n Star,\n Eye,\n ArrowDownCircle,\n BarChart3,\n CreditCard,\n LayoutList,\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 { cn } from '../../utils/cn';\nimport { formatCurrency, formatDate } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types & mock data\n// ---------------------------------------------------------------------------\n\ninterface Investment {\n id: string;\n cartId: string;\n cartName: string;\n cartOwner: string;\n investmentDate: string;\n amount: number;\n currentValue: number;\n returns: number;\n returnsPercentage: number;\n ownership: number;\n status: 'active' | 'matured' | 'exited';\n monthlyRevenue: number;\n monthlyDividend: number;\n nextPayoutDate: string;\n riskLevel: 'low' | 'medium' | 'high';\n category: string;\n location: string;\n performanceMetrics: {\n monthlyOrders: number;\n averageRating: number;\n growthRate: number;\n };\n}\n\ninterface Transaction {\n id: string;\n type: 'investment' | 'dividend' | 'withdrawal';\n cartName: string;\n amount: number;\n date: string;\n status: 'completed' | 'pending' | 'failed';\n}\n\nconst mockInvestments: Investment[] = [\n {\n id: 'inv-001',\n cartId: 'SERV-001',\n cartName: 'Quick Cuts Salon',\n cartOwner: 'Ravi Kumar',\n investmentDate: '2023-06-15',\n amount: 50000,\n currentValue: 62500,\n returns: 12500,\n returnsPercentage: 25,\n ownership: 15,\n status: 'active',\n monthlyRevenue: 185000,\n monthlyDividend: 2775,\n nextPayoutDate: '2024-07-01',\n riskLevel: 'low',\n category: 'Personal Care & Beauty',\n location: 'Indiranagar, Bangalore',\n performanceMetrics: { monthlyOrders: 1250, averageRating: 4.8, growthRate: 12 },\n },\n {\n id: 'inv-002',\n cartId: 'SERV-003',\n cartName: 'Fix-It Mobile Repair',\n cartOwner: 'Amit Sharma',\n investmentDate: '2023-08-20',\n amount: 30000,\n currentValue: 35400,\n returns: 5400,\n returnsPercentage: 18,\n ownership: 10,\n status: 'active',\n monthlyRevenue: 120000,\n monthlyDividend: 1200,\n nextPayoutDate: '2024-07-01',\n riskLevel: 'medium',\n category: 'Repair & Maintenance',\n location: 'Jayanagar, Bangalore',\n performanceMetrics: { monthlyOrders: 890, averageRating: 4.6, growthRate: 8 },\n },\n {\n id: 'inv-003',\n cartId: 'SERV-005',\n cartName: 'Spotless Cleaning Services',\n cartOwner: 'Priya Cleaning',\n investmentDate: '2023-04-10',\n amount: 40000,\n currentValue: 52000,\n returns: 12000,\n returnsPercentage: 30,\n ownership: 20,\n status: 'active',\n monthlyRevenue: 95000,\n monthlyDividend: 1900,\n nextPayoutDate: '2024-07-01',\n riskLevel: 'low',\n category: 'Home Services',\n location: 'HSR Layout, Bangalore',\n performanceMetrics: { monthlyOrders: 1450, averageRating: 4.7, growthRate: 15 },\n },\n {\n id: 'inv-004',\n cartId: 'FOOD-001',\n cartName: 'Dosa Express',\n cartOwner: 'Rajesh Kumar',\n investmentDate: '2023-10-05',\n amount: 25000,\n currentValue: 27500,\n returns: 2500,\n returnsPercentage: 10,\n ownership: 5,\n status: 'active',\n monthlyRevenue: 150000,\n monthlyDividend: 750,\n nextPayoutDate: '2024-07-01',\n riskLevel: 'high',\n category: 'Food & Beverage',\n location: 'Koramangala, Bangalore',\n performanceMetrics: { monthlyOrders: 780, averageRating: 4.5, growthRate: 5 },\n },\n];\n\nconst mockTransactions: Transaction[] = [\n {\n id: 'txn-001',\n type: 'investment',\n cartName: 'Quick Cuts Salon',\n amount: 50000,\n date: '2023-06-15',\n status: 'completed',\n },\n {\n id: 'txn-002',\n type: 'dividend',\n cartName: 'Quick Cuts Salon',\n amount: 2775,\n date: '2024-06-01',\n status: 'completed',\n },\n {\n id: 'txn-003',\n type: 'dividend',\n cartName: 'Fix-It Mobile Repair',\n amount: 1200,\n date: '2024-06-01',\n status: 'completed',\n },\n {\n id: 'txn-004',\n type: 'investment',\n cartName: 'Spotless Cleaning Services',\n amount: 40000,\n date: '2023-04-10',\n status: 'completed',\n },\n {\n id: 'txn-005',\n type: 'dividend',\n cartName: 'Spotless Cleaning Services',\n amount: 1900,\n date: '2024-06-01',\n status: 'pending',\n },\n];\n\nconst categories = [\n '',\n 'Personal Care & Beauty',\n 'Repair & Maintenance',\n 'Home Services',\n 'Food & Beverage',\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getRiskBadge(risk: Investment['riskLevel']) {\n const map = {\n low: { color: 'bg-status-success-bg-subtle text-status-success-text', label: 'Low Risk' },\n medium: {\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n label: 'Medium Risk',\n },\n high: { color: 'bg-status-error-bg-subtle text-status-error-text', label: 'High Risk' },\n };\n const { color, label } = map[risk];\n return <span className={cn('rounded-full px-2 py-0.5 text-xs font-medium', color)}>{label}</span>;\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 } = useKadaikodi();\n const [activeTab, setActiveTab] = useState<'overview' | 'investments' | 'transactions'>(\n 'overview'\n );\n const [filterCategory, setFilterCategory] = useState('');\n\n const filteredInvestments = useMemo(() => {\n if (!filterCategory) return mockInvestments;\n return mockInvestments.filter((inv) => inv.category === filterCategory);\n }, [filterCategory]);\n\n const totalInvested = filteredInvestments.reduce((s, i) => s + i.amount, 0);\n const currentValue = filteredInvestments.reduce((s, i) => s + i.currentValue, 0);\n const totalReturns = currentValue - totalInvested;\n const returnsPercentage = totalInvested > 0 ? (totalReturns / totalInvested) * 100 : 0;\n const monthlyDividend = filteredInvestments.reduce((s, i) => s + i.monthlyDividend, 0);\n const activeCount = filteredInvestments.filter((i) => i.status === 'active').length;\n\n const riskScores: Record<string, number> = { low: 1, medium: 2, high: 3 };\n const avgRiskScore =\n filteredInvestments.length > 0\n ? filteredInvestments.reduce((s, i) => s + riskScores[i.riskLevel], 0) /\n filteredInvestments.length\n : 0;\n\n const bestPerformer = filteredInvestments.reduce(\n (best, inv) => (inv.returnsPercentage > best.returnsPercentage ? inv : best),\n filteredInvestments[0] || { cartName: '', returnsPercentage: 0 }\n );\n\n const handleWithdraw = useCallback((investmentId: string) => {\n alert(`Withdrawal request submitted for ${investmentId}`);\n }, []);\n\n // Asset allocation\n const allocationMap = filteredInvestments.reduce<Record<string, number>>((acc, inv) => {\n acc[inv.category] = (acc[inv.category] || 0) + inv.currentValue;\n return acc;\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 categories and risk levels, the dividends\n coming your way, and a full history of your transactions. Switch tabs to drill into your\n holdings or activity, and open any holding to manage 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=\"up\"\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={formatCurrency(monthlyDividend, { minimumFractionDigits: 0 })}\n label=\"Monthly Dividend\"\n trend=\"up\"\n trendValue=\"Next: July 1\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Additional Stats */}\n <div className=\"mt-4 grid grid-cols-2 gap-3 lg:grid-cols-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Active Investments</p>\n <p className=\"text-xl font-bold text-text-primary\">{activeCount}</p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Avg Risk Score</p>\n <div className=\"mt-1 flex items-center gap-2\">\n <div className=\"h-2 flex-1 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={cn(\n 'h-full rounded-full',\n avgRiskScore <= 1.5\n ? 'bg-status-success-text'\n : avgRiskScore <= 2.5\n ? 'bg-status-warning-text'\n : 'bg-status-error-text'\n )}\n style={{ width: `${(avgRiskScore / 3) * 100}%` }}\n />\n </div>\n <span className=\"text-sm font-medium text-text-primary\">\n {avgRiskScore.toFixed(1)}/3\n </span>\n </div>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Best Performer</p>\n <p className=\"truncate text-sm font-bold text-text-primary\">{bestPerformer.cartName}</p>\n <p className=\"text-xs text-status-success-text\">\n {fmtPct(bestPerformer.returnsPercentage)}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Next Payout</p>\n <p className=\"text-lg font-bold text-text-primary\">July 1</p>\n <p className=\"text-xs text-text-secondary\">In 7 days</p>\n </div>\n </div>\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 (${filteredInvestments.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 {/* Performance placeholder */}\n <div>\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">\n Portfolio Performance\n </h3>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/50 p-8 text-center\">\n <BarChart3 className=\"mx-auto mb-2 h-8 w-8 text-text-secondary/50\" />\n <p className=\"text-sm text-text-secondary\">Performance chart visualization</p>\n <p className=\"mt-1 text-xs text-text-secondary\">\n Shows portfolio value over time\n </p>\n </div>\n </div>\n\n {/* Asset Allocation */}\n <div>\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">Asset Allocation</h3>\n <div className=\"space-y-3\">\n {Object.entries(allocationMap).map(([category, value]) => (\n <div key={category} className=\"flex items-center\">\n <span className=\"w-40 truncate text-sm text-text-primary\">{category}</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 </div>\n )}\n\n {/* Investments Tab */}\n {activeTab === 'investments' && (\n <div>\n {/* Category filter */}\n <div className=\"mb-4\">\n <select\n value={filterCategory}\n onChange={(e) => setFilterCategory(e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Categories</option>\n {categories.filter(Boolean).map((cat) => (\n <option key={cat} value={cat}>\n {cat}\n </option>\n ))}\n </select>\n </div>\n\n {/* Investment list */}\n {filteredInvestments.length === 0 ? (\n <EmptyState\n illustration={filterCategory ? 'empty-search' : 'empty-data'}\n title=\"No holdings to show\"\n description={\n filterCategory\n ? 'No holdings in this category. Try a different one or clear the filter.'\n : \"You don't hold any investments yet. Explore opportunities to start building your portfolio.\"\n }\n action={\n filterCategory ? (\n <button\n type=\"button\"\n onClick={() => setFilterCategory('')}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Clear filter\n </button>\n ) : (\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 ) : (\n <div className=\"space-y-4\">\n {filteredInvestments.map((inv) => (\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=\"text-sm text-text-secondary\">\n Owned by {inv.cartOwner} • {inv.location}\n </p>\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n <span className=\"text-sm text-text-secondary\">{inv.category}</span>\n {getRiskBadge(inv.riskLevel)}\n </div>\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 inv.returns > 0 ? 'text-status-success-text' : 'text-status-error-text'\n )}\n >\n {formatCurrency(Math.abs(inv.returns), { minimumFractionDigits: 0 })} (\n {fmtPct(inv.returnsPercentage)})\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.amount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Ownership</p>\n <p className=\"text-sm font-medium text-text-primary\">{inv.ownership}%</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Monthly Dividend</p>\n <p className=\"text-sm font-medium text-text-primary\">\n {formatCurrency(inv.monthlyDividend, { minimumFractionDigits: 0 })}\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, { hour: undefined, minute: undefined })}\n </p>\n </div>\n </div>\n\n {/* Performance metrics */}\n <div className=\"border-t border-border-subtle pt-4\">\n <p className=\"mb-2 text-sm font-medium text-text-secondary\">\n Performance Metrics\n </p>\n <div className=\"grid grid-cols-3 gap-3 text-center\">\n <div>\n <p className=\"text-lg font-bold text-text-primary\">\n {inv.performanceMetrics.monthlyOrders}\n </p>\n <p className=\"text-xs text-text-secondary\">Monthly Orders</p>\n </div>\n <div>\n <div className=\"flex items-center justify-center gap-1\">\n <Star className=\"h-4 w-4 fill-status-warning-text text-status-warning-text\" />\n <p className=\"text-lg font-bold text-text-primary\">\n {inv.performanceMetrics.averageRating}\n </p>\n </div>\n <p className=\"text-xs text-text-secondary\">Rating</p>\n </div>\n <div>\n <p className=\"text-lg font-bold text-status-success-text\">\n +{inv.performanceMetrics.growthRate}%\n </p>\n <p className=\"text-xs text-text-secondary\">Growth Rate</p>\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"mt-4 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 {inv.status === 'active' && (\n <button\n type=\"button\"\n onClick={() => handleWithdraw(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 <ArrowDownCircle className=\"h-4 w-4\" />\n Withdraw\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Transactions Tab */}\n {activeTab === 'transactions' && (\n <div className=\"space-y-3\">\n {mockTransactions.map((txn) => (\n <div\n key={txn.id}\n className=\"flex flex-col gap-3 rounded-lg border border-border-subtle p-4 hover:bg-accent/50 transition-colors sm:flex-row sm:items-center sm:justify-between\"\n >\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-full',\n txn.type === 'investment'\n ? 'bg-[var(--color-accent-soft)]'\n : txn.type === 'dividend'\n ? 'bg-status-success-bg-subtle'\n : 'bg-status-error-bg-subtle'\n )}\n >\n {txn.type === 'investment' ? (\n <Wallet className=\"h-5 w-5 text-text-primary\" />\n ) : txn.type === 'dividend' ? (\n <TrendingUp className=\"h-5 w-5 text-status-success-text\" />\n ) : (\n <TrendingDown className=\"h-5 w-5 text-status-error-text\" />\n )}\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {txn.type === 'investment'\n ? 'Investment in'\n : txn.type === 'dividend'\n ? 'Dividend from'\n : 'Withdrawal from'}{' '}\n {txn.cartName}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {formatDate(txn.date, { hour: undefined, minute: undefined })}\n </p>\n </div>\n </div>\n <div className=\"flex items-center justify-between sm:gap-4\">\n <p\n className={cn(\n 'text-sm font-bold',\n txn.type === 'dividend' ? 'text-status-success-text' : 'text-text-primary'\n )}\n >\n {txn.type === 'dividend' ? '+' : '-'}\n {formatCurrency(txn.amount, { minimumFractionDigits: 0 })}\n </p>\n <span\n className={cn(\n 'rounded-full px-2.5 py-0.5 text-xs font-medium',\n txn.status === 'completed'\n ? 'bg-status-success-bg-subtle text-status-success-text'\n : txn.status === 'pending'\n ? 'bg-status-warning-bg-subtle text-status-warning-text'\n : 'bg-status-error-bg-subtle text-status-error-text'\n )}\n >\n {txn.status}\n </span>\n </div>\n </div>\n ))}\n </div>\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 * 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":"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"}
|