added base dashboard

This commit is contained in:
Bojan Kucera 2025-06-02 20:12:20 -04:00
parent 94e3c96ef6
commit 114c280734
29 changed files with 1022 additions and 950 deletions

View file

@ -0,0 +1,48 @@
/* Dashboard specific styles */
.portfolio-card {
background-color: white !important;
border-radius: 0.5rem;
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
border: 1px solid #f3f4f6;
padding: 1.5rem;
}
.metric-value {
font-size: 1.5rem;
font-weight: 700;
}
.metric-label {
font-size: 0.875rem;
color: #6b7280;
margin-top: 0.25rem;
}
.metric-change-positive {
color: #16a34a;
font-weight: 500;
}
.metric-change-negative {
color: #dc2626;
font-weight: 500;
}
.status-chip-active {
background-color: #dcfce7;
color: #166534;
padding: 0.25rem 0.5rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 500;
display: inline-block;
}
.status-chip-medium {
background-color: #dbeafe;
color: #1e40af;
padding: 0.25rem 0.5rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 500;
}

View file

@ -0,0 +1,154 @@
<!-- Portfolio Summary Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
<!-- Total Portfolio Value -->
<mat-card class="portfolio-card">
<div class="flex items-center justify-between">
<div>
<p class="metric-label">Portfolio Value</p>
<p class="metric-value text-gray-900">
${{ portfolioValue().toLocaleString('en-US', {minimumFractionDigits: 2}) }}
</p>
</div>
<mat-icon class="text-blue-600 text-3xl">account_balance_wallet</mat-icon>
</div>
</mat-card>
<!-- Day Change -->
<mat-card class="portfolio-card">
<div class="flex items-center justify-between">
<div>
<p class="metric-label">Day Change</p>
<p class="metric-value"
[class.metric-change-positive]="dayChange() > 0"
[class.metric-change-negative]="dayChange() < 0">
${{ dayChange().toLocaleString('en-US', {minimumFractionDigits: 2}) }}
</p>
<p class="text-sm font-medium"
[class.metric-change-positive]="dayChangePercent() > 0"
[class.metric-change-negative]="dayChangePercent() < 0">
{{ dayChangePercent() > 0 ? '+' : '' }}{{ dayChangePercent().toFixed(2) }}%
</p>
</div>
<mat-icon
class="text-3xl"
[class.metric-change-positive]="dayChange() > 0"
[class.metric-change-negative]="dayChange() < 0">
{{ dayChange() > 0 ? 'trending_up' : 'trending_down' }}
</mat-icon>
</div>
</mat-card>
<!-- Active Strategies -->
<mat-card class="portfolio-card">
<div class="flex items-center justify-between">
<div>
<p class="metric-label">Active Strategies</p>
<p class="metric-value text-gray-900">3</p>
<span class="status-chip-active">Running</span>
</div>
<mat-icon class="text-purple-600 text-3xl">psychology</mat-icon>
</div>
</mat-card>
<!-- Risk Level -->
<mat-card class="portfolio-card">
<div class="flex items-center justify-between">
<div>
<p class="metric-label">Risk Level</p>
<p class="metric-value text-green-600">Low</p>
<span class="status-chip-medium">Moderate</span>
</div>
<mat-icon class="text-green-600 text-3xl">security</mat-icon>
</div>
</mat-card>
</div>
<!-- Market Data Table -->
<mat-card class="p-6 mb-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-900">Market Watchlist</h3>
<button mat-raised-button color="primary">
<mat-icon>refresh</mat-icon>
Refresh
</button>
</div>
<div class="overflow-x-auto">
<table mat-table [dataSource]="marketData()" 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 stock" class="font-semibold text-gray-900">{{ stock.symbol }}</td>
</ng-container>
<!-- Price Column -->
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Price</th>
<td mat-cell *matCellDef="let stock" class="text-right font-medium text-gray-900">
${{ stock.price.toFixed(2) }}
</td>
</ng-container>
<!-- Change Column -->
<ng-container matColumnDef="change">
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Change</th>
<td mat-cell *matCellDef="let stock"
class="text-right font-medium"
[class.text-green-600]="stock.change > 0"
[class.text-red-600]="stock.change < 0">
{{ stock.change > 0 ? '+' : '' }}${{ stock.change.toFixed(2) }}
</td>
</ng-container>
<!-- Change Percent Column -->
<ng-container matColumnDef="changePercent">
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Change %</th>
<td mat-cell *matCellDef="let stock"
class="text-right font-medium"
[class.text-green-600]="stock.changePercent > 0"
[class.text-red-600]="stock.changePercent < 0">
{{ stock.changePercent > 0 ? '+' : '' }}{{ stock.changePercent.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>
<!-- Tabs for Additional Content -->
<mat-tab-group>
<mat-tab label="Chart">
<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;">show_chart</mat-icon>
<p class="mb-4">Chart visualization 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_long</mat-icon>
<p class="mb-4">Order history and management will be implemented here</p>
</div>
</mat-card>
</div>
</mat-tab>
<mat-tab label="Analytics">
<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;">analytics</mat-icon>
<p class="mb-4">Advanced analytics and performance metrics will be implemented here</p>
</div>
</mat-card>
</div>
</mat-tab>
</mat-tab-group>

View file

@ -0,0 +1,44 @@
import { Component, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatTabsModule } from '@angular/material/tabs';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTableModule } from '@angular/material/table';
export interface MarketDataItem {
symbol: string;
price: number;
change: number;
changePercent: number;
}
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [
CommonModule,
MatCardModule,
MatTabsModule,
MatButtonModule,
MatIconModule,
MatTableModule
],
templateUrl: './dashboard.component.html',
styleUrl: './dashboard.component.css'
})
export class DashboardComponent {
// Mock data for the dashboard
protected marketData = signal<MarketDataItem[]>([
{ symbol: 'AAPL', price: 192.53, change: 2.41, changePercent: 1.27 },
{ symbol: 'GOOGL', price: 138.21, change: -1.82, changePercent: -1.30 },
{ symbol: 'MSFT', price: 378.85, change: 4.12, changePercent: 1.10 },
{ symbol: 'TSLA', price: 248.42, change: -3.21, changePercent: -1.28 },
]);
protected portfolioValue = signal(125420.50);
protected dayChange = signal(2341.20);
protected dayChangePercent = signal(1.90);
protected displayedColumns: string[] = ['symbol', 'price', 'change', 'changePercent'];
}

