moved dashboard to top level and created a new system plan
This commit is contained in:
parent
5e692f4ab5
commit
7993148a95
76 changed files with 783 additions and 500 deletions
203
apps/dashboard/src/app/pages/portfolio/portfolio.component.html
Normal file
203
apps/dashboard/src/app/pages/portfolio/portfolio.component.html
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
<div class="space-y-6">
|
||||
<!-- Page Header -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-gray-900">Portfolio</h1>
|
||||
<p class="text-gray-600 mt-1">Manage and monitor your investment portfolio</p>
|
||||
</div>
|
||||
<button mat-raised-button color="primary" (click)="refreshData()" [disabled]="isLoading()">
|
||||
<mat-icon>refresh</mat-icon>
|
||||
@if (isLoading()) {
|
||||
<mat-spinner diameter="20" class="mr-2"></mat-spinner>
|
||||
}
|
||||
Refresh Data
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Portfolio Summary Cards -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-6">
|
||||
<mat-card class="p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-gray-600">Total Value</p>
|
||||
<p class="text-lg font-semibold text-gray-900">${{ portfolioSummary().totalValue.toLocaleString() }}</p>
|
||||
</div>
|
||||
<mat-icon class="text-blue-600 text-3xl">account_balance_wallet</mat-icon>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
<mat-card class="p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-gray-600">Total P&L</p>
|
||||
<p class="text-lg font-semibold" [class]="getPnLColor(portfolioSummary().totalPnL)">
|
||||
{{ portfolioSummary().totalPnL > 0 ? '+' : '' }}${{ portfolioSummary().totalPnL.toLocaleString() }}
|
||||
({{ portfolioSummary().totalPnLPercent.toFixed(2) }}%)
|
||||
</p>
|
||||
</div>
|
||||
<mat-icon class="text-green-600 text-3xl" *ngIf="portfolioSummary().totalPnL >= 0">trending_up</mat-icon>
|
||||
<mat-icon class="text-red-600 text-3xl" *ngIf="portfolioSummary().totalPnL < 0">trending_down</mat-icon>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
<mat-card class="p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-gray-600">Day Change</p>
|
||||
<p class="text-lg font-semibold" [class]="getPnLColor(portfolioSummary().dayChange)">
|
||||
{{ portfolioSummary().dayChange > 0 ? '+' : '' }}${{ portfolioSummary().dayChange.toLocaleString() }}
|
||||
({{ portfolioSummary().dayChangePercent.toFixed(2) }}%)
|
||||
</p>
|
||||
</div>
|
||||
<mat-icon class="text-purple-600 text-3xl">today</mat-icon>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
<mat-card class="p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-gray-600">Cash Available</p>
|
||||
<p class="text-lg font-semibold text-gray-900">${{ portfolioSummary().cash.toLocaleString() }}</p>
|
||||
</div>
|
||||
<mat-icon class="text-yellow-600 text-3xl">attach_money</mat-icon>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
<!-- Portfolio Tabs -->
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Positions">
|
||||
<div class="p-6">
|
||||
<mat-card class="p-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900">Current Positions</h3>
|
||||
<div class="flex gap-2">
|
||||
<button mat-button>
|
||||
<mat-icon>add</mat-icon>
|
||||
Add Position
|
||||
</button>
|
||||
<button mat-button>
|
||||
<mat-icon>file_download</mat-icon>
|
||||
Export
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (isLoading()) {
|
||||
<div class="flex justify-center items-center py-8">
|
||||
<mat-spinner diameter="40"></mat-spinner>
|
||||
<span class="ml-3 text-gray-600">Loading portfolio...</span>
|
||||
</div>
|
||||
} @else if (error()) {
|
||||
<div class="text-center py-8">
|
||||
<mat-icon class="text-red-500 text-4xl">error</mat-icon>
|
||||
<p class="text-red-600 mt-2">{{ error() }}</p>
|
||||
<button mat-button color="primary" (click)="refreshData()" class="mt-2">
|
||||
<mat-icon>refresh</mat-icon>
|
||||
Try Again
|
||||
</button>
|
||||
</div>
|
||||
} @else if (positions().length === 0) {
|
||||
<div class="text-center py-8 text-gray-500">
|
||||
<mat-icon class="text-4xl">account_balance_wallet</mat-icon>
|
||||
<p class="mt-2">No positions found</p>
|
||||
<button mat-button color="primary" class="mt-2">
|
||||
<mat-icon>add</mat-icon>
|
||||
Add Your First Position
|
||||
</button>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="overflow-x-auto">
|
||||
<table mat-table [dataSource]="positions()" class="mat-elevation-z0 w-full">
|
||||
<!-- Symbol Column -->
|
||||
<ng-container matColumnDef="symbol">
|
||||
<th mat-header-cell *matHeaderCellDef class="font-medium text-gray-900">Symbol</th>
|
||||
<td mat-cell *matCellDef="let position" class="font-semibold text-gray-900">{{ position.symbol }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Quantity Column -->
|
||||
<ng-container matColumnDef="quantity">
|
||||
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Quantity</th>
|
||||
<td mat-cell *matCellDef="let position" class="text-right text-gray-600">
|
||||
{{ position.quantity.toLocaleString() }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Average Price Column -->
|
||||
<ng-container matColumnDef="avgPrice">
|
||||
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Avg Price</th>
|
||||
<td mat-cell *matCellDef="let position" class="text-right text-gray-600">
|
||||
${{ position.avgPrice.toFixed(2) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Current Price Column -->
|
||||
<ng-container matColumnDef="currentPrice">
|
||||
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Current Price</th>
|
||||
<td mat-cell *matCellDef="let position" class="text-right font-medium text-gray-900">
|
||||
${{ position.currentPrice.toFixed(2) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Market Value Column -->
|
||||
<ng-container matColumnDef="marketValue">
|
||||
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Market Value</th>
|
||||
<td mat-cell *matCellDef="let position" class="text-right font-medium text-gray-900">
|
||||
${{ position.marketValue.toLocaleString() }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Unrealized P&L Column -->
|
||||
<ng-container matColumnDef="unrealizedPnL">
|
||||
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Unrealized P&L</th>
|
||||
<td mat-cell *matCellDef="let position"
|
||||
class="text-right font-medium"
|
||||
[class]="getPnLColor(position.unrealizedPnL)">
|
||||
{{ position.unrealizedPnL > 0 ? '+' : '' }}${{ position.unrealizedPnL.toLocaleString() }}
|
||||
({{ position.unrealizedPnLPercent.toFixed(2) }}%)
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Day Change Column -->
|
||||
<ng-container matColumnDef="dayChange">
|
||||
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Day Change</th>
|
||||
<td mat-cell *matCellDef="let position"
|
||||
class="text-right font-medium"
|
||||
[class]="getPnLColor(position.dayChange)">
|
||||
{{ position.dayChange > 0 ? '+' : '' }}${{ position.dayChange.toFixed(2) }}
|
||||
({{ position.dayChangePercent.toFixed(2) }}%)
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</mat-card>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="Performance">
|
||||
<div class="p-6">
|
||||
<mat-card class="p-6 h-96 flex items-center">
|
||||
<div class="text-center text-gray-500 w-full">
|
||||
<mat-icon style="font-size: 4rem; width: 4rem; height: 4rem;">trending_up</mat-icon>
|
||||
<p class="mb-4">Performance charts and analytics will be implemented here</p>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="Orders">
|
||||
<div class="p-6">
|
||||
<mat-card class="p-6 h-96 flex items-center">
|
||||
<div class="text-center text-gray-500 w-full">
|
||||
<mat-icon style="font-size: 4rem; width: 4rem; height: 4rem;">receipt</mat-icon>
|
||||
<p class="mb-4">Order history and management will be implemented here</p>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue