Commit Graph

50 Commits

Author SHA1 Message Date
Tim Leikauf
f5c7fbcd57 feat: prompt_styles + picture_jobs in CMT Datenbankübersicht
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 21:02:55 +02:00
e78be430c7 feat: Placeholder farbig markieren in Freigabe-View und Pair-Modal
Objekt-Placeholder indigo, Wort-Placeholder grün, geleakte ⟦PHn⟧-Tokens rot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 22:43:46 +02:00
96c436e0e9 feat: Published-Bilder ausblenden + Bild-Lösch-Button in Content Erstellen
Die Blätter-Ansicht lädt veröffentlichte Bilder nicht mehr (Filter beim
Laden/Reload, Entfernen beim manuellen Publish). Neuer 🗑-Button löscht
ein Bild komplett (S3 + DB inkl. Objekte und Pairs via API-Kaskade).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 21:27:57 +02:00
e383cacd45 feat: KI-Korrektur-Schritt in der Pipeline-Fortschrittsanzeige
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 21:41:35 +02:00
af00d3323d feat: Voice-Auswahl aus ElevenLabs-Account in den TTS-Einstellungen
Dropdown mit den Account-Stimmen (GET /tts-settings/voices/available)
plus Warnung, wenn die gespeicherte Voice-ID nicht im Account existiert
— so fällt eine ungültige Stimme (Ursache der fehlenden sv-Audios)
sofort auf statt still fehlzuschlagen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 21:04:13 +02:00
2cec5bc362 feat: 'Übersetzungen nachholen' + 'Audios nachholen' immer verfügbar
Beide Nachhol-Aktionen jetzt dauerhaft im Karten-Header (nicht nur bei
unvollständigen Pairs) — Reihenfolge Übersetzen → Audio, da Audio alle
Sprachen braucht.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 22:03:25 +02:00
ae25dc9428 feat: Objekt-Zuweisung + Audio-Nachholen in der Veröffentlichen-Ansicht
- Pro Pair: erkannte Objekt-Wörter als 🔗-Chips, ein Klick weist das Wort
  in allen Sprachen dem Objekt zu ({{wort.o:objectId}})
- '🔊 Fehlende Audios generieren' bei unvollständigen Pairs
- Bundle-Refresh nach Zuweisung/Audio-Fill

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 21:48:13 +02:00
86145941eb feat: Auto-Pipeline-Flow (Bild freigeben → Veröffentlichen-Übersicht)
- ContentCreation: '🚀 Bild freigeben'-Button startet die serverseitige
  Pipeline (Pairs → Übersetzung → Audio); Status-Chip pro Bild
- Veröffentlichen-Seite neu: Live-Fortschritt (Polling), pro Bild eine
  flache Karte mit Objekten, Pairs (3 Sprachspalten), Audio-Indikatoren,
  🚩-Flag zum Ausschließen, Ein-Klick-Publish des ganzen Bildes
- Settings: Pipeline-Sektion (Pairs pro Objekt)
- lib/pairRows.js: geteilte 3-Sprachen-Anzeige-Helfer (aus PairReviewModal)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:57:25 +02:00
11e3ce8770 feat: Geführter Pair-Review-Flow (Wizard) pro Objekt
'🚀 Review-Flow starten' läuft die Pairs des Objekts der Reihe nach durch:
Inline bearbeiten + speichern oder 'Speichern & übersetzen' (Prüf-Grid),
Reviewed/Blocked — danach automatisch das nächste Pair, bis alle durch sind.
Orchestrierungs-Hülle um EditPairForm + PairReviewModal, keine Logik dupliziert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 22:14:37 +02:00
2a6d203d1c fix: Negativ-Zeile im Review-Modal immer zeigen (fehlt sichtbar machen)
question/word-Pairs zeigen die Negativ-Zeile jetzt auch wenn leer ('fehlt'
statt stilles Ausblenden), damit eine fehlende Negativ-Antwort auffaellt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 22:14:28 +02:00
840996fce9 feat: 'Speichern & übersetzen' im Edit-Formular
Neuer Button im EditPairForm: speichert das Pair und öffnet direkt das
Übersetzen-&-Prüfen-Modal (handleSave({translateAfter}) → onSavedAndTranslate
→ handleTranslate). Bestehender Speichern-Button unverändert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 21:39:08 +02:00
350614d6e0 feat: '🔄 Neu übersetzen' im Review-Modal (überschreibt Zielsprachen)
Ruft /pairs/:id/translate mit overwrite:true, um falsche bestehende
Übersetzungen (z.B. SV) neu zu generieren, und lädt den Modal-Inhalt neu.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 21:29:20 +02:00
4fd9c3c4e4 fix: Review-Modal pro answer_type korrekt anzeigen
- word: 'Positiv-Wörter' / 'Negativ-Wörter' (statt irreführendem Satz-Feld)
- yes_no: Ja/Nein-Antwort als Einzelwert statt leerem Satz
- text/question: Sätze wie bisher

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 21:01:36 +02:00
ae94721466 feat: Pro-Pair Übersetzen-&-Prüfen mit Review-Modal
- PairReviewModal: zeigt Frage/Positiv/Negativ in de/en/sv (Wörter bei
  word-Typ) zum Gegenprüfen, mit Reviewed/Blocked-Buttons; bei 409 wird
  die missing-Liste inline angezeigt.
