180 lines
6.9 KiB
Plaintext
180 lines
6.9 KiB
Plaintext
@inject IJSRuntime JS
|
|
|
|
@if (_active)
|
|
{
|
|
@* Dark Backdrop Overlay *@
|
|
<div class="onboarding-backdrop"></div>
|
|
|
|
@* Onboarding Instruction Card *@
|
|
<div class="onboarding-card-container">
|
|
<MudCard Class="onboarding-info-card pa-5 rounded-xl shadow-2xl">
|
|
<MudCardContent Class="pa-0">
|
|
<MudStack Spacing="3">
|
|
@* Header / Title *@
|
|
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
|
|
<MudIcon Icon="@Icons.Material.Filled.AutoAwesome" Style="color: #0EA5E9;" />
|
|
<MudText Typo="Typo.h6" Style="font-weight: 700; color: white;">
|
|
@_steps[_currentStep].Title
|
|
</MudText>
|
|
</MudStack>
|
|
|
|
@* Explanation Text *@
|
|
<MudText Typo="Typo.body2" Style="color: #CBD5E1; line-height: 1.6; min-height: 60px;">
|
|
@_steps[_currentStep].Content
|
|
</MudText>
|
|
|
|
@* Footer / Progress & Buttons *@
|
|
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.SpaceBetween" Class="mt-2">
|
|
@* Step Count *@
|
|
<MudText Typo="Typo.caption" Style="color: #94A3B8; font-weight: 600;">
|
|
Schritt @(_currentStep + 1) von @_steps.Count
|
|
</MudText>
|
|
|
|
@* Navigation Button Stack *@
|
|
<MudStack Row="true" Spacing="2" AlignItems="AlignItems.Center">
|
|
@if (_currentStep > 0)
|
|
{
|
|
<MudButton Variant="Variant.Text"
|
|
Style="color: #94A3B8; text-transform: none; border-radius: 12px;"
|
|
OnClick="PrevStep"
|
|
Size="Size.Small">
|
|
Zurück
|
|
</MudButton>
|
|
}
|
|
else
|
|
{
|
|
<MudButton Variant="Variant.Text"
|
|
Style="color: #94A3B8; text-transform: none; border-radius: 12px;"
|
|
OnClick="CompleteTour"
|
|
Size="Size.Small">
|
|
Überspringen
|
|
</MudButton>
|
|
}
|
|
|
|
<MudButton Variant="Variant.Filled"
|
|
Color="Color.Secondary"
|
|
Style="text-transform: none; border-radius: 12px; font-weight: 700; min-width: 80px;"
|
|
OnClick="NextStep"
|
|
Size="Size.Small">
|
|
@(_currentStep == _steps.Count - 1 ? "Fertig" : "Weiter")
|
|
</MudButton>
|
|
</MudStack>
|
|
</MudStack>
|
|
</MudStack>
|
|
</MudCardContent>
|
|
</MudCard>
|
|
</div>
|
|
}
|
|
|
|
<style>
|
|
/* Backdrop behind cards but below the spotlight highlight */
|
|
.onboarding-backdrop {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
background: rgba(15, 23, 42, 0.4);
|
|
backdrop-filter: blur(2px);
|
|
z-index: 9999;
|
|
pointer-events: all;
|
|
}
|
|
|
|
/* Fixed positioned instruction box at the bottom center */
|
|
.onboarding-card-container {
|
|
position: fixed;
|
|
bottom: 32px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 90%;
|
|
max-width: 480px;
|
|
z-index: 10001;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
/* Dark theme styling for the instruction card */
|
|
.onboarding-info-card {
|
|
background: rgba(15, 23, 42, 0.9) !important;
|
|
backdrop-filter: blur(16px) !important;
|
|
-webkit-backdrop-filter: blur(16px) !important;
|
|
border: 1px solid rgba(255, 255, 255, 0.08) !important;
|
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.4) !important;
|
|
}
|
|
</style>
|
|
|
|
@code {
|
|
[Parameter] public EventCallback OnFinished { get; set; }
|
|
|
|
private bool _active = true;
|
|
private int _currentStep = 0;
|
|
|
|
private readonly List<OnboardingStep> _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;
|
|
}
|
|
}
|
|
}
|