@page "/settings" @rendermode InteractiveServer @attribute [Authorize] @inject TimetrackerService TrackerService @inject HolidayService HolidayService @inject ISnackbar Snackbar @inject AuthenticationStateProvider AuthStateProvider Einstellungen – Timetracker @if (_settings == null) { } else { @* ── Header ── *@ Einstellungen Arbeitszeit, Arbeitstage und Urlaub konfigurieren @* ── Arbeitszeit ── *@ Arbeitszeit Tagesberechnung Netto (Soll) @FormatHours(_settings.DailyTargetHours) + Mindestpause @_settings.MinimumBreakMinutes min = Brutto-Anwesenheit @FormatHours(_settings.DailyTargetHours + _settings.MinimumBreakMinutes / 60.0) @* ── Arbeitstage ── *@ Arbeitstage Wähle die Wochentage, an denen du arbeitest. @foreach (var (label, getter, setter) in WorkDayToggles) { var isChecked = getter(_settings); @label } @* ── Region & Feiertage ── *@ Region & Feiertage Wähle dein Bundesland aus, um Bundesland-spezifische Feiertage zu berücksichtigen. @foreach (var state in GermanStates) { @state.Value } @* ── Gleitzeitkonto ── *@ Gleitzeitkonto-Start @* ── Speichern-Button ── *@ Einstellungen speichern @* ── Urlaubsverwaltung ── *@ Urlaubsverwaltung @_vacYear @* ── Urlaubskontingent ── *@ @* ── Statistik-Chips ── *@ @_settings.VacationDaysPerYear Gesamt @_vacationDays.Count Genommen = 0 ? "76,175,80" : "255,152,0")},0.08);")"> @_vacRemaining Verbleibend @* ── Fortschrittsbalken ── *@ @VacationUsedPercent % des Jahresurlaubs @_vacYear verbraucht @* ── Urlaub hinzufügen ── *@ Urlaub eintragen Hinzufügen @* ── Liste der Urlaubstage ── *@ @if (_vacationDays.Count == 0) { Noch keine Urlaubstage für @_vacYear eingetragen. } else { @foreach (var v in _vacationDays) { @v.Date.ToString("dddd, dd. MMMM yyyy", _deCulture) @if (!string.IsNullOrWhiteSpace(v.Note)) { @v.Note } } } @* ── Feiertagsverwaltung ── *@ Feiertage (Deutschland) @_holYear @if (_fetchingHolidays) { } Von API laden @if (_holHolidays.Count == 0) { Keine Feiertage für @_holYear gespeichert. Klicke "Von API laden". } else { @foreach (var h in _holHolidays) { @h.Date.ToString("dddd, dd. MMMM yyyy", _deCulture) @h.Name } } } @code { private static readonly System.Globalization.CultureInfo _deCulture = new("de-DE"); private AppSettings? _settings; private int _userId; private DateTime? _flexStartDate { get => _settings?.FlexTimeStartDate?.ToDateTime(TimeOnly.MinValue); set => _settings!.FlexTimeStartDate = value.HasValue ? DateOnly.FromDateTime(value.Value) : null; } private static readonly Dictionary GermanStates = new() { { "DE-BW", "Baden-Württemberg" }, { "DE-BY", "Bayern" }, { "DE-BE", "Berlin" }, { "DE-BB", "Brandenburg" }, { "DE-HB", "Bremen" }, { "DE-HH", "Hamburg" }, { "DE-HE", "Hessen" }, { "DE-MV", "Mecklenburg-Vorpommern" }, { "DE-NI", "Niedersachsen" }, { "DE-NW", "Nordrhein-Westfalen" }, { "DE-RP", "Rheinland-Pfalz" }, { "DE-SL", "Saarland" }, { "DE-SN", "Sachsen" }, { "DE-ST", "Sachsen-Anhalt" }, { "DE-SH", "Schleswig-Holstein" }, { "DE-TH", "Thüringen" } }; private int _vacYear = DateTime.Today.Year; private List _vacationDays = []; private DateTime? _newVacDateFrom; private DateTime? _newVacDateTo; private string _newVacNote = ""; private int _holYear = DateTime.Today.Year; private List _holHolidays = []; private bool _fetchingHolidays; private int _vacRemaining => (_settings?.VacationDaysPerYear ?? 0) - _vacationDays.Count; private int VacationUsedPercent => _settings?.VacationDaysPerYear > 0 ? (int)Math.Round(_vacationDays.Count * 100.0 / _settings.VacationDaysPerYear) : 0; // Arbeitstage-Konfiguration als Liste von (Label, Getter, Setter) private static readonly (string Label, Func Get, Action Set)[] WorkDayToggles = [ ("Montag", s => s.WorkMonday, (s, v) => s.WorkMonday = v), ("Dienstag", s => s.WorkTuesday, (s, v) => s.WorkTuesday = v), ("Mittwoch", s => s.WorkWednesday, (s, v) => s.WorkWednesday = v), ("Donnerstag", s => s.WorkThursday, (s, v) => s.WorkThursday = v), ("Freitag", s => s.WorkFriday, (s, v) => s.WorkFriday = v), ("Samstag", s => s.WorkSaturday, (s, v) => s.WorkSaturday = v), ("Sonntag", s => s.WorkSunday, (s, v) => s.WorkSunday = v), ]; protected override async Task OnInitializedAsync() { var authState = await AuthStateProvider.GetAuthenticationStateAsync(); var claim = authState.User.FindFirst(ClaimTypes.NameIdentifier); if (claim == null) return; _userId = int.Parse(claim.Value); _settings = await TrackerService.GetSettingsAsync(_userId); await LoadVacations(); _holHolidays = await HolidayService.GetHolidaysAsync(_holYear, _settings.GermanState); } private async Task LoadVacations() { _vacationDays = await TrackerService.GetVacationDaysAsync(_userId, _vacYear); } private async Task ChangeYear(int delta) { _vacYear += delta; await LoadVacations(); } private async Task Save() { if (_settings == null) return; await TrackerService.SaveSettingsAsync(_settings); // Nach dem Speichern Feiertage neu laden, falls sich das Bundesland geändert hat _holHolidays = await HolidayService.GetHolidaysAsync(_holYear, _settings.GermanState); Snackbar.Add("Einstellungen gespeichert", Severity.Success); } private async Task AddVacation() { if (_newVacDateFrom == null) return; var from = DateOnly.FromDateTime(_newVacDateFrom.Value); var to = _newVacDateTo.HasValue ? DateOnly.FromDateTime(_newVacDateTo.Value) : from; if (to < from) to = from; var note = string.IsNullOrWhiteSpace(_newVacNote) ? null : _newVacNote.Trim(); var current = from; var added = 0; while (current <= to) { if (_settings!.IsWorkDay(current.DayOfWeek)) { await TrackerService.AddVacationDayAsync(new VacationDay { UserId = _userId, Date = current, Note = note }); added++; } current = current.AddDays(1); } _newVacDateFrom = null; _newVacDateTo = null; _newVacNote = ""; await LoadVacations(); Snackbar.Add(added == 1 ? "Urlaubstag eingetragen" : $"{added} Urlaubstage eingetragen", Severity.Success); } private async Task RemoveVacation(int id) { await TrackerService.RemoveVacationDayAsync(_userId, id); await LoadVacations(); Snackbar.Add("Urlaubstag entfernt", Severity.Info); } // ── Feiertage ──────────────────────────────────────────────── private async Task ChangeHolYear(int delta) { _holYear += delta; _holHolidays = await HolidayService.GetHolidaysAsync(_holYear, _settings?.GermanState); } private async Task FetchHolidays() { _fetchingHolidays = true; var (success, message) = await HolidayService.FetchAndStoreAsync(_holYear); _holHolidays = await HolidayService.GetHolidaysAsync(_holYear, _settings?.GermanState); _fetchingHolidays = false; Snackbar.Add(message, success ? Severity.Success : Severity.Error); } private async Task DeleteHoliday(int id) { await HolidayService.DeleteAsync(id); _holHolidays = await HolidayService.GetHolidaysAsync(_holYear, _settings?.GermanState); Snackbar.Add("Feiertag entfernt", Severity.Info); } private static string FormatHours(double hours) { var ts = TimeSpan.FromHours(hours); return $"{(int)ts.TotalHours}:{ts.Minutes:D2} h"; } }