From a02ddf3bb91131f2de044b360a67353075ae865d Mon Sep 17 00:00:00 2001 From: FlorianEisenmenger Date: Wed, 17 Jun 2026 02:02:22 +0200 Subject: [PATCH] updated md files --- CLAUDE.md | 45 +++++++++++++++++++++++++++++++++++-- httpdocs/PROJEKT_KONTEXT.md | 40 +++++++++++++++++++++++++++------ 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 861c4ad..525afda 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -101,10 +101,51 @@ bash httpdocs/deploy.sh - **Rounding**: Konfigurierbar per `Account.trackingInterval` (1/15/30/60 Min) - **API-Pattern**: `/api/...` Routen, JSON Request/Response, kein CSRF auf API-Endpunkten - **Rollen**: `admin` (alles), `member` (eigene + fremde Einträge sehen), `tracker` (nur eigene) -- **Translations**: `messages.de.yaml`, JS-Strings via `window.TT.i18n` / `window.Report.i18n`. Auch Backend-Services (z.B. `ReportExportService`) nutzen `TranslatorInterface` — keine hardcoded Strings. -- **SCSS**: BEM-ähnlich, Atoms → Components → Sections → Themes - **CSS Custom Properties**: Brand-Farben via `:root`-Variablen (`--color-primary`, etc.) +### Translations — keine hardcodierten Strings + +Alle UI-Texte leben zentral in `translations/messages.de.yaml`. Nirgends dürfen deutsche Strings direkt im Code stehen. + +- **Twig**: `{{ 'app.section.key'|trans }}` bzw. `{{ 'app.key'|trans({'%placeholder%': value}) }}` +- **PHP Controller/Services**: `TranslatorInterface` injizieren, `$this->translator->trans('app.key')` nutzen +- **JS**: Strings werden im Twig-Template als `window.XX.i18n`-Objekt übergeben (z.B. `window.CRUD.i18n`, `window.ACCOUNT.i18n`). JS-Module nutzen `createTranslator('XX')` aus `utils.js` zum Zugriff: `const t = createTranslator('CRUD'); t('confirmDelete')` +- **Schlüsselstruktur**: `app.{section}.{key}` (z.B. `app.team.btn_new`, `app.error.access_denied`, `app.validation.email_required`) + +### Kein Inline-CSS + +Keine `style="..."`-Attribute in Twig-Templates oder JS-generiertem HTML. Stattdessen eigene SCSS-Klassen verwenden. + +### SCSS: Mixins statt Duplikation + +Wiederkehrende Patterns sind in `atoms/_mixins.scss` ausgelagert. Bei neuen Komponenten die vorhandenen Mixins nutzen: +- `@include card($bg, $radius)` — Karte mit Schatten +- `@include icon-btn($size, $shape)` — Icon-Button (rund, transparent) +- `@include page-shell` — Seiten-Grundlayout (min-height, flex-column, bg) +- `@include section-header` — Header-Gradient mit Flex-Layout +- `@include text-truncate` — Einzeiliger Text mit Ellipsis +- `@include form-label` — Formular-Label-Styling + +### JS: utils.js + +Gemeinsame Hilfsfunktionen in `assets/scripts/utils.js`: +- `esc(str)` — HTML-Escaping für dynamische Inhalte (XSS-Prävention). Immer nutzen wenn User-Daten in JS-generiertes HTML eingefügt werden. +- `createTranslator(namespace)` — i18n-Zugriff (siehe Translations) +- `removeWithAnimation(el, className)` / `animateIn(el, className)` — Animierte DOM-Operationen +- Konstanten: `ANIMATION_MS`, `FADE_MS`, `MINUTES_PER_DAY` + +### Globale `[hidden]`-Regel + +`main.scss` enthält `[hidden] { display: none !important; }`. Kein `&[hidden] { display: none !important; }` in einzelnen Komponenten nötig. + +### PHP: `readonly` Constructor Promotion + +Controller-Abhängigkeiten immer mit `private readonly` deklarieren. + +### Twig: Wiederverwendbare Macros + +Komplexe Logik die in mehreren Templates vorkommt wird in `templates/_macros/helpers.html.twig` als Macro ausgelagert (z.B. `smart_date`). + ## Rollen-System | Rolle | Rechte | diff --git a/httpdocs/PROJEKT_KONTEXT.md b/httpdocs/PROJEKT_KONTEXT.md index c30dccf..db8fb6e 100644 --- a/httpdocs/PROJEKT_KONTEXT.md +++ b/httpdocs/PROJEKT_KONTEXT.md @@ -249,9 +249,10 @@ templates/ ``` assets/styles/ -├── main.scss ← Entry Point +├── main.scss ← Entry Point + globale [hidden]-Regel ├── atoms/ │ ├── _variables.scss ← SCSS-Vars + :root CSS Custom Properties +│ ├── _mixins.scss ← Wiederverwendbare Mixins (card, icon-btn, page-shell, etc.) │ ├── _typography.scss │ ├── _buttons.scss ← .btn, .btn-primary, .btn-secondary │ └── _inputs.scss ← .input, .select, .textarea @@ -285,6 +286,8 @@ assets/styles/ assets/ ├── app.js ← Entry: importiert main.scss, calendar.js, entries.js └── scripts/ + ├── utils.js ← Gemeinsame Hilfsfunktionen: esc(), createTranslator(), + │ removeWithAnimation(), animateIn(), Konstanten ├── calendar.js ← WeekCalendar (Wochennavigation, Monatsansicht) │ Positioniert Monatskalender relativ zum Cal-Icon ├── entries.js ← EntryManager (CRUD, fetch, localStorage) @@ -316,18 +319,41 @@ assets/ ## Wichtige Konventionen +### Translations — keine hardcodierten Strings +- **Alle** UI-Texte leben in `translations/messages.de.yaml` — nirgends deutsche Strings direkt im Code +- **Twig**: `{{ 'app.section.key'|trans }}`, mit Platzhaltern: `{{ 'app.key'|trans({'%name%': value}) }}` +- **PHP Controller/Services**: `TranslatorInterface` injizieren → `$this->translator->trans('app.key')` +- **JS**: Strings als `window.XX.i18n`-Objekt im Twig-Template übergeben (z.B. `window.CRUD.i18n`, `window.ACCOUNT.i18n`), Zugriff via `createTranslator('XX')` aus `utils.js` +- **Schlüsselstruktur**: `app.{section}.{key}` (z.B. `app.team.btn_new`, `app.error.access_denied`) +- Datums-Arrays weiterhin in `AppExtension.php` als Twig-Funktionen: `deMonths()`, `deMonthsShort()`, `deWeekdays()`, `deWeekdaysShort()` + +### Kein Inline-CSS +- Keine `style="..."`-Attribute in Twig-Templates oder JS-generiertem HTML +- Stattdessen eigene SCSS-Klassen anlegen + +### SCSS: Mixins statt Duplikation +- Wiederkehrende Patterns in `atoms/_mixins.scss`: `card()`, `icon-btn()`, `page-shell`, `section-header`, `text-truncate`, `form-label` +- Neue Komponenten sollen vorhandene Mixins nutzen statt CSS-Properties zu duplizieren +- `main.scss` enthält `[hidden] { display: none !important; }` — kein separates `&[hidden]` pro Komponente nötig + +### JS: utils.js — gemeinsame Hilfsfunktionen +- `esc(str)` — HTML-Escaping für User-Daten in JS-generiertem HTML (XSS-Prävention, immer nutzen!) +- `createTranslator(namespace)` — i18n-Zugriff (siehe Translations) +- `removeWithAnimation()` / `animateIn()` — animierte DOM-Operationen +- Konstanten: `ANIMATION_MS`, `FADE_MS`, `MINUTES_PER_DAY` + +### PHP: `readonly` Constructor Promotion +- Controller-Abhängigkeiten immer mit `private readonly` deklarieren + +### Twig: Wiederverwendbare Macros +- Komplexe Logik die in mehreren Templates vorkommt → `templates/_macros/helpers.html.twig` als Macro (z.B. `smart_date`) + ### Durations - Gespeichert als **Integer (Minuten)** in der DB - Eingabe: `1:30`, `8 12` (von-bis), `1,75` (Dezimal), `0:00` (Reset) - Runden: konfigurierbar per `Account.trackingInterval` (1, 15, 30, 60 Minuten) - Anzeige: `formatMinutes()` → `"1:30"` -### Translations -- Alle UI-Strings in `translations/messages.de.yaml` -- Datums-Arrays in `AppExtension.php` als Twig-Funktionen: `deMonths()`, `deMonthsShort()`, `deWeekdays()`, `deWeekdaysShort()` -- JS bekommt Strings via `window.TT.i18n` (Timetracking) bzw. `window.Report.i18n` (Report) etc. -- JS-Zugriff: `function t(key) { return window.X?.i18n?.[key] ?? key; }` - ### API-Pattern - Alle API-Routen unter `/api/...` - JSON Request/Response