# ORGANISMS — manager-system organism-katalógus

**Forrás.** Ez a fájl a `SITEMAP.md` használat-mátrixából vezeti le az építési
sorrendet és az organism-API-kat. Per organism: mi a szerepe, mit fogyaszt
a DS-ből, milyen variációkkal jár, milyen propsokat vár.

A részletes implementáció (JSX + CSS) az `organisms/`-ban születik majd; ez a
fájl a **tervrajz**.

---

## 0. Konvenciók

**Hogyan használunk organism-et.**
- Mind React-komponens, JSX-fájl per organism *(`app-shell.jsx`, `status-track.jsx`, …)*.
- A class-nevek `mgr-<organism-name>` prefix-szel *(pl. `mgr-status-track__step`)*
  — így a DS `u-*` névsávjától egyértelműen elválik.
- Saját CSS *(konszolidálva egy `organisms/_styles.css`-ben — egy hely, egy import)*.
- **Csak DS-tokeneket fogyaszt** *(`--u-*`)*; egyetlen magic-number sem.
- **Inline-style csak akkor**, ha tényleg dinamikus *(pl. progress-bar `width: ${pct}%`)*.

**Hogyan dokumentálunk variációkat.**
- Egy organism = több állapot *(üres, betöltés, hibás, normál, sikeres)*.
- Minden állapot egy named prop-érték *(`state="empty|loading|error|ready"`)*, nem
  separate component.

**Honnan tudja egy szereplő, hogy organism készen áll.**
- A `preview/` mappában lesz egy `index.html`, ami katalógus-szerűen mutatja
  az összes organism-et minden állapotában. Egy "DS-szerű" specimen-felület
  csak ide.

---

## 1. TIER 0 — minden screenhez kötelező

### `AppShell`

A teljes admin-felület chrome-keret: bal navi + felső sáv + content-slot.
Az `app/screen-*.jsx` minden file `<AppShell>`-be csomagolja a content-jét.

| Prop | Típus | Cél |
|---|---|---|
| `active` | string | A bal navi aktív menüpontja (pl. `"bejelentesek"`) |
| `breadcrumb` | string[] | Felső sáv breadcrumb-elemei *(spec: `Bejelentések · Új bejelentés`)* |
| `topBarRight` | ReactNode | Page-szintű CTA jobbra a top bar-ban *(opcionális)* |
| `pageTemplate` | `"mgr"`\|`"detail"`\|`"form"`\|`"tree"`\|`"mgr-dense"` | A content-wrapper `.u-page--<x>` osztálya |
| `children` | ReactNode | A screen tartalma |

**DS-deps.** `.u-page`, `.u-page--{template}` *(ds-patch eredménye)*; `--u-bg`,
`--u-fg-1`, `--u-border`, `--u-font-sans` tokenek.

**Beágyazott organism-ek.** `LeftNav`, `TopBar` — külön komponensek, az `AppShell`
komponál.

---

### `LeftNav` *(AppShell-bef.)*

Bal sticky 240px sáv: brand-block + nav-csoportok + footer (current user). Collapsed
állapotban 64px csak ikonokkal.

| Prop | Típus | Cél |
|---|---|---|
| `active` | string | Az aktív item key-je |
| `tenant` | object | Megjelenített tenant *(név + short-név)* |
| `currentUser` | object | Footer-block adatai |
| `collapsed` | boolean | Csukva = 64px |
| `counts` | object | Per-nav-item badge-érték *(pl. `{ bejelentesek: 47 }`)* — opcionális |

**Variációk.** Default · collapsed · count-badge-zel.

**DS-deps.** `--u-surface`, `--u-border`, `--u-primary-soft`, `--u-blue-700`,
`components/avatar.css`. Logo-svg az `assets/logo-mark-white.svg`-ből.

---

### `TopBar`

Sticky 56px top bar: breadcrumb (bal), global-search (közép), bell (jobb), CTA-slot (jobbra végül).

| Prop | Típus | Cél |
|---|---|---|
| `breadcrumb` | string[] | Path-elemek |
| `children` | ReactNode | Jobboldali CTA-slot |
| `searchPlaceholder` | string | Default: "Keresés…" |

**DS-deps.** `components/breadcrumb.css`, `--u-surface-alt`, `--u-border`,
`components/icon.css`. Backdrop-blur `rgba(255,255,255,0.92)`.

---

### `PageHeader`

A content-wrapper első elem: kis "eyebrow" felirat (opcionális, ALL CAPS letter-spacing),
H1 cím, opcionális leírás, jobboldali action-row.

| Prop | Típus | Cél |
|---|---|---|
| `eyebrow` | string | "EZ A HÉT" / dátumtartomány / kategória — opcionális kis felirat |
| `title` | string | A page H1 — kötelező |
| `description` | string | Egy sor magyarázat / context — opcionális |
| `actions` | ReactNode | Jobboldali button-cluster — opcionális |
| `back` | string \| null | Vissza-link (URL) — adatlap-screenen kötelező |

**Variációk.** Sima cím · eyebrow-val · vissza-linkkel · action-bar-ral.

**DS-deps.** `--u-font-display`, `--u-fg-1`/`-2`/`-3`, button.css.

---

### `EmptyState`

Generikus "nincs adat" állapot egy szekción belül. Három fő variáció:
*"még nincs ilyen"*, *"nincs jogosultság"*, *"hibajelzés"*.

| Prop | Típus | Cél |
|---|---|---|
| `kind` | `"empty"`\|`"no-permission"`\|`"error"`\|`"no-results"` | Variant |
| `title` | string | Pl. *"Még nincs bejelentés."* |
| `description` | string | Egy mondat magyarázat |
| `action` | ReactNode | Opcionális CTA (gomb) |
| `icon` | string | Lucide-ikon-név — default a `kind`-ból |

**DS-deps.** `--u-fg-2`/`-3`, button atom; ikonok Lucide-ból. A `docs/spacing.md` §5.7
empty-state recept.

---

## 2. TIER 1 — gyakran használt cross-cutting

### `ConfirmDialog`

Generikus megerősítő-dialog wrapper. Az "Elutasítás", "Visszanyitás", "Összevonás",
"Letiltás" stb. mind ennek a `kind` propon paraméterezett variánsai.

| Prop | Típus | Cél |
|---|---|---|
| `open` | boolean | — |
| `kind` | `"info"`\|`"danger"`\|`"warning"` | A header-bar színe és az ikon |
| `title` | string | — |
| `message` | string \| ReactNode | Body; lehet űrlap-mező is *(elutasítás-indok)* |
| `confirmLabel` | string | Default kind szerint *(pl. danger → "Elutasítás")* |
| `cancelLabel` | string | Default: "Mégse" |
| `onConfirm` / `onCancel` | function | — |

**Specializációk.** A bejelentés-elutasítás (`RejectionDialog`), a visszanyitás
(`ReopenDialog`), az összevonás (`MergeConfirmDialog`) **nem külön organism**,
hanem ennek `kind` + `message` használata — annyit írunk csak ki, hogy egy
felhasználói flow konkrét megerősítő-szövege ott jelenik meg.

**DS-deps.** `components/dialog.css`, `.u-dialog`, `.u-dialog--sm`/`--md`. Az
elutasítás-indok-mezőhöz a `--u-status-elutasitva-*` tokenek a header-tin sávhoz.

---

### `SettingsSection`

A beállítási screenek standard szekció-blokkja: kis section-cím (eyebrow-szerű)
+ leírás + content + opcionális footer-action-row.

| Prop | Típus | Cél |
|---|---|---|
| `title` | string | "Tenant alapadatok" |
| `description` | string | Egy mondat |
| `actions` | ReactNode | Opcionális section-szintű CTA (pl. "Mentés") |
| `children` | ReactNode | A szekció tartalma |

**DS-deps.** `components/card.css`, `--u-card-padding-lg`, `--u-divider`.

---

### `SettingsSubNav`

A `/beallitasok/*` top-tabs sávja: Általános · Kategóriák · Csoportok · Felhasználók.
A DS `.u-tabs` default (underline) variánsát közvetlenül fogyasztja —
külön `u-tabs--underline` osztály NEM szükséges.

| Prop | Típus | Cél |
|---|---|---|
| `active` | `"altalanos"`\|`"kategoriak"`\|`"csoportok"`\|`"felhasznalok"` | — |

**DS-deps.** `components/tabs.css` default variánsa.

---

### `UserChip`

Avatar (DS molecule) + név + role-suffix kis chip-formában. Lista-soron, naplóban,
csapat-táblán használt.

| Prop | Típus | Cél |
|---|---|---|
| `name` | string | "Kovács Anna" |
| `role` | string | "diszpécser" |
| `initials` | string | "KA" — fallback, ha nincs avatar-kép |
| `email` | string | Opcionális kiegészítő |
| `size` | `"sm"`\|`"md"`\|`"lg"` | — |
| `disabled` | boolean | Letiltott Users — halványabb avatar + szürkébb név |
| `meta` | string | Override a `role`-t (pl. "Meghívva — még nem aktiválta a fiókját") |

**Variációk.** Sima név · név+role · meta-override · disabled.

**DS-deps.** `components/avatar.css`, `--u-fg-1`/`-2`.

---

## 3. TIER 2 — lista-screen család

A lista-screenek (Bejelentések, Felhasználók, Csoportok, Hírek, Programok, …)
fő organism-jei. Eredetileg Tier-1-ben voltak (D-2 előtt), de a komplexitásuk
és a finomítási iterációk miatt önálló tierbe kerültek.

### `DataTable`

Generikus tábla a manager-listához. Spec: a `01_kozos_mintak.md` `TableStateConfig`
mintája — pilotra már ennek a vizuális oldala. **2026.05.22 audit + D-13** alatt
kibővítve a Tier-2 inline-ban élő, de organism-szintre nem átemelt funkciókkal:
sortable fejléc-cellák, controlled sort-state, row-click callback, per-row class hook,
loading-overlay (T-9). Lásd: `preview/tier-2-datatable-contract.html`.

| Prop | Típus | Cél |
|---|---|---|
| `columns` | object[] | `{ key, label, width?, align?, render?, sortable?, defaultSortDir?, tdClass?, thClass? }` |
| `rows` | object[] | Adatsorok (mindenkinek `id`-vel) |
| `sortKey` | string | A controlled-rendezett oszlop key-je (T-4) |
| `sortDir` | `"asc"`\|`"desc"` | Aktív irány |
| `onSortChange` | function | `(key, dir) => void` — fejléc-kattintáskor hívva |
| `onRowClick` | function | `(row, event) => void` — D-3 sor-klikk, navigáció |
| `rowClassName` | function | `(row) => string` — per-row class hook (T-7: dim Lezárt/Elutasítva) |
| `loading` | boolean | T-9 viselkedés: van adat → dim-overlay, nincs adat → skeleton |
| `selectable` | boolean | Sor-kijelölés bal-szélső oszloppal |
| `density` | `"work"`\|`"compact"`\|`"cozy"` | sűrűség |
| `emptyState` | ReactNode | `<EmptyState>` instance, ha `rows.length === 0` |
| `pagination` | object | `{ page, total, perPage, onChange }` |
| `barActions` | ReactNode | Jobb oldali action-cluster a header-barban |
| `countLabel` | ReactNode | Bal oldali számláló (default: "N rekord") — `frissítve N perce`-typusú freshness-indikátor is ide írható |
| `showHeader` | boolean | bar (count + actions) be/ki (default `true`) |
| `showRowChevron` | boolean | chevron sor-end (default `true` — D-3 bake-in) |

**Sort viselkedés.** Új oszlopra kattintva: a `columns[].defaultSortDir`-rel indul (default `'desc'`). Már sortolt oszlopra kattintva: toggle asc↔desc. A `aria-sort` attribútum a fejléc-cellán beáll.

**Loading viselkedés.** `loading=true && rows.length > 0` → meglévő sorok halványítva + "Frissítjük a listát…" pill-spinner overlay (T-9-B). `loading=true && rows.length === 0` → 6 sor magasságú shimmer-skeleton (initial-load).

**Variációk.** Default · sorted · loading-overlay · loading-skeleton · empty · compact · selectable · bulk-action-bar.

**DS-deps.** `components/table.css`, `.u-table`, `components/pagination.css`,
`components/chip.css` (status-chip cellákhoz).

**Megjegyzés.** Per-feature *(A1 = Bejelentés-lista)* nem külön komponens; egy
`<DataTable columns={ticketColumns} rows={tickets} … />`-instance + a "felelős
oszlop UserChip-pel" típusú cell-render. A column-render-ek a feature-screen
fájlban élnek, így a `DataTable` maga generikus marad. A spec-szerinti
default-sort (`createdAt DESC` minden tabon, `dueDate ASC` az overdue-on) a
screen-szintű `useState({key, dir})` indító-állapota.

---

### `FilterPillBar`

A lista-screenek tetején a tab-szűrő alatt: bal-oldalt keresőmező, középen pill-ek
a fő szűrőkkel *(Kategória · Felelős · Állapot · Dátum)*, jobbra "Mind törlése"
link, ha van aktív szűrő.

| Prop | Típus | Cél |
|---|---|---|
| `filters` | object[] | `{ key, label, value, active? }` |
| `searchValue` | string | Bal-oldali search-input értéke |
| `searchPlaceholder` | string | Default: "Keresés cím, azonosító, leírás alapján…" |
| `hasActive` | boolean | "Mind törlése" link látható-e |
| `onChange` | function | Filter-változás |
| `onClear` | function | "Mind törlése" |

**Variációk.** Üres állapot *(nincs aktív filter)* · 1-2 aktív filter · keresőszó-val.

**DS-deps.** `components/chip.css` (`.u-chip--filter` flavor), `components/input.css`
(search-input).

---

### `TabFilter`

A lista-screenek fő-tab-szűrője a PageHeader alatt. Spec: a Bejelentés-lista
*(`10_bejelentes_lista_es_adatlap.md` 4.2)* 5 tabja — Új · Hozzám rendelt ·
Késésben · Lezárt · Mind — count-badge-ekkel és az "overdue"-tonon piros dot-tal.

**2026.05.22 audit utáni státusz.** A `organisms/tab-filter.jsx` fájl-szinten
létezik (a 8. lépés első iterációjának kiemelése). DS `.u-tabs` default
(underline) variánst fogyaszt; az `aria-selected` és `data-tone="overdue"`
atribútumokkal kódolja a state-eket.

| Prop | Típus | Cél |
|---|---|---|
| `tabs` | object[] | `{ key, label, count?, tone? }` — `tone === 'overdue'` → piros dot ha `count > 0` |
| `active` | string | Aktív tab key |
| `onChange` | function | `(key) => void` — tab-váltás |
| `ariaLabel` | string | Default `"Szűrők"` |

**Variációk.** A tab-szettet feature-szinten kapja meg (A1 a Bejelentés-szettet,
A8 a Felhasználó-szettet stb.) — generikus organism, konkrét tabok feature-szinten.

**DS-deps.** `components/tabs.css` default (underline) variánsa, `--u-status-*`
tokenek a count-badge színezésre, `--u-red-500` az overdue-dot-hoz.

---

## 4. TIER 3 — ág-specifikus, többször használt

### `StatusTrack`

A 4-step állapot-csík az adatlap tetején. **2026.05.22 audit után** kiemelve
`organisms/status-track.jsx`-be (korábban inline a `tier-3.html`-ben).
Exportok: `StatusTrack`, `StatusTrackBranched`.

| Prop | Típus | Cél |
|---|---|---|
| `steps` | `{ key, label, date? }[]` | 4 lépés az állapotgépből |
| `current` | string \| null | Az aktuális `step.key` (null = ne legyen "current" kiemelés) |

A `StatusTrackBranched` plusz propjai: `reason: { title, text }`, `actor`, `date`.

| Prop | Típus | Cél |
|---|---|---|
| `steps` | object[] | `{ key, label, date?, state: "done"|"current"|"pending"|"branched" }` |
| `branched` | object | `{ key, label, message }` — pl. "Elutasítva" mellékág |

**Variációk.** Normál (folyamatban) · branched (elutasítva) · all-done (lezárt).

**DS-deps.** `--u-status-*` tokenek, `--u-green-*`, `--u-amber-*`. Az "Elutasítva"
mellékág a fő tracktől különálló banner.

---

### `KpiCard`

Nagyméretű KPI-kártya tabular-nums-szal. DS-promóció jelölt.

**2026.05.22 audit utáni státusz.** `organisms/kpi-card.jsx` fájl-szinten
létezik (D-12 emelte ki). **D-16 (2026.05.24) hatása:** a `delta` prop
**deprecated** — a spec NEM ír delta-mérést a 4 dashboard-KPI-hoz; a propsignature
backward-compat´-ből megmarad, de a screen-mock-fájl nem adja át.

| Prop | Típus | Cél |
|---|---|---|
| `label` | string | "Nyitott ügyek" |
| `value` | number\|string | "47" — tabular-nums |
| `hint` | string | "Mind a négy nyitott státusz" |
| `tone` | `"default"`\|`"danger"` | Pl. overdue piros |
| `delta` | object | `{ dir: 'up'\|'down', label }` — **deprecated D-16 után** |
| `href` | string | Lefúrás-URL — egész kártya kattintható |
| `onClick` | function | Alternatíva a `href`-nek |

**DS-deps.** `--u-font-display`, `--u-fg-1`, `--u-red-700`/`-500`, tabular-nums.

---

### `ContentEditor`

Egységes szerkesztő-organism a Hír / Program / CityInfo-szerkesztéshez. Egy
core API, három instance.

| Prop | Típus | Cél |
|---|---|---|
| `kind` | `"news"`\|`"event"`\|`"cityinfo"` | Mit szerkesztünk — befolyásolja a mezőkészletet |
| `value` | object | Az entitás aktuális állapota |
| `onChange` | function | — |
| `state` | `"draft"`\|`"published"`\|`"saving"` | — |

**Variációk.** Új tétel (üres) · vázlat-szerkesztés · publikált-szerkesztés.

**Tartalmazza.** Cím, leírás (`RichTextEditor` az A10/A11-en), `CoverImageUploader`
(A10/A11), `DateTimeRangePicker` (A11), `LinkValidator` (A12), publish-akció.

**DS-deps.** `components/form-field.css`, `.u-page--form` template.

---

### `PublishStateChip`

A 2-állapotos publikálási státusz-chip *(Vázlat / Publikálva)*. Hasonló a
státusz-chip-hez (Ticket), de **saját** színpárokkal — nincs külön
`--u-status-draft-*` token a DS-ben.

**2026.05.22 audit utáni státusz.** A `organisms/publish-state-chip.jsx`
fájl-szinten létezik (D-13 nyomán kiemelve). Minimális 15-soros komponens,
`.mgr-pub-chip` + `.mgr-pub-chip--draft`/`--published` modifierrel.

| Prop | Típus | Cél |
|---|---|---|
| `state` | `"draft"` \| `"published"` | Default `"draft"` |

Lehet, hogy a DS-be kerül egy `content-status` family-ként. Egyelőre lokális.

---

### `WeeklyReportCard` *(megnevezés-revízió szükséges — lásd D-16)*

A Dashboard / Riport-archívum letöltő-kártyája: dátumtartomány + generálás-státusz
+ letöltés CTA + opcionális "újraküldés"-link.

**2026.05.22 audit után** kiemelve `organisms/weekly-report-card.jsx`-be (korábban
inline a `tier-3.html`-ben).

| Prop | Típus | Cél |
|---|---|---|
| `week` | string | "2026. 19. hét (05.04 – 05.10)" |
| `generatedAt` | string | "2026.05.11. 06:00" |
| `pdfUrl` | string | Letöltés-link |
| `recipientsSent` | number | Hány címzettnek ment ki |
| `deliveryStatus` | `"pending"`\|`"sent"`\|`"partial"`\|`"failed"` | — |
| `compact` | boolean | Sűrűbb verzió (archívum-lista-soron) |

**DS-deps.** `components/card.css`, status-tokenek.

---

### `PhotoGallery`

Kép-galéria az adatlap olvasói nézetén *(A1)* + a tartalom-ágon (A10/A11). 3-oszlopos
rács képekkel, lightbox-előkészület.

**2026.05.22 audit utáni státusz.** A `organisms/photo-gallery.jsx` fájl-szinten
létezik (D-13 nyomán kiemelve). Overflow-cella (`+N`) a `maxVisible` felett.

| Prop | Típus | Cél |
|---|---|---|
| `photos` | object[] | `{ id, caption?, url? }` — 0..N kép |
| `maxVisible` | number | Default `6` |
| `onPhotoClick` | function | `(photo, index) => void` — lightbox-trigger |

**DS-deps.** `.mgr-gallery*` CSS-osztály-család. Lightbox-implementáció a
screen-mock-fájlra hagyva (overlay + escape-close).

### `PhotoUploader`

Drag-drop kép-feltöltő dropzone-mintával — A2 új-bejelentés-form + A10 Hír +
A11 Programok (a borítóképtől különálló).

**2026.05.22 audit utáni státusz.** A `organisms/photo-uploader.jsx` fájl-szinten
létezik (D-13 nyomán kiemelve). Drag-drop + click-to-browse a `<label>` natív
file-input-burkán.

| Prop | Típus | Cél |
|---|---|---|
| `files` | object[] | `{ id?, name?, previewUrl? }` — már feltöltött fotók |
| `maxCount` | number | Default `4` |
| `maxSizeMB` | number | Default `5` (UI-hint, validáció szerver-oldalon) |
| `onAdd` | function | `(files) => void` |
| `onRemove` | function | `(file, index) => void` |
| `pending` | boolean | Mentés folyamatban — feltöltő-felület disabled |

**DS-deps.** `.mgr-photo-uploader` + `.mgr-uploader*` CSS-osztály-család.
Feltöltött thumbnails 3-oszlopos rácsban, X-gomb minden cellán.

---

### `ContentEditor` *(kiemelve fájl-szinten — D-13 és D-17)*

Egységes szerkesztő-héj az A10/A11/A12 számára. A közös elemek (cím, body,
borítókép, publish-bar) az organism-be vannak kötve; a kind-specifikus mezők
slot-szerűen kerülnek (extraFields prop).

**Publish-bar** D-17 szerint: `[Eldobás]` bal-szélen · spacer · `[Vázlat-mentés]
[Publikálás]` jobb-szélen.

**Split-view (C-4)** : ha a `previewSlot` prop ki van töltve, a host adhat egy
éle előnézet-pane-t (pl. polgári app csempe-mock); a layout két oszlopra esik.

| Prop | Típus | Cél |
|---|---|---|
| `kind` | `"news"` \| `"event"` \| `"cityinfo"` | A label-eket és publishCta-t befolyásolja |
| `value` | object | `{ title, body, coverImageUrl, coverImageMeta, publishState, ... }` |
| `onChange` | function | `(patch) => void` |
| `onSaveDraft` | function | `() => void` — Vázlat-mentés gomb |
| `onPublish` | function | `() => void` — Publikálás gomb |
| `onDiscard` | function | `() => void` — Eldobás gomb (opcionális) |
| `onUploadCover` / `onDeleteCover` | function | CoverImageUploader-bekötés |
| `onUploadGallery` / `onRemoveGalleryItem` | function | PhotoUploader-bekötés (ha `showGallery`) |
| `galleryFiles` | object[] | Ha `showGallery=true` |
| `pending` | boolean | Mentés folyamatban |
| `lastSavedLabel` | string | Pl. `"utoljára mentve 14:32"` |
| `showCover` | boolean | Default `true` (A10/A11), `false` A12-höz |
| `showGallery` | boolean | Default `false` |
| `extraFields` | ReactNode | A11 `DateTimeRangePicker`, A12 `LinkValidator` slot |
| `previewSlot` | ReactNode | Élő előnézet jobb-oszlop (C-4 split-view) |
| `fieldErrors` | object | `{ title?, body?, coverImage?, ... }` |

**Beágyazott organism-ek.** `PublishStateChip`, `CoverImageUploader`,
`RichTextEditor`, `PhotoUploader` — a host script-tagjeiben pre-loadolva
elvárt (`window.X` minta).

### `RichTextEditor` *(pilot-szintű impl. — D-13)*

Egyszerű WYSIWYG az A10 Hír + A11 Programok body-mezőjéhez. **FK-1 pilot-scope:**
bold, italic, underline, lista, link — heading nincs.

**Pilot-szint:** kontrollált `<div contentEditable>` + toolbar; `document.execCommand`
a formázásra. Éles deployment a fejlesztő-átadáskor cserélhető TipTap /
ProseMirror-ra.

| Prop | Típus | Cél |
|---|---|---|
| `value` | string | Kontrollált HTML-tartalom |
| `onChange` | function | `(value) => void` |
| `placeholder` | string | Default `"Írj ide…"` |
| `minHeight` | number | Default `140` |

### `CoverImageUploader` *(kiemelve — D-13)*

16:9 borítókép-feltöltő A10/A11-höz. Mintája a `LogoUploader` (D-11), de
szélesebb aspect-ratio-val és a polgári app hír-csempéje-szerű preview-val.

**Két állapot:** üres (drop-zone) · kitöltött (preview + Csere/Eltávolítás).
`__`-prefixum az `imageUrl`-ben fallback-rendert kódol (mock-mintára).

| Prop | Típus | Cél |
|---|---|---|
| `imageUrl` | string \| null | URL vagy `null` ha üres |
| `imageMeta` | object | `{ filename, size, uploadedAt }` opcionális |
| `onUpload` | function | `(file) => void` |
| `onDelete` | function | `() => void` (opcionális — null = Eltávolítás gomb rejtve) |
| `pending` | boolean | Feltöltés folyamatban |
| `uploadError` | string | Hibaszöveg |

### `DateTimeRangePicker` *(új — D-15)*

Kezdő + záró dátum+idő két külön mezővel az A11 SD-69 kötelezőjéhez.
Két `<input type="datetime-local">` + magyar hosszúdátum-display ("2026. máj. 24.
szombat · 14:00"). Ha mindkét érték azonos napra esik, hint-sor
(`mgr-dtp__same-day-hint`) emeli ki.

| Prop | Típus | Cél |
|---|---|---|
| `value` | object | `{ startAt: Date\|string\|null, endAt: Date\|string\|null }` |
| `onChange` | function | `({ startAt, endAt }) => void` |
| `minDate` | Date \| string | Opcionális — kezdés-előtt nem lehet érték |
| `error` | string | Egész-komponens-szintű hiba |
| `startError` / `endError` | string | Mező-specifikus hiba |

**Belső komponens.** `DateTimeField` — egységes mező-rendererelő (label +
datetime-local input + display).

### `LinkValidator` *(új — A12 specifikus)*

URL-mező a polgári app cityinfo-elemeihez. **On-blur validáció** indikátor-
state-tel (loading / valid / invalid / unreachable) + favicon-grab a valid
URL-hez.

| Prop | Típus | Cél |
|---|---|---|
| `value` | string | URL |
| `onChange` | function | `(url) => void` |
| `state` | `"idle"` \| `"loading"` \| `"valid"` \| `"invalid"` \| `"unreachable"` | A host kezeli — debounced backend-hívás eredménye |
| `meta` | object | `{ title?, faviconUrl? }` — valid esetén |
| `onValidate` | function | `(url) => void` — explicit revalidate-trigger (újra-ellenőrzés gomb) |
| `error` | string | Mező-szintű hiba |
| `placeholder` | string | Default `"https://…"` |

**DS-deps.** `.mgr-lv*` CSS-osztály-család. A host felelős a debounced
backend-hívásért és a `state` propalapra állításáért.

### `RecipientList`

Az A5/A9 közös címzett-lista. Inline szerkesztés (A9-en),
read-only fogyasztás (A5-ön).

| Prop | Típus | Cél |
|---|---|---|
| `recipients` | object[] | `{ id, name?, email, isActive }` |
| `readOnly` | boolean | A5-ön true, A9-en false |
| `onAdd` / `onUpdate` / `onRemove` / `onToggleActive` | function | Csak ha `readOnly === false` |

**DS-deps.** `components/list-tile.css`, `components/input.css`, switch-atom *(még nincs DS-ben — TBD)*.

---

## 5. TIER 4 — egyszer szerepel, screen-specifikus

**Tier-besorolás-revízió (2026.05.24).**
- `MapWidget`, `LocationPicker` — eredetileg Tier-3.5 / Tier-2 listán szerepeltek;
  a D-7 nyomán a `LocationPicker` Tier-4 organism (A2 + jövőben A11),
  a `MapWidget` Tier-3.5 cross-cutting (két fogyasztó: LocationPicker + jövőbeli
  adatlap-térkép).
- `KpiCard`, `TeamPerformanceTable` — Tier-3 organism-ek, fájl-szinten léteznek.
- `WeeklyReportCard`, `StatusTrack` — Tier-3 organism-ek, fájl-szinten léteznek
  (2026.05.22 audit P0 alatt kiemelve).
- `ContentEditor`, `RichTextEditor`, `CoverImageUploader`, `PhotoGallery`,
  `PhotoUploader`, `PublishStateChip` — Tier-3 organism-ek, mind fájl-szinten
  (D-13 nyomán kiemelve a 8. lépés első iterációján).

Per organism: 1-2 mondat + a host-screen. **A Tier-4 a 2026.05.22 audit-meneten lezárva** — az alábbi organism-ek mind készek `organisms/`-ban, vagy explicit a screen-fázisra (8. lépés) halasztva.

- **`TriageBar`** *(A1 adatlap-header)* — A 4 triage-mező *(kategória, prioritás, határidő, felelős)*
  inline-szerkeszthető sávként. Spec: `10_bejelentes_lista_es_adatlap.md` 3.2.
- **`TicketMetaBar`** *(A1 adatlap / A2 új-bejelentés-form-header)* — Cím + cím-sor meta
  *(helyszín · bejelentő · beérkezve · azonosító)*.
- **`ActivityTimeline`** *(A1 adatlap sidebar)* — Spec: `00_domain_model.md` 1.4 `ActivityLog`.
- **`InternalNotesPanel`** *(A1 adatlap)* — `TicketNote` entitás megjelenítése + új-jegyzet form. Spec: `00_domain_model.md` 1.5.
- **`SimilarTicketsBox`** *(A3, az A1 adatlap-ban renderelve)* — Spec: `20_duplikacio_es_osszevonas.md` 3.
- **`ActionBar`** *(A1 adatlap-alján)* — Státusz-akció-cluster *(állapotgép-spec szerinti megengedett akciók)*.
- **`TicketCreateForm`** *(A2)* — Új-bejelentés form. Lehet, hogy ez nem-szigorúan-manager organism, mert a polgári app-ban is hasonló mezők — DS-promóció jelölt.
- **`TeamPerformanceTable`** *(A4)* — Csapat-tábla név × lezárt × folyamatban × átl. lezárási idő. **D-16 (2026.05.24) hatása:** üj `rows[].isTopPerformer: boolean` mező — a hét csillaga (`max(resolvedThisWeek)` egy-tagú szűrés esetén) a sor jobb-szélén vizuális jelzéssel. Megnevezés a screen-mock-on: **„Terepi csapat-teljesítmény”** (nem „csapat” általánosan).
- **`PdfPreview`** *(A5 adatlap)* — Beágyazott PDF-iframe.
- **`CategoryTreeEditor`** *(A6)* — Kétszintű fa-szerkesztő. Layout-döntés: drag-drop vs. inline-add.
- **`IconPicker`** *(A6)* — A kategória `iconRef` választó (előre definiált szett).
- **`GroupMemberList`** *(A7 adatlap)* — Csoport-tag-lista add/remove-vel.
- **`UserPicker`** *(A7 tag-felvétel)* — `TenantUser`-keresés + select.
- **`UserInviteDialog`** *(A8)* — E-mail + szerepkör-választó. Spec: `20_felhasznalokezeles.md`.
- **`RoleEditor`** *(A8 adatlap)* — Felhasználó szerepkör-listájának szerkesztése *(több jelölhető)*.
- **`LogoUploader`** *(A9)* — A tenant `logoFileRef` feltöltése.
- **`TenantInfoForm`** *(A9)* — Tenant-alapadatok form.
- **`RichTextEditor`** *(A10, A11)* — D-13 nyomán Tier-3-ra promotálva (lásd fenti szekció).
- **`CoverImageUploader`** *(A10, A11)* — D-13 nyomán Tier-3-ra promotálva (lásd fenti szekció).
- **`DateTimeRangePicker`** *(A11)* — D-15 nyomán Tier-3-ra promotálva (lásd fenti szekció).
- **`LinkValidator`** *(A12)* — A CityInfo URL érvényesítés + favicon-grab; D-13 nyomán Tier-3-ban implementálva.
- **`ReorderableList`** *(A12 + A6 fa-rendezés)* — Explicit kihagyva: a `CategoryTreeEditor` inline absorbeálta a drag-grip-et (D-8); az A12 cityinfo-listán külön drag-organism szükségtelen.
- **`PublishStateChip`** *(A10/A11/A12)* — D-13 nyomán Tier-3-ra promotálva.
- **`MergeConfirmDialog`** *(A3)* — A `ConfirmDialog` specifikus message-tartalma + két-Ticket-summary.
- **`RejectionDialog`** *(A1)* — A `ConfirmDialog` specifikus body-formja: strukturált indok-dropdown + szabad szöveg.
- **`ReopenDialog`** *(A1)* — A `ConfirmDialog` specifikus body-formja: kötelező indok.

---

## 6. Az építési sorrend

> **Státusz (2026.05.22 audit).** Az 1–5. menet **lefutott** — az alsó sorrendi tábla a történeti terv, nem a végrehajtási globális státusz. Tier-besorolási finomítások az audit után: a `MapWidget` és `LocationPicker` ide-oda mozgott Tier-3.5/Tier-4 között; a `KpiCard` Tier-3-ban él, de D-12 nyomán `organisms/kpi-card.jsx`-fájlon; a `StatusTrack` és `WeeklyReportCard` szintén Tier-3-ban él, az audit utáni cleanup nyomán már szintén `organisms/`-ban fájl-szinten.

A `SITEMAP.md` 3. szakasz tier-besorolása + a függőségi gondolat: az `AppShell`
és `PageHeader` nélkül nem létezik screen, ezért ezek mennek először.

### 1. menet *(Tier 0)* — a "screen-építhetőséget" teremti meg
1. `AppShell` *(LeftNav + TopBar együtt)*
2. `PageHeader`
3. `EmptyState`

→ Egy validáló screen *(legegyszerűbb: az új `/beallitasok/altalanos` form-screen csak header + 1 SettingsSection-nel)*.

### 2. menet *(Tier 1)* — cross-cutting + form-screen foundation
4. `UserChip`
5. `SettingsSection`
6. `SettingsSubNav`
7. `ConfirmDialog` *(+ Rejection/Reopen/Merge bodies)*

→ Validáció: a Beállítások / Általános in-context screen *(SettingsSection × N + UserChip)*.

### 3. menet *(Tier 2)* — lista-screen család
8. `DataTable` *(+ pagination + density + selectable)*
9. `FilterPillBar`
10. `TabFilter`

→ Validáció: a Bejelentés-lista in-context screen *(TabFilter + FilterPillBar + DataTable)*.

### 4. menet *(Tier 3, ág-specifikus)*
11. `StatusTrack` *(A1 adatlap + DS-promóció előkészítése)*
12. `KpiCard` *(A4 Dashboard)*
13. `ContentEditor` + `PublishStateChip` *(A10/A11/A12)*
14. `WeeklyReportCard` *(A4/A5)*
15. `RecipientList` *(A5/A9)*
16. `PhotoUploader` / `PhotoGallery` *(A1/A2/A10/A11)*

### 5. menet *(Tier 4, screen-specifikus)*
17. `TriageBar`, `TicketMetaBar`, `ActivityTimeline`, `InternalNotesPanel`, `SimilarTicketsBox`, `ActionBar`
18. `CategoryTreeEditor`, `IconPicker`, `GroupMemberList`, `UserPicker`, `UserInviteDialog`, `RoleEditor`
19. `LogoUploader`, `TenantInfoForm`, `RichTextEditor`, `CoverImageUploader`, `DateTimeRangePicker`, `LinkValidator`, `ReorderableList`
20. *(többi menet közben, screen-igény szerint)*

### 6. menet — Screen-mock-ok
A 12 admin screen mint vékony composition. Mind a 6 + 2-3 dialog-screen, a hierarchia szerint a Tier-3/4 organism-eket is itt fogyasztja.

### 7. menet — Átadási csomag
`HANDOFF.md` + `starter/` Angular-projekt-scaffold (PrimeNG Aura + Tailwind v4
integrációval, 1-2 demó-screennel mintaként). Per-organism Angular-skeleton
+ PrimeNG-mapping táblázat. A fejlesztő ezzel tudja a többi screent kódolni.

---

## 7. Mit teszünk félre most

- **Részletes interaktivitás** — kattintható prototípus, állapot-management. A
  mockok statikus React-komponensek; az állapot-variációkat külön props-példánnyal mutatjuk.
- **Mobile-reszponzív** — a manager felület desktop-first, a mobil az A1 spec
  szerint a triage-folyamatra korlátozódik *(`00_architektura_v4.md` 5.1)*.
  Ezt a Tier-4-es menet végén nézzük.
- **i18n** — minden szöveg magyar, hardcoded. A Claude Code majd a `hu.json`-be
  emeli; itt csak látszik a végeredmény.
- **Dark mode** — pilotban nincs.
