+ {/* Header */}
+
+
+
+ Portfolio Manager
+
+
+ Gestiona tus activos y alcanza tus metas financieras
+
+
+
+
+
+
+ Nuevo Portfolio
+
+
+
+
+ {/* Portfolio Selector (if multiple) */}
+ {portfolios.length > 1 && (
+
+ {portfolios.map((p) => (
+
+ ))}
+
+ )}
+
+ {/* Tabs */}
+
+
+
+
+
+ {activeTab === 'overview' && selectedPortfolio && (
+ <>
+ {/* Stats Grid */}
+
+
}
+ color="bg-blue-100 dark:bg-blue-900/30"
+ />
+
= 0 ? '+' : ''}$${Math.abs(
+ selectedPortfolio.unrealizedPnl
+ ).toLocaleString(undefined, { minimumFractionDigits: 2 })}`}
+ change={selectedPortfolio.unrealizedPnlPercent}
+ icon={}
+ color="bg-green-100 dark:bg-green-900/30"
+ />
+ }
+ color="bg-purple-100 dark:bg-purple-900/30"
+ />
+ }
+ color="bg-orange-100 dark:bg-orange-900/30"
+ />
+
+
+ {/* Main Content Grid */}
+
+ {/* Left: Allocation Chart & Table */}
+
+ {/* Chart Card */}
+
+
+ Distribución de Activos
+
+
+
+
+ {/* Table Card */}
+
+
+
+ Detalle de Posiciones
+
+
+ Editar Allocaciones
+
+
+
+
+
+
+ {/* Right: Rebalance & Performance */}
+
+
+
+ {/* Best/Worst Performers */}
+ {stats && (
+
+
+ Rendimiento
+
+
+
+
+ 🏆
+
+ Mejor: {stats.bestPerformer.asset}
+
+
+
+ +{stats.bestPerformer.change.toFixed(2)}%
+
+
+
+
+ 📉
+
+ Peor: {stats.worstPerformer.asset}
+
+
+
+ {stats.worstPerformer.change.toFixed(2)}%
+
+
+
+
+ )}
+
+ {/* Quick Info */}
+
+
+ Información
+
+
+
+
+ Perfil de Riesgo
+
+
+ {selectedPortfolio.riskProfile === 'conservative'
+ ? 'Conservador'
+ : selectedPortfolio.riskProfile === 'moderate'
+ ? 'Moderado'
+ : 'Agresivo'}
+
+
+
+
+ Último Rebalanceo
+
+
+ {selectedPortfolio.lastRebalanced
+ ? new Date(selectedPortfolio.lastRebalanced).toLocaleDateString()
+ : 'Nunca'}
+
+
+
+
+ Activos
+
+
+ {selectedPortfolio.allocations.length}
+
+
+
+
+
+
+ >
+ )}
+
+ {activeTab === 'goals' && (
+ <>
+ {/* Goals Header */}
+
+
+ Establece y monitorea tus metas financieras
+
+
+
+ Nueva Meta
+
+
+
+ {goals.length === 0 ? (
+
+
🎯
+
+ No tienes metas definidas
+
+
+ Establece tus objetivos financieros y monitorea tu progreso
+
+
+ Crear Primera Meta
+
+
+ ) : (
+
+ {goals.map((goal) => (
+
+ ))}
+
+ )}
+ >
+ )}
+
+ {/* Empty State for no portfolios */}
+ {portfolios.length === 0 && (
+
+
📊
+
+ Crea tu primer Portfolio
+
+
+ Diversifica tus inversiones según tu perfil de riesgo
+
+
+ Crear Portfolio
+
+
+ )}
+
+ );
+}
diff --git a/src/services/portfolio.service.ts b/src/services/portfolio.service.ts
new file mode 100644
index 0000000..f09ad38
--- /dev/null
+++ b/src/services/portfolio.service.ts
@@ -0,0 +1,254 @@
+/**
+ * Portfolio Service
+ * Client for connecting to the Portfolio API
+ */
+
+const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3080';
+
+// ============================================================================
+// Types
+// ============================================================================
+
+export type RiskProfile = 'conservative' | 'moderate' | 'aggressive';
+
+export interface Portfolio {
+ id: string;
+ userId: string;
+ name: string;
+ riskProfile: RiskProfile;
+ allocations: PortfolioAllocation[];
+ totalValue: number;
+ totalCost: number;
+ unrealizedPnl: number;
+ unrealizedPnlPercent: number;
+ realizedPnl: number;
+ lastRebalanced: string | null;
+ createdAt: string;
+ updatedAt: string;
+}
+
+export interface PortfolioAllocation {
+ id: string;
+ portfolioId: string;
+ asset: string;
+ targetPercent: number;
+ currentPercent: number;
+ quantity: number;
+ value: number;
+ cost: number;
+ pnl: number;
+ pnlPercent: number;
+ deviation: number;
+}
+
+export interface PortfolioGoal {
+ id: string;
+ userId: string;
+ name: string;
+ targetAmount: number;
+ currentAmount: number;
+ targetDate: string;
+ monthlyContribution: number;
+ progress: number;
+ projectedCompletion: string | null;
+ status: 'on_track' | 'at_risk' | 'behind';
+ createdAt: string;
+ updatedAt: string;
+}
+
+export interface RebalanceRecommendation {
+ asset: string;
+ currentPercent: number;
+ targetPercent: number;
+ action: 'buy' | 'sell' | 'hold';
+ amount: number;
+ amountUSD: number;
+ priority: 'high' | 'medium' | 'low';
+}
+
+export interface PortfolioStats {
+ totalValue: number;
+ dayChange: number;
+ dayChangePercent: number;
+ weekChange: number;
+ weekChangePercent: number;
+ monthChange: number;
+ monthChangePercent: number;
+ allTimeChange: number;
+ allTimeChangePercent: number;
+ bestPerformer: { asset: string; change: number };
+ worstPerformer: { asset: string; change: number };
+}
+
+export interface CreatePortfolioInput {
+ name: string;
+ riskProfile: RiskProfile;
+ initialValue?: number;
+}
+
+export interface CreateGoalInput {
+ name: string;
+ targetAmount: number;
+ targetDate: string;
+ monthlyContribution: number;
+}
+
+// ============================================================================
+// Portfolio API Functions
+// ============================================================================
+
+/**
+ * Get user's portfolios
+ */
+export async function getUserPortfolios(): Promise