Commit Graph

5 Commits

Author SHA1 Message Date
MechaCat02
1cdab21514 fix(frontend): a11y backdrop, ≥44px PIN button, test-ids on auth & upload
- account/+page.svelte: remove `aria-hidden="true"` from the
  leave-confirm and data-mode-warning bottom-sheet backdrops. The
  attribute cascaded into the dialog children, making the inner
  Abmelden/Aktivieren/Abbrechen buttons unreachable in the accessibility
  tree (and to Playwright's `getByRole`). Discovered while writing the
  E2E suite; the visual layout is unchanged.

- join/+page.svelte: bump the PIN-copy button from `py-1` (28px tall) to
  `min-h-11 min-w-11 py-2` so it clears the ≥44px touch-target floor on
  mobile. Touch-target audit revealed the gap.

- data-testid attributes on stable interactive elements (join name input,
  join submit, PIN modal + copy + continue, recovery PIN + submit + try-
  different-name, admin login password + submit + error, recover name +
  PIN + submit + error, upload header submit + sticky submit + caption
  textarea). Targeted at ~20 spots where semantic locators were ambiguous
  (e.g. two "Hochladen" buttons on /upload, German strings that may iterate).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 19:01:54 +02:00
MechaCat02
e619a3bd64 feat(ui): v0.16 features + dark mode across every page
Wires up everything from the previous commits into actual UI surfaces, and
applies Tailwind dark: variants throughout. All pages now support the
'system' / 'light' / 'dark' preference set in the onboarding step or in
Mein Konto → Design.

Layout & nav:
- routes/+layout.svelte: initTheme(), global pin-reset SSE handler that
  filters by user_id and calls clearPin(), one-shot /me/context fetch
  on boot to hydrate privacyNote + quota.
- components/BottomNav.svelte: dark variants on the frosted-glass bar.
- components/UploadSheet.svelte: dark variants on backdrop, sheet,
  source buttons.
- components/OnboardingGuide.svelte: new "Helles oder dunkles Design?"
  step (3-option custom-radio grid), reactive currentStep with proper
  type narrowing, dark variants throughout. Privacy-note nudge appears
  on the PIN step only when one is configured.

Feed:
- routes/feed/+page.svelte: diashow entry icon (tablet/desktop only),
  long-press → ContextSheet (Löschen for own posts, Original anzeigen
  for all), upload-deleted + feed-delta SSE handlers, dark variants on
  header, search, autocomplete, filter chips, empty states.
- components/FeedListCard.svelte: long-press wireup, double-tap-to-like,
  data-mode-aware mediaSrc via pickMediaUrl, kebab fallback for desktop,
  isOwn prop, dark variants.
- components/FeedGrid.svelte: long-press wireup, dark variants.
- components/LightboxModal.svelte: data-mode-aware src, double-tap heart
  burst, dark variants on card / comments / input.
- components/HashtagChips.svelte: dark variants.

Account:
- routes/account/+page.svelte: theme picker (3-button radio grid), data
  mode picker (with confirm sheet for Original), live quota widget,
  preformatted Datenschutzhinweis block, diashow tile (mobile only),
  pin now sourced from the $currentPin store so a global pin-reset
  clears it live, clearQueue() on explicit logout, dark variants
  across every card + both bottom sheets.

Upload:
- routes/upload/+page.svelte: per-user quota progress bar above the
  submit button, dark variants.

Host & Admin:
- routes/host/+page.svelte: PIN-reset confirm + one-time PIN modal,
  hosts may demote other hosts, canResetPinFor() helper, dark variants
  on all cards, modals, stats, toast.
- routes/admin/+page.svelte: Config form rebuilt as CONFIG_GROUPS with
  per-field kind (number / bool / text), renders toggles for the
  rate-limit + quota switches and a textarea for the privacy_note;
  Nutzer tab gains PIN reset + hosts-may-demote-hosts wiring; same
  one-time PIN modal; dark variants everywhere.
- routes/admin/login/+page.svelte: dark variants.

Join / Recover / Export:
- routes/join/+page.svelte: rename inline link to
  "Ich habe bereits einen Account", dark variants.
- routes/recover/+page.svelte: dark variants.
- routes/export/+page.svelte: dark variants on status cards + HTML
  guide modal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 14:33:30 +02:00
MechaCat02
4a5506f32d feat: mobile-first UI redesign (v0.15.0)
- Persistent bottom tab bar (Feed · FAB · Account) on all authenticated pages
- Upload FAB triggers bottom sheet (Galerie / Kamera) → navigates to composer
- Upload page redesigned as full-screen composer with thumbnail strip, textarea,
  quick-tag chips, sticky submit button; bottom nav suppressed while composing
- Slim upload progress bar above bottom nav driven by queue state
- Feed: list/grid view toggle; list = chronological full-width FeedListCard;
  grid = 3-col with search bar, autocomplete from loaded posts, filter chips
- Account page: role-gated dashboard links (Host / Admin); Konto section with
  leave-confirm bottom sheet; no more per-page header nav icons
- Host dashboard: back arrow, collapsible sections, 2-col stats, user search
- Admin dashboard: back arrow, inner tab bar (Stats/Config/Export/Nutzer),
  stacked config inputs with sticky save, new Nutzer tab
- BottomNav hidden on unauthenticated pages via isAuthenticated store
- FeedGrid: threeCol prop; OnboardingGuide upload step updated for FAB
- Concept docs added to docs/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 18:40:57 +02:00
MechaCat02
25f4fb1810 feat: implement camera capture step
Add in-app camera capture to the upload flow. Guests can now take photos
and record videos directly via getUserMedia without leaving the app.
The captured media is immediately queued through the existing IndexedDB
upload pipeline alongside library-picked files.

- CameraCapture.svelte: fullscreen overlay with live preview, photo
  capture (JPEG via canvas), video recording (WebM/MP4 via MediaRecorder),
  front/back camera toggle, recording timer, and permission-denied error state
- Upload page: side-by-side "Gallery" and "Camera" pickers; shared
  caption/hashtags fields apply to both sources; Blob→File conversion
  with timestamped filename before enqueue
- .env.test: reference environment config for local testing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 20:20:51 +02:00
fabi
4e1f1d6426 feat: implement client-side upload queue with IndexedDB persistence
- upload-queue.ts: IndexedDB-backed queue manager using idb library
  - File blobs stored in IndexedDB (survives page reloads)
  - Sequential upload processing (one file at a time)
  - XHR-based upload with per-file progress tracking
  - Retry failed uploads, remove/clear completed items
  - Auto-resumes pending items on page load
- UploadQueue.svelte: queue progress UI component
  - Per-file: filename, size, progress bar, status badge
  - Retry button on failed items, remove button, clear completed
  - Processing indicator with pulse animation
- /upload page: file picker (multiple, image/video) with caption + hashtags
  - Drop zone UI with drag-and-drop styling
  - Caption supports inline #hashtags
  - Separate comma-separated hashtags field
  - Link to gallery feed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 18:59:23 +02:00