- ContentCreation: pro Pair-Karte '🪄 Übersetzen & prüfen' (ruft
  /pairs/:id/translate, öffnet Modal); nach Review werden Pairs, Objekte
  und Bilder neu geladen.
- api.js: Fehler-Payload (z.B. { missing }) wird am Error durchgereicht.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 14:28:10 +02:00
7680f4f9e3 feat: TranslationHub, Pair-Review-Button (Action-Bar), reviewed für Bilder
- TranslationHub (/translations): Coverage-Matrix, Batch-Übersetzen pro Tabelle×Sprache
- Pair Status: StatusSelect ersetzt durch Action-Bar ✓Reviewed/↩Draft/🚫Block,
  Reviewed kaskadiert via /pairs/:id/review (Backend prüft 3-Sprachen-Vollständigkeit)
- Top-Nav: 'Übersetzungen' zwischen Inhalte und Audio
- Dashboard: Übersetzungen-Kachel
- tables.js: pictures-Status um 'reviewed' erweitert

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 07:36:20 +02:00
9eecee9ace feat: Veröffentlichen-Seite, Einstellungen (TTS-Stimmen), klarere Navigation
- Navigation: Dashboard/Inhalte/Audio/Veröffentlichen/Datenbank/Einstellungen mit Active-State
- Veröffentlichen (/publish): Pairs sortiert nach 'am wenigsten fehlt', 1-Klick-Publish je Sprache
- Einstellungen (/settings): TTS-Stimme + Parameter pro Sprache bearbeiten
- tts-settings in DB-Admin; Dashboard-Kacheln ergänzt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 22:02:18 +02:00
465c6e4954 feat: Dashboard-Pipeline, AudioHub, WordGenerator, reviewed-Status
- Dashboard: Pipeline-Übersicht (Counts pro Status) + Werkzeug-Kacheln
- AudioHub (/audio): Coverage-Matrix je Tabelle×Sprache, Generieren-Buttons, Player
- WordGenerator (/content/words): Thema→KI-Vorschau→Übernehmen als translated
- reviewed in STATUS_COLORS + Status-Optionen (objects/questions/statements/pairs)
- audios-Tabelle um source_*/language erweitert

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 21:30:03 +02:00
232ba1ece5 feat: vollständiges DB-Admin-Tool mit Spalten-Toggle, Sortierung und FK-Auflösung
- Audios-Tabelle in TABLES-Config ergänzt
- Spalten dynamisch aus geladenen Daten abgeleitet; Sichtbarkeit per localStorage persistiert
- Spalten-Toggle-Dropdown mit Checkboxen und Reset
- Sortierung per Klick auf Spaltenheader (▲/▼)
- FK-Felder zeigen aufgelöste Labels statt rohe UUIDs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 13:24:46 +02:00
7564f23ef1 fix: use allObjects._words to restore objectAssignments on EditPairForm load
Replace async word search with synchronous lookup via allObjects._words,
which is already populated. Eliminates race conditions and fetch failures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 22:19:56 +02:00
08d22a1440 fix: restore objectAssignments during load by fetching word IDs directly
Instead of waiting for the wordMap effect to reconcile, look up word IDs
for each label→objectId pair immediately in load() so objectAssignments
is set before the user sees the form.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 22:12:48 +02:00
93975f40c7 fix: restore objectAssignments in EditPairForm on load
Extract {{label.o:objectId}} refs from raw sentence text before resolving
placeholders, then reconcile with wordMap once it's built so the object
assignment dropdown reflects the saved state on re-open.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 22:08:47 +02:00
4d618bd5b3 fix: prevent pronouns/function words from being detected as vocabulary
- fuzzyMatch threshold 0.6 → 0.85 (man/Mann 0.75 now fails)
- min token length 2 → 4 (excludes man, der, die, das, ich, wir...)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 21:53:59 +02:00
c595cbb448 feat: status dropdowns, difficulty badges, published=violet
- STATUS_COLORS: published → violet, draft → gray
- StatusSelect: shared dropdown component with status colors
- Top bar: picture status dropdown (uploaded/published/blocked)
- ObjectListPanel: per-object status dropdown, changeable inline
- PairsPanel collapsed: difficulty badge (Leicht/Mittel) + status badge
- EditPairForm: status dropdown at top of edit form

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 21:45:31 +02:00
acc15849f3 feat: add word-type pairs + difficulty_level to auto create
- Claude now generates 40 pairs: +10 × word type (positive_words / negative_words)
- difficulty easy→1, medium→2 stored as difficulty_level on each pair
- findOrCreateWord() looks up or creates words by title before linking
- savePairsForObject handles all 4 pair types (text/yes_no/question/word)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 21:31:08 +02:00
b39a3cca9f refactor: auto pairs now loops all objects, no selection needed
Button moves to ObjectListPanel (visible when ≥1 object exists).
One Claude call per object — image + that object's words & coordinates.
Progress shows "Objekt 2/3 — Pair 12/30". Pair saving logic extracted
into shared savePairsForObject() helper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 21:15:01 +02:00
d7ba2c2c47 refactor: route Claude API call through backend proxy
Removes direct browser→Anthropic call (CORS issue).
Now calls /api/claude/generate-pairs on the snakkimo-API,
which holds the API key server-side.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 21:00:37 +02:00
8d514170c7 feat: auto create pairs via Claude Haiku AI
Adds " Auto Pairs erstellen" button to the PairsPanel. On click,
sends the image and all object coordinates to Claude Haiku, which
returns 30 structured pairs (10× text, 10× yes_no, 10× question,
each split easy/medium difficulty) as JSON. Pairs are then created
and linked via the API with a live progress indicator.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 17:57:54 +02:00
51588f291c Fix JSX ReferenceError: escape {{wordId}} literal in option text
{{wordId}} in JSX is parsed as a JS expression trying to resolve the variable
`wordId`. Wrap in a string expression so it renders as literal text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 14:59:39 +02:00
399b59dc87 Fix white-page crash in PairForm word detection
- tokenize(): add try/catch + filter empty/null parts so a bad regex never
  propagates to the React render tree