View file

@ -0,0 +1 @@
/* Market Data specific styles */

View file

@ -0,0 +1,158 @@
<div class="space-y-6">
<!-- Page Header -->
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">Market Data</h1>
<p class="text-gray-600 mt-1">Real-time market information and analytics</p>
</div>
<button mat-raised-button color="primary">
<mat-icon>refresh</mat-icon>
Refresh Data
</button>
</div>
<!-- Market Overview Cards -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<mat-card class="p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-gray-600">Market Status</p>
<p class="text-lg font-semibold text-green-600">Open</p>
</div>
<mat-icon class="text-green-600 text-3xl">schedule</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">Active Instruments</p>
<p class="text-lg font-semibold text-gray-900">{{ marketData().length }}</p>
</div>
<mat-icon class="text-blue-600 text-3xl">trending_up</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">Last Update</p>
<p class="text-lg font-semibold text-gray-900">{{ new Date().toLocaleTimeString() }}</p>
</div>
<mat-icon class="text-purple-600 text-3xl">access_time</mat-icon>
</div>
</mat-card>
</div>
<!-- Market Data Table -->
<mat-card class="p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-900">Live Market Data</h3>
<div class="flex gap-2">
<button mat-button>
<mat-icon>filter_list</mat-icon>
Filter
</button>
<button mat-button>
<mat-icon>file_download</mat-icon>
Export
</button>
</div>
</div>
<div class="overflow-x-auto">
<table mat-table [dataSource]="marketData()" 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 stock" class="font-semibold text-gray-900">{{ stock.symbol }}</td>
</ng-container>
<!-- Price Column -->
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Price</th>
<td mat-cell *matCellDef="let stock" class="text-right font-medium text-gray-900">
${{ stock.price.toFixed(2) }}
</td>
</ng-container>
<!-- Change Column -->
<ng-container matColumnDef="change">
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Change</th>
<td mat-cell *matCellDef="let stock"
class="text-right font-medium"
[class.text-green-600]="stock.change > 0"
[class.text-red-600]="stock.change < 0">
{{ stock.change > 0 ? '+' : '' }}${{ stock.change.toFixed(2) }}
</td>
</ng-container>
<!-- Change Percent Column -->
<ng-container matColumnDef="changePercent">
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Change %</th>
<td mat-cell *matCellDef="let stock"
class="text-right font-medium"
[class.text-green-600]="stock.changePercent > 0"
[class.text-red-600]="stock.changePercent < 0">
{{ stock.changePercent > 0 ? '+' : '' }}{{ stock.changePercent.toFixed(2) }}%
</td>
</ng-container>
<!-- Volume Column -->
<ng-container matColumnDef="volume">
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Volume</th>
<td mat-cell *matCellDef="let stock" class="text-right text-gray-600">
{{ stock.volume.toLocaleString() }}
</td>
</ng-container>
<!-- Market Cap Column -->
<ng-container matColumnDef="marketCap">
<th mat-header-cell *matHeaderCellDef class="text-right font-medium text-gray-900">Market Cap</th>
<td mat-cell *matCellDef="let stock" class="text-right text-gray-600">
${{ stock.marketCap }}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
</mat-card>
<!-- Market Analytics Tabs -->
<mat-tab-group>
<mat-tab label="Technical Analysis">
<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;">bar_chart</mat-icon>
<p class="mb-4">Technical analysis charts and indicators will be implemented here</p>
</div>
</mat-card>
</div>
</mat-tab>
<mat-tab label="Market Trends">
<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;">timeline</mat-icon>
<p class="mb-4">Market trends and sector analysis will be implemented here</p>
</div>
</mat-card>
</div>
</mat-tab>
<mat-tab label="News & Events">
<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;">article</mat-icon>
<p class="mb-4">Market news and economic events will be implemented here</p>
</div>
</mat-card>
</div>
</mat-tab>
</mat-tab-group>
</div>

