@inject IJSRuntime JS @if (_active) { @* Dark Backdrop Overlay *@
@* Onboarding Instruction Card *@
@* Header / Title *@ @_steps[_currentStep].Title @* Explanation Text *@ @_steps[_currentStep].Content @* Footer / Progress & Buttons *@ @* Step Count *@ Schritt @(_currentStep + 1) von @_steps.Count @* Navigation Button Stack *@ @if (_currentStep > 0) { Zurück } else { Überspringen } @(_currentStep == _steps.Count - 1 ? "Fertig" : "Weiter")
} @code { [Parameter] public EventCallback OnFinished { get; set; } private bool _active = true; private int _currentStep = 0; private readonly List _steps = [ new(".onboarding-nav-menu", "Die Navigation", "Hier auf der linken Seite findest du das Hauptmenü. Du kannst ganz einfach zwischen der Wochen- und Monatsübersicht wechseln oder deine Statistiken einsehen."), new(".onboarding-week-header", "Kalenderwoche blättern", "Hier siehst du die aktuell ausgewählte Woche. Verwende die Pfeiltasten links und rechts, um in vergangenen oder zukünftigen Wochen deine Zeiten zu erfassen."), new(".onboarding-day-card", "Zeiterfassung pro Tag", "Das Herzstück des Timetrackers. Trage hier deine täglichen Start- und Endzeiten sowie deine Pausen ein. Das System errechnet die Zeiten und Überstunden in Echtzeit."), new(".onboarding-week-summary", "Wochenzusammenfassung", "Hier siehst du auf einen Blick, wie viele Stunden du in dieser Woche gearbeitet hast, wie viel Pause du gemacht hast und wie sich dein Stundensaldo verändert hat."), new(".onboarding-overtime-balance", "Gleitzeitkonto", "Hier wird dein gesamtes Gleitzeitkonto über das Jahr hinweg zusammengerechnet. So weißt du immer genau, wie viele Überstunden du angesammelt hast.") ]; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await HighlightStep(); } } private async Task HighlightStep() { if (_active && _steps.Count > 0) { var step = _steps[_currentStep]; await JS.InvokeVoidAsync("window.onboarding.highlight", step.TargetSelector); } } private async Task NextStep() { if (_currentStep < _steps.Count - 1) { _currentStep++; await HighlightStep(); } else { await CompleteTour(); } } private async Task PrevStep() { if (_currentStep > 0) { _currentStep--; await HighlightStep(); } } private async Task CompleteTour() { _active = false; await JS.InvokeVoidAsync("window.onboarding.clear"); await OnFinished.InvokeAsync(); } private class OnboardingStep { public string TargetSelector { get; } public string Title { get; } public string Content { get; } public OnboardingStep(string targetSelector, string title, string content) { TargetSelector = targetSelector; Title = title; Content = content; } } }