Commit graph

68 commits

Author SHA1 Message Date
aca014af94 Trigger: Deploy — Offline-Faehigkeit (Datenspiegel, SW-Fallback) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
2026-08-31 19:11:15 +02:00
a108664854 App ohne Netz lesbar statt "Failed to fetch"
Gemeldet: die App zeigte beim Oeffnen nur "Failed to fetch", waehrend das
Teilen aus WhatsApp weiter ging. Deploy und API waren in Ordnung — die
Meldung ist die rohe Browserausgabe eines fetch(), das gar nicht bis zum
Server kam, und stand 1:1 im UI, weil die Routen im catch e.message
anzeigten. Das Teilen fiel nicht auf, weil share.html sich die letzten
Auftraege seit eaad796 lokal merkt; die Hauptapp hatte fuer die Listen
keinen Offline-Fallback.

- api.js uebersetzt Netzfehler in einen eigenen Fehler mit offline=true
  und deutschem Text; 4xx/5xx bleiben Serverfehler
- isTransient() in offline.js erkannte Netzfehler an "instanceof TypeError".
  Ohne Anpassung waere ein Foto aus dem Funkloch als dauerhaft
  fehlgeschlagen gewertet und nach sechs Versuchen in Quarantaene gelandet
- Datenspiegel in IndexedDB: Auftrags-, Kunden- und Berichtsliste sowie
  geoeffnete Details (letzte 30). Ohne Netz wird der Stand angezeigt,
  mit Band "Kein Netz — Stand von HH:MM Uhr", und die Suche filtert darin
- beim Abmelden wird der Spiegel geloescht (geteiltes Geraet)
- sw.js: der Same-Origin-Zweig endete auf caches.match(); fand der Cache
  nichts, wurde respondWith(undefined) aufgerufen und die Anfrage
  scheiterte erneut mit genau der Meldung, die verhindert werden sollte.
  Jetzt immer eine echte Response, nur vollstaendige Antworten im Cache
- Precache nach Deploy: die Seite meldet dem Worker ihre echten Asset-URLs,
  sonst ist der Cache direkt nach einem Deploy leer (?v=<mtime>)

