@page "/"
@rendermode InteractiveWebAssembly
@attribute [Authorize]
@inject ITimetrackerService TrackerService
@inject AuthenticationStateProvider AuthStateProvider
@inject IJSRuntime JSRuntime
Dashboard – Timetracker
@if (_loading)
{
Lade Dashboard…
}
else
{
@* ── Header & Einstellungen ── *@
@* ── Gamification Widgets ── *@
@if (_showEarlyBird)
{
🌅
Early Bird
@FormatTimeSpan(_stats.EarliestStart)
Frühester Beginn im Monat
}
@if (_showNightOwl)
{
🦉
Night Owl
@FormatTimeSpan(_stats.LatestEnd)
Spätestes Ende im Monat
}
@if (_showPausenkonig)
{
☕
Pausenkönig
@((int)_stats.AverageBreak.TotalMinutes) Min.
Ø Pause im Monat
}
@if (_showStreaks)
{
🔥
Streak
@_stats.CurrentStreak / @_stats.LongestStreak
Aktuell / Bester (Tage)
}
@* ── Diagramme ── *@
@if (_showCharts)
{
Gleitzeit-Verlauf @DateTime.Today.Year
Jahres-Verteilung
}
}
@code {
private bool _loading = true;
private DashboardStatsVm _stats = new();
private DashboardChartDataVm _chartData = new();
private bool _showEarlyBird = true;
private bool _showNightOwl = true;
private bool _showPausenkonig = true;
private bool _showStreaks = true;
private bool _showCharts = true;
private List> _barChartSeries = new();
private string[] _barChartLabels = Array.Empty();
private double[] _pieChartData = Array.Empty();
private string[] _pieChartLabels = Array.Empty();
protected override async Task OnInitializedAsync()
{
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
var claim = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
if (claim == null) return;
int userId = int.Parse(claim.Value);
int year = DateTime.Today.Year;
int month = DateTime.Today.Month;
await LoadSettings();
_stats = await TrackerService.GetDashboardStatsAsync(userId, year, month);
_chartData = await TrackerService.GetDashboardChartDataAsync(userId, year);
// Prepare Bar Chart
_barChartSeries = new List>
{
new ChartSeries { Name = "Überstunden", Data = _chartData.MonthlyOvertime.Select(m => m.OvertimeHours).ToArray() }
};
_barChartLabels = _chartData.MonthlyOvertime.Select(m => m.MonthName).ToArray();
// Prepare Pie Chart
_pieChartData = new double[] { _chartData.WorkDaysCount, _chartData.VacationDaysCount, _chartData.PublicHolidaysCount };
_pieChartLabels = new string[] { "Arbeit", "Urlaub", "Feiertage" };
_loading = false;
}
private async Task LoadSettings()
{
try
{
var eb = await JSRuntime.InvokeAsync("localStorage.getItem", "widget_EarlyBird");
if (eb != null) _showEarlyBird = eb == "true";
var no = await JSRuntime.InvokeAsync("localStorage.getItem", "widget_NightOwl");
if (no != null) _showNightOwl = no == "true";
var pk = await JSRuntime.InvokeAsync("localStorage.getItem", "widget_Pausenkonig");
if (pk != null) _showPausenkonig = pk == "true";
var st = await JSRuntime.InvokeAsync("localStorage.getItem", "widget_Streaks");
if (st != null) _showStreaks = st == "true";
var ch = await JSRuntime.InvokeAsync("localStorage.getItem", "widget_Charts");
if (ch != null) _showCharts = ch == "true";
}
catch
{
// SSR Fallback
}
}
private async Task ToggleWidget(string widget)
{
bool newState = true;
if (widget == "EarlyBird") { _showEarlyBird = !_showEarlyBird; newState = _showEarlyBird; }
if (widget == "NightOwl") { _showNightOwl = !_showNightOwl; newState = _showNightOwl; }
if (widget == "Pausenkonig") { _showPausenkonig = !_showPausenkonig; newState = _showPausenkonig; }
if (widget == "Streaks") { _showStreaks = !_showStreaks; newState = _showStreaks; }
if (widget == "Charts") { _showCharts = !_showCharts; newState = _showCharts; }
try
{
await JSRuntime.InvokeVoidAsync("localStorage.setItem", $"widget_{widget}", newState.ToString().ToLower());
}
catch { }
}
private string FormatTimeSpan(TimeSpan? ts)
{
if (!ts.HasValue) return "-";
return $"{ts.Value.Hours:D2}:{ts.Value.Minutes:D2}";
}
}