- Word detection useEffect: wrap entire async block and each per-token fetch
  in try/catch; filter null/malformed word objects out of the map before
  setWordMap() so the render never receives w.id === undefined
- "Erkannte Wörter" sections in PairForm and EditPairForm: filter wordMap
  entries where w?.id is falsy; use (allObjects || []) defensively
- handleCreateWord: only update wordMap when the API response contains w.id
- After successful save in PairForm: reset all text/word state so the form
  starts clean for the next pair

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 14:55:34 +02:00
da3d7319a6 feat: delete pair button in EditPairForm with confirmation
Two-step: "Pair löschen" → confirm "Wirklich löschen" before DELETE /pairs/:id.
On success closes the form and reloads the pairs list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 14:40:38 +02:00
d57313084f fix: robust placeholder resolution + readable pair cards
- resolvePlaceholders: replace fragile [wo] char class with general
  /^(.+?)\.[a-z]+:[0-9a-f-]{36}$/i — handles any type prefix safely
- Add sync stripPlaceholders() helper for card display (no async needed)
- PairsPanel cards now show actual sentence text instead of UUID stubs,
  using enriched pair.question / pair.positive_statement data from API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:46:06 +02:00
f739f529e9 feat: new placeholder format, fuzzy word detection, editable word input
- Placeholder format: {{Hund.w:uuid}} / {{Hund.o:uuid}} — label embedded,
  no API lookup needed on render/edit load
- resolvePlaceholders handles both new format (fast) and old {{uuid}} (fallback)
- Word auto-detection: fuzzy match via search API + client-side starts-with
  + 60% length ratio (e.g. "Hunde" matches "Hund")
