163 lines
4.8 KiB
Markdown
163 lines
4.8 KiB
Markdown
|
|
# Header-Countdown (Pensionsantritt)
|
||
|
|
|
||
|
|
Zeigt im Header der Landingpage zwei Live-Werte bis zu einem Zieldatum:
|
||
|
|
|
||
|
|
- verbleibende **Kalendertage**
|
||
|
|
- verbleibende **Arbeitstage** (Mo-Fr, ohne die im Burgenland geltenden Feiertage)
|
||
|
|
|
||
|
|
Beschriftung: "X Tage bis zum Pensionsantritt" / "Y Arbeitstage bis zum
|
||
|
|
Pensionsantritt". Kein Backend noetig - die Feiertage kommen CORS-freundlich
|
||
|
|
von der kostenlosen Nager.Date API. Das Feature folgt demselben Muster wie
|
||
|
|
die bestehenden Komponenten `pihole-control` / `tasmota-control`.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Funktionsumfang
|
||
|
|
|
||
|
|
- **Kalendertage**: volle Tage zwischen heute und Zieldatum.
|
||
|
|
- **Arbeitstage**: Mo-Fr zwischen heute und Zieldatum, abzueglich der fuer das
|
||
|
|
gewaehlte Bundesland geltenden Feiertage.
|
||
|
|
- **Live-Aktualisierung**: einmal pro Minute neu berechnet (Tageswechsel).
|
||
|
|
- **Fehler-Fallback**: bei nicht erreichbarer API werden Arbeitstage OHNE
|
||
|
|
Feiertagsabzug gezaehlt (Badge zeigt "*" + Tooltip); waehrend des Ladens
|
||
|
|
erscheint "Tage werden berechnet ...".
|
||
|
|
- **Caching**: Feiertagsliste pro Jahr im localStorage mit Tagesgueltigkeit
|
||
|
|
(Key `nager_holidays_<Jahr>`).
|
||
|
|
- **Zieldatum erreicht/ueberschritten**: zeigt "Pensionsantritt (<Datum>)
|
||
|
|
erreicht".
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Dateien
|
||
|
|
|
||
|
|
```
|
||
|
|
src/app/countdown/countdown.component.ts Logik: Berechnung, API, Cache, Filter
|
||
|
|
src/app/countdown/countdown.component.html zwei Badges + Fallback-Zustaende
|
||
|
|
src/app/countdown/countdown.component.css Badge-Styles (an Header anpassbar)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Integration
|
||
|
|
|
||
|
|
### 1. Komponente registrieren (`app.module.ts`)
|
||
|
|
|
||
|
|
```ts
|
||
|
|
import { CountdownComponent } from './countdown/countdown.component';
|
||
|
|
|
||
|
|
@NgModule({
|
||
|
|
declarations: [
|
||
|
|
// ... bestehende ...
|
||
|
|
CountdownComponent
|
||
|
|
]
|
||
|
|
})
|
||
|
|
export class AppModule {}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Im Header einbinden (`app.component.html`)
|
||
|
|
|
||
|
|
```html
|
||
|
|
<app-countdown></app-countdown>
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Konfiguration (oben in `countdown.component.ts`)
|
||
|
|
|
||
|
|
### Zieldatum
|
||
|
|
|
||
|
|
```ts
|
||
|
|
// 31.12.2026 -> new Date(2026, 11, 31) (Monat 0-basiert: 11 = Dezember!)
|
||
|
|
const TARGET_DATE = new Date(2026, 11, 31);
|
||
|
|
```
|
||
|
|
|
||
|
|
> Der Monat in JavaScript ist 0-basiert: Januar = 0, Maerz = 2, Dezember = 11.
|
||
|
|
> Das genaue Zieldatum erscheint zusaetzlich im Tooltip der Badges.
|
||
|
|
|
||
|
|
### Beschriftung
|
||
|
|
|
||
|
|
```ts
|
||
|
|
const TARGET_LABEL_SUFFIX = 'bis zum Pensionsantritt';
|
||
|
|
```
|
||
|
|
|
||
|
|
### Bundesland-Filter
|
||
|
|
|
||
|
|
```ts
|
||
|
|
const COUNTY: string | null = 'AT-1'; // Burgenland
|
||
|
|
// AT-2 Kaernten, AT-3 Niederoesterreich, AT-4 Oberoesterreich,
|
||
|
|
// AT-5 Salzburg, AT-6 Steiermark, AT-7 Tirol, AT-8 Vorarlberg, AT-9 Wien.
|
||
|
|
// null = nur bundesweite Feiertage abziehen.
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Feiertagslogik
|
||
|
|
|
||
|
|
Nager.Date liefert je Feiertag `global` (bundesweit) und `counties`
|
||
|
|
(regionale Gueltigkeit, z.B. `["AT-1"]`). Abgezogen werden:
|
||
|
|
|
||
|
|
- alle **bundesweiten** Feiertage (`global: true`), UND
|
||
|
|
- **regionale** Feiertage, deren `counties` das gewaehlte Bundesland enthalten.
|
||
|
|
|
||
|
|
Bei Zeitraeumen ueber einen Jahreswechsel wird die API fuer jedes betroffene
|
||
|
|
Jahr separat abgefragt und die Ergebnisse werden kombiniert.
|
||
|
|
|
||
|
|
Datenquelle: Nager.Date
|
||
|
|
`https://date.nager.at/api/v3/PublicHolidays/{Jahr}/AT`
|
||
|
|
(Doku: https://date.nager.at/de/api)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Verifizierte Berechnung (echte Feiertage, Burgenland-Filter)
|
||
|
|
|
||
|
|
Stand heute 27.07.2026 bis Pensionsantritt 31.12.2026:
|
||
|
|
|
||
|
|
| Wert | Ergebnis |
|
||
|
|
|---|---|
|
||
|
|
| Kalendertage | **157** |
|
||
|
|
| Arbeitstage (AT-1) | **109** |
|
||
|
|
|
||
|
|
Abgezogene Feiertage (Mo-Fr):
|
||
|
|
|
||
|
|
| Datum | Wochentag | Feiertag | Grund |
|
||
|
|
|---|---|---|---|
|
||
|
|
| 26.10.2026 | Mo | Nationalfeiertag | bundesweit |
|
||
|
|
| 11.11.2026 | Mi | Martinstag | Landesfeiertag Burgenland (AT-1) |
|
||
|
|
| 08.12.2026 | Di | Mariae Empfaengnis | bundesweit |
|
||
|
|
| 25.12.2026 | Fr | Weihnachten | bundesweit |
|
||
|
|
|
||
|
|
Nicht abgezogen: Rupertitag (24.09., nur Salzburg AT-5); Maria Himmelfahrt
|
||
|
|
(15.08.) und Stefanitag (26.12.) fallen 2026 auf einen Samstag.
|
||
|
|
|
||
|
|
> Hinweis: Nager.Date klassifiziert regionale Tage (inkl. Martinstag) intern
|
||
|
|
> als Typ `School`. Ob der Martinstag im konkreten Betrieb ein freier
|
||
|
|
> Arbeitstag ist, haengt von der jeweiligen Dienst-/Betriebsregelung ab.
|
||
|
|
> Bei Abweichung kann der Filter angepasst werden.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Fehlerbehandlung & Edge-Cases
|
||
|
|
|
||
|
|
| Situation | Verhalten |
|
||
|
|
|---|---|
|
||
|
|
| API nicht erreichbar | Arbeitstage ohne Feiertagsabzug, Badge zeigt "*" + Tooltip |
|
||
|
|
| Ladephase | "Tage werden berechnet ..." |
|
||
|
|
| Zieldatum in Vergangenheit/heute | "Pensionsantritt (<Datum>) erreicht", beide Werte 0 |
|
||
|
|
| Zeitraum ueber Jahreswechsel | Feiertage aller betroffenen Jahre kombiniert |
|
||
|
|
| localStorage deaktiviert/voll | Cache-Schreiben wird ignoriert, API wird direkt genutzt |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Styling
|
||
|
|
|
||
|
|
Die Badges nutzen neutrale Styles (`.countdown-badge`) mit `color: inherit`,
|
||
|
|
damit sie die Header-Textfarbe uebernehmen. Passe Farben bei Bedarf an die
|
||
|
|
bestehenden Header-Variablen an, z.B.:
|
||
|
|
|
||
|
|
```css
|
||
|
|
.countdown-badge { background: var(--header-accent, rgba(255,255,255,.12)); }
|
||
|
|
```
|
||
|
|
|
||
|
|
Das Arbeitstage-Badge (`.countdown-badge--work`) hat einen dezenten Gruenton
|
||
|
|
- analog zum Pi-hole-"kein Blocking"-Gruen.
|