@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;
}
}
}