- "Als Wort erstellen" now shows editable input pre-filled with selection,
  user can correct before saving

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 14:55:29 +02:00
29786c531b feat: complete tables config — all tables, all fields, boolean type
- Add missing tables: languages, users, blocklist, user-names, users-public
- Fix categories field names (name_de → titel_de/en/sv)
- Add missing fields: objects_created, sentence_sv, answer, negative_statement_id, etc.
- Fix pairs answer_type options (yes_no/text/question/word)
- Add boolean field type support in RecordModal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 18:19:58 +02:00
8242dab18c feat: unified ContentCreation tool (Object + Statement creation merged)
- New ContentCreation.jsx: 3-column layout
  Left: object list + "+ Objekt hinzufügen" button
  Center: dual-mode canvas (draw OR highlight)
  Right: ObjectAddPanel (mode=add) or PairsPanel (mode=objectId)
- After saving object → auto-switches to PairsPanel for that object
- All ObjectCreation + StatementCreation logic merged into one page
- All pictures loaded (no objects_created filter)
- "Objekte abgeschlossen" button marks picture (visual badge)
- ContentHub: 2 tiles (Content Erstellen + Veröffentlichen placeholder)
- App.jsx: /content/creation route, old /content/objects + /content/statements removed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 17:28:16 +02:00
6cdf09707a feat: edit existing pairs inline in PairsPanel
- EditPairForm: loads question + statement text (resolves {{uuid}} back
  to word titles via resolvePlaceholders), pre-fills all fields
- Per-type editing: text/yes_no/question/word with same UX as create
- Word link diff on save (add new, remove removed via apiUnlink)
- Creates missing question/statement records if type or content added
- ✏️ button per pair card opens EditPairForm, replaces card inline
- onPairsReload: re-fetches pairs list after edit saved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 16:32:28 +02:00
aa4b37c3a4 feat: object assignment per word placeholder in statements
- withPlaceholders(text, wordMap, objectAssignments) — uses {{objectId}}
  when an object is assigned to a word, otherwise {{wordId}}
- PairForm: objectAssignments state (carried over between saves)
- Detected words section shows object dropdown per word
  — only objects from current picture that have the word linked
  — shows "Objekt #N — word1, word2" labels
  — unselected = {{wordId}}, selected = {{objectId}}

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 16:25:58 +02:00
6c730889be fix: word detection + highlighting for all pair types
- Remove needsWordDetection guard — wordMap always populated
- "Als Wort erstellen" banner shown for all types
- Erkannte Wörter indicator shown for all types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 16:14:35 +02:00
0c816d3f2d refactor: PairForm — single type dropdown, 4 variants, carry-over behavior
- answer_type is now a single value (text/yes_no/question/word)
- Dropdown replaces checkboxes, per-type field sections
- Text: only positive statement
- Yes/No: optional question + answer picker
- Question: question* + positive* + optional negative
- Word: optional question + word pickers
- After save: texts/words carry over, type resets for next pair
- Fix: closed missing div in PairsPanel scroll container

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 16:11:02 +02:00
99ca1c58c2 fix: make PairsPanel fully scrollable including PairForm
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 20:54:51 +02:00
25c31adbdf feat: rework PairForm — 3 checkboxes, validation logic, word pickers
Replaces the answer_type dropdown with 3 independent checkboxes:
- Text: positive statement required; negative requires question+positive;
  question is optional standalone; auto-detects words + {{uuid}} placeholders
- Ja/Nein: addon, adds answer field (null/true/false) to positive statement
- Wort: opens positive/negative word pickers → linked via statement_positive/negative_words

Validation rules:
- At least one type must be checked
- Text: positive statement non-empty
- Negative statement only allowed when question + positive both filled

Word creation: highlight text in any field → 'Als Wort erstellen' button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 20:50:18 +02:00
c92191db63 feat: Statement Creation + objects_created workflow + native language
ObjectCreation:
- Filter: only shows pictures where objects_created=false
- New '✓ Alle Objekte erstellt' button (enabled when ≥1 object linked)
  → PATCHes picture with objects_created:true + auto timestamp
  → removes picture from list immediately

ContentHub:
- Statement Creation tile enabled (was: grayed out)

api.js:
- getUserLang() → reads native_lang from stored user (default 'de')
- langField(suffix) → returns e.g. 'sentence_de' based on user lang
- login() stores native_lang in localStorage user object

StatementCreation (/content/statements):
- Shows pictures where objects_created=true
- Left 1/5: clickable objects list → highlights selections on canvas
- Center 2/5: image with canvas, draws selected object's polygons in color
- Right 2/5: PairsPanel
  - answer_type dropdown + 'Add new pair' toggle
  - PairForm: Question / Positive / Negative textareas
  - HighlightedTextarea: overlay technique, auto-detects words from DB
    (debounced GET /words?titel_de=, colored mark via rgba background)
  - 'Als Wort erstellen' button when text is selected
  - 'Save pair' → creates question + 2 separate statements + pair
    → sentences stored with {{uuid}} placeholders for matched words
    → pair linked to selected object
  - List of existing pairs with question/positive/negative preview

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 19:23:50 +02:00
e1d5390386 feat: Content Verwaltung — ContentHub + Object Creation
Adds a full Content Management section:
- Nav link "Content" in header (all pages)
- ContentHub at /content with 3 tiles (Object/Statement/Content Creation)
- ObjectCreation at /content/objects:
  - Top bar: ← → pagination through all "uploaded" pictures
  - Left panel (1/5): existing objects per picture with their words, + button to start draw mode
  - Center: image on dark bg with canvas overlay for polygon drawing
  - Right words panel (1/5): picture words + new object words (each with search/create)
  - Right toolbar (1/5): draw instructions, "Auswahl hinzufügen", numbered selections list, "Objekt speichern" (requires ≥1 selection + ≥1 object word)
- Canvas drawing: click=add point, dblclick=close polygon, live preview line to mouse cursor
- Selections stored as [{points:[{x,y},...]}] (relative 0-1 coords) in objects.selections JSONB
- Object saved with status "draft", linked picture + words

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 21:53:23 +02:00
6c8eaab034 feat: delete rows via trash icon in all tables
Each row gets a trash can button that appears on hover. Clicking it
shows an inline confirm (✓ / ✕) to prevent accidental deletion. On
confirm, calls DELETE /endpoint/:id and removes the row from state.
If the deleted record is open in the modal, the modal closes too.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:24:37 +02:00
211bd464d2 feat: picture modal hero panel with image preview
Adds a split-layout hero section at the top of the RecordModal
for pictures: left side shows the image preview (~40%), right side
shows status, design (both editable) and the linked words relation
manager inline. Remaining fields (blurhash, picture_link, metadata)
continue to appear in the sections below.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 08:54:03 +02:00
3c59713c25 Use server-side ?search= API instead of client-side filtering
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:50:53 +02:00
bdf3bd590e Fix relation search: fetch limit=500 instead of 20 for client-side filtering
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:48:52 +02:00
a02705734d Add relation manager: link/unlink records directly in modal
- RelationManager component: shows linked items as removable tags,
  live search to find and add new links (×-button to unlink)
- tables.js: full fetchRelated config with linkEndpoint + searchEndpoint
  for words↔pictures, words↔categories, objects↔words, objects↔pictures
- api.js: add apiLink, apiUnlink, apiDelete helpers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:43:48 +02:00
a8ff541117 Add create modal for words and pictures tables
- + Button in TableView for tables with a create form (words, pictures)
- Words: form with titel_de/en/sv + difficulty_level → POST /words
- Pictures: design field + image uploader → POST /pictures then POST /pictures/:id/upload
- Image drag-drop area with preview before upload, sends multipart to Hetzner via API
- New record prepended to table on success
- apiPost + apiUpload helpers added to api.js

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:17:55 +02:00
e6c86a97fc Add RecordModal: row-click detail popup with inline editing
- Click any table row to open a full-detail popup
- Editable fields (text, textarea, select, number) with PATCH save
- Read-only display for IDs, timestamps, arrays
- Pictures table fetches words via /pictures/:id/words in modal
- Stop propagation on linked-field chips so they don't trigger modal
- apiPatch + apiFetchOne helpers in api.js
- editableFields + fetchRelated config in tables.js

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 21:53:45 +02:00
74082cd333 Initial commit: snakkimo CMT
React + Vite + Tailwind dashboard with:
- Login (JWT via snakkimo auth)
- Dashboard with Datenbankverwaltung + Contentverwaltung tiles
- Table overview with record counts (total, published, blocked)
- Table record viewer with text/status filters and linked field navigation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 21:29:12 +02:00