View file

@ -0,0 +1,89 @@
import { Component, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTableModule } from '@angular/material/table';
import { MatTabsModule } from '@angular/material/tabs';
export interface ExtendedMarketData {
symbol: string;
price: number;
change: number;
changePercent: number;
volume: number;
marketCap: string;
high52Week: number;
low52Week: number;
}
@Component({
selector: 'app-market-data',
standalone: true,
imports: [
CommonModule,
MatCardModule,
MatButtonModule,
MatIconModule,
MatTableModule,
MatTabsModule
],
templateUrl: './market-data.component.html',
styleUrl: './market-data.component.css'
})
export class MarketDataComponent {
protected marketData = signal<ExtendedMarketData[]>([
{
symbol: 'AAPL',
price: 192.53,
change: 2.41,
changePercent: 1.27,
volume: 45230000,
marketCap: '2.98T',
high52Week: 199.62,
low52Week: 164.08
},
{
symbol: 'GOOGL',
price: 138.21,
change: -1.82,
changePercent: -1.30,
volume: 23450000,
marketCap: '1.75T',
high52Week: 152.10,
low52Week: 125.45
},
{
symbol: 'MSFT',
price: 378.85,
change: 4.12,
changePercent: 1.10,
volume: 34560000,
marketCap: '2.82T',
high52Week: 384.30,
low52Week: 309.45
},
{
symbol: 'TSLA',
price: 248.42,
change: -3.21,
changePercent: -1.28,
volume: 67890000,
marketCap: '789B',
high52Week: 299.29,
low52Week: 138.80
},
{
symbol: 'AMZN',
price: 145.67,
change: 1.89,
changePercent: 1.31,
volume: 29340000,
marketCap: '1.52T',
high52Week: 155.20,
low52Week: 118.35
}
]);
protected displayedColumns: string[] = ['symbol', 'price', 'change', 'changePercent', 'volume', 'marketCap'];
}

View file

@ -0,0 +1 @@
/* Portfolio specific styles */

View file

@ -0,0 +1,15 @@
<div class="space-y-6">
<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>
</div>
<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;">account_balance_wallet</mat-icon>
<p class="mb-4">Portfolio management features will be implemented here</p>
</div>
</mat-card>
</div>

View file

@ -0,0 +1,13 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'app-portfolio',
standalone: true,
imports: [CommonModule, MatCardModule, MatIconModule],
templateUrl: './portfolio.component.html',
styleUrl: './portfolio.component.css'
})
export class PortfolioComponent {}

View file

@ -0,0 +1 @@
/* Risk Management specific styles */

View file

@ -0,0 +1,15 @@
<div class="space-y-6">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">Risk Management</h1>
<p class="text-gray-600 mt-1">Monitor and control trading risks and exposure</p>
</div>
</div>
<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;">security</mat-icon>
<p class="mb-4">Risk management tools and monitoring will be implemented here</p>
</div>
</mat-card>
</div>

View file

@ -0,0 +1,13 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'app-risk-management',
standalone: true,
imports: [CommonModule, MatCardModule, MatIconModule],
templateUrl: './risk-management.component.html',
styleUrl: './risk-management.component.css'
})
export class RiskManagementComponent {}

View file

@ -0,0 +1 @@
/* Settings specific styles */

View file

@ -0,0 +1,15 @@
<div class="space-y-6">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">Settings</h1>
<p class="text-gray-600 mt-1">Configure application preferences and system settings</p>
</div>
</div>
<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;">settings</mat-icon>
<p class="mb-4">Application settings and configuration will be implemented here</p>
</div>
</mat-card>
</div>

View file

@ -0,0 +1,13 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'app-settings',
standalone: true,
imports: [CommonModule, MatCardModule, MatIconModule],
templateUrl: './settings.component.html',
styleUrl: './settings.component.css'
})
export class SettingsComponent {}

View file

@ -0,0 +1 @@
/* Strategies specific styles */

View file

@ -0,0 +1,15 @@
<div class="space-y-6">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">Trading Strategies</h1>
<p class="text-gray-600 mt-1">Configure and monitor your automated trading strategies</p>
</div>
</div>
<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;">psychology</mat-icon>
<p class="mb-4">Strategy management and configuration will be implemented here</p>
</div>
</mat-card>
</div>

View file

@ -0,0 +1,13 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'app-strategies',
standalone: true,
imports: [CommonModule, MatCardModule, MatIconModule],
templateUrl: './strategies.component.html',
styleUrl: './strategies.component.css'
})
export class StrategiesComponent {}