@burdenoff/microfe-atheletebridge 2026.624.1 → 2026.625.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/atheletebridge/components/EmptyState.js +18 -11
- package/dist/atheletebridge/components/EmptyState.js.map +1 -1
- package/dist/atheletebridge/components/InvestmentCard.js +7 -7
- package/dist/atheletebridge/components/InvestmentCard.js.map +1 -1
- package/dist/atheletebridge/components/MetricsCard.js +20 -14
- package/dist/atheletebridge/components/MetricsCard.js.map +1 -1
- package/dist/atheletebridge/components/PageLayout.js +30 -19
- package/dist/atheletebridge/components/PageLayout.js.map +1 -1
- package/dist/atheletebridge/pages/HomePage.js +210 -195
- package/dist/atheletebridge/pages/HomePage.js.map +1 -1
- package/dist/atheletebridge/pages/admin/AdminAnalyticsPage.js +90 -82
- package/dist/atheletebridge/pages/admin/AdminAnalyticsPage.js.map +1 -1
- package/dist/atheletebridge/pages/admin/AdminDashboard.js +76 -44
- package/dist/atheletebridge/pages/admin/AdminDashboard.js.map +1 -1
- package/dist/atheletebridge/pages/admin/AdminFinancialPage.js +63 -55
- package/dist/atheletebridge/pages/admin/AdminFinancialPage.js.map +1 -1
- package/dist/atheletebridge/pages/admin/AdminOrdersPage.js +244 -237
- package/dist/atheletebridge/pages/admin/AdminOrdersPage.js.map +1 -1
- package/dist/atheletebridge/pages/admin/AdminProfilePage.js +59 -57
- package/dist/atheletebridge/pages/admin/AdminProfilePage.js.map +1 -1
- package/dist/atheletebridge/pages/admin/AdminSettingsPage.js +110 -106
- package/dist/atheletebridge/pages/admin/AdminSettingsPage.js.map +1 -1
- package/dist/atheletebridge/pages/admin/CartManagementPage.js +166 -159
- package/dist/atheletebridge/pages/admin/CartManagementPage.js.map +1 -1
- package/dist/atheletebridge/pages/admin/UserManagementPage.js +310 -303
- package/dist/atheletebridge/pages/admin/UserManagementPage.js.map +1 -1
- package/dist/atheletebridge/pages/cart-owner/AnalyticsDashboard.js +86 -81
- package/dist/atheletebridge/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
- package/dist/atheletebridge/pages/cart-owner/BusinessSettingsPage.js +170 -166
- package/dist/atheletebridge/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
- package/dist/atheletebridge/pages/cart-owner/CartOwnerDashboard.js +141 -109
- package/dist/atheletebridge/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
- package/dist/atheletebridge/pages/cart-owner/CartOwnerProfilePage.js +139 -134
- package/dist/atheletebridge/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
- package/dist/atheletebridge/pages/cart-owner/CartServiceConfigPage.js +109 -107
- package/dist/atheletebridge/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
- package/dist/atheletebridge/pages/cart-owner/InventoryManagementPage.js +318 -318
- package/dist/atheletebridge/pages/cart-owner/InventoryManagementPage.js.map +1 -1
- package/dist/atheletebridge/pages/cart-owner/OrderManagementPage.js +262 -262
- package/dist/atheletebridge/pages/cart-owner/OrderManagementPage.js.map +1 -1
- package/dist/atheletebridge/pages/cart-owner/StaffManagementPage.js +170 -162
- package/dist/atheletebridge/pages/cart-owner/StaffManagementPage.js.map +1 -1
- package/dist/atheletebridge/pages/common/HelpSupportPage.js +292 -298
- package/dist/atheletebridge/pages/common/HelpSupportPage.js.map +1 -1
- package/dist/atheletebridge/pages/common/NotificationCenterPage.js +100 -91
- package/dist/atheletebridge/pages/common/NotificationCenterPage.js.map +1 -1
- package/dist/atheletebridge/pages/common/SettingsPage.js +742 -734
- package/dist/atheletebridge/pages/common/SettingsPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/BookingDetailsPage.js +365 -356
- package/dist/atheletebridge/pages/customer/BookingDetailsPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/CartDetailPage.js +277 -241
- package/dist/atheletebridge/pages/customer/CartDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/CartDiscoveryPage.js +261 -250
- package/dist/atheletebridge/pages/customer/CartDiscoveryPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/CheckoutPage.js +93 -89
- package/dist/atheletebridge/pages/customer/CheckoutPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/CustomerDashboard.js +430 -387
- package/dist/atheletebridge/pages/customer/CustomerDashboard.js.map +1 -1
- package/dist/atheletebridge/pages/customer/CustomerProfilePage.js +526 -490
- package/dist/atheletebridge/pages/customer/CustomerProfilePage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/DirectServiceBookingPage.js +524 -512
- package/dist/atheletebridge/pages/customer/DirectServiceBookingPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/FavoritesPage.js +84 -75
- package/dist/atheletebridge/pages/customer/FavoritesPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/OrderHistoryPage.js +117 -108
- package/dist/atheletebridge/pages/customer/OrderHistoryPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/OrderTrackingPage.js +66 -61
- package/dist/atheletebridge/pages/customer/OrderTrackingPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/PaymentMethodsPage.js +81 -75
- package/dist/atheletebridge/pages/customer/PaymentMethodsPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/ReviewsPage.js +81 -72
- package/dist/atheletebridge/pages/customer/ReviewsPage.js.map +1 -1
- package/dist/atheletebridge/pages/customer/SavedAddressesPage.js +63 -55
- package/dist/atheletebridge/pages/customer/SavedAddressesPage.js.map +1 -1
- package/dist/atheletebridge/pages/investor/InvestmentDetailsPage.js +93 -61
- package/dist/atheletebridge/pages/investor/InvestmentDetailsPage.js.map +1 -1
- package/dist/atheletebridge/pages/investor/InvestmentOpportunitiesPage.js +90 -84
- package/dist/atheletebridge/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
- package/dist/atheletebridge/pages/investor/InvestorAnalyticsPage.js +60 -55
- package/dist/atheletebridge/pages/investor/InvestorAnalyticsPage.js.map +1 -1
- package/dist/atheletebridge/pages/investor/InvestorDashboard.js +345 -311
- package/dist/atheletebridge/pages/investor/InvestorDashboard.js.map +1 -1
- package/dist/atheletebridge/pages/investor/InvestorInvestmentsPage.js +38 -32
- package/dist/atheletebridge/pages/investor/InvestorInvestmentsPage.js.map +1 -1
- package/dist/atheletebridge/pages/investor/InvestorPortfolioPage.js +75 -67
- package/dist/atheletebridge/pages/investor/InvestorPortfolioPage.js.map +1 -1
- package/dist/atheletebridge/pages/investor/InvestorProfilePage.js +385 -381
- package/dist/atheletebridge/pages/investor/InvestorProfilePage.js.map +1 -1
- package/dist/atheletebridge/pages/worker/TaskDetailsPage.js +353 -319
- package/dist/atheletebridge/pages/worker/TaskDetailsPage.js.map +1 -1
- package/dist/atheletebridge/pages/worker/WorkerDashboard.js +353 -318
- package/dist/atheletebridge/pages/worker/WorkerDashboard.js.map +1 -1
- package/dist/atheletebridge/pages/worker/WorkerOrdersPage.js +134 -128
- package/dist/atheletebridge/pages/worker/WorkerOrdersPage.js.map +1 -1
- package/dist/atheletebridge/pages/worker/WorkerProfilePage.js +81 -77
- package/dist/atheletebridge/pages/worker/WorkerProfilePage.js.map +1 -1
- package/dist/atheletebridge/pages/worker/WorkerSchedulePage.js +352 -342
- package/dist/atheletebridge/pages/worker/WorkerSchedulePage.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvestorDashboard.js","names":[],"sources":["../../../../src/atheletebridge/pages/investor/InvestorDashboard.tsx"],"sourcesContent":["/**\n * Investor Dashboard Page\n * @module atheletebridge/pages/investor\n *\n * Portfolio overview with metrics, tab navigation (portfolio/opportunities),\n * AI insights sidebar, quick actions, market updates, and recent activity.\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport {\n Wallet,\n TrendingUp,\n PieChart,\n Briefcase,\n ArrowRight,\n Activity,\n IndianRupee,\n Target,\n Award,\n Filter,\n Eye,\n Plus,\n MapPin,\n Lightbulb,\n BarChart3,\n} from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { InvestmentCard } from '../../components/InvestmentCard';\nimport { RatingDisplay } from '../../components/RatingDisplay';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useInvestmentOpportunities, useInvestments } from '../../hooks/useAthleteBridgeApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface DashboardInvestment {\n id: string;\n cartName: string;\n cartOwner: string;\n investmentAmount: number;\n equityPercentage: number;\n investmentDate: string;\n currentValue: number;\n monthlyReturns: number;\n status: 'active' | 'pending' | 'completed';\n location: string;\n category: string;\n rating: number;\n riskLevel: 'low' | 'medium' | 'high';\n}\n\nconst mockAiInsights = [\n {\n id: '1',\n type: 'opportunity' as const,\n title: 'High-Potential Business Detected',\n description:\n 'Glow Beauty Services in Koramangala shows 95% growth potential based on location analytics and market demand.',\n confidence: 94,\n },\n {\n id: '2',\n type: 'suggestion' as const,\n title: 'Portfolio Diversification Recommended',\n description:\n 'Consider investing in Education & Skills to balance your services-heavy portfolio. Current allocation: 70% services, 30% retail.',\n confidence: 87,\n },\n {\n id: '3',\n type: 'trend' as const,\n title: 'Market Trend Alert',\n description:\n 'Health & Wellness businesses in tech hubs are experiencing 40% higher returns. Whitefield shows promising opportunities.',\n confidence: 91,\n },\n];\n\nconst mockRecentActivity = [\n {\n id: 'act-1',\n type: 'dividend',\n description: 'Dividend received from Quick Cuts Salon',\n amount: 4200,\n date: '2024-01-14T10:00:00Z',\n },\n {\n id: 'act-2',\n type: 'investment',\n description: 'Invested in Spotless Cleaning Services',\n amount: -40000,\n date: '2024-01-10T09:30:00Z',\n },\n {\n id: 'act-3',\n type: 'return',\n description: 'Returns from Fix-It Mobile Repair',\n amount: 6800,\n date: '2024-01-05T14:00:00Z',\n },\n {\n id: 'act-4',\n type: 'investment',\n description: 'Invested in Fix-It Mobile Repair',\n amount: -75000,\n date: '2023-12-20T11:00:00Z',\n },\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getRiskBadgeColor(risk: string): string {\n switch (risk) {\n case 'low':\n return 'bg-green-500/20 text-green-600 dark:text-green-400';\n case 'medium':\n return 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400';\n case 'high':\n return 'bg-red-500/20 text-red-600 dark:text-red-400';\n default:\n return 'bg-secondary text-secondary-foreground';\n }\n}\n\nfunction getStatusBadgeColor(status: string): string {\n switch (status) {\n case 'active':\n return 'bg-green-500/20 text-green-600 dark:text-green-400';\n case 'pending':\n return 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400';\n case 'completed':\n return 'bg-blue-500/20 text-blue-600 dark:text-blue-400';\n default:\n return 'bg-secondary text-secondary-foreground';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorDashboard() {\n const { navigateTo, currentUser } = useAthleteBridge();\n const [activeTab, setActiveTab] = useState<'portfolio' | 'opportunities'>('portfolio');\n\n const { data: opportunities = [], isLoading: opportunitiesLoading } =\n useInvestmentOpportunities();\n const { data: investments = [], isLoading: investmentsLoading } = useInvestments(\n currentUser?.id || ''\n );\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'Investor';\n\n const activeOpportunities = opportunities.filter((inv) => inv.status === 'active');\n\n const portfolioSummary = useMemo(() => {\n const totalInvested = investments.reduce((sum, inv) => sum + inv.investedAmount, 0);\n const currentValue = investments.reduce((sum, inv) => sum + inv.currentValue, 0);\n const totalReturns = investments.reduce((sum, inv) => sum + inv.returns, 0);\n const monthlyIncome = totalReturns / 12; // Simple mock derivation\n const roi = totalInvested > 0 ? (totalReturns / totalInvested) * 100 : 0;\n\n return {\n totalInvested,\n currentValue,\n totalReturns,\n monthlyIncome,\n roi,\n };\n }, [investments]);\n\n if (opportunitiesLoading || investmentsLoading) {\n return (\n <PageLayout title=\"Investment Dashboard\" description=\"Loading your portfolio...\">\n <div className=\"flex items-center justify-center py-20\">\n <div className=\"text-center\">\n <div className=\"mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary\" />\n <p className=\"text-sm text-text-secondary\">Loading your portfolio...</p>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`Welcome back, ${firstName}!`}\n description=\"Here's your investment portfolio overview.\"\n >\n {/* Portfolio Summary Metrics */}\n <section>\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Portfolio Overview</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"up\"\n trendValue=\"Across all businesses\"\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend=\"up\"\n trendValue={`+${portfolioSummary.roi.toFixed(1)}%`}\n />\n <MetricsCard\n icon={<Target className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.totalReturns, { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n trend=\"up\"\n trendValue=\"+15.2% this month\"\n />\n <MetricsCard\n icon={<Activity className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.monthlyIncome, { minimumFractionDigits: 0 })}\n label=\"Monthly Income\"\n trend=\"up\"\n trendValue=\"+8.5% vs last month\"\n />\n </div>\n </section>\n\n {/* Main Content + Sidebar */}\n <div className=\"mt-8 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Main Content */}\n <div className=\"lg:col-span-2\">\n {/* Tab Navigation */}\n <div className=\"mb-6 flex rounded-lg bg-bg-sunken p-1\">\n <button\n type=\"button\"\n onClick={() => setActiveTab('portfolio')}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n activeTab === 'portfolio'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n My Investments\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('opportunities')}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n activeTab === 'opportunities'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n New Opportunities\n </button>\n </div>\n\n {/* Portfolio Tab */}\n {activeTab === 'portfolio' && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">Active Investments</h3>\n <button\n type=\"button\"\n onClick={() => alert('Filter functionality coming soon!')}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Filter className=\"h-4 w-4\" />\n Filter\n </button>\n </div>\n\n {investments.length === 0 ? (\n <div className=\"rounded-lg border border-dashed border-border-subtle p-8 text-center\">\n <Briefcase className=\"mx-auto h-12 w-12 text-text-secondary opacity-20\" />\n <p className=\"mt-2 text-sm text-text-secondary\">No active investments found.</p>\n <button\n type=\"button\"\n onClick={() => setActiveTab('opportunities')}\n className=\"mt-4 text-sm font-medium text-primary hover:underline\"\n >\n Browse opportunities\n </button>\n </div>\n ) : (\n investments.map((investment) => (\n <div\n key={investment.id}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 shadow-sm hover:shadow-md transition-shadow\"\n >\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex-1\">\n <div className=\"mb-2 flex flex-wrap items-center gap-2\">\n <h4 className=\"text-base font-semibold text-text-primary\">\n {investment.cartName}\n </h4>\n <span\n className={cn(\n 'rounded-full px-2 py-0.5 text-xs font-medium',\n getStatusBadgeColor(investment.status)\n )}\n >\n {investment.status}\n </span>\n </div>\n <div className=\"mb-3 flex flex-wrap items-center gap-3 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <MapPin className=\"h-3.5 w-3.5\" />\n {'India'}\n </span>\n <span>{'Services'}</span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(investment.investedAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Current Value</p>\n <p className=\"text-sm font-semibold text-green-600 dark:text-green-400\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Returns</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(investment.returns, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Growth</p>\n <p className=\"text-sm font-semibold text-green-600 dark:text-green-400\">\n {investment.returnsPercentage}%\n </p>\n </div>\n </div>\n </div>\n ))\n )}\n </div>\n )}\n\n {/* Opportunities Tab */}\n {activeTab === 'opportunities' && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n Investment Opportunities\n </h3>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n Browse All\n </button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {activeOpportunities.slice(0, 2).map((opp) => (\n <InvestmentCard\n key={opp.id}\n id={opp.id}\n cartName={opp.cartName}\n targetAmount={opp.targetAmount}\n raisedAmount={opp.raisedAmount}\n expectedReturns={`${opp.expectedReturns}%`}\n riskLevel={opp.riskLevel}\n status={opp.status}\n onClick={(id) => navigateTo(`/investor/opportunities/${id}`)}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Recent Activity */}\n <section className=\"mt-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Recent Activity</h2>\n <div className=\"divide-y divide-border rounded-lg border border-border-subtle bg-bg-surface\">\n {mockRecentActivity.map((activity) => (\n <div key={activity.id} className=\"flex items-center justify-between px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n 'flex h-8 w-8 items-center justify-center rounded-full',\n activity.amount > 0 ? 'bg-green-500/10' : 'bg-bg-sunken'\n )}\n >\n <Activity\n className={cn(\n 'h-4 w-4',\n activity.amount > 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-text-secondary'\n )}\n />\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{activity.description}</p>\n <p className=\"text-xs text-text-secondary\">\n {new Date(activity.date).toLocaleDateString('en-IN', {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n })}\n </p>\n </div>\n </div>\n <span\n className={cn(\n 'text-sm font-semibold',\n activity.amount > 0 ? 'text-green-600 dark:text-green-400' : 'text-text-primary'\n )}\n >\n {activity.amount > 0 ? '+' : ''}\n {formatCurrency(Math.abs(activity.amount), { minimumFractionDigits: 0 })}\n </span>\n </div>\n ))}\n </div>\n </section>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* AI Insights */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-3 flex items-center gap-2\">\n <Lightbulb className=\"h-5 w-5 text-yellow-500\" />\n <h3 className=\"text-base font-semibold text-text-primary\">AI Insights</h3>\n </div>\n <div className=\"space-y-3\">\n {mockAiInsights.map((insight) => (\n <div key={insight.id} className=\"rounded-lg border border-border-subtle bg-bg-sunken/50 p-3\">\n <div className=\"mb-1 flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-text-primary\">{insight.title}</h4>\n <span className=\"rounded-full bg-action-primary-bg/10 px-2 py-0.5 text-xs font-medium text-primary\">\n {insight.confidence}%\n </span>\n </div>\n <p className=\"text-xs leading-relaxed text-text-secondary\">\n {insight.description}\n </p>\n </div>\n ))}\n </div>\n </div>\n\n {/* Quick Actions */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Quick Actions</h3>\n <div className=\"space-y-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/portfolio')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <PieChart className=\"h-4 w-4 text-text-secondary\" />\n View Full Portfolio\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Target className=\"h-4 w-4 text-text-secondary\" />\n Browse Opportunities\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/analytics')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n Investment Analytics\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/profile')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Award className=\"h-4 w-4 text-text-secondary\" />\n View Profile\n </button>\n </div>\n </div>\n\n {/* Market Updates */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Market Updates</h3>\n <div className=\"space-y-3\">\n <div className=\"border-l-4 border-green-500 pl-3\">\n <h4 className=\"text-xs font-semibold text-text-primary\">\n Mobile Services Market Growing\n </h4>\n <p className=\"mt-1 text-xs leading-relaxed text-text-secondary\">\n Mobile service industry shows 35% growth in Q4 2024\n </p>\n </div>\n <div className=\"border-l-4 border-blue-500 pl-3\">\n <h4 className=\"text-xs font-semibold text-text-primary\">\n New Investment Tax Benefits\n </h4>\n <p className=\"mt-1 text-xs leading-relaxed text-text-secondary\">\n Government announces SME investment incentives\n </p>\n </div>\n <div className=\"border-l-4 border-yellow-500 pl-3\">\n <h4 className=\"text-xs font-semibold text-text-primary\">\n Home Services Demand Surge\n </h4>\n <p className=\"mt-1 text-xs leading-relaxed text-text-secondary\">\n Cleaning and maintenance businesses up 25% this quarter\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InvestorDashboard.js","names":[],"sources":["../../../../src/atheletebridge/pages/investor/InvestorDashboard.tsx"],"sourcesContent":["/**\n * Investor Dashboard Page\n * @module atheletebridge/pages/investor\n *\n * Portfolio overview with metrics, tab navigation (portfolio/opportunities),\n * AI insights sidebar, quick actions, market updates, and recent activity.\n */\n\nimport { useState, useMemo } from 'react';\nimport {\n Wallet,\n TrendingUp,\n PieChart,\n ArrowRight,\n Activity,\n IndianRupee,\n Target,\n Award,\n Filter,\n Eye,\n Plus,\n MapPin,\n Lightbulb,\n BarChart3,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { InvestmentCard } from '../../components/InvestmentCard';\nimport { RatingDisplay } from '../../components/RatingDisplay';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useInvestmentOpportunities, useInvestments } from '../../hooks/useAthleteBridgeApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface DashboardInvestment {\n id: string;\n cartName: string;\n cartOwner: string;\n investmentAmount: number;\n equityPercentage: number;\n investmentDate: string;\n currentValue: number;\n monthlyReturns: number;\n status: 'active' | 'pending' | 'completed';\n location: string;\n category: string;\n rating: number;\n riskLevel: 'low' | 'medium' | 'high';\n}\n\nconst mockAiInsights = [\n {\n id: '1',\n type: 'opportunity' as const,\n title: 'High-Potential Business Detected',\n description:\n 'Glow Beauty Services in Koramangala shows 95% growth potential based on location analytics and market demand.',\n confidence: 94,\n },\n {\n id: '2',\n type: 'suggestion' as const,\n title: 'Portfolio Diversification Recommended',\n description:\n 'Consider investing in Education & Skills to balance your services-heavy portfolio. Current allocation: 70% services, 30% retail.',\n confidence: 87,\n },\n {\n id: '3',\n type: 'trend' as const,\n title: 'Market Trend Alert',\n description:\n 'Health & Wellness businesses in tech hubs are experiencing 40% higher returns. Whitefield shows promising opportunities.',\n confidence: 91,\n },\n];\n\nconst mockRecentActivity = [\n {\n id: 'act-1',\n type: 'dividend',\n description: 'Dividend received from Quick Cuts Salon',\n amount: 4200,\n date: '2024-01-14T10:00:00Z',\n },\n {\n id: 'act-2',\n type: 'investment',\n description: 'Invested in Spotless Cleaning Services',\n amount: -40000,\n date: '2024-01-10T09:30:00Z',\n },\n {\n id: 'act-3',\n type: 'return',\n description: 'Returns from Fix-It Mobile Repair',\n amount: 6800,\n date: '2024-01-05T14:00:00Z',\n },\n {\n id: 'act-4',\n type: 'investment',\n description: 'Invested in Fix-It Mobile Repair',\n amount: -75000,\n date: '2023-12-20T11:00:00Z',\n },\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getRiskBadgeColor(risk: string): string {\n switch (risk) {\n case 'low':\n return 'bg-green-500/20 text-green-600 dark:text-green-400';\n case 'medium':\n return 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400';\n case 'high':\n return 'bg-red-500/20 text-red-600 dark:text-red-400';\n default:\n return 'bg-secondary text-secondary-foreground';\n }\n}\n\nfunction getStatusBadgeColor(status: string): string {\n switch (status) {\n case 'active':\n return 'bg-green-500/20 text-green-600 dark:text-green-400';\n case 'pending':\n return 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400';\n case 'completed':\n return 'bg-blue-500/20 text-blue-600 dark:text-blue-400';\n default:\n return 'bg-secondary text-secondary-foreground';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorDashboard() {\n const { navigateTo, currentUser } = useAthleteBridge();\n const [activeTab, setActiveTab] = useState<'portfolio' | 'opportunities'>('portfolio');\n\n const { data: opportunities = [], isLoading: opportunitiesLoading } =\n useInvestmentOpportunities();\n const { data: investments = [], isLoading: investmentsLoading } = useInvestments(\n currentUser?.id || ''\n );\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'Investor';\n\n const activeOpportunities = opportunities.filter((inv) => inv.status === 'active');\n\n const portfolioSummary = useMemo(() => {\n const totalInvested = investments.reduce((sum, inv) => sum + inv.investedAmount, 0);\n const currentValue = investments.reduce((sum, inv) => sum + inv.currentValue, 0);\n const totalReturns = investments.reduce((sum, inv) => sum + inv.returns, 0);\n const monthlyIncome = totalReturns / 12; // Simple mock derivation\n const roi = totalInvested > 0 ? (totalReturns / totalInvested) * 100 : 0;\n\n return {\n totalInvested,\n currentValue,\n totalReturns,\n monthlyIncome,\n roi,\n };\n }, [investments]);\n\n if (opportunitiesLoading || investmentsLoading) {\n return (\n <PageLayout title=\"Investment Dashboard\" description=\"Loading your portfolio...\">\n <div className=\"flex items-center justify-center py-20\">\n <div className=\"text-center\">\n <div className=\"mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary\" />\n <p className=\"text-sm text-text-secondary\">Loading your portfolio...</p>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`Welcome back, ${firstName}!`}\n description=\"Here's your investment portfolio overview.\"\n >\n <PagePurpose className=\"mb-6\">\n Your investment command center. See how your money is performing across every business\n you back — total invested, current value, returns and monthly income — then act on AI-spotted\n opportunities. Use this page to track your portfolio and decide where to invest next.\n </PagePurpose>\n\n <NextSteps\n className=\"mb-6\"\n storageKey=\"atheletebridge-investor-dashboard\"\n steps={[\n {\n id: 'browse',\n label: 'Browse investment opportunities',\n description: 'Discover vetted carts seeking funding and their expected returns.',\n icon: <Target className=\"h-4 w-4\" />,\n onClick: () => navigateTo('/investor/opportunities'),\n },\n {\n id: 'portfolio',\n label: 'Review your full portfolio',\n description: 'Drill into each active investment and its performance.',\n icon: <PieChart className=\"h-4 w-4\" />,\n onClick: () => navigateTo('/investor/portfolio'),\n },\n {\n id: 'analytics',\n label: 'Open investment analytics',\n description: 'See diversification, ROI trends and risk breakdown.',\n icon: <BarChart3 className=\"h-4 w-4\" />,\n onClick: () => navigateTo('/investor/analytics'),\n },\n ]}\n />\n\n {/* Portfolio Summary Metrics */}\n <EmphasisPanel>\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Portfolio Overview</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"up\"\n trendValue=\"Across all businesses\"\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend=\"up\"\n trendValue={`+${portfolioSummary.roi.toFixed(1)}%`}\n />\n <MetricsCard\n icon={<Target className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.totalReturns, { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n trend=\"up\"\n trendValue=\"+15.2% this month\"\n />\n <MetricsCard\n icon={<Activity className=\"h-5 w-5\" />}\n value={formatCurrency(portfolioSummary.monthlyIncome, { minimumFractionDigits: 0 })}\n label=\"Monthly Income\"\n trend=\"up\"\n trendValue=\"+8.5% vs last month\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Main Content + Sidebar */}\n <div className=\"mt-8 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Main Content */}\n <div className=\"lg:col-span-2\">\n {/* Tab Navigation */}\n <div className=\"mb-6 flex rounded-lg bg-bg-sunken p-1\">\n <button\n type=\"button\"\n onClick={() => setActiveTab('portfolio')}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n activeTab === 'portfolio'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n My Investments\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('opportunities')}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n activeTab === 'opportunities'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n New Opportunities\n </button>\n </div>\n\n {/* Portfolio Tab */}\n {activeTab === 'portfolio' && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">Active Investments</h3>\n <button\n type=\"button\"\n onClick={() => alert('Filter functionality coming soon!')}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Filter className=\"h-4 w-4\" />\n Filter\n </button>\n </div>\n\n {investments.length === 0 ? (\n <div className=\"rounded-lg border border-dashed border-border-subtle\">\n <EmptyState\n illustration=\"empty-data\"\n title=\"No active investments yet\"\n description=\"Once you back a business, it will show up here with live performance. Start by exploring open opportunities.\"\n action={\n <button\n type=\"button\"\n onClick={() => setActiveTab('opportunities')}\n className=\"inline-flex items-center gap-1.5 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 <Target className=\"h-4 w-4\" />\n Browse opportunities\n </button>\n }\n />\n </div>\n ) : (\n investments.map((investment) => (\n <div\n key={investment.id}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 shadow-sm hover:shadow-md transition-shadow\"\n >\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex-1\">\n <div className=\"mb-2 flex flex-wrap items-center gap-2\">\n <h4 className=\"text-base font-semibold text-text-primary\">\n {investment.cartName}\n </h4>\n <span\n className={cn(\n 'rounded-full px-2 py-0.5 text-xs font-medium',\n getStatusBadgeColor(investment.status)\n )}\n >\n {investment.status}\n </span>\n </div>\n <div className=\"mb-3 flex flex-wrap items-center gap-3 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <MapPin className=\"h-3.5 w-3.5\" />\n {'India'}\n </span>\n <span>{'Services'}</span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(investment.investedAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Current Value</p>\n <p className=\"text-sm font-semibold text-green-600 dark:text-green-400\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Returns</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(investment.returns, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Growth</p>\n <p className=\"text-sm font-semibold text-green-600 dark:text-green-400\">\n {investment.returnsPercentage}%\n </p>\n </div>\n </div>\n </div>\n ))\n )}\n </div>\n )}\n\n {/* Opportunities Tab */}\n {activeTab === 'opportunities' && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n Investment Opportunities\n </h3>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n Browse All\n </button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {activeOpportunities.slice(0, 2).map((opp) => (\n <InvestmentCard\n key={opp.id}\n id={opp.id}\n cartName={opp.cartName}\n targetAmount={opp.targetAmount}\n raisedAmount={opp.raisedAmount}\n expectedReturns={`${opp.expectedReturns}%`}\n riskLevel={opp.riskLevel}\n status={opp.status}\n onClick={(id) => navigateTo(`/investor/opportunities/${id}`)}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Recent Activity */}\n <section className=\"mt-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Recent Activity</h2>\n <div className=\"divide-y divide-border rounded-lg border border-border-subtle bg-bg-surface\">\n {mockRecentActivity.map((activity) => (\n <div key={activity.id} className=\"flex items-center justify-between px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n 'flex h-8 w-8 items-center justify-center rounded-full',\n activity.amount > 0 ? 'bg-green-500/10' : 'bg-bg-sunken'\n )}\n >\n <Activity\n className={cn(\n 'h-4 w-4',\n activity.amount > 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-text-secondary'\n )}\n />\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{activity.description}</p>\n <p className=\"text-xs text-text-secondary\">\n {new Date(activity.date).toLocaleDateString('en-IN', {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n })}\n </p>\n </div>\n </div>\n <span\n className={cn(\n 'text-sm font-semibold',\n activity.amount > 0 ? 'text-green-600 dark:text-green-400' : 'text-text-primary'\n )}\n >\n {activity.amount > 0 ? '+' : ''}\n {formatCurrency(Math.abs(activity.amount), { minimumFractionDigits: 0 })}\n </span>\n </div>\n ))}\n </div>\n </section>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* AI Insights */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-3 flex items-center gap-2\">\n <Lightbulb className=\"h-5 w-5 text-yellow-500\" />\n <h3 className=\"text-base font-semibold text-text-primary\">AI Insights</h3>\n </div>\n <div className=\"space-y-3\">\n {mockAiInsights.map((insight) => (\n <div key={insight.id} className=\"rounded-lg border border-border-subtle bg-bg-sunken/50 p-3\">\n <div className=\"mb-1 flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-text-primary\">{insight.title}</h4>\n <span className=\"rounded-full bg-action-primary-bg/10 px-2 py-0.5 text-xs font-medium text-primary\">\n {insight.confidence}%\n </span>\n </div>\n <p className=\"text-xs leading-relaxed text-text-secondary\">\n {insight.description}\n </p>\n </div>\n ))}\n </div>\n </div>\n\n {/* Quick Actions */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Quick Actions</h3>\n <div className=\"space-y-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/portfolio')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <PieChart className=\"h-4 w-4 text-text-secondary\" />\n View Full Portfolio\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Target className=\"h-4 w-4 text-text-secondary\" />\n Browse Opportunities\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/analytics')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <BarChart3 className=\"h-4 w-4 text-text-secondary\" />\n Investment Analytics\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/profile')}\n className=\"flex w-full items-center gap-2 rounded-lg border border-border-subtle px-3 py-2.5 text-left text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Award className=\"h-4 w-4 text-text-secondary\" />\n View Profile\n </button>\n </div>\n </div>\n\n {/* Market Updates */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Market Updates</h3>\n <div className=\"space-y-3\">\n <div className=\"border-l-4 border-green-500 pl-3\">\n <h4 className=\"text-xs font-semibold text-text-primary\">\n Mobile Services Market Growing\n </h4>\n <p className=\"mt-1 text-xs leading-relaxed text-text-secondary\">\n Mobile service industry shows 35% growth in Q4 2024\n </p>\n </div>\n <div className=\"border-l-4 border-blue-500 pl-3\">\n <h4 className=\"text-xs font-semibold text-text-primary\">\n New Investment Tax Benefits\n </h4>\n <p className=\"mt-1 text-xs leading-relaxed text-text-secondary\">\n Government announces SME investment incentives\n </p>\n </div>\n <div className=\"border-l-4 border-yellow-500 pl-3\">\n <h4 className=\"text-xs font-semibold text-text-primary\">\n Home Services Demand Surge\n </h4>\n <p className=\"mt-1 text-xs leading-relaxed text-text-secondary\">\n Cleaning and maintenance businesses up 25% this quarter\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -7,8 +7,9 @@ import { formatCurrency as a, formatDate as o } from "../../utils/formatters.js"
|
|
|
7
7
|
import { useEffect as s, useMemo as c, useState as l } from "react";
|
|
8
8
|
import { AlertCircle as u, CheckCircle2 as d, Clock as f, Eye as p, IndianRupee as m, Plus as h, TrendingDown as g, TrendingUp as _, Wallet as v } from "lucide-react";
|
|
9
9
|
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
10
|
+
import { EmphasisPanel as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
|
|
10
11
|
//#region src/atheletebridge/pages/investor/InvestorInvestmentsPage.tsx
|
|
11
|
-
var
|
|
12
|
+
var C = [
|
|
12
13
|
{
|
|
13
14
|
id: "inv-001",
|
|
14
15
|
cartName: "South Indian Express",
|
|
@@ -84,7 +85,7 @@ var x = [
|
|
|
84
85
|
nextPayout: "-",
|
|
85
86
|
totalReturns: 12e3
|
|
86
87
|
}
|
|
87
|
-
],
|
|
88
|
+
], w = {
|
|
88
89
|
totalInvested: 255e3,
|
|
89
90
|
currentValue: 283700,
|
|
90
91
|
totalReturns: 28700,
|
|
@@ -93,7 +94,7 @@ var x = [
|
|
|
93
94
|
profitLoss: 28700,
|
|
94
95
|
profitLossPercentage: 11.3
|
|
95
96
|
};
|
|
96
|
-
function
|
|
97
|
+
function T(e) {
|
|
97
98
|
switch (e) {
|
|
98
99
|
case "active": return "bg-green-500/20 text-green-600 dark:text-green-400";
|
|
99
100
|
case "pending": return "bg-yellow-500/20 text-yellow-600 dark:text-yellow-400";
|
|
@@ -102,7 +103,7 @@ function C(e) {
|
|
|
102
103
|
default: return "bg-secondary text-secondary-foreground";
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
function
|
|
106
|
+
function E(e) {
|
|
106
107
|
switch (e) {
|
|
107
108
|
case "active": return /* @__PURE__ */ y(d, { className: "h-4 w-4" });
|
|
108
109
|
case "pending": return /* @__PURE__ */ y(f, { className: "h-4 w-4" });
|
|
@@ -110,13 +111,13 @@ function w(e) {
|
|
|
110
111
|
default: return /* @__PURE__ */ y(u, { className: "h-4 w-4" });
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
|
-
function
|
|
114
|
-
let { navigateTo: u } = e(), [f,
|
|
114
|
+
function D() {
|
|
115
|
+
let { navigateTo: u } = e(), [f, D] = l(!0), [O, k] = l("all");
|
|
115
116
|
s(() => {
|
|
116
|
-
let e = setTimeout(() =>
|
|
117
|
+
let e = setTimeout(() => D(!1), 600);
|
|
117
118
|
return () => clearTimeout(e);
|
|
118
119
|
}, []);
|
|
119
|
-
let
|
|
120
|
+
let A = c(() => O === "all" ? C : C.filter((e) => e.status === O), [O]), j = [
|
|
120
121
|
{
|
|
121
122
|
key: "all",
|
|
122
123
|
label: "All Investments"
|
|
@@ -134,8 +135,8 @@ function T() {
|
|
|
134
135
|
label: "Matured"
|
|
135
136
|
}
|
|
136
137
|
];
|
|
137
|
-
function
|
|
138
|
-
return e === "all" ?
|
|
138
|
+
function M(e) {
|
|
139
|
+
return e === "all" ? C.length : C.filter((t) => t.status === e).length;
|
|
139
140
|
}
|
|
140
141
|
return f ? /* @__PURE__ */ y(n, {
|
|
141
142
|
title: "My Investments",
|
|
@@ -160,57 +161,61 @@ function T() {
|
|
|
160
161
|
children: [/* @__PURE__ */ y(h, { className: "h-4 w-4" }), "New Investment"]
|
|
161
162
|
}),
|
|
162
163
|
children: [
|
|
163
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ y(S, {
|
|
165
|
+
className: "mb-6",
|
|
166
|
+
children: "Manage the businesses you've already invested in. See your total invested, current value and returns, filter by status, and open any holding to track its performance or take action. This is your active-investments workspace."
|
|
167
|
+
}),
|
|
168
|
+
/* @__PURE__ */ y(x, { children: /* @__PURE__ */ b("div", {
|
|
164
169
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
165
170
|
children: [
|
|
166
171
|
/* @__PURE__ */ y(r, {
|
|
167
172
|
icon: /* @__PURE__ */ y(v, { className: "h-5 w-5" }),
|
|
168
|
-
value: a(
|
|
173
|
+
value: a(w.totalInvested, { minimumFractionDigits: 0 }),
|
|
169
174
|
label: "Total Invested",
|
|
170
175
|
trend: "up",
|
|
171
176
|
trendValue: "Total amount invested"
|
|
172
177
|
}),
|
|
173
178
|
/* @__PURE__ */ y(r, {
|
|
174
179
|
icon: /* @__PURE__ */ y(m, { className: "h-5 w-5" }),
|
|
175
|
-
value: a(
|
|
180
|
+
value: a(w.currentValue, { minimumFractionDigits: 0 }),
|
|
176
181
|
label: "Current Value",
|
|
177
|
-
trend:
|
|
178
|
-
trendValue: `${
|
|
182
|
+
trend: w.profitLoss > 0 ? "up" : "down",
|
|
183
|
+
trendValue: `${w.profitLossPercentage > 0 ? "+" : ""}${w.profitLossPercentage}% total returns`
|
|
179
184
|
}),
|
|
180
185
|
/* @__PURE__ */ y(r, {
|
|
181
186
|
icon: /* @__PURE__ */ y(_, { className: "h-5 w-5" }),
|
|
182
|
-
value: a(
|
|
187
|
+
value: a(w.totalReturns, { minimumFractionDigits: 0 }),
|
|
183
188
|
label: "Total Returns",
|
|
184
189
|
trend: "up",
|
|
185
190
|
trendValue: "Total profit earned"
|
|
186
191
|
}),
|
|
187
192
|
/* @__PURE__ */ y(r, {
|
|
188
193
|
icon: /* @__PURE__ */ y(d, { className: "h-5 w-5" }),
|
|
189
|
-
value: String(
|
|
194
|
+
value: String(w.activeInvestments),
|
|
190
195
|
label: "Active Investments",
|
|
191
196
|
trend: "neutral",
|
|
192
|
-
trendValue: `${
|
|
197
|
+
trendValue: `${w.averageRoi}% avg ROI`
|
|
193
198
|
})
|
|
194
199
|
]
|
|
195
|
-
}),
|
|
200
|
+
}) }),
|
|
196
201
|
/* @__PURE__ */ y("div", {
|
|
197
202
|
className: "mt-6 rounded-lg border border-border-subtle bg-bg-surface p-4",
|
|
198
203
|
children: /* @__PURE__ */ y("div", {
|
|
199
204
|
className: "flex flex-wrap gap-2",
|
|
200
|
-
children:
|
|
205
|
+
children: j.map((e) => /* @__PURE__ */ b("button", {
|
|
201
206
|
type: "button",
|
|
202
|
-
onClick: () =>
|
|
203
|
-
className: t("flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors",
|
|
207
|
+
onClick: () => k(e.key),
|
|
208
|
+
className: t("flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors", O === e.key ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-primary hover:bg-bg-sunken/80"),
|
|
204
209
|
children: [e.label, /* @__PURE__ */ y("span", {
|
|
205
|
-
className: t("rounded-full px-2 py-0.5 text-xs",
|
|
206
|
-
children:
|
|
210
|
+
className: t("rounded-full px-2 py-0.5 text-xs", O === e.key ? "bg-primary-foreground/20 text-action-primary-text" : "bg-action-primary-bg/10 text-primary"),
|
|
211
|
+
children: M(e.key)
|
|
207
212
|
})]
|
|
208
213
|
}, e.key))
|
|
209
214
|
})
|
|
210
215
|
}),
|
|
211
216
|
/* @__PURE__ */ y("div", {
|
|
212
217
|
className: "mt-6 space-y-4",
|
|
213
|
-
children:
|
|
218
|
+
children: A.length > 0 ? A.map((e) => /* @__PURE__ */ b("div", {
|
|
214
219
|
className: "rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6",
|
|
215
220
|
children: [/* @__PURE__ */ b("div", {
|
|
216
221
|
className: "block space-y-4 lg:hidden",
|
|
@@ -224,8 +229,8 @@ function T() {
|
|
|
224
229
|
className: "text-sm text-text-secondary",
|
|
225
230
|
children: ["by ", e.cartOwner]
|
|
226
231
|
})] }), /* @__PURE__ */ b("span", {
|
|
227
|
-
className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium",
|
|
228
|
-
children: [
|
|
232
|
+
className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium", T(e.status)),
|
|
233
|
+
children: [E(e.status), /* @__PURE__ */ y("span", {
|
|
229
234
|
className: "capitalize",
|
|
230
235
|
children: e.status
|
|
231
236
|
})]
|
|
@@ -301,8 +306,8 @@ function T() {
|
|
|
301
306
|
className: "text-lg font-semibold text-text-primary",
|
|
302
307
|
children: e.cartName
|
|
303
308
|
}), /* @__PURE__ */ b("span", {
|
|
304
|
-
className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium",
|
|
305
|
-
children: [
|
|
309
|
+
className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium", T(e.status)),
|
|
310
|
+
children: [E(e.status), /* @__PURE__ */ y("span", {
|
|
306
311
|
className: "capitalize",
|
|
307
312
|
children: e.status
|
|
308
313
|
})]
|
|
@@ -379,9 +384,10 @@ function T() {
|
|
|
379
384
|
})]
|
|
380
385
|
})]
|
|
381
386
|
}, e.id)) : /* @__PURE__ */ y(i, {
|
|
387
|
+
illustration: "empty-data",
|
|
382
388
|
icon: /* @__PURE__ */ y(g, { className: "h-12 w-12" }),
|
|
383
|
-
title: `No ${
|
|
384
|
-
description:
|
|
389
|
+
title: `No ${O === "all" ? "" : O} investments found`,
|
|
390
|
+
description: O === "all" ? "You haven't made any investments yet. Start exploring opportunities to grow your wealth." : `You don't have any ${O} investments at the moment.`,
|
|
385
391
|
action: /* @__PURE__ */ y("button", {
|
|
386
392
|
type: "button",
|
|
387
393
|
onClick: () => u("/investor/opportunities"),
|
|
@@ -394,6 +400,6 @@ function T() {
|
|
|
394
400
|
});
|
|
395
401
|
}
|
|
396
402
|
//#endregion
|
|
397
|
-
export {
|
|
403
|
+
export { D as InvestorInvestmentsPage };
|
|
398
404
|
|
|
399
405
|
//# sourceMappingURL=InvestorInvestmentsPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvestorInvestmentsPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/investor/InvestorInvestmentsPage.tsx"],"sourcesContent":["/**\n * Investor Investments Page\n * @module atheletebridge/pages/investor\n *\n * MetricsGrid summary cards, filter tabs (all/active/pending/matured) with counts,\n * responsive mobile/desktop layouts, P&L display, ROI display, status icons,\n * empty state.\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport {\n TrendingUp,\n TrendingDown,\n Briefcase,\n Eye,\n BarChart3,\n AlertCircle,\n CheckCircle2,\n Clock,\n Wallet,\n IndianRupee,\n Plus,\n Target,\n} from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatDate } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Investment {\n id: string;\n cartName: string;\n cartOwner: string;\n investmentAmount: number;\n currentValue: number;\n profitLoss: number;\n profitLossPercentage: number;\n investmentDate: string;\n status: 'active' | 'pending' | 'matured' | 'withdrawn';\n roiAnnual: number;\n duration: string;\n nextPayout: string;\n totalReturns: number;\n}\n\ninterface InvestmentSummary {\n totalInvested: number;\n currentValue: number;\n totalReturns: number;\n activeInvestments: number;\n averageRoi: number;\n profitLoss: number;\n profitLossPercentage: number;\n}\n\ntype FilterKey = 'all' | 'active' | 'pending' | 'matured';\n\n// ---------------------------------------------------------------------------\n// Mock data\n// ---------------------------------------------------------------------------\n\nconst mockInvestments: Investment[] = [\n {\n id: 'inv-001',\n cartName: 'South Indian Express',\n cartOwner: 'Raj Kumar',\n investmentAmount: 50000,\n currentValue: 58500,\n profitLoss: 8500,\n profitLossPercentage: 17.0,\n investmentDate: '2024-01-15',\n status: 'active',\n roiAnnual: 22.5,\n duration: '18 months',\n nextPayout: '2024-12-15',\n totalReturns: 8500,\n },\n {\n id: 'inv-002',\n cartName: 'Pizza Corner',\n cartOwner: 'Priya Singh',\n investmentAmount: 75000,\n currentValue: 82000,\n profitLoss: 7000,\n profitLossPercentage: 9.3,\n investmentDate: '2024-03-10',\n status: 'active',\n roiAnnual: 18.0,\n duration: '24 months',\n nextPayout: '2024-12-10',\n totalReturns: 7000,\n },\n {\n id: 'inv-003',\n cartName: 'Healthy Bites',\n cartOwner: 'Amit Patel',\n investmentAmount: 30000,\n currentValue: 31200,\n profitLoss: 1200,\n profitLossPercentage: 4.0,\n investmentDate: '2024-06-01',\n status: 'active',\n roiAnnual: 15.0,\n duration: '12 months',\n nextPayout: '2024-12-01',\n totalReturns: 1200,\n },\n {\n id: 'inv-004',\n cartName: 'Street Food Junction',\n cartOwner: 'Neha Sharma',\n investmentAmount: 40000,\n currentValue: 40000,\n profitLoss: 0,\n profitLossPercentage: 0,\n investmentDate: '2024-08-15',\n status: 'pending',\n roiAnnual: 20.0,\n duration: '15 months',\n nextPayout: '2025-01-15',\n totalReturns: 0,\n },\n {\n id: 'inv-005',\n cartName: 'Biryani House',\n cartOwner: 'Suresh Reddy',\n investmentAmount: 60000,\n currentValue: 72000,\n profitLoss: 12000,\n profitLossPercentage: 20.0,\n investmentDate: '2023-12-01',\n status: 'matured',\n roiAnnual: 25.0,\n duration: '12 months',\n nextPayout: '-',\n totalReturns: 12000,\n },\n];\n\nconst mockSummary: InvestmentSummary = {\n totalInvested: 255000,\n currentValue: 283700,\n totalReturns: 28700,\n activeInvestments: 3,\n averageRoi: 19.6,\n profitLoss: 28700,\n profitLossPercentage: 11.3,\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getStatusColor(status: string): string {\n switch (status) {\n case 'active':\n return 'bg-green-500/20 text-green-600 dark:text-green-400';\n case 'pending':\n return 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400';\n case 'matured':\n return 'bg-blue-500/20 text-blue-600 dark:text-blue-400';\n case 'withdrawn':\n return 'bg-secondary text-secondary-foreground';\n default:\n return 'bg-secondary text-secondary-foreground';\n }\n}\n\nfunction getStatusIcon(status: string) {\n switch (status) {\n case 'active':\n return <CheckCircle2 className=\"h-4 w-4\" />;\n case 'pending':\n return <Clock className=\"h-4 w-4\" />;\n case 'matured':\n return <CheckCircle2 className=\"h-4 w-4\" />;\n default:\n return <AlertCircle className=\"h-4 w-4\" />;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorInvestmentsPage() {\n const { navigateTo } = useAthleteBridge();\n const [isLoading, setIsLoading] = useState(true);\n const [filter, setFilter] = useState<FilterKey>('all');\n\n useEffect(() => {\n const timer = setTimeout(() => setIsLoading(false), 600);\n return () => clearTimeout(timer);\n }, []);\n\n const filteredInvestments = useMemo(() => {\n if (filter === 'all') return mockInvestments;\n return mockInvestments.filter((inv) => inv.status === filter);\n }, [filter]);\n\n const filterTabs: Array<{ key: FilterKey; label: string }> = [\n { key: 'all', label: 'All Investments' },\n { key: 'active', label: 'Active' },\n { key: 'pending', label: 'Pending' },\n { key: 'matured', label: 'Matured' },\n ];\n\n function getCount(key: FilterKey): number {\n if (key === 'all') return mockInvestments.length;\n return mockInvestments.filter((inv) => inv.status === key).length;\n }\n\n if (isLoading) {\n return (\n <PageLayout title=\"My Investments\" description=\"Loading your investments...\">\n <div className=\"flex items-center justify-center py-20\">\n <div className=\"text-center\">\n <div className=\"mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary\" />\n <p className=\"text-sm text-text-secondary\">Loading your investments...</p>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"My Investments\"\n description=\"Track and manage your investment portfolio\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n New Investment\n </button>\n }\n >\n {/* Investment Summary */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"up\"\n trendValue=\"Total amount invested\"\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend={mockSummary.profitLoss > 0 ? 'up' : 'down'}\n trendValue={`${mockSummary.profitLossPercentage > 0 ? '+' : ''}${mockSummary.profitLossPercentage}% total returns`}\n />\n <MetricsCard\n icon={<TrendingUp className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.totalReturns, { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n trend=\"up\"\n trendValue=\"Total profit earned\"\n />\n <MetricsCard\n icon={<CheckCircle2 className=\"h-5 w-5\" />}\n value={String(mockSummary.activeInvestments)}\n label=\"Active Investments\"\n trend=\"neutral\"\n trendValue={`${mockSummary.averageRoi}% avg ROI`}\n />\n </div>\n\n {/* Filter Tabs */}\n <div className=\"mt-6 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex flex-wrap gap-2\">\n {filterTabs.map((tab) => (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => setFilter(tab.key)}\n className={cn(\n 'flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors',\n filter === tab.key\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary hover:bg-bg-sunken/80'\n )}\n >\n {tab.label}\n <span\n className={cn(\n 'rounded-full px-2 py-0.5 text-xs',\n filter === tab.key\n ? 'bg-primary-foreground/20 text-action-primary-text'\n : 'bg-action-primary-bg/10 text-primary'\n )}\n >\n {getCount(tab.key)}\n </span>\n </button>\n ))}\n </div>\n </div>\n\n {/* Investments List */}\n <div className=\"mt-6 space-y-4\">\n {filteredInvestments.length > 0 ? (\n filteredInvestments.map((investment) => (\n <div key={investment.id} className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6\">\n {/* Mobile Layout */}\n <div className=\"block space-y-4 lg:hidden\">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">{investment.cartName}</h3>\n <p className=\"text-sm text-text-secondary\">by {investment.cartOwner}</p>\n </div>\n <span\n className={cn(\n 'flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium',\n getStatusColor(investment.status)\n )}\n >\n {getStatusIcon(investment.status)}\n <span className=\"capitalize\">{investment.status}</span>\n </span>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invested</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.investmentAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Current Value</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">P&L</p>\n <p\n className={cn(\n 'font-semibold',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n {investment.profitLoss >= 0 ? '+' : ''}\n {formatCurrency(investment.profitLoss, { minimumFractionDigits: 0 })} (\n {investment.profitLossPercentage >= 0 ? '+' : ''}\n {investment.profitLossPercentage}%)\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">ROI</p>\n <p className=\"font-semibold text-text-primary\">{investment.roiAnnual}% p.a.</p>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between border-t border-border-subtle pt-2\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested on</p>\n <p className=\"text-sm font-medium text-text-primary\">\n {formatDate(investment.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n </div>\n\n {/* Desktop Layout */}\n <div className=\"hidden lg:flex lg:items-center lg:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"mb-2 flex items-center justify-between\">\n <h3 className=\"text-lg font-semibold text-text-primary\">{investment.cartName}</h3>\n <span\n className={cn(\n 'flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium',\n getStatusColor(investment.status)\n )}\n >\n {getStatusIcon(investment.status)}\n <span className=\"capitalize\">{investment.status}</span>\n </span>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">by {investment.cartOwner}</p>\n\n <div className=\"grid grid-cols-5 gap-6\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invested</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.investmentAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Current Value</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">P&L</p>\n <p\n className={cn(\n 'font-semibold',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n {investment.profitLoss >= 0 ? '+' : ''}\n {formatCurrency(investment.profitLoss, { minimumFractionDigits: 0 })}\n </p>\n <p\n className={cn(\n 'text-xs',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n ({investment.profitLossPercentage >= 0 ? '+' : ''}\n {investment.profitLossPercentage}%)\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">ROI</p>\n <p className=\"font-semibold text-text-primary\">{investment.roiAnnual}% p.a.</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Invested on</p>\n <p className=\"font-semibold text-text-primary\">\n {formatDate(investment.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\n </div>\n </div>\n </div>\n\n <div className=\"ml-6\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n </div>\n </div>\n ))\n ) : (\n <EmptyState\n icon={<TrendingDown className=\"h-12 w-12\" />}\n title={`No ${filter !== 'all' ? filter : ''} investments found`}\n description={\n filter === 'all'\n ? \"You haven't made any investments yet. Start exploring opportunities to grow your wealth.\"\n : `You don't have any ${filter} investments at the moment.`\n }\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n Explore Investment Opportunities\n </button>\n }\n />\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InvestorInvestmentsPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/investor/InvestorInvestmentsPage.tsx"],"sourcesContent":["/**\n * Investor Investments Page\n * @module atheletebridge/pages/investor\n *\n * MetricsGrid summary cards, filter tabs (all/active/pending/matured) with counts,\n * responsive mobile/desktop layouts, P&L display, ROI display, status icons,\n * empty state.\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport {\n TrendingUp,\n TrendingDown,\n Briefcase,\n Eye,\n BarChart3,\n AlertCircle,\n CheckCircle2,\n Clock,\n Wallet,\n IndianRupee,\n Plus,\n Target,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency, formatDate } from '../../utils/formatters';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Investment {\n id: string;\n cartName: string;\n cartOwner: string;\n investmentAmount: number;\n currentValue: number;\n profitLoss: number;\n profitLossPercentage: number;\n investmentDate: string;\n status: 'active' | 'pending' | 'matured' | 'withdrawn';\n roiAnnual: number;\n duration: string;\n nextPayout: string;\n totalReturns: number;\n}\n\ninterface InvestmentSummary {\n totalInvested: number;\n currentValue: number;\n totalReturns: number;\n activeInvestments: number;\n averageRoi: number;\n profitLoss: number;\n profitLossPercentage: number;\n}\n\ntype FilterKey = 'all' | 'active' | 'pending' | 'matured';\n\n// ---------------------------------------------------------------------------\n// Mock data\n// ---------------------------------------------------------------------------\n\nconst mockInvestments: Investment[] = [\n {\n id: 'inv-001',\n cartName: 'South Indian Express',\n cartOwner: 'Raj Kumar',\n investmentAmount: 50000,\n currentValue: 58500,\n profitLoss: 8500,\n profitLossPercentage: 17.0,\n investmentDate: '2024-01-15',\n status: 'active',\n roiAnnual: 22.5,\n duration: '18 months',\n nextPayout: '2024-12-15',\n totalReturns: 8500,\n },\n {\n id: 'inv-002',\n cartName: 'Pizza Corner',\n cartOwner: 'Priya Singh',\n investmentAmount: 75000,\n currentValue: 82000,\n profitLoss: 7000,\n profitLossPercentage: 9.3,\n investmentDate: '2024-03-10',\n status: 'active',\n roiAnnual: 18.0,\n duration: '24 months',\n nextPayout: '2024-12-10',\n totalReturns: 7000,\n },\n {\n id: 'inv-003',\n cartName: 'Healthy Bites',\n cartOwner: 'Amit Patel',\n investmentAmount: 30000,\n currentValue: 31200,\n profitLoss: 1200,\n profitLossPercentage: 4.0,\n investmentDate: '2024-06-01',\n status: 'active',\n roiAnnual: 15.0,\n duration: '12 months',\n nextPayout: '2024-12-01',\n totalReturns: 1200,\n },\n {\n id: 'inv-004',\n cartName: 'Street Food Junction',\n cartOwner: 'Neha Sharma',\n investmentAmount: 40000,\n currentValue: 40000,\n profitLoss: 0,\n profitLossPercentage: 0,\n investmentDate: '2024-08-15',\n status: 'pending',\n roiAnnual: 20.0,\n duration: '15 months',\n nextPayout: '2025-01-15',\n totalReturns: 0,\n },\n {\n id: 'inv-005',\n cartName: 'Biryani House',\n cartOwner: 'Suresh Reddy',\n investmentAmount: 60000,\n currentValue: 72000,\n profitLoss: 12000,\n profitLossPercentage: 20.0,\n investmentDate: '2023-12-01',\n status: 'matured',\n roiAnnual: 25.0,\n duration: '12 months',\n nextPayout: '-',\n totalReturns: 12000,\n },\n];\n\nconst mockSummary: InvestmentSummary = {\n totalInvested: 255000,\n currentValue: 283700,\n totalReturns: 28700,\n activeInvestments: 3,\n averageRoi: 19.6,\n profitLoss: 28700,\n profitLossPercentage: 11.3,\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getStatusColor(status: string): string {\n switch (status) {\n case 'active':\n return 'bg-green-500/20 text-green-600 dark:text-green-400';\n case 'pending':\n return 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400';\n case 'matured':\n return 'bg-blue-500/20 text-blue-600 dark:text-blue-400';\n case 'withdrawn':\n return 'bg-secondary text-secondary-foreground';\n default:\n return 'bg-secondary text-secondary-foreground';\n }\n}\n\nfunction getStatusIcon(status: string) {\n switch (status) {\n case 'active':\n return <CheckCircle2 className=\"h-4 w-4\" />;\n case 'pending':\n return <Clock className=\"h-4 w-4\" />;\n case 'matured':\n return <CheckCircle2 className=\"h-4 w-4\" />;\n default:\n return <AlertCircle className=\"h-4 w-4\" />;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorInvestmentsPage() {\n const { navigateTo } = useAthleteBridge();\n const [isLoading, setIsLoading] = useState(true);\n const [filter, setFilter] = useState<FilterKey>('all');\n\n useEffect(() => {\n const timer = setTimeout(() => setIsLoading(false), 600);\n return () => clearTimeout(timer);\n }, []);\n\n const filteredInvestments = useMemo(() => {\n if (filter === 'all') return mockInvestments;\n return mockInvestments.filter((inv) => inv.status === filter);\n }, [filter]);\n\n const filterTabs: Array<{ key: FilterKey; label: string }> = [\n { key: 'all', label: 'All Investments' },\n { key: 'active', label: 'Active' },\n { key: 'pending', label: 'Pending' },\n { key: 'matured', label: 'Matured' },\n ];\n\n function getCount(key: FilterKey): number {\n if (key === 'all') return mockInvestments.length;\n return mockInvestments.filter((inv) => inv.status === key).length;\n }\n\n if (isLoading) {\n return (\n <PageLayout title=\"My Investments\" description=\"Loading your investments...\">\n <div className=\"flex items-center justify-center py-20\">\n <div className=\"text-center\">\n <div className=\"mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary\" />\n <p className=\"text-sm text-text-secondary\">Loading your investments...</p>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"My Investments\"\n description=\"Track and manage your investment portfolio\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n New Investment\n </button>\n }\n >\n <PagePurpose className=\"mb-6\">\n Manage the businesses you've already invested in. See your total invested, current\n value and returns, filter by status, and open any holding to track its performance or take\n action. This is your active-investments workspace.\n </PagePurpose>\n\n {/* Investment Summary */}\n <EmphasisPanel>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.totalInvested, { minimumFractionDigits: 0 })}\n label=\"Total Invested\"\n trend=\"up\"\n trendValue=\"Total amount invested\"\n />\n <MetricsCard\n icon={<IndianRupee className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.currentValue, { minimumFractionDigits: 0 })}\n label=\"Current Value\"\n trend={mockSummary.profitLoss > 0 ? 'up' : 'down'}\n trendValue={`${mockSummary.profitLossPercentage > 0 ? '+' : ''}${mockSummary.profitLossPercentage}% total returns`}\n />\n <MetricsCard\n icon={<TrendingUp className=\"h-5 w-5\" />}\n value={formatCurrency(mockSummary.totalReturns, { minimumFractionDigits: 0 })}\n label=\"Total Returns\"\n trend=\"up\"\n trendValue=\"Total profit earned\"\n />\n <MetricsCard\n icon={<CheckCircle2 className=\"h-5 w-5\" />}\n value={String(mockSummary.activeInvestments)}\n label=\"Active Investments\"\n trend=\"neutral\"\n trendValue={`${mockSummary.averageRoi}% avg ROI`}\n />\n </div>\n </EmphasisPanel>\n\n {/* Filter Tabs */}\n <div className=\"mt-6 rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex flex-wrap gap-2\">\n {filterTabs.map((tab) => (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => setFilter(tab.key)}\n className={cn(\n 'flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors',\n filter === tab.key\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary hover:bg-bg-sunken/80'\n )}\n >\n {tab.label}\n <span\n className={cn(\n 'rounded-full px-2 py-0.5 text-xs',\n filter === tab.key\n ? 'bg-primary-foreground/20 text-action-primary-text'\n : 'bg-action-primary-bg/10 text-primary'\n )}\n >\n {getCount(tab.key)}\n </span>\n </button>\n ))}\n </div>\n </div>\n\n {/* Investments List */}\n <div className=\"mt-6 space-y-4\">\n {filteredInvestments.length > 0 ? (\n filteredInvestments.map((investment) => (\n <div\n key={investment.id}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6\"\n >\n {/* Mobile Layout */}\n <div className=\"block space-y-4 lg:hidden\">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {investment.cartName}\n </h3>\n <p className=\"text-sm text-text-secondary\">by {investment.cartOwner}</p>\n </div>\n <span\n className={cn(\n 'flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium',\n getStatusColor(investment.status)\n )}\n >\n {getStatusIcon(investment.status)}\n <span className=\"capitalize\">{investment.status}</span>\n </span>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invested</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.investmentAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Current Value</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">P&L</p>\n <p\n className={cn(\n 'font-semibold',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n {investment.profitLoss >= 0 ? '+' : ''}\n {formatCurrency(investment.profitLoss, { minimumFractionDigits: 0 })} (\n {investment.profitLossPercentage >= 0 ? '+' : ''}\n {investment.profitLossPercentage}%)\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">ROI</p>\n <p className=\"font-semibold text-text-primary\">{investment.roiAnnual}% p.a.</p>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between border-t border-border-subtle pt-2\">\n <div>\n <p className=\"text-xs text-text-secondary\">Invested on</p>\n <p className=\"text-sm font-medium text-text-primary\">\n {formatDate(investment.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n </div>\n\n {/* Desktop Layout */}\n <div className=\"hidden lg:flex lg:items-center lg:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"mb-2 flex items-center justify-between\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {investment.cartName}\n </h3>\n <span\n className={cn(\n 'flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium',\n getStatusColor(investment.status)\n )}\n >\n {getStatusIcon(investment.status)}\n <span className=\"capitalize\">{investment.status}</span>\n </span>\n </div>\n <p className=\"mb-4 text-sm text-text-secondary\">by {investment.cartOwner}</p>\n\n <div className=\"grid grid-cols-5 gap-6\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invested</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.investmentAmount, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Current Value</p>\n <p className=\"font-semibold text-text-primary\">\n {formatCurrency(investment.currentValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">P&L</p>\n <p\n className={cn(\n 'font-semibold',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n {investment.profitLoss >= 0 ? '+' : ''}\n {formatCurrency(investment.profitLoss, { minimumFractionDigits: 0 })}\n </p>\n <p\n className={cn(\n 'text-xs',\n investment.profitLoss >= 0\n ? 'text-green-600 dark:text-green-400'\n : 'text-red-600 dark:text-red-400'\n )}\n >\n ({investment.profitLossPercentage >= 0 ? '+' : ''}\n {investment.profitLossPercentage}%)\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">ROI</p>\n <p className=\"font-semibold text-text-primary\">\n {investment.roiAnnual}% p.a.\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Invested on</p>\n <p className=\"font-semibold text-text-primary\">\n {formatDate(investment.investmentDate, {\n hour: undefined,\n minute: undefined,\n })}\n </p>\n </div>\n </div>\n </div>\n\n <div className=\"ml-6\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`/investor/investments/${investment.id}`)}\n className=\"flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n </div>\n </div>\n ))\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<TrendingDown className=\"h-12 w-12\" />}\n title={`No ${filter !== 'all' ? filter : ''} investments found`}\n description={\n filter === 'all'\n ? \"You haven't made any investments yet. Start exploring opportunities to grow your wealth.\"\n : `You don't have any ${filter} investments at the moment.`\n }\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/investor/opportunities')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n Explore Investment Opportunities\n </button>\n }\n />\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|