diff --git a/README.md b/README.md index 58d7e7a..826ad9a 100644 --- a/README.md +++ b/README.md @@ -465,6 +465,21 @@ Dort lässt sich - der Code **löschen** (mit Bestätigungsdialog), - das Bild erneut als PNG oder SVG **herunterladen**. +**Liste oder Karten.** Voreingestellt ist die **Liste** — eine Zeile je Code, +gedacht für viele Projekte nebeneinander. Über die beiden Schalter rechts neben +der Sortierung wechselst du zur **Kartenansicht** mit großer Vorschau. Die Wahl +merkt sich der Browser. + +Dazu kommen + +- ein **Suchfeld** über Name, Ziel, Kurz-URL und Typ, +- eine **Sortierung** nach Datum, Name oder Scan-Anzahl, +- ein **Gruppenfilter**, sobald Codes in mehr als einer Gruppe liegen. + +Auf schmalen Bildschirmen blendet die Liste die hinteren Spalten aus; die +Kurz-URL rückt dann unter den Namen. Zum Herunterladen dient dort die +Kartenansicht. + Statische Codes erscheinen hier nicht, weil sie nicht gespeichert werden. > Version 1 ist für den Einzelplatz-/LAN-Betrieb gedacht und hat **keine diff --git a/src/app/meine-codes/page.tsx b/src/app/meine-codes/page.tsx index 5156811..9880e3c 100644 --- a/src/app/meine-codes/page.tsx +++ b/src/app/meine-codes/page.tsx @@ -10,8 +10,10 @@ export const dynamic = "force-dynamic"; export default async function MyCodesPage() { await requirePageActor(); + // Breiter als die übrigen Seiten: Die Liste soll viele Projekte + // nebeneinander zeigen können. return ( -
Codes werden geladen …
; } + /** Herunterladen und Löschen — in beiden Ansichten dieselben Ziele. */ + const pngHref = (code: QrCodeDto) => + `/api/codes/${code.id}/qr?format=png&download=1`; + const svgHref = (code: QrCodeDto) => + `/api/codes/${code.id}/qr?format=svg&download=1`; + + const toolbar = codes.length > 0 && ( ++ {visible.length === codes.length + ? `${codes.length} ${codes.length === 1 ? "Code" : "Codes"}` + : `${visible.length} von ${codes.length} Codes`} +
+ ) : null; + return (+ Kein Code passt zur Suche.{" "} + +
+| + Name + | ++ Kurz-URL + | ++ Ziel + | + {groups.length > 1 ? ( ++ Gruppe + | + ) : null} ++ Scans + | ++ Erstellt + | ++ Aktionen + | +
|---|---|---|---|---|---|---|
|
+
+ {/* Reines Bild zum Wiedererkennen — zum Herunterladen
+ stehen PNG und SVG am Zeilenende. */}
+
+ {/* eslint-disable-next-line @next/next/no-img-element -- vom Server gerendertes SVG */}
+
+
+
+
+ {displayName(code)}
+
+ {/* Solange die Kurz-URL keine eigene Spalte hat, steht
+ sie hier — sie ist wichtiger als der Typ. */}
+
+ {/* Nur der Pfad: Der Hostname ist auf dem Handy
+ gleich für alle Zeilen, der Slug unterscheidet. */}
+
+ {code.shortUrl.replace(/^https?:\/\/[^/]+/, "")}
+
+
+ {qrTypes[code.type]?.title ?? code.type}
+
+
+ |
+
+ + + | + ++ {code.target ? ( + + {code.target.replace(/^https?:\/\//, "")} + + ) : ( + + {code.summary} + + )} + | + + {groups.length > 1 ? ( ++ + {code.groupName ?? "—"} + + | + ) : null} + ++ {code.scans} + | + ++ {formatShortDate(code.createdAt)} + | + ++ + | +