Files
Encelado/TradingBot/Components/Pages/Dashboard.razor
Alberto Balbo d25b4443c0 Aggiunta Bootstrap 5.3.3 (CSS, JS, RTL, mappe) al progetto
Sono stati aggiunti tutti i file principali di Bootstrap 5.3.3, inclusi CSS, JavaScript (bundle, ESM, UMD, minificati), versioni RTL, utility, reboot, griglia e relative mappe delle sorgenti. Questi file abilitano un sistema di design moderno, responsive e accessibile, con supporto per layout LTR e RTL, debugging avanzato tramite source map e tutte le funzionalità di Bootstrap per lo sviluppo dell’interfaccia utente. Nessuna modifica ai file esistenti.
2025-12-12 23:27:28 +01:00

186 lines
7.2 KiB
Plaintext

@page "/"
@using TradingBot.Models
@using TradingBot.Services
@inject TradingBotService BotService
@inject NavigationManager Navigation
@implements IDisposable
@rendermode InteractiveServer
<PageTitle>Dashboard - TradingBot</PageTitle>
<div class="dashboard-page">
<div class="page-header">
<div>
<h1>Dashboard</h1>
<p class="subtitle">Panoramica completa delle performance e attività di trading</p>
</div>
</div>
<!-- Summary Cards -->
<div class="summary-grid">
<div class="summary-card primary">
<div class="card-icon">
<span class="bi bi-wallet2"></span>
</div>
<div class="card-content">
<div class="card-label">Valore Portfolio</div>
<div class="card-value">$@portfolioStats.TotalBalance.ToString("N2")</div>
<div class="card-change @(portfolioStats.TotalProfitPercentage >= 0 ? "positive" : "negative")">
<span class="bi @(portfolioStats.TotalProfitPercentage >= 0 ? "bi-arrow-up" : "bi-arrow-down")"></span>
@Math.Abs(portfolioStats.TotalProfitPercentage).ToString("F2")%
</div>
</div>
</div>
<div class="summary-card">
<div class="card-icon success">
<span class="bi bi-graph-up-arrow"></span>
</div>
<div class="card-content">
<div class="card-label">Profitto Totale</div>
<div class="card-value @(portfolioStats.TotalProfit >= 0 ? "profit" : "loss")">
$@portfolioStats.TotalProfit.ToString("N2")
</div>
<div class="card-meta">Da $@portfolioStats.InitialBalance.ToString("N2")</div>
</div>
</div>
<div class="summary-card">
<div class="card-icon info">
<span class="bi bi-arrow-left-right"></span>
</div>
<div class="card-content">
<div class="card-label">Operazioni Totali</div>
<div class="card-value">@portfolioStats.TotalTrades</div>
<div class="card-meta">Win Rate: @portfolioStats.WinRate.ToString("F1")%</div>
</div>
</div>
<div class="summary-card">
<div class="card-icon warning">
<span class="bi bi-currency-exchange"></span>
</div>
<div class="card-content">
<div class="card-label">Asset Attivi</div>
<div class="card-value">@portfolioStats.ActiveAssets/@portfolioStats.TotalAssets</div>
<div class="card-meta">In trading</div>
</div>
</div>
</div>
<!-- Active Assets -->
<div class="section">
<div class="section-header">
<h2>Asset Attivi</h2>
<a href="/trading" class="btn-link">Vedi Tutti <span class="bi bi-arrow-right"></span></a>
</div>
<div class="assets-quick-grid">
@foreach (var config in BotService.AssetConfigurations.Values.Where(c => c.IsEnabled).Take(6))
{
var price = BotService.GetLatestPrice(config.Symbol);
<div class="asset-quick-card">
<div class="asset-header">
<span class="asset-symbol">@config.Symbol</span>
@if (price != null)
{
<span class="asset-change @(price.Change24h >= 0 ? "positive" : "negative")">
@price.Change24h.ToString("F2")%
</span>
}
</div>
<div class="asset-price">$@(price?.Price.ToString("N2") ?? "Loading...")</div>
<div class="asset-profit @(config.TotalProfit >= 0 ? "profit" : "loss")">
$@config.TotalProfit.ToString("N2")
</div>
</div>
}
</div>
</div>
<!-- Recent Activity -->
<div class="section">
<div class="section-header">
<h2>Attività Recente</h2>
<a href="/trading" class="btn-link">Vedi Storico <span class="bi bi-arrow-right"></span></a>
</div>
@if (BotService.Trades.Count == 0)
{
<div class="empty-state">
<span class="bi bi-inbox"></span>
<p>Nessuna operazione ancora</p>
</div>
}
else
{
<div class="activity-list">
@foreach (var trade in BotService.Trades.Take(8))
{
<div class="activity-item">
<div class="activity-icon @(trade.Type == TradeType.Buy ? "buy" : "sell")">
<span class="bi @(trade.Type == TradeType.Buy ? "bi-arrow-down-circle-fill" : "bi-arrow-up-circle-fill")"></span>
</div>
<div class="activity-content">
<div class="activity-main">
<span class="activity-type">@(trade.Type == TradeType.Buy ? "ACQUISTO" : "VENDITA")</span>
<span class="activity-symbol">@trade.Symbol</span>
@if (trade.IsBot)
{
<span class="bot-badge">
<span class="bi bi-robot"></span> BOT
</span>
}
</div>
<div class="activity-details">
<span>@trade.Amount.ToString("F6") &#64; $@trade.Price.ToString("N2")</span>
<span class="separator">•</span>
<span>@trade.Timestamp.ToLocalTime().ToString("HH:mm:ss")</span>
</div>
</div>
<div class="activity-value">
$@((trade.Amount * trade.Price).ToString("N2"))
</div>
</div>
}
</div>
}
</div>
</div>
@code {
private PortfolioStatistics portfolioStats = new();
protected override void OnInitialized()
{
BotService.OnStatusChanged += HandleUpdate;
BotService.OnTradeExecuted += HandleTradeExecuted;
BotService.OnPriceUpdated += HandlePriceUpdate;
if (!BotService.Status.IsRunning)
{
BotService.Start();
}
RefreshData();
}
private void RefreshData()
{
portfolioStats = BotService.GetPortfolioStatistics();
StateHasChanged();
}
private void HandleUpdate() => InvokeAsync(RefreshData);
private void HandleTradeExecuted(Trade trade) => InvokeAsync(RefreshData);
private void HandlePriceUpdate(string symbol, MarketPrice price) => InvokeAsync(RefreshData);
public void Dispose()
{
BotService.OnStatusChanged -= HandleUpdate;
BotService.OnTradeExecuted -= HandleTradeExecuted;
BotService.OnPriceUpdated -= HandlePriceUpdate;
}
}