fix: design critique findings, and the settings card that saved nothing
The critique found a functional bug I had shipped an hour earlier: the whole
e-mail configuration was never sent. `saveSettings` builds its body from a fixed
field list, and none of the smtp_* fields or share_default_days were in it, and
the password input had no state at all. Filling in the card and pressing save
lost everything while the toast said "Gespeichert." That card is the
precondition for password reset, job notifications and mailing share links, so
it would have looked like the whole feature was broken. Now sent, with the
password held separately like the other secrets, and a failed PATCH no longer
reports success.
The public page told recipients how to bypass "view only": the hint about
long-pressing to save was printed regardless of allow_download, two lines under
a caption saying "Nur ansehen". The backend takes that setting seriously enough
to withhold the original even for cutouts; the page undid it. Now the two cases
have separate copy, worded for Android as well as iOS, and the hint sits above
the grid where it is actually read rather than under twenty tiles.
The share dialog had two blue buttons in step two, the exact mistake DESIGN.md
records as having happened once before, and asked five questions before a link
existed when the common case ("one picture for grandma") needs none of them.
One blue button now, and the rarely-used settings collapse behind a summary
that states what currently applies.
/konto was unreachable on a phone: the only way in was the username in the top
bar, which is hidden below 480px. It is a tab bar entry now, with short labels
so eight items still fit at 390px (49x48px each).
Network failures rendered as content: a failed load showed "nothing shared yet"
alongside an invitation to share something, and /konto and /admin hung on
"loading" forever. All three have an error state with a retry now.
Also: the public page nested a second <main> inside the app shell and inherited
padding for a tab bar anonymous visitors never see; admin inputs were 14px, so
iOS zoomed on focus at tablet width; the admin had no media queries at all, so
"Postausgangsserver" got ~156px on a phone; "Jetzt umbenennen" was clickable
without the dry run PRODUCT.md requires; share_default_days did not reach the
dialog; partial mail success was coloured as failure by a regex on the message
text; the passphrase sheet ignored the home indicator; the privacy line claimed
"encrypted" for what is a salted hash.
Added PRODUCT.md and DESIGN.md, written from the code and the wiki rather than
invented, so future design work has something to be measured against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BNhLunz586g6DeYMa7Qsd1
This commit is contained in:
9 files changed
+345
-60
No files matched your search
@@ -67,6 +67,7 @@ const meldung: Record<string, { h: string; t: string }> = {
|
||||
{status === 'ok' && share ? (
|
||||
<>
|
||||
<header class="kopf">
|
||||
<p class="marke"><span class="regmark"></span> geteilt über Klarbild</p>
|
||||
<h1>{titel}</h1>
|
||||
{share.note && <p class="notiz">{share.note}</p>}
|
||||
<p class="mono-label">
|
||||
@@ -75,8 +76,21 @@ const meldung: Record<string, { h: string; t: string }> = {
|
||||
</p>
|
||||
</header>
|
||||
|
||||
{share.allow_download ? (
|
||||
<p class="hinweis">
|
||||
<b>Herunterladen</b> speichert die Datei in voller Auflösung.
|
||||
Am Handy geht es auch so: lange auf ein Bild drücken und speichern.
|
||||
</p>
|
||||
) : (
|
||||
<p class="hinweis">
|
||||
Diese Bilder sind zum Ansehen gedacht. Wenn du eine Datei brauchst, frag bei
|
||||
der Person nach, die dir den Link geschickt hat.
|
||||
</p>
|
||||
)}
|
||||
|
||||
{bilder.length === 0 ? (
|
||||
<p class="leer">Zu diesem Link gibt es gerade keine Bilder.</p>
|
||||
<p class="leer">Hier ist gerade nichts zu sehen. Vielleicht wurden die Bilder inzwischen
|
||||
entfernt — frag am besten noch einmal bei der Person nach, die dir den Link geschickt hat.</p>
|
||||
) : (
|
||||
<div class={bilder.length === 1 ? 'raster einzeln' : 'raster'}>
|
||||
{bilder.map((b) => (
|
||||
@@ -99,14 +113,10 @@ const meldung: Record<string, { h: string; t: string }> = {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p class="hinweis">
|
||||
Am Handy: Bild antippen, dann lange darauf drücken und „Zu Fotos hinzufügen" wählen.
|
||||
{share.allow_download && <> Über <b>Herunterladen</b> kommt die Datei in voller Auflösung.</>}
|
||||
</p>
|
||||
<p class="datenschutz">
|
||||
Wer dir diesen Link geschickt hat, sieht, <b>wann</b> und mit welcher Art Gerät er geöffnet
|
||||
wurde — nicht, <b>wer</b> das war. Deine Adresse wird nur verschlüsselt abgelegt und nach
|
||||
90 Tagen gelöscht.
|
||||
wurde. Nicht, <b>wer</b> das war: Von deiner Internet-Adresse wird nur ein unkenntlicher
|
||||
Zahlenwert gespeichert, und der wird nach 90 Tagen gelöscht.
|
||||
</p>
|
||||
</>
|
||||
) : status === 'passwort' ? (
|
||||
@@ -132,6 +142,9 @@ const meldung: Record<string, { h: string; t: string }> = {
|
||||
<style>
|
||||
.teilen { max-width: 1000px; margin: 0 auto; padding: 40px 20px 72px; }
|
||||
.kopf { margin-bottom: 26px; }
|
||||
.marke { display: flex; align-items: center; gap: 8px; margin: 0 0 10px;
|
||||
font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em;
|
||||
text-transform: uppercase; color: var(--soft); }
|
||||
.kopf h1 { font-size: clamp(1.5rem, 4vw, 2rem); margin: 0 0 8px; letter-spacing: -0.02em; }
|
||||
.notiz { margin: 0 0 10px; color: var(--ink-soft); max-width: 60ch; line-height: 1.6; }
|
||||
|
||||
@@ -146,9 +159,12 @@ const meldung: Record<string, { h: string; t: string }> = {
|
||||
padding: 8px 14px; border-radius: 3px; white-space: nowrap; }
|
||||
.fein { font-size: 12px; color: var(--soft); }
|
||||
.leer { color: var(--soft); }
|
||||
.hinweis { margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--line);
|
||||
/* Steht über den Bildern: Unter zwanzig Kacheln würde ihn niemand lesen. */
|
||||
.hinweis { margin: 0 0 20px; padding: 11px 13px; border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm); background: var(--card);
|
||||
font-size: 13px; color: var(--ink-soft); line-height: 1.6; max-width: 62ch; }
|
||||
.datenschutz { margin: 10px 0 0; font-size: 12px; color: var(--soft); line-height: 1.6; max-width: 62ch; }
|
||||
.datenschutz { margin: 30px 0 0; padding-top: 16px; border-top: 1px solid var(--line);
|
||||
font-size: 12px; color: var(--soft); line-height: 1.6; max-width: 62ch; }
|
||||
|
||||
.tor { max-width: 460px; margin: 8vh auto 0; text-align: center; }
|
||||
.tor h1 { font-size: 1.4rem; margin: 0 0 12px; }
|
||||
|
||||
Reference in new issue
Block a user