@burdenoff/microfe-coolandlovely 2026.625.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/coolandlovely/pages/HomePage.js +263 -258
- package/dist/coolandlovely/pages/HomePage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminAnalyticsPage.js +67 -61
- package/dist/coolandlovely/pages/admin/AdminAnalyticsPage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminDashboard.js +79 -45
- package/dist/coolandlovely/pages/admin/AdminDashboard.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminFinancialPage.js +39 -33
- package/dist/coolandlovely/pages/admin/AdminFinancialPage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminOrdersPage.js +227 -222
- package/dist/coolandlovely/pages/admin/AdminOrdersPage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminProfilePage.js +65 -60
- package/dist/coolandlovely/pages/admin/AdminProfilePage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminSettingsPage.js +235 -230
- package/dist/coolandlovely/pages/admin/AdminSettingsPage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/CartManagementPage.js +268 -263
- package/dist/coolandlovely/pages/admin/CartManagementPage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/UserManagementPage.js +268 -263
- package/dist/coolandlovely/pages/admin/UserManagementPage.js.map +1 -1
- package/dist/coolandlovely/pages/cart-owner/AnalyticsDashboard.js +92 -84
- package/dist/coolandlovely/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
- package/dist/coolandlovely/pages/cart-owner/BusinessSettingsPage.js +257 -252
- package/dist/coolandlovely/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
- package/dist/coolandlovely/pages/cart-owner/CartOwnerDashboard.js +587 -548
- package/dist/coolandlovely/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
- package/dist/coolandlovely/pages/cart-owner/CartOwnerProfilePage.js +171 -166
- package/dist/coolandlovely/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
- package/dist/coolandlovely/pages/cart-owner/CartServiceConfigPage.js +219 -211
- package/dist/coolandlovely/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
- package/dist/coolandlovely/pages/cart-owner/InventoryManagementPage.js +671 -670
- package/dist/coolandlovely/pages/cart-owner/InventoryManagementPage.js.map +1 -1
- package/dist/coolandlovely/pages/cart-owner/OrderManagementPage.js +515 -514
- package/dist/coolandlovely/pages/cart-owner/OrderManagementPage.js.map +1 -1
- package/dist/coolandlovely/pages/cart-owner/StaffManagementPage.js +244 -246
- package/dist/coolandlovely/pages/cart-owner/StaffManagementPage.js.map +1 -1
- package/dist/coolandlovely/pages/common/HelpSupportPage.js +96 -96
- package/dist/coolandlovely/pages/common/HelpSupportPage.js.map +1 -1
- package/dist/coolandlovely/pages/common/NotificationCenterPage.js +50 -44
- package/dist/coolandlovely/pages/common/NotificationCenterPage.js.map +1 -1
- package/dist/coolandlovely/pages/common/SettingsPage.js +745 -736
- package/dist/coolandlovely/pages/common/SettingsPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/BookingDetailsPage.js +394 -357
- package/dist/coolandlovely/pages/customer/BookingDetailsPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/CartDetailPage.js +179 -176
- package/dist/coolandlovely/pages/customer/CartDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/CartDiscoveryPage.js +215 -204
- package/dist/coolandlovely/pages/customer/CartDiscoveryPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/CheckoutPage.js +212 -215
- package/dist/coolandlovely/pages/customer/CheckoutPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/CustomerDashboard.js +438 -396
- package/dist/coolandlovely/pages/customer/CustomerDashboard.js.map +1 -1
- package/dist/coolandlovely/pages/customer/CustomerProfilePage.js +525 -488
- package/dist/coolandlovely/pages/customer/CustomerProfilePage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/DirectServiceBookingPage.js +522 -513
- package/dist/coolandlovely/pages/customer/DirectServiceBookingPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/FavoritesPage.js +86 -76
- package/dist/coolandlovely/pages/customer/FavoritesPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/OrderHistoryPage.js +118 -109
- package/dist/coolandlovely/pages/customer/OrderHistoryPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/OrderTrackingPage.js +312 -275
- package/dist/coolandlovely/pages/customer/OrderTrackingPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/PaymentMethodsPage.js +82 -76
- package/dist/coolandlovely/pages/customer/PaymentMethodsPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/ReviewsPage.js +83 -73
- package/dist/coolandlovely/pages/customer/ReviewsPage.js.map +1 -1
- package/dist/coolandlovely/pages/customer/SavedAddressesPage.js +61 -55
- package/dist/coolandlovely/pages/customer/SavedAddressesPage.js.map +1 -1
- package/dist/coolandlovely/pages/investor/InvestmentDetailsPage.js +293 -255
- package/dist/coolandlovely/pages/investor/InvestmentDetailsPage.js.map +1 -1
- package/dist/coolandlovely/pages/investor/InvestmentOpportunitiesPage.js +238 -232
- package/dist/coolandlovely/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
- package/dist/coolandlovely/pages/investor/InvestorAnalyticsPage.js +61 -55
- package/dist/coolandlovely/pages/investor/InvestorAnalyticsPage.js.map +1 -1
- package/dist/coolandlovely/pages/investor/InvestorDashboard.js +356 -320
- package/dist/coolandlovely/pages/investor/InvestorDashboard.js.map +1 -1
- package/dist/coolandlovely/pages/investor/InvestorInvestmentsPage.js +107 -101
- package/dist/coolandlovely/pages/investor/InvestorInvestmentsPage.js.map +1 -1
- package/dist/coolandlovely/pages/investor/InvestorPortfolioPage.js +170 -137
- package/dist/coolandlovely/pages/investor/InvestorPortfolioPage.js.map +1 -1
- package/dist/coolandlovely/pages/investor/InvestorProfilePage.js +386 -381
- package/dist/coolandlovely/pages/investor/InvestorProfilePage.js.map +1 -1
- package/dist/coolandlovely/pages/worker/TaskDetailsPage.js +359 -322
- package/dist/coolandlovely/pages/worker/TaskDetailsPage.js.map +1 -1
- package/dist/coolandlovely/pages/worker/WorkerDashboard.js +574 -537
- package/dist/coolandlovely/pages/worker/WorkerDashboard.js.map +1 -1
- package/dist/coolandlovely/pages/worker/WorkerOrdersPage.js +81 -76
- package/dist/coolandlovely/pages/worker/WorkerOrdersPage.js.map +1 -1
- package/dist/coolandlovely/pages/worker/WorkerProfilePage.js +82 -77
- package/dist/coolandlovely/pages/worker/WorkerProfilePage.js.map +1 -1
- package/dist/coolandlovely/pages/worker/WorkerSchedulePage.js +78 -73
- package/dist/coolandlovely/pages/worker/WorkerSchedulePage.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvestorDashboard.js","names":[],"sources":["../../../../src/coolandlovely/pages/investor/InvestorDashboard.tsx"],"sourcesContent":["/**\n * Investor Dashboard Page\n * @module coolandlovely/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 { useCoolAndLovely } from'../../context/CoolAndLovelyContext';\nimport { useInvestmentOpportunities, useInvestments } from'../../hooks/useCoolAndLovelyApi';\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-status-success-bg-subtle/20 text-status-success-text';\n case'medium':\n return'bg-status-warning-bg-subtle/20 text-status-warning-text';\n case'high':\n return'bg-status-error-bg-subtle/20 text-status-error-text';\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-status-success-bg-subtle/20 text-status-success-text';\n case'pending':\n return'bg-status-warning-bg-subtle/20 text-status-warning-text';\n case'completed':\n return'bg-accent-blue-subtle/20 text-accent-blue';\n default:\n return'bg-secondary text-secondary-foreground';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorDashboard() {\n const { navigateTo, currentUser } = useCoolAndLovely();\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-seam bg-bg-surface p-4 hover:shadow-md transition-shadow bg-gloss-card shadow-pop\"\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-status-success-text\">\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-status-success-text\">\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-status-success-bg-subtle/10' : 'bg-bg-sunken'\n )}\n >\n <Activity\n className={cn(\n 'h-4 w-4',\n activity.amount > 0\n ? 'text-status-success-text'\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-status-success-text' : '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-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\n <div className=\"mb-3 flex items-center gap-2\">\n <Lightbulb className=\"h-5 w-5 text-status-warning-text\" />\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-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\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-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\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-status-success-border 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-accent-blue-subtle 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-status-warning-border 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/coolandlovely/pages/investor/InvestorDashboard.tsx"],"sourcesContent":["/**\n * Investor Dashboard Page\n * @module coolandlovely/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 { EmphasisPanel, PagePurpose, NextSteps } from'@burdenoff/fe-libs/ui';\nimport { PageLayout } from'../../components/PageLayout';\nimport { MetricsCard } from'../../components/MetricsCard';\nimport { InvestmentCard } from'../../components/InvestmentCard';\nimport { RatingDisplay } from'../../components/RatingDisplay';\nimport { EmptyState } from'../../components/EmptyState';\nimport { useCoolAndLovely } from'../../context/CoolAndLovelyContext';\nimport { useInvestmentOpportunities, useInvestments } from'../../hooks/useCoolAndLovelyApi';\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-status-success-bg-subtle/20 text-status-success-text';\n case'medium':\n return'bg-status-warning-bg-subtle/20 text-status-warning-text';\n case'high':\n return'bg-status-error-bg-subtle/20 text-status-error-text';\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-status-success-bg-subtle/20 text-status-success-text';\n case'pending':\n return'bg-status-warning-bg-subtle/20 text-status-warning-text';\n case'completed':\n return'bg-accent-blue-subtle/20 text-accent-blue';\n default:\n return'bg-secondary text-secondary-foreground';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function InvestorDashboard() {\n const { navigateTo, currentUser } = useCoolAndLovely();\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\" icon={<TrendingUp className=\"h-4 w-4\" />}>\n Your money at work across local businesses. Track what you've invested,\n what it's worth now and the income it generates, switch between your\n holdings and fresh opportunities, and act on AI insights and market\n updates to grow your portfolio.\n </PagePurpose>\n\n <NextSteps\n className=\"mb-6\"\n storageKey=\"coolandlovely-investor-dashboard\"\n steps={[\n {\n id: 'review-portfolio',\n label: 'Review your portfolio',\n description: 'See the full breakdown and performance of your holdings.',\n icon: <PieChart className=\"h-4 w-4\" />,\n onClick: () => navigateTo('/investor/portfolio'),\n done: investments.length > 0,\n },\n {\n id: 'browse',\n label: 'Browse new opportunities',\n description: 'Find businesses open for investment that fit your goals.',\n icon: <Target className=\"h-4 w-4\" />,\n onClick: () => navigateTo('/investor/opportunities'),\n },\n {\n id: 'analytics',\n label: 'Check your analytics',\n description: 'Dig into returns, allocation and trends across investments.',\n icon: <BarChart3 className=\"h-4 w-4\" />,\n onClick: () => navigateTo('/investor/analytics'),\n },\n ]}\n />\n\n {/* Portfolio Summary Metrics — primary emphasis zone */}\n <EmphasisPanel className=\"p-5\">\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 <EmptyState\n illustration=\"empty-data\"\n title=\"No active investments found\"\n description=\"You haven't invested in any businesses yet. Explore opportunities to put your money to work.\"\n action={\n <button\n type=\"button\"\n onClick={() => setActiveTab('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 investments.map((investment) => (\n <div\n key={investment.id}\n className=\"rounded-lg border border-border-seam bg-bg-surface p-4 hover:shadow-md transition-shadow bg-gloss-card shadow-pop\"\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-status-success-text\">\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-status-success-text\">\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-status-success-bg-subtle/10' : 'bg-bg-sunken'\n )}\n >\n <Activity\n className={cn(\n 'h-4 w-4',\n activity.amount > 0\n ? 'text-status-success-text'\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-status-success-text' : '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-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\n <div className=\"mb-3 flex items-center gap-2\">\n <Lightbulb className=\"h-5 w-5 text-status-warning-text\" />\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-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\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-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\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-status-success-border 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-accent-blue-subtle 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-status-warning-border 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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"}
|
|
@@ -5,10 +5,11 @@ import { MetricsCard as r } from "../../components/MetricsCard.js";
|
|
|
5
5
|
import { EmptyState as i } from "../../components/EmptyState.js";
|
|
6
6
|
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
|
-
import { AlertCircle as u, CheckCircle2 as d, Clock as f, Eye as p, IndianRupee as m, Plus as h,
|
|
9
|
-
import { jsx as
|
|
8
|
+
import { AlertCircle as u, CheckCircle2 as d, Clock as f, Eye as p, IndianRupee as m, Plus as h, TrendingUp as g, Wallet as _ } from "lucide-react";
|
|
9
|
+
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
10
|
+
import { EmphasisPanel as b, PagePurpose as x } from "@burdenoff/fe-libs/ui";
|
|
10
11
|
//#region src/coolandlovely/pages/investor/InvestorInvestmentsPage.tsx
|
|
11
|
-
var
|
|
12
|
+
var S = [
|
|
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
|
+
], C = {
|
|
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 w(e) {
|
|
97
98
|
switch (e) {
|
|
98
99
|
case "active": return "bg-status-success-bg-subtle/20 text-status-success-text";
|
|
99
100
|
case "pending": return "bg-status-warning-bg-subtle/20 text-status-warning-text";
|
|
@@ -102,21 +103,21 @@ function C(e) {
|
|
|
102
103
|
default: return "bg-secondary text-secondary-foreground";
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
function
|
|
106
|
+
function T(e) {
|
|
106
107
|
switch (e) {
|
|
107
|
-
case "active": return /* @__PURE__ */
|
|
108
|
-
case "pending": return /* @__PURE__ */
|
|
109
|
-
case "matured": return /* @__PURE__ */
|
|
110
|
-
default: return /* @__PURE__ */
|
|
108
|
+
case "active": return /* @__PURE__ */ v(d, { className: "h-4 w-4" });
|
|
109
|
+
case "pending": return /* @__PURE__ */ v(f, { className: "h-4 w-4" });
|
|
110
|
+
case "matured": return /* @__PURE__ */ v(d, { className: "h-4 w-4" });
|
|
111
|
+
default: return /* @__PURE__ */ v(u, { className: "h-4 w-4" });
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
|
-
function
|
|
114
|
-
let { navigateTo: u } = e(), [f,
|
|
114
|
+
function E() {
|
|
115
|
+
let { navigateTo: u } = e(), [f, E] = l(!0), [D, O] = l("all");
|
|
115
116
|
s(() => {
|
|
116
|
-
let e = setTimeout(() =>
|
|
117
|
+
let e = setTimeout(() => E(!1), 600);
|
|
117
118
|
return () => clearTimeout(e);
|
|
118
119
|
}, []);
|
|
119
|
-
let
|
|
120
|
+
let k = c(() => D === "all" ? S : S.filter((e) => e.status === D), [D]), A = [
|
|
120
121
|
{
|
|
121
122
|
key: "all",
|
|
122
123
|
label: "All Investments"
|
|
@@ -134,124 +135,129 @@ function T() {
|
|
|
134
135
|
label: "Matured"
|
|
135
136
|
}
|
|
136
137
|
];
|
|
137
|
-
function
|
|
138
|
-
return e === "all" ?
|
|
138
|
+
function j(e) {
|
|
139
|
+
return e === "all" ? S.length : S.filter((t) => t.status === e).length;
|
|
139
140
|
}
|
|
140
|
-
return f ? /* @__PURE__ */
|
|
141
|
+
return f ? /* @__PURE__ */ v(n, {
|
|
141
142
|
title: "My Investments",
|
|
142
143
|
description: "Loading your investments...",
|
|
143
|
-
children: /* @__PURE__ */
|
|
144
|
+
children: /* @__PURE__ */ v("div", {
|
|
144
145
|
className: "flex items-center justify-center py-20",
|
|
145
|
-
children: /* @__PURE__ */
|
|
146
|
+
children: /* @__PURE__ */ y("div", {
|
|
146
147
|
className: "text-center",
|
|
147
|
-
children: [/* @__PURE__ */
|
|
148
|
+
children: [/* @__PURE__ */ v("div", { className: "mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-primary" }), /* @__PURE__ */ v("p", {
|
|
148
149
|
className: "text-sm text-text-secondary",
|
|
149
150
|
children: "Loading your investments..."
|
|
150
151
|
})]
|
|
151
152
|
})
|
|
152
153
|
})
|
|
153
|
-
}) : /* @__PURE__ */
|
|
154
|
+
}) : /* @__PURE__ */ y(n, {
|
|
154
155
|
title: "My Investments",
|
|
155
156
|
description: "Track and manage your investment portfolio",
|
|
156
|
-
actions: /* @__PURE__ */
|
|
157
|
+
actions: /* @__PURE__ */ y("button", {
|
|
157
158
|
type: "button",
|
|
158
159
|
onClick: () => u("/investor/opportunities"),
|
|
159
160
|
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",
|
|
160
|
-
children: [/* @__PURE__ */
|
|
161
|
+
children: [/* @__PURE__ */ v(h, { className: "h-4 w-4" }), "New Investment"]
|
|
161
162
|
}),
|
|
162
163
|
children: [
|
|
163
|
-
/* @__PURE__ */
|
|
164
|
-
className: "
|
|
164
|
+
/* @__PURE__ */ v(x, {
|
|
165
|
+
className: "mb-6",
|
|
166
|
+
icon: /* @__PURE__ */ v(_, { className: "h-4 w-4" }),
|
|
167
|
+
children: "A focused view of the businesses you've already backed. See total invested, current value and returns at a glance, filter by status, and open any holding to track its performance — then add a new investment whenever you're ready."
|
|
168
|
+
}),
|
|
169
|
+
/* @__PURE__ */ y(b, {
|
|
170
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4 p-4",
|
|
165
171
|
children: [
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
icon: /* @__PURE__ */
|
|
168
|
-
value: a(
|
|
172
|
+
/* @__PURE__ */ v(r, {
|
|
173
|
+
icon: /* @__PURE__ */ v(_, { className: "h-5 w-5" }),
|
|
174
|
+
value: a(C.totalInvested, { minimumFractionDigits: 0 }),
|
|
169
175
|
label: "Total Invested",
|
|
170
176
|
trend: "up",
|
|
171
177
|
trendValue: "Total amount invested"
|
|
172
178
|
}),
|
|
173
|
-
/* @__PURE__ */
|
|
174
|
-
icon: /* @__PURE__ */
|
|
175
|
-
value: a(
|
|
179
|
+
/* @__PURE__ */ v(r, {
|
|
180
|
+
icon: /* @__PURE__ */ v(m, { className: "h-5 w-5" }),
|
|
181
|
+
value: a(C.currentValue, { minimumFractionDigits: 0 }),
|
|
176
182
|
label: "Current Value",
|
|
177
|
-
trend:
|
|
178
|
-
trendValue: `${
|
|
183
|
+
trend: C.profitLoss > 0 ? "up" : "down",
|
|
184
|
+
trendValue: `${C.profitLossPercentage > 0 ? "+" : ""}${C.profitLossPercentage}% total returns`
|
|
179
185
|
}),
|
|
180
|
-
/* @__PURE__ */
|
|
181
|
-
icon: /* @__PURE__ */
|
|
182
|
-
value: a(
|
|
186
|
+
/* @__PURE__ */ v(r, {
|
|
187
|
+
icon: /* @__PURE__ */ v(g, { className: "h-5 w-5" }),
|
|
188
|
+
value: a(C.totalReturns, { minimumFractionDigits: 0 }),
|
|
183
189
|
label: "Total Returns",
|
|
184
190
|
trend: "up",
|
|
185
191
|
trendValue: "Total profit earned"
|
|
186
192
|
}),
|
|
187
|
-
/* @__PURE__ */
|
|
188
|
-
icon: /* @__PURE__ */
|
|
189
|
-
value: String(
|
|
193
|
+
/* @__PURE__ */ v(r, {
|
|
194
|
+
icon: /* @__PURE__ */ v(d, { className: "h-5 w-5" }),
|
|
195
|
+
value: String(C.activeInvestments),
|
|
190
196
|
label: "Active Investments",
|
|
191
197
|
trend: "neutral",
|
|
192
|
-
trendValue: `${
|
|
198
|
+
trendValue: `${C.averageRoi}% avg ROI`
|
|
193
199
|
})
|
|
194
200
|
]
|
|
195
201
|
}),
|
|
196
|
-
/* @__PURE__ */
|
|
202
|
+
/* @__PURE__ */ v("div", {
|
|
197
203
|
className: "mt-6 rounded-lg border border-border-seam bg-bg-surface p-4 bg-gloss-card shadow-pop",
|
|
198
|
-
children: /* @__PURE__ */
|
|
204
|
+
children: /* @__PURE__ */ v("div", {
|
|
199
205
|
className: "flex flex-wrap gap-2",
|
|
200
|
-
children:
|
|
206
|
+
children: A.map((e) => /* @__PURE__ */ y("button", {
|
|
201
207
|
type: "button",
|
|
202
|
-
onClick: () =>
|
|
203
|
-
className: t("flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors",
|
|
204
|
-
children: [e.label, /* @__PURE__ */
|
|
205
|
-
className: t("rounded-full px-2 py-0.5 text-xs",
|
|
206
|
-
children:
|
|
208
|
+
onClick: () => O(e.key),
|
|
209
|
+
className: t("flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors", D === e.key ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-primary hover:bg-bg-sunken/80"),
|
|
210
|
+
children: [e.label, /* @__PURE__ */ v("span", {
|
|
211
|
+
className: t("rounded-full px-2 py-0.5 text-xs", D === e.key ? "bg-primary-foreground/20 text-action-primary-text" : "bg-action-primary-bg/10 text-primary"),
|
|
212
|
+
children: j(e.key)
|
|
207
213
|
})]
|
|
208
214
|
}, e.key))
|
|
209
215
|
})
|
|
210
216
|
}),
|
|
211
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ v("div", {
|
|
212
218
|
className: "mt-6 space-y-4",
|
|
213
|
-
children:
|
|
219
|
+
children: k.length > 0 ? k.map((e) => /* @__PURE__ */ y("div", {
|
|
214
220
|
className: "rounded-lg border border-border-seam bg-bg-surface p-4 sm:p-6 bg-gloss-card shadow-pop",
|
|
215
|
-
children: [/* @__PURE__ */
|
|
221
|
+
children: [/* @__PURE__ */ y("div", {
|
|
216
222
|
className: "block space-y-4 lg:hidden",
|
|
217
223
|
children: [
|
|
218
|
-
/* @__PURE__ */
|
|
224
|
+
/* @__PURE__ */ y("div", {
|
|
219
225
|
className: "flex items-start justify-between",
|
|
220
|
-
children: [/* @__PURE__ */
|
|
226
|
+
children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h3", {
|
|
221
227
|
className: "text-lg font-semibold text-text-primary",
|
|
222
228
|
children: e.cartName
|
|
223
|
-
}), /* @__PURE__ */
|
|
229
|
+
}), /* @__PURE__ */ y("p", {
|
|
224
230
|
className: "text-sm text-text-secondary",
|
|
225
231
|
children: ["by ", e.cartOwner]
|
|
226
|
-
})] }), /* @__PURE__ */
|
|
227
|
-
className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium",
|
|
228
|
-
children: [
|
|
232
|
+
})] }), /* @__PURE__ */ y("span", {
|
|
233
|
+
className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium", w(e.status)),
|
|
234
|
+
children: [T(e.status), /* @__PURE__ */ v("span", {
|
|
229
235
|
className: "capitalize",
|
|
230
236
|
children: e.status
|
|
231
237
|
})]
|
|
232
238
|
})]
|
|
233
239
|
}),
|
|
234
|
-
/* @__PURE__ */
|
|
240
|
+
/* @__PURE__ */ y("div", {
|
|
235
241
|
className: "grid grid-cols-2 gap-4",
|
|
236
242
|
children: [
|
|
237
|
-
/* @__PURE__ */
|
|
243
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
238
244
|
className: "text-sm text-text-secondary",
|
|
239
245
|
children: "Invested"
|
|
240
|
-
}), /* @__PURE__ */
|
|
246
|
+
}), /* @__PURE__ */ v("p", {
|
|
241
247
|
className: "font-semibold text-text-primary",
|
|
242
248
|
children: a(e.investmentAmount, { minimumFractionDigits: 0 })
|
|
243
249
|
})] }),
|
|
244
|
-
/* @__PURE__ */
|
|
250
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
245
251
|
className: "text-sm text-text-secondary",
|
|
246
252
|
children: "Current Value"
|
|
247
|
-
}), /* @__PURE__ */
|
|
253
|
+
}), /* @__PURE__ */ v("p", {
|
|
248
254
|
className: "font-semibold text-text-primary",
|
|
249
255
|
children: a(e.currentValue, { minimumFractionDigits: 0 })
|
|
250
256
|
})] }),
|
|
251
|
-
/* @__PURE__ */
|
|
257
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
252
258
|
className: "text-sm text-text-secondary",
|
|
253
259
|
children: "P&L"
|
|
254
|
-
}), /* @__PURE__ */
|
|
260
|
+
}), /* @__PURE__ */ y("p", {
|
|
255
261
|
className: t("font-semibold", e.profitLoss >= 0 ? "text-status-success-text" : "text-status-error-text"),
|
|
256
262
|
children: [
|
|
257
263
|
e.profitLoss >= 0 ? "+" : "",
|
|
@@ -262,83 +268,83 @@ function T() {
|
|
|
262
268
|
"%)"
|
|
263
269
|
]
|
|
264
270
|
})] }),
|
|
265
|
-
/* @__PURE__ */
|
|
271
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
266
272
|
className: "text-sm text-text-secondary",
|
|
267
273
|
children: "ROI"
|
|
268
|
-
}), /* @__PURE__ */
|
|
274
|
+
}), /* @__PURE__ */ y("p", {
|
|
269
275
|
className: "font-semibold text-text-primary",
|
|
270
276
|
children: [e.roiAnnual, "% p.a."]
|
|
271
277
|
})] })
|
|
272
278
|
]
|
|
273
279
|
}),
|
|
274
|
-
/* @__PURE__ */
|
|
280
|
+
/* @__PURE__ */ y("div", {
|
|
275
281
|
className: "flex items-center justify-between border-t border-border-subtle pt-2",
|
|
276
|
-
children: [/* @__PURE__ */
|
|
282
|
+
children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
277
283
|
className: "text-xs text-text-secondary",
|
|
278
284
|
children: "Invested on"
|
|
279
|
-
}), /* @__PURE__ */
|
|
285
|
+
}), /* @__PURE__ */ v("p", {
|
|
280
286
|
className: "text-sm font-medium text-text-primary",
|
|
281
287
|
children: o(e.investmentDate, {
|
|
282
288
|
hour: void 0,
|
|
283
289
|
minute: void 0
|
|
284
290
|
})
|
|
285
|
-
})] }), /* @__PURE__ */
|
|
291
|
+
})] }), /* @__PURE__ */ y("button", {
|
|
286
292
|
type: "button",
|
|
287
293
|
onClick: () => u(`/investor/investments/${e.id}`),
|
|
288
294
|
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",
|
|
289
|
-
children: [/* @__PURE__ */
|
|
295
|
+
children: [/* @__PURE__ */ v(p, { className: "h-4 w-4" }), "View Details"]
|
|
290
296
|
})]
|
|
291
297
|
})
|
|
292
298
|
]
|
|
293
|
-
}), /* @__PURE__ */
|
|
299
|
+
}), /* @__PURE__ */ y("div", {
|
|
294
300
|
className: "hidden lg:flex lg:items-center lg:justify-between",
|
|
295
|
-
children: [/* @__PURE__ */
|
|
301
|
+
children: [/* @__PURE__ */ y("div", {
|
|
296
302
|
className: "min-w-0 flex-1",
|
|
297
303
|
children: [
|
|
298
|
-
/* @__PURE__ */
|
|
304
|
+
/* @__PURE__ */ y("div", {
|
|
299
305
|
className: "mb-2 flex items-center justify-between",
|
|
300
|
-
children: [/* @__PURE__ */
|
|
306
|
+
children: [/* @__PURE__ */ v("h3", {
|
|
301
307
|
className: "text-lg font-semibold text-text-primary",
|
|
302
308
|
children: e.cartName
|
|
303
|
-
}), /* @__PURE__ */
|
|
304
|
-
className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium",
|
|
305
|
-
children: [
|
|
309
|
+
}), /* @__PURE__ */ y("span", {
|
|
310
|
+
className: t("flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium", w(e.status)),
|
|
311
|
+
children: [T(e.status), /* @__PURE__ */ v("span", {
|
|
306
312
|
className: "capitalize",
|
|
307
313
|
children: e.status
|
|
308
314
|
})]
|
|
309
315
|
})]
|
|
310
316
|
}),
|
|
311
|
-
/* @__PURE__ */
|
|
317
|
+
/* @__PURE__ */ y("p", {
|
|
312
318
|
className: "mb-4 text-sm text-text-secondary",
|
|
313
319
|
children: ["by ", e.cartOwner]
|
|
314
320
|
}),
|
|
315
|
-
/* @__PURE__ */
|
|
321
|
+
/* @__PURE__ */ y("div", {
|
|
316
322
|
className: "grid grid-cols-5 gap-6",
|
|
317
323
|
children: [
|
|
318
|
-
/* @__PURE__ */
|
|
324
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
319
325
|
className: "text-sm text-text-secondary",
|
|
320
326
|
children: "Invested"
|
|
321
|
-
}), /* @__PURE__ */
|
|
327
|
+
}), /* @__PURE__ */ v("p", {
|
|
322
328
|
className: "font-semibold text-text-primary",
|
|
323
329
|
children: a(e.investmentAmount, { minimumFractionDigits: 0 })
|
|
324
330
|
})] }),
|
|
325
|
-
/* @__PURE__ */
|
|
331
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
326
332
|
className: "text-sm text-text-secondary",
|
|
327
333
|
children: "Current Value"
|
|
328
|
-
}), /* @__PURE__ */
|
|
334
|
+
}), /* @__PURE__ */ v("p", {
|
|
329
335
|
className: "font-semibold text-text-primary",
|
|
330
336
|
children: a(e.currentValue, { minimumFractionDigits: 0 })
|
|
331
337
|
})] }),
|
|
332
|
-
/* @__PURE__ */
|
|
333
|
-
/* @__PURE__ */
|
|
338
|
+
/* @__PURE__ */ y("div", { children: [
|
|
339
|
+
/* @__PURE__ */ v("p", {
|
|
334
340
|
className: "text-sm text-text-secondary",
|
|
335
341
|
children: "P&L"
|
|
336
342
|
}),
|
|
337
|
-
/* @__PURE__ */
|
|
343
|
+
/* @__PURE__ */ y("p", {
|
|
338
344
|
className: t("font-semibold", e.profitLoss >= 0 ? "text-status-success-text" : "text-status-error-text"),
|
|
339
345
|
children: [e.profitLoss >= 0 ? "+" : "", a(e.profitLoss, { minimumFractionDigits: 0 })]
|
|
340
346
|
}),
|
|
341
|
-
/* @__PURE__ */
|
|
347
|
+
/* @__PURE__ */ y("p", {
|
|
342
348
|
className: t("text-xs", e.profitLoss >= 0 ? "text-status-success-text" : "text-status-error-text"),
|
|
343
349
|
children: [
|
|
344
350
|
"(",
|
|
@@ -348,17 +354,17 @@ function T() {
|
|
|
348
354
|
]
|
|
349
355
|
})
|
|
350
356
|
] }),
|
|
351
|
-
/* @__PURE__ */
|
|
357
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
352
358
|
className: "text-sm text-text-secondary",
|
|
353
359
|
children: "ROI"
|
|
354
|
-
}), /* @__PURE__ */
|
|
360
|
+
}), /* @__PURE__ */ y("p", {
|
|
355
361
|
className: "font-semibold text-text-primary",
|
|
356
362
|
children: [e.roiAnnual, "% p.a."]
|
|
357
363
|
})] }),
|
|
358
|
-
/* @__PURE__ */
|
|
364
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
|
|
359
365
|
className: "text-sm text-text-secondary",
|
|
360
366
|
children: "Invested on"
|
|
361
|
-
}), /* @__PURE__ */
|
|
367
|
+
}), /* @__PURE__ */ v("p", {
|
|
362
368
|
className: "font-semibold text-text-primary",
|
|
363
369
|
children: o(e.investmentDate, {
|
|
364
370
|
hour: void 0,
|
|
@@ -368,21 +374,21 @@ function T() {
|
|
|
368
374
|
]
|
|
369
375
|
})
|
|
370
376
|
]
|
|
371
|
-
}), /* @__PURE__ */
|
|
377
|
+
}), /* @__PURE__ */ v("div", {
|
|
372
378
|
className: "ml-6",
|
|
373
|
-
children: /* @__PURE__ */
|
|
379
|
+
children: /* @__PURE__ */ y("button", {
|
|
374
380
|
type: "button",
|
|
375
381
|
onClick: () => u(`/investor/investments/${e.id}`),
|
|
376
382
|
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",
|
|
377
|
-
children: [/* @__PURE__ */
|
|
383
|
+
children: [/* @__PURE__ */ v(p, { className: "h-4 w-4" }), "View Details"]
|
|
378
384
|
})
|
|
379
385
|
})]
|
|
380
386
|
})]
|
|
381
|
-
}, e.id)) : /* @__PURE__ */
|
|
382
|
-
|
|
383
|
-
title: `No ${
|
|
384
|
-
description:
|
|
385
|
-
action: /* @__PURE__ */
|
|
387
|
+
}, e.id)) : /* @__PURE__ */ v(i, {
|
|
388
|
+
illustration: "empty-data",
|
|
389
|
+
title: `No ${D === "all" ? "" : D} investments found`,
|
|
390
|
+
description: D === "all" ? "You haven't made any investments yet. Start exploring opportunities to grow your wealth." : `You don't have any ${D} investments at the moment.`,
|
|
391
|
+
action: /* @__PURE__ */ v("button", {
|
|
386
392
|
type: "button",
|
|
387
393
|
onClick: () => u("/investor/opportunities"),
|
|
388
394
|
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",
|
|
@@ -394,6 +400,6 @@ function T() {
|
|
|
394
400
|
});
|
|
395
401
|
}
|
|
396
402
|
//#endregion
|
|
397
|
-
export {
|
|
403
|
+
export { E as InvestorInvestmentsPage };
|
|
398
404
|
|
|
399
405
|
//# sourceMappingURL=InvestorInvestmentsPage.js.map
|