Commit Graph
6 Commits
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 1ff1873b27 feat(i18n): Konto, Editor und Karte auf Englisch
Task 10: alle sichtbaren Texte von account/, editor/, card/ und der Seite „Passwort neu setzen“ (Texte, aria-label, title, Meldungen,
Rückfragen) gehen durch t()/msg(); en.ts bekommt 87 Einträge.

- account/: Konto-Menü, Login-Dialog (Titel, Reiter, Felder, Meldungen) und errors.ts (errorMessage übersetzt beim Zurückgeben).
  validatePassword nutzt {min}/{max}. Der Login-Dialog wird nur einmal gebaut: die Beschriftung des Schließen-Knopfs wird bei jedem
  Öffnen in der aktuellen Sprache gesetzt. LOGIN_NEEDED und DEFAULT_CARD_NAME bleiben deutsche Konstanten (msg), angezeigt werden sie
  mit t(); der Standardname einer neuen Karte folgt damit der Sprache („My card“).
- editor/: Vorlagen-, Options- und Vorschauspalte, Bild-Upload, Speichern, Download, Rückfragen. Konstanten (upload.ts, download.ts,
  editor-page.ts) bleiben deutsche Strings per msg(); validateImageFile, pngSizeWarning und das Speichern („Speichern fehlgeschlagen –
  {reason}“) liefern den Text schon übersetzt, Fehler tragen weiter die deutsche Konstante (Vergleiche mit READ_MESSAGE/PIXELS_MESSAGE
  gehen weiter) und werden beim Anzeigen mit t(error.message) übersetzt. Zoom „100 %“ / „100%“ und „Bearbeitet: {name}“ mit Platzhaltern.
- card/: Bezeichnungen der Marken (msg) und die Meldungen des Renderers (msg, Anzeige im Editor über t()).
- pages/reset-page.ts, account/login-dialog.ts: Die Meldung „Die Passwörter stimmen nicht überein.“ ist nicht mehr der Schlüssel zum
  Fokus: es zählt die Bedingung selbst, nicht der Vergleich mit dem (nun übersetzten) Text.
- i18n/coverage.test.ts: Heuristik für deutsche Text-Literale außerhalb von t()/msg() (Umlaut/ß, mindestens zwei Wörter, einzelnes
  großgeschriebenes Wort; gelesen wird der Syntaxbaum) für account/, editor/, card/ und pages/reset-page.ts; Ausnahmen mit Grund, jede
  muss noch zutreffen; Scanner mit eigenen Tests. Die Liste der Bereiche ist eine Konstante für Task 11.
- i18n/english-ui.test.ts (neu): Stichproben auf Englisch (Konto-Menü, Login-Dialog, Passwort-Seite, Editor inkl. Fehlerwege) und
  „kein deutscher Wörterbuchtext auf der englischen Seite“.
- test-setup.ts: Wer Module mit vi.resetModules() frisch lädt, bekam eine neue Kopie von i18n.ts mit der Browsersprache (happy-dom: en-US);
  der Browser meldet im Test jetzt Deutsch, damit auch diese Tests deutsch beginnen. main.test.ts: nach dem Wechsel auf Englisch heißt
  der Knopf des Konto-Menüs „Sign in“.
- Tests: Vitest 53 Dateien, 1779 Tests grün, tsc und Build sauber.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 23:58:49 +00:00
ClaudeandClaude Opus 5.5 0be5abd954 feat(card): Marken-Logos entfernt, Community-Logo unten rechts im Renderer
- card/config.ts: network und das Apple-Logo entfallen. CardConfig.logo ist die ID eines Community-Logos (Muster ID_PATTERN,
  sonst null), DEFAULT_CONFIG.logo = null, serializeConfig schreibt {v, template, logo, details, brand, crop}. Ein altes network
  wird ignoriert, brand 'apple' fällt auf den Standard. ID_PATTERN steht jetzt hier (die reine Konfiguration prüft die Logo-ID,
  ohne Appwrite zu laden), account/cards.ts reicht sie weiter; single-sources.test.ts sorgt für genau eine Definition.