Muster aus KB #1037 und #1041. Verifiziert auf der lokalen Testinstanz
inklusive echtem Funkloch (setOffline + reload): App startet aus dem
Cache, zeigt Band und Auftragsliste, keine JS-Fehler.
2026-08-31 19:07:09 +02:00
Eddy
eaad796ab6 Teilen-Seite merkt sich die letzten Aufträge — Serie kostet nur noch einen Tipp [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
Wenn die Kundin drei Nachrichten hintereinander schickt, musste man den Auftrag
bisher jedes Mal neu heraussuchen. Jetzt stehen die letzten drei benutzten
Aufträge unter "Zuletzt benutzt" ganz oben.

Wurde einer davon in den letzten 30 Minuten benutzt, ist er vorausgewählt und
der Knopf ist sofort scharf ("In SO2608-0044 ablegen") — die zweite und dritte
Ladung kosten damit einen einzigen Tipp. Nach Ablauf der 30 Minuten steht der
Auftrag nur noch als Schnellzugriff da, ohne Vorauswahl: eine dauerhafte
Vorauswahl würde irgendwann still im Auftrag von vorgestern landen, und die
Auftragsnummer steht deshalb auch immer im Knopftext.

Die Merkliste (IndexedDB 'share_recent_orders') wird beim erfolgreichen Ablegen
fortgeschrieben, neuester zuerst, ohne Duplikate, maximal drei Einträge.
Kartenaufbau und Auswahl-Logik liegen jetzt in gemeinsamen Helfern
(karteHtml/bindeKarten/waehleAuftrag), damit Schnellzugriff und Suchtreffer
denselben Auftrag synchron markieren.

Lokal durchgespielt: erste Ladung ohne Merkliste (keine Vorauswahl), zweite
direkt danach (vorausgewählt, ein Tipp, landet im selben Auftrag), und ein
drei Stunden alter Eintrag (Schnellzugriff sichtbar, aber Knopf grau).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 20:19:37 +02:00
Eddy
b7e80fac8c Doku-Drift beseitigt: Push-Notifications, Heute-Route, drei API-Endpunkte fehlten
Beim Doku-Abgleich (/docs) gegen den Code aufgefallen:
- ntfy-Push-Notifications sind laengst fertig (app.js Einstellungen-Route),
  README fuehrte sie noch unter "Geplant" als offen
- "Heute"-Ansicht (Route /today, Google-Maps-Tagesroute) fehlte komplett
- API-Abschnitt: verify.php, logout.php, orders.php?action=create und
  config.php wurden von lib/api.js schon lange genutzt, standen aber nicht
  in der Endpunkt-Liste

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 20:12:31 +02:00
Eddy
707638808c Teilen aus WhatsApp: Bilder UND Text landen jetzt wirklich im Auftrag [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
Jeder Teilen-Vorgang endete bisher in einer Sackgasse — Login-Hinweis oder
"Keine geteilten Fotos gefunden", und danach war das Geteilte weg. Zwei Ursachen:

1. share.html prüfte api.getToken() — ein JWT in IndexedDB, das es seit der
   SSO-Umstellung nicht mehr gibt (api.login() legt nur noch 'user' ab, die
   Sitzung steckt im HttpOnly-Cookie awl_sso). Der Wert war immer leer, also kam
   IMMER "Bitte zuerst anmelden"; der Weg "Zur App" verwarf das Geteilte.
   Jetzt: Cookie-Prüfung über api/verify.php wie in ensureAuth(), und die
   Anmeldung (Passwort + Passkey) läuft IN der Teilen-Seite — das Geteilte bleibt
   dabei gesichert und der Ablauf geht danach direkt weiter.

2. Der Service Worker sicherte nur Dateien. Titel, Text und Link aus dem
   share_target wurden weggeworfen, ein reiner Text-Share schrieb gar nichts.
   Jetzt wird das ganze Paket gesichert und immer weitergeleitet (absolute
   Redirect-URL, leere File-Platzhalter fliegen raus).

Die Teilen-Seite zeigt Bildvorschau, Betreff und Text zum Nachbessern und eine
Auftragssuche (ohne Suchbegriff die offenen Aufträge, mit Suchbegriff alle).
Beim Ablegen gehen die Bilder über die normale Upload-Queue (Persist-First),
der Text wird als notiz_*.txt über api/note.php gespeichert. Scheitert die
Notiz (kein Netz), bleibt der Text gesichert und der Vorgang ist wiederholbar.

Dazu ein Banner in der App, wenn noch ein Paket unabgelegt bereitliegt —
abgebrochene Vorgänge findet sonst niemand wieder. share.html liest auch den
alten IndexedDB-Schlüssel, damit der erste Share nach dem Deploy (noch alter
Service Worker) nicht verlorengeht.

Lokal durchgespielt: Bild+Text, nur Text, und abgemeldet teilen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 18:03:46 +02:00
Eddy
c2bf4e7c30 Background Sync, volle Kameraqualitaet, Persist-First streng [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
Drei Sachen, die zusammengehoeren — alle drei Ursachen dafuer, dass Fotos
fehlten oder nichts drauf zu erkennen war.

1. BACKGROUND SYNC (sw.js)
   Nachliefern lief bisher NUR in der offenen Seite: online-Ereignis,
   „wieder sichtbar", 15-Sekunden-Takt. Display aus oder App weggewischt =
   eingefrorene Timer, es passierte nichts. Der Service Worker haengt sich
   jetzt an dieselbe IndexedDB-Queue und laedt selbst hoch; die Anmeldung
   steckt im HttpOnly-Cookie awl_sso und geht bei same-origin automatisch mit,
   also braucht es dort kein Token-Handling.
   - geloescht wird nur bei bestaetigtem Upload: 2xx UND application/json UND
     relpath. 2xx mit HTML (Proxy/abgelaufene Anmeldung) gilt als Fehlschlag
   - bleibt etwas offen, wird das Sync-Versprechen abgelehnt -> der Browser
     stellt erneut zu
   - Erfolg meldet der SW per postMessage an die App (Badge/Miniaturen)
   - periodicSync zusaetzlich, falls der Browser ihn gewaehrt

2. VOLLE KAMERAQUALITAET (app.js)
   Ausgeloest wird jetzt ueber ImageCapture.takePhoto() — das liefert die
   native JPEG-Datei der Kamera in Sensoraufloesung samt EXIF, statt ein
   Standbild aus dem Video-Stream abzugreifen. Kann der Browser das nicht,
   bleibt das Standbild als Rueckfallebene (dann mit Qualitaet 0.95 statt 0.92).
   Verkleinert wird nur noch, wenn es im Admin eingestellt ist (Vorgabe: nein).

3. PERSIST-FIRST STRENG (app.js)
   Das Foto geht unveraendert und als allererstes in die Queue; Verkleinern
   passiert erst DANACH und ersetzt den Eintrag nur bei Erfolg
   (offline.replaceQueuedBlob). Vorher lag das Verkleinern davor — und weil es
   bei ausgeschaltetem Display haengen bleibt, war das Foto in dem Moment
   nirgends gesichert. Genau so gingen am 28.08. acht Fotos verloren. Jetzt
   kann nach dem Sichern nichts mehr passieren, was ein Foto kostet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 19:07:06 +02:00
Eddy
130d9d1ec3 Fotos gingen beim Screen-Aus verloren: Verkleinern konnte ewig haengen [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 14s
Eddy: „beim ersten Upload nach Screen schliessen kamen nicht mehr alle an, ich
habe noch die gruenen Labels gesehen, aber die Bilder waren nicht da".

Ursache: uploadPhoto() verkleinert das Foto, BEVOR es in die Queue geschrieben
wird. resizeImage() haengt an img.onload / canvas.toBlob und hatte keinen
Timeout — schaltet sich das Display ab, pausiert der Browser Decoding und
Canvas, es feuert weder onload noch onerror, das Promise loest nie auf. Damit
war das Foto NIRGENDS gesichert (nicht in der Queue, nicht am Server), und weil
die Galerie-Auswahl sequentiell laeuft, stand die komplette restliche Auswahl.
Deshalb hat auch nichts automatisch nachgeladen: es gab nichts nachzuholen.
An Auftrag (PROV105) fehlten so 8 von 19 Fotos.

- resizeImage() bekommt eine Schutzzeit (Promise.race, 15s): im Zweifel wird
  das unverkleinerte Original gesichert statt gar nichts
- Auswahl-Schleife: jedes Foto einzeln abgesichert, ein Fehlschlag blockiert die
  restliche Auswahl nicht mehr
- Wake Lock schon waehrend der Auswahl-Verarbeitung, nicht erst beim Sync — das
  Verkleinern ist genau die Stelle, die pausiert wurde. Refcount, weil sich
  Auswahl-Schleife und Sync verschachteln

Schutzzeit isoliert geprueft (haengendes Decoding simuliert): faellt nach der
Frist auf das Original zurueck statt zu blockieren.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 18:58:35 +02:00
Eddy
65bc09d9f1 Upload-Serie: Screen-Aus bricht nicht mehr ab, Duplikate erkannt [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 16s
Schaltet sich das Display waehrend einer Foto-Serie ab, friert der Browser die
laufenden fetch-Aufrufe ein — die halbe Serie blieb liegen, der zweite Anlauf
erzeugte Duplikate (28.08.2026, Auftrag PROV105: 11 doppelte Fotos).

- Wake Lock waehrend syncQueue(), inkl. Neuanforderung nach App-Wechsel
  (visibilitychange). Scheitert die Anforderung, laeuft der Sync unveraendert
  weiter — die Queue faengt Abbrueche ohnehin ab
- duplicate:true aus der Server-Antwort wandert durch das photo-uploaded-Event;
  die Miniatur zeigt dann „War schon hochgeladen" statt eines zweiten Fotos
- api.js: Kommentar auf den neuen Server-Vertrag gebracht (Bericht 1.6.0 legt
  identische Dateien nicht erneut ab, at-least-once bleibt Rueckfallebene)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 18:42:12 +02:00
Eddy
10d5f915df Trigger: Deploy Textnotizen + Thumbnails + eigene Dialoge [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 18:23:18 +02:00
Eddy
4a53ab0ebe Textnotizen, echte Thumbnails, eigene Dialoge, Bild-Cache
Textnotizen: neuer Punkt "Notizen (n)" am Auftrag, direkt unter der Sprachnotiz.
Liste mit Betreff, Vorschau und Zeitstempel; antippen oeffnet die Notiz zum Lesen und
Aendern, loeschen mit Rueckfrage. Gespeichert wird ueber api/note.php als
notiz_<betreff>_<datum>.txt im Auftragsordner - derselbe Weg wie bei der Sprachnotiz,
damit die Notiz auch im Dolibarr-Auftrag und in der Anhaenge-Spalte des Bericht-Editors
auftaucht. In "Weitere Dokumente" sind Notizen ausgefiltert, sie haetten dort doppelt
gestanden.

Fotokacheln laden jetzt serverseitige Thumbnails (photo.php?size=thumb) statt der
Originale: rund 10 KB statt mehrerer hundert KB je Kachel. Das <img> haengt direkt an
der URL statt an einer Blob-URL - damit greifen HTTP-Cache und loading="lazy"
tatsaechlich und der Browser laedt parallel. Vorher lief eine sequenzielle Schleife, die
jedes Foto komplett holte, bevor das naechste anfing, und im Fehlerfall ein zweites Mal.

Bericht-Seiten zeigen composite_path, wenn vorhanden - also das im Editor gebaute
Seitenbild mit Anmerkungen statt der Rohdatei. Raster-Layouts bekommen ein Kennzeichen
("4"); Seiten ohne Bildquelle zeigen keine Fehlerkachel mehr.

confirm/alert/prompt sind an allen zehn Stellen durch eigene Modale ersetzt
(confirmDialog/alertDialog/inputDialog). Browser-Dialoge zeigen in der installierten PWA
die Herkunfts-URL und wirken wie ein Systemfehler. Der Hardware-Zurueck-Button schliesst
sie als Abbruch.

Service Worker: eigener Cache baustelle-media (cache-first, LRU 300) fuer Thumbnails.
Vorher war ohne Netz kein einziges schon angesehenes Foto verfuegbar. Der Cache ueberlebt
Deploys bewusst und wird beim Abmelden geleert (CLEAR_MEDIA), damit keine Kundenfotos auf
dem Geraet zurueckbleiben.

Nebenbei behoben:
- .modal-header, .close-btn und .modal-body hatten ueberhaupt kein CSS, obwohl das Markup
  sie nutzt (u. a. beim Loeschen eines Berichts) - der Schliessen-Knopf sass unter der
  Ueberschrift statt daneben.
- Das Laden eines Thumbnails ueberschrieb den ganzen Kachel-Inhalt und nahm die Overlays
  mit: Auswahl-Haekchen und Seitennummer verschwanden, sobald das Bild da war.
- manifest.webmanifest: share_target.action war eine absolute URL auf den Prod-Host und
  lag damit ausserhalb des Scopes - der Browser verwarf das share_target komplett. Jetzt
  relativ ("share.html"), funktioniert lokal und auf Prod.

ROADMAP.md neu angelegt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 18:12:09 +02:00
Eddy
7c7de58460 Trigger: Deploy (Doku-Update) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
2026-08-15 16:29:34 +02:00
Eddy
19b291cb77 Doku: Direkt-Freigabe legt keine Std-Lohn-Zeile mehr an
Das Backend (Bericht 1.4.0) validiert den Auftrag jetzt ohne Position - die
Leistungen kommen aus dem Stundenzettel. Am PWA-Code selbst aendert sich
nichts, das Antwortfeld added_line wurde hier nie ausgewertet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 16:25:59 +02:00
Eddy
f560fd3a58 Doku: README auf SSO/awlauth + Neuer-Auftrag-Flow aktualisiert [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 14s
- Auth-Doku von JWT auf zentrales SSO (HttpOnly-Cookie awl_sso, same-origin)
  umgestellt: Stack, Feature-Login, lib-Beschreibung, /auth.php, photo.php/pdf.php
  (?jwt= entfaellt, Cookie wird same-origin auch fuer img/object mitgeschickt)
- Feature 'Neuer Auftrag' dokumentiert (Ihr Zeichen/Beschreibung/Liefertermin/Freigabe)
2026-07-18 14:55:34 +02:00
Eddy
efc5cc2d29 Fix: Neuer-Auftrag-Formular oben statt mittig + Tastatur-Handling [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 14s
- fs-body des Modals hatte per globalem CSS justify-content:center; bei
  flex-direction:column zentrierte das den Inhalt vertikal -> Formular sass
  'weit unten' (gemessen: Content-Top 255px statt 71px bei 390x740).
  Inline justify-content:flex-start ergaenzt -> Formular oben unter dem Header.
- scrollIntoView({block:'center'}) beim Fokus der Textfelder, damit das aktive
  Feld ueber die Bildschirmtastatur geschoben wird (mobile).
2026-07-18 13:53:26 +02:00
Eddy
ad8779ce75 Feature: Neuer-Auftrag-Formular — Ihr Zeichen Pflicht, Liefertermin, Freigabe [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
- Feldreihenfolge getauscht: "Ihr Zeichen" (ref_client) jetzt an erster
  Stelle und Pflicht; "Auftragsbeschreibung" (Titel) an zweiter Stelle
  und optional (vorher genau umgekehrt)
- Neues Feld "Geplanter Liefertermin" (datetime-local -> date_livraison)
- Neue Checkbox "Auftrag direkt freigeben" (validate-Flag ans Backend)
- Erfolgsmeldung zeigt Freigabe-Status bzw. Warnung aus dem Backend
2026-07-18 13:35:41 +02:00
Eddy
125e2fd196 PWA-Login: Fingerabdruck-/Passkey-Anmeldung (WebAuthn) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
Zweiter, gleichwertiger Login-Weg neben Passwort — nutzt die zentrale
awlauth-WebAuthn-JS (/custom/awlauth/js/awlauth-webauthn.js), analog zum
Stundenzettel-Pilot.

- Script-Einbindung nach app.js in index.php (same-origin, /custom/awlauth).
- Neuer Button "Mit Fingerabdruck anmelden" im Login-Template (app.js),
  type="button", versteckt bis awlauthWebAuthn.isSupported() true ist.
- Klick-Handler: awlauthWebAuthn.login() -> bei Erfolg Profil aus dem
  Login-Result in idb('user') ablegen (wie api.login es tut, sonst zeigt
  Einstellungen nach reinem Passkey-Login "Unbekannt") -> showToast +
  router.go('#/orders') wie der Passwort-Login-Pfad.
- Passkey ist domainweit (RP awl.data-it-solution.de): ein z.B. ueber
  Stundenzettel registrierter Passkey funktioniert hier direkt mit.

Lokal verifiziert: php -l / node --check sauber, Playwright + Virtual-
Authenticator (CDP) — Button korrekt sichtbar/gestylt (eigene Dark-Palette),
Klick loest webauthn_login_options.php (200) aus, Fehlerpfad reaktiviert den
Button, bleibt auf #/login, 0 Console-Errors. Adversarialer Code-Review fand
1 kosmetischen Befund (fehlendes idb-Profil) — bereits gefixt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 15:41:37 +02:00
Eddy
b8ed5f2276 PWA-Login: Passwort-Sichtbar-Toggle (Auge-Icon)
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
Auge-Button im Passwort-Feld schaltet zwischen Klartext und Punkten um.
Hilft Tippfehler zu vermeiden (z.B. bei EN-Tastaturlayout via Remote-Desktop).

[deploy]
2026-07-06 16:16:10 +02:00
Eddy
17575f38e4 Baustelle-PWA: SSO-Migration auf awlauth (JWT -> awl_sso-Cookie)
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
- lib/api.js request(): Authorization:Bearer raus, X-Requested-With +
  credentials:same-origin rein (Vanilla fetch setzt X-Requested-With nicht
  automatisch -> ohne ihn 403 an awlauth_require).
- login(): kein setToken mehr (Session im HttpOnly-Cookie); logout() ruft
  jetzt /logout.php (Single-Logout).
- Blob-Loader (photo/pdf/file/shipment-pdf): jwt-Query raus, credentials rein;
  Shipment-PDF setzt zusaetzlich X-Requested-With (shipments.php=CSRF).
- app.js: ensureAuth() prueft /verify.php (offline nicht ausloggen),
  Token-Preload raus, confirm-POST mit X-Requested-With, Audio-/PDF-Download
  ohne jwt-Query.

[deploy]
2026-07-06 15:25:53 +02:00
Eddy
3608fef216 Doku: README auf Live-Kamera + Persist-First, korrekter Deploy-Pfad/URL, Struktur
All checks were successful
Deploy baustelle-pwa / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 11:33:23 +02:00
Eddy
5e7b1a9ec7 Feature: Live-Kamera (Schnellschuss + Filmstreifen), Datenverlust-Schutz (Persist-First) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 14s
- Kamera bleibt nach jedem Schnappschuss offen (getUserMedia Live-Video statt
  native capture-Input, der nach jedem Foto schliesst)
- Filmstreifen mit Status-Badges pro Foto (💾 gesichert →  lädt hoch → ✓ fertig)
- Persist-First: Foto zuerst in IndexedDB schreiben, Upload erst danach
- Foto verlässt Queue NUR nach HTTP-2xx mit gültigem relpath
- 2xx-HTML (abgelaufene Session, Proxy-Loginseite) wird als Fehler erkannt
- HTTP-Status auf Error-Objekt: 5xx/429/408 sind transient (nicht quarantänisiert)
- 45-Sekunden-Upload-Timeout via AbortController
- Quarantäne nach 6 Fehlversuchen, Recovery via Status-Badge-Tipp
- Beforeunload-Warnung wenn Fotos noch nicht gesichert
- idb.queueUpdate() für state-preserving ItemUpdates ohne Datenverlust

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 10:46:36 +02:00
Eddy
fdd0ab163d Trigger: Deploy [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 07:58:48 +02:00
Eddy
0e019d40b7 Doku: README um Lieferungen + Kundenunterschrift erweitert
- Features-Liste: Lieferschein-Vorschau, Vollbild-Querformat-Signatur, GPS,
  Auto-Validate/Close der Expedition
- API-Liste: /shipments.php (order_id list, detail, pdf, confirm)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 07:58:06 +02:00
Eddy
9e5b531ae5 CI: Ntfy-Benachrichtigungen (Start/Success/Failure) via data/ntfy-action
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 13s
[deploy]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 06:54:44 +02:00
Eddy
e9b5b05b16 Feature: Lieferungen-Liste + Vollbild-Signatur-Modal
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
- Neue Route #/orders/:id/shipments: Lieferungen zum Auftrag laden und anzeigen
- Neue Route #/shipments/🆔 Lieferschein-PDF inline (alle Seiten via PDF.js), Button Unterschreiben
- Vollbild-Landscape-Signatur-Modal: Fullscreen-API + screen.orientation.lock, HiDPI-Canvas
- Canvas transparent (kein fillRect), trimCanvasToInk() schneidet auf bemalte Fläche
- Name des Unterzeichners vorausgefüllt mit Kundenname aus Order
- POST api/shipments.php?action=confirm: Signatur-PNG + signer_name + GPS
- GPS-Abfrage (timeout 3s, graceful bei Verweigerung)
- Signed-PDF direkt nach Bestätigung anzeigen (?variant=signed)
- Fehlermeldung im Modal (kein hinter Fullscreen versteckter Toast)
- lib/api.js: listShipments, getShipment, getShipmentPdfBlobUrl, confirmShipment

[deploy]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 06:48:56 +02:00
Eddy
2c32093090 Trigger: Deploy README-Update [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-18 12:43:50 +02:00
Eddy
d51eed49f2 Doku: README um neue Features (Share, Mehrfachauswahl, Back-Button) ergänzt
All checks were successful
Deploy baustelle-pwa / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 12:43:42 +02:00
Eddy
0a78d9e5d9 PWA: Dokumente (PDFs) in Mehrfachauswahl + Back-Button schließt Auswahl [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 4s
- PDFs/Dokumente lassen sich jetzt auch im Auswahl-Modus markieren und
  mitteilen (bisher öffnete der Tap immer den Viewer)
- ☑ Auswählen-Button erscheint auch wenn nur Dokumente vorhanden sind
- Android-Zurück-Button im Select-Modus: hebt die Auswahl auf und
  beendet den Auswahl-Modus (statt die Seite zu verlassen)
- ✕ Abbrechen-Button nutzt denselben History-Back-Pfad

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 12:38:06 +02:00
Eddy
427fdeb0c0 PWA: Android-Zurück-Button-Fix + Datei-Teilen via Share-Sheet [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
- Modal-Stack mit History-API: jedes Modal pusht einen History-Eintrag,
  Android-Zurück schließt das Modal statt die App zu beenden
- Top-Level-Routen: "Nochmal drücken zum Beenden"-Toast (2s Fenster)
- shareFile()/shareFiles(): native Android-Share-Sheet für Fotos, PDFs, Dokumente
- Multi-Select in Fotogalerie: Mehrere Fotos gleichzeitig auswählen und teilen
- PDF-Teilen: auto-.pdf-Extension damit Android-Apps die Datei akzeptieren
- openPdfModal: Share-Button neben Download-Button

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 12:33:31 +02:00
Eddy
8be49c279f Fix: Nutze window.pdfjsLib statt window.pdfjs [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 13:13:10 +02:00
Eddy
e2bcb8250e Debug: Detailliertes Logging für PDF.js Init [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 13:12:38 +02:00
Eddy
9930ad2345 Fix: PDF.js-Pfad absolut (/custom/bericht/js/lib/) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 4s
2026-04-17 13:11:59 +02:00
Eddy
cef7c35075 Fix: Lade PDF.js vom Bericht-Modul (js/lib/pdf.min.js) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 13:11:25 +02:00
Eddy
99cd5876b4 Fix: PDF.js Worker-Pfad SOFORT nach Script-Load setzen [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 13:07:49 +02:00
Eddy
99c5537a2d PWA: Mehr Debug-Logs für File-Viewer (zeigt ob PDF.js geladen ist) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 13:07:01 +02:00
Eddy
69f50b0fe5 PWA: PDF-Viewer mit ausführlichem Debug-Logging [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 13:04:11 +02:00
Eddy
e579523020 PWA: PDF-Download über API (Content-Disposition, kein Dialog) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 12:56:22 +02:00
Eddy
0294509ee5 Fix: PDF-Download-Button zeigt kein Dialog, nur Download [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 12:54:07 +02:00
Eddy
125a6302ab PWA: PDF-Viewer mit PDF.js (inline, kein Download nötig) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
2026-04-17 12:52:47 +02:00
Eddy
a192cbfa27 Fix: PDFs + Dokumente direkt zum Download (kein problematischer iframe) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 4s
2026-04-17 12:50:51 +02:00
Eddy
a538dbb744 PWA: Weitere Dokumente anzeigen + öffnen (PDF-Viewer, Download) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 6s
- otherDocs-Sektion mit gestylten doc-items (Icon, Name, Größe, Datum)
- getFileBlobUrl() in api.js ohne Mime-Filter
- PDF/Bilder: Fullscreen-Modal mit iframe/img + Download-Button
- Andere Dateitypen: direkter Download
- CSS analog zu .audio-item

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-17 12:49:15 +02:00
Eddy
46f680039d [deploy] Layout-Fix: FAB aus #app-Flex-Container lösen + padding-bottom
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 4s
Der FAB hing als Kind im #app Flex-Layout (display:flex, column) und hat
die bottom-nav nach unten gedrängt. Jetzt sitzt er auf Body-Ebene,
beeinflusst kein Flex mehr. Zusätzlich hat #main padding-bottom:90px
damit der letzte Listeneintrag nicht vom FAB verdeckt wird.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 17:47:29 +02:00
Eddy
d4e4d09366 [deploy] Schnell-Auftrag-Erfassen via FAB + Login-Persistenz-Fix
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
- FAB unten rechts (halbtransparent) öffnet Fullscreen-Modal zur
  Auftrags-Anlage: Kundensuche mit Debounce und "Zuletzt verwendet"-
  Quick-Pick aus IndexedDB → Anzeige der übernommenen Defaults →
  Titel + optional Kunden-Ref → direkter Sprung auf #/orders/<id>
  wo die Fotos aufgenommen werden können.
- appBoot() preloadet das JWT aktiv aus IndexedDB bevor der Router
  läuft — fixt "nach App-Neustart immer wieder einloggen müssen".
- setNav() steuert zusätzlich die FAB-Sichtbarkeit mit.
- api.createOrder() als neuer Wrapper für POST /orders.php?action=create.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 17:44:14 +02:00
Eddy
cb8dc396b3 Kunden-Bestellnr. in Auftragsliste anzeigen
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
- ref_client wird neben Auftragsnummer angezeigt (wenn vorhanden)
- CSS-Styling für .ref-client

[deploy]

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-16 10:49:49 +02:00
Eddy
295ac82f43 Toggle "Auch abgeschlossene" für Auftragsliste + Doku aktualisiert
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s
PWA:
- Checkbox in /orders Route hinzugefügt
- Filter in localStorage persistiert
- CSS für .filter-toggle

Doku:
- README.md komplett aktualisiert mit allen Features
- API-Dokumentation erweitert

[deploy]

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-16 10:45:25 +02:00
Eddy
0a9c4d4db3 [deploy] Bild-Viewer mit Pinch-Zoom, Swipe und Navigation
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 0s
- Pinch-to-Zoom (2 Finger)
- Doppeltap für Zoom-Toggle
- Swipe links/rechts zum Bildwechsel
- Navigation-Buttons + Counter
- Tastatur: Pfeiltasten + Escape

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-13 13:26:56 +02:00
645624eeb6 Bericht löschen: Button + Dialog in Report-Detail, api.deleteReport() [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
- Lösch-Button (rot) unter Report-Detail
- Eigener Bestätigungs-Dialog (kein browser-confirm())
- api.deleteReport(id) → DELETE /reports.php?id=X
- CSS: .btn-danger Klasse

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:33:32 +02:00
3dad52367c feat: PWA Block D — Mess-Werkzeug, Materialliste, Heute-Tab, ntfy-Push
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
5.4 Mess-Werkzeug mit Skala-Kalibrierung:
- Zwei neue Sketch-Tools: 📏⚙ Kalibrieren + 📏 Messen
- Kalibrieren: 2 Punkte ziehen → reale Länge eingeben (cm/m/mm)
- Messen: 2 Punkte ziehen → Live-Distanz-Label mit berechnetem Wert
- pxPerUnit + unit werden im State gehalten, Linie im Canvas gezeichnet

5.9 Materialliste pro Auftrag:
- 📦 Materialliste-Button im Auftrags-Detail
- Modal: Bezeichnung + Menge + Einheit (Stk/m/m²/kg/l/Set/Pa/h) + Notiz
- Live-Liste mit Löschen pro Eintrag

5.8 Tages-Baustellen-Map:
- Neuer Bottom-Nav-Tab ☀️ Heute (ganz links)
- Filtert Aufträge nach heutigem Datum
- Route-Button öffnet Google Maps mit allen heutigen Adressen als Waypoints
- Darunter noch die offenen Aufträge als Backup

4.d Benachrichtigungen via ntfy (statt VAPID):
- Settings → Benachrichtigungen: ntfy-Server + Topic
- EventSource auf /topic/sse → native Browser-Notifications
- Test-Nachricht-Button sendet POST an das Topic
- Auto-Reconnect bei Fehlern nach 10s
- Auto-Start beim Boot wenn Topic gesetzt und Permission granted

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
[deploy]
2026-04-09 09:18:31 +02:00
54eea0fb22 feat: Block C — Seiten-Titel + api.request exposed
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
- openPageActionsModal bekommt Titel-Feld (wird im PDF groß oben auf
  der Seite gedruckt, wenn gesetzt) zusätzlich zur Notiz
- Save sendet beide Felder zusammen via api.request POST
- Seiten-Thumbs zeigen Titel als Badge unten (ellipsis bei langem
  Text)
- lib/api.js exposed request() als Low-Level-Funktion für
  Spezialfälle wie dieses Update

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
[deploy]
2026-04-09 09:10:57 +02:00
31a690454c feat: PWA Schnell-Bericht + Template-Dropdown + Whisper-Transkribieren
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
Schnell-Bericht-Modal (Phase 4.a + 4.i):
- '📑 Neuen Bericht anlegen…' Button im Auftrags-Detail
- openNewReportModal: Titel, Format/Orientation, Vorlage-Dropdown,
  ODT-Deckblatt-Dropdown
- Auto-Select der Default-ODT-Vorlage aus Admin-Config
- api.createReport() als Wrapper für /reports.php?action=create
- api.listTemplates() + api.listOdtTemplates()

Whisper-Transkription (Phase 5.7):
- Neuer 📝-Button je Audio-Item
- Tap → api.transcribeAudio(relpath) → Server ruft Whisper-Endpoint
- Transkribierter Text erscheint direkt unter dem Audio-Player
- Text ist wählbar und kann kopiert werden

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
[deploy]
2026-04-09 08:27:46 +02:00
0e8ebed717 feat: PIN-Schutz + Seiten-Reorder + Stamps
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
4.c PIN-Schutz (optional):
- Settings → Sicherheit → Toggle aktiviert PIN
- 4-stelliger Keypad-Dialog (promptPin/promptNewPin)
- SHA256 mit random Salt, beides in IndexedDB
- appBoot() Lockscreen vor Router-Start
- PIN ändern, deaktivieren jederzeit möglich
- Logout löscht PIN-Daten

4.f Seiten umsortieren:
- Long-Press (500ms) auf Seiten-Thumb → Drag-Modus
- Touch-basierter Reorder mit elementFromPoint
- Vibrationshinweis beim Drag-Start
- Beim Release: api.reorderPages + Nummern-Badges updaten

5.1 Stamps im Sketch-Editor:
- Vier vordefinierte Stempel in der Toolbar:
  ⚠ Achtung, ✓ OK, ✗ Mangel, 🔧 Reparatur
- Ein-Klick-Platzierung, Farbe aus Color-Picker,
  weißer Outline damit sie auf jedem Bild sichtbar sind
- 96px Bold-Font

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
[deploy]
2026-04-09 08:18:53 +02:00