111 lines
3.7 KiB
HTML
111 lines
3.7 KiB
HTML
<div class="dashboard">
|
|
<header class="dashboard__header">
|
|
<div class="dashboard__brand">
|
|
<a routerLink="/dashboard" class="ev-brand-link">
|
|
<ev-brand class="dashboard__logo" />
|
|
</a>
|
|
<div>
|
|
<h1>Vue d'ensemble</h1>
|
|
<p class="dashboard__subtitle">Consommation instantanée du parc</p>
|
|
</div>
|
|
</div>
|
|
<div class="dashboard__actions">
|
|
<a routerLink="/sites" class="ev-link">Voir les sites</a>
|
|
<ev-button
|
|
class="logout-button"
|
|
variant="secondary"
|
|
[fullWidth]="false"
|
|
(click)="onLogout()"
|
|
>Déconnexion</ev-button
|
|
>
|
|
</div>
|
|
</header>
|
|
|
|
@if (statsError(); as message) {
|
|
<ev-alert severity="danger" class="banner-error">{{ message }}</ev-alert>
|
|
}
|
|
@if (alertsError(); as message) {
|
|
<ev-alert severity="danger" class="banner-error">{{ message }}</ev-alert>
|
|
}
|
|
@if (predictionsError(); as message) {
|
|
<ev-alert severity="danger" class="banner-error">{{ message }}</ev-alert>
|
|
}
|
|
|
|
@if (stats(); as s) {
|
|
<section class="overview">
|
|
<ev-card class="card card--gauge">
|
|
<span class="card__label">Consommation vs capacité</span>
|
|
<app-consumption-gauge
|
|
[consumption]="s.total_consumption_kw"
|
|
[capacity]="s.total_capacity_kw"
|
|
/>
|
|
<span class="card__value"
|
|
>{{ s.total_consumption_kw | number: '1.0-1' }} /
|
|
{{ s.total_capacity_kw | number }} kW</span
|
|
>
|
|
</ev-card>
|
|
|
|
<ev-card class="card">
|
|
<span class="card__label">Charge moyenne du parc</span>
|
|
<span class="card__value">{{ s.average_load_percent }} %</span>
|
|
<div class="progress-bar">
|
|
<div class="progress-bar__fill" [style.width.%]="s.average_load_percent"></div>
|
|
</div>
|
|
</ev-card>
|
|
|
|
<ev-card class="card">
|
|
<span class="card__label">Sites suivis</span>
|
|
<span class="card__value">{{ s.total_sites }}</span>
|
|
</ev-card>
|
|
</section>
|
|
|
|
<section class="chart-section">
|
|
<h2>Charge et alerte visuelle par site</h2>
|
|
<app-site-load-chart [sites]="s.sites" />
|
|
</section>
|
|
}
|
|
|
|
@if (alerts().length > 0) {
|
|
<section class="alerts-section">
|
|
<h2>Alertes actives</h2>
|
|
<ul class="alerts-list">
|
|
@for (alert of alerts(); track alert.alert_id) {
|
|
<li class="alert-item">
|
|
<ev-badge [tone]="badgeToneForSeverity(alert.severity)">{{ alert.severity }}</ev-badge>
|
|
<span class="alert-item__message">{{ alert.message }}</span>
|
|
</li>
|
|
}
|
|
</ul>
|
|
</section>
|
|
}
|
|
|
|
@if (predictions().length > 0) {
|
|
<section class="predictions-section">
|
|
<h2>Prévisions de consommation</h2>
|
|
<ul class="predictions-list">
|
|
@for (site of predictions(); track site.site_id) {
|
|
<li class="prediction-item">
|
|
<span class="prediction-item__site">{{ site.site_name }}</span>
|
|
@if (site.prediction; as prediction) {
|
|
@if (prediction.status === 'available') {
|
|
<span class="prediction-item__value">
|
|
{{ prediction.predicted_value | number: '1.0-1' }} kWh
|
|
<span class="prediction-item__target"
|
|
>{{ prediction.target_at | date: "dd/MM 'à' HH:mm" }}</span
|
|
>
|
|
</span>
|
|
} @else {
|
|
<ev-badge [tone]="badgeToneForPredictionStatus(prediction.status)">{{
|
|
prediction.status === 'insufficient_data' ? 'Historique insuffisant' : 'Erreur'
|
|
}}</ev-badge>
|
|
}
|
|
} @else {
|
|
<ev-badge tone="neutral">Pas encore de prévision</ev-badge>
|
|
}
|
|
</li>
|
|
}
|
|
</ul>
|
|
</section>
|
|
}
|
|
</div>
|