- card/geometry.ts: fitLogo und LOGO_MAX_H (125) ersetzen fitNetwork, Layout.network heißt Layout.logo.
- card/marks.ts: nur noch die AirCard-IOS-Marken (BRAND_MARKS, getBrandMark, svgAspect, tintSvg, loadMarkImage). Die 19 SVGs
  der Netzwerke und von Apple sind per git rm gelöscht, ein Test hält assets/marks auf die zwei AirCard-Dateien.
- card/render.ts: LogoAsset, CardAssets.logo statt network, LoadedAssets.logoMissing. loadCardAssets(config, image, loadLogo =
  loadLogoAsset): ohne Logo kein Aufruf, null vom Lader ergibt logoMissing, ein Ladefehler wirft. Der Renderer zeichnet das
  Logo mit fitLogo(w / h) unten rechts, wenn Vorlage und Bilder eines haben.
- logos/logo-asset.ts (neu): loadLogoAsset(id, tone) holt Zeile (getLogo) und PNG (loadLogoBlob) und dekodiert mit
  createImageBitmap, sonst über ein Image. Einfarbige Logos werden in einem eigenen Canvas mit source-in in der Details-Farbe
  gefüllt, mehrfarbige bleiben. Fehlende Zeile, ausgeblendetes Logo (auch für Hochlader und Admins), Datei 404, unlesbare
  Datei und mehr als 1 000 000 Pixel ergeben null. Je (id, tone) ein Ladevorgang, ein Fehler bleibt nicht im Cache.
  rememberLogo, forgetLogo und LOGO_MISSING nach der Schnittstelle des Plans.
- editor/options-panel.ts: keine Netzwerk-Kacheln mehr, Überschrift „Logo oben links“ mit Symbol, Text und Kein Logo (ohne
  Apple), dazu logoSlot als leerer Platz oben für Task 8 (editor.css: Details rückt bei leerem Platz wie bisher nach oben).
- editor/editor-page.ts: logoKey aus Logo, Details und Marke, der Logo-Zustand hält missing. Fehlt das Logo, wird die Karte
  ohne es gezeichnet und der Hinweis LOGO_MISSING gezeigt, solange das so bleibt; ein Wechsel auf ein vorhandenes Logo oder
  auf kein Logo nimmt nur diesen Hinweis weg (PNG-Größe und „Bild fehlt“ stehen getrennt und bleiben). Kein LOGO_ERROR bei
  fehlendem Logo, nur bei echtem Ladefehler, auch beim Download.
- community/publish.ts: LOGO_MISSING_PUBLISH, renderForGallery (jetzt exportiert) bricht bei logoMissing vor dem Rendern ab,
  es wird nichts hochgeladen. publish-dialog.ts lässt den Text im Wortlaut durch.
- i18n/en.ts: englische Texte zu LOGO_MISSING, LOGO_MISSING_PUBLISH und „Logo oben links“.
- Tests: config, geometry, marks, render und die Fixtures von cards, theme, cards-page auf das neue Modell; neu
  logo-asset.test.ts (28) und options-panel.test.ts (10); editor-page (14 neue), publish und publish-dialog erweitert.
  Vitest 45 Dateien, 1319 Tests grün, tsc und Build sauber.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 20:32:45 +00:00
ClaudeandClaude Sonnet 5.5 89c86fd578 feat(community): Datenschicht für Galerie, API und Veröffentlichen
- gallery.ts: Galerie aus Appwrite lesen (Abfragen für Liste, Suche, Cursor, Admin-Filter),
  getGalleryCard (404 und ungültige ID ergeben null), eigene Veröffentlichungen, Meldungen, Bilder
- api.ts: Aufrufe von aircard-api mit JWT (Cache je Nutzer, 10 Minuten, geleert bei Auth-Änderung,
  genau eine Wiederholung bei 401), ApiError mit code, Netz-/Proxy-Fehler als 503
- publish.ts: rendern, zwei Uploads in gallery-images, API; bei Fehler genau die zwei Dateien
  dieses Versuchs löschen; normalizeTags
- cards.ts: eigenständiges fetchFile(bucketId, fileId); CardsApi.fetchFile bleibt Hülle
- appwrite.ts: IDS für gallery, reports, gallery-images

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:39:30 +00:00
ClaudeandClaude Opus 5.5 0c51689dfd fix(cards): Sitzung, Entwurf und Datei-Aufräumen beim Öffnen und Speichern
- Gäste/abgelaufene Sitzung: Appwrite antwortet mit 404; withLogin und
  openSavedCard melden dann an (Dialog, einmal wiederholen) statt
  „nicht gefunden“ zu zeigen.
- Öffnen einer Karte fragt vor dem Verwerfen eines ungespeicherten Entwurfs
  nach; ein fehlgeschlagenes Öffnen setzt einen gefüllten Editor nicht zurück.
- Update ohne Bildwechsel schickt kein imageFileId mehr (veralteter Stand
  zeigte sonst auf eine gelöschte Datei).
- Uploads werden nur nach eindeutiger Ablehnung (4xx ohne 408/429) gelöscht,
  nicht bei Netzfehler, 5xx oder 429.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:01:28 +00:00
ClaudeandClaude Opus 5.5 38b361ad7a fix(cards): Editor an Karte und Konto koppeln (Neue Karte, Abmelden, Kontowechsel)
- Editor zeigt „Bearbeitet: <Name>“, solange eine gespeicherte Karte gebunden ist,
  und bietet „Neue Karte“ (setzt zurück, bricht Laden ab, entfernt ?karte=;
  fragt bei ungespeicherten Änderungen per eigenem Dialog „Verwerfen?“)
- EditorState.savedConfig als Vergleichsbasis für ungespeicherte Änderungen
- bindEditorToAuth: Abmelden leert den Editor, Kontowechsel A -> B entkoppelt die
  Karte (Entwurf bleibt), Anmelden ohne Vorgänger und abgelaufene Sitzung behalten
  den Entwurf; auth.onLogout unterscheidet eigenes Abmelden von bemerktem Ablauf
- Speichern nimmt den Schnappschuss pro Klick (auch für die Wiederholung nach 401)
- save: row_not_found beim Update legt eine neue Karte an (inkl. Aufräumen)
- Karten-Seite: Editor-Abgleich auch nach dem Verlassen der Seite, Löschen-Dialog
  wird beim Verlassen geschlossen, keine doppelten Vorschau-URLs
- confirm-dialog als gemeinsames Modul (Löschen, Verwerfen)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 09:32:19 +00:00
ClaudeandClaude Opus 5.5 ba4d9f76d4 feat(cards): Karten speichern und Meine Karten
- account/cards.ts: Kartendienst (neu/bestehend speichern mit Aufräumen halber
  Uploads, Umbenennen, Löschen, Laden) über ein schmales CardsApi-Interface,
  Appwrite-Anschluss mit 22.4.1-Objektparametern, fetchFile über
  client.prepareRequest (Projekt-Header + Cookie, kein getFileView)
- account/with-login.ts: bei 401 Nutzer neu prüfen, einmal anmelden, wiederholen
- editor/save.ts: Speichern-Ablauf (ein Lauf zur Zeit, 401 -> Login -> einmal
  wiederholen, deutsche Fehlermeldung)
- Editor: Speichern mit Schnappschuss und 480-px-Vorschau, Karte öffnen über
  ?karte=<id>, Bildwechsel während des Speicherns gesperrt
- pages/cards-page.ts: /karten mit Kacheln, Öffnen, Herunterladen, Umbenennen,
  Löschen (eigener Dialog), Abmelde- und Leer-Ansicht
- Tests für Dienst, withLogin, Speichern-Ablauf, Karten-Seite und Editor-Anbindung

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 09:18:27 +00:00