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>
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>
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>
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>
- + 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>
- 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>
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>