Files
EventSnap/docs/CONCEPT_MOBILE_UI.md
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

19 KiB
Raw Blame History

Mobile-First UI/UX Redesign Concept

Overview

EventSnap is intended for mobile use at live events, but the current UI is desktop-oriented. This document describes a full mobile-first redesign covering navigation, the feed/gallery, account page, host dashboard, and admin dashboard.


1. Navigation: Bottom Tab Bar

Replace all per-page top-right icon links with a single persistent bottom tab bar present on every page. The bar sits at the very bottom with proper padding-bottom for iPhone home indicator (safe-area-inset-bottom).

Tab Composition by Role

Role Tabs
Guest 🏠 Feed · [📷+] · 👤 Account
Host 🏠 Feed · [📷+] · 👤 Account
Admin 🏠 Feed · [📷+] · 👤 Account

All roles see the same three tabs. Role-specific dashboard links (Host, Admin) live inside the Account page — not as separate tabs. This keeps the bar simple and avoids conditional tab rendering.

Visual Style

  • Frosted glass background: bg-white/85 backdrop-blur-md
  • Thin top border: border-t border-gray-200
  • Subtle shadow upward
  • Active tab: colored icon + small label below
  • Inactive tab: gray icon, small gray label

Upload FAB (Floating Action Button)

The center tab is an elevated circular button, not a flat tab icon:

  • Circle ~56 px diameter, bg-blue-600
  • Icon: camera outline with a small + badge overlaid at bottom-right
  • Raised above the bar with a drop shadow
  • Press: slight scale-down (scale-95) + haptic feedback where available
  • Communicates "capture new or upload existing"

Header

┌─────────────────────────────────────────┐
│  Sommerfest 2025              ≡  ⊞      │
└─────────────────────────────────────────┘
  • Event name left-aligned
  • List/grid view toggle icons right-aligned (≡ list, ⊞ grid)
  • Header collapses on downward scroll (only toggle remains visible), expands on upward scroll

View A — Chronological List (default)

Full-width post cards, newest at top, infinite scroll.

┌─────────────────────────────────────────┐
│  👤 MaxMustermann          · vor 2 Min  │
│ ┌───────────────────────────────────┐   │
│ │                                   │   │
│ │          [photo / video]          │   │
│ │                                   │   │
│ └───────────────────────────────────┘   │
│  Tolle Stimmung! #party #spaß           │
│  ❤️ 12   💬 3                           │
└─────────────────────────────────────────┘
  • Media: full-width, native aspect ratio, capped at 80 vh
  • Avatar: colored initial circle, no photo
  • Timestamp: relative ("vor 2 Min", "vor 1 Std")
  • Tap media → fullscreen lightbox, swipe left/right navigates feed
  • No search bar in list view

View B — Grid View

Transition animation when toggling: list collapses, grid fades/scales in (~200 ms).

Search Bar (grid view only)

┌─────────────────────────────────────────┐
│  🔍  Nutzer oder #Tag suchen…      ×   │
└─────────────────────────────────────────┘
  • Appears below the header only in grid view
  • Slides in as part of the view transition
  • × clears current input
  • Auto-focuses when grid view is activated

Autocomplete Dropdown

Appears immediately on focus and updates on every keystroke. Data source: the already-loaded posts in memory — no extra API calls.

Two suggestion lists are derived at load time:

  • allTags: unique hashtags from all post captions, sorted by frequency descending
  • allUploaders: unique display names, sorted alphabetically
User input Suggestions shown
(focus, empty) Top 3 tags by frequency + top 3 uploaders
# All tags, frequency-sorted
#par Tags with prefix "par": #party, #parade
Max Uploaders matching "max" (case-insensitive)
a Uploaders containing "a" + tags containing "a"

Dropdown layout:

┌─────────────────────────────────────────┐
│  👤 Nutzer                              │
│     MaxMustermann                       │
│     AnnaSchulz                          │
│  # Tags                                 │
│     #party    #tanz    #spaß            │
└─────────────────────────────────────────┘

Max ~5 total suggestions. Tapping a suggestion adds it as an active filter chip and clears the search bar for another entry.

Active Filter Chips

┌─────────────────────────────────────────┐
│  👤 MaxMustermann ×   # party ×         │
│  Alle Filter löschen                    │  ← shown when 2+ chips active
└─────────────────────────────────────────┘

Filter combination logic:

Combination Logic
Two tags: #party + #tanz OR — posts with either tag
Two uploaders: Max + Anna OR — posts from either
Uploader + tag: Max + #party AND — posts by Max that also have #party

Grid Layout

┌───────┬───────┬───────┐
│       │       │       │
│       │       │       │  3-column, equal square cells
├───────┼───────┼───────┤  small gap (2 px)
│       │  ▶    │       │  ← video: small ▶ badge + duration
│       │  0:42 │       │
└───────┴───────┴───────┘
  • Tap cell → fullscreen lightbox, swipe navigates filtered set only
  • Virtualized grid for performance on large events

3. Upload Flow

Step 1 — Source Selection (Bottom Sheet)

Tapping the FAB slides up a bottom sheet (~300 ms spring animation). Frosted glass, rounded top corners, drag handle at top. Tap outside or swipe down to dismiss.

┌──────────────────────────────────┐
│          ▬  (drag handle)        │
│                                  │
│  📸  Kamera                      │
│      Jetzt aufnehmen             │
│                                  │
│  🖼  Galerie                     │
│      Foto oder Video wählen      │
│                                  │
│  [  Abbrechen  ]                 │
└──────────────────────────────────┘

Step 2a — Camera

Triggers <input type="file" accept="image/*,video/*" capture="environment">. Native camera opens. After capture → Step 3.

Triggers <input type="file" accept="image/*,video/*" multiple>. Native gallery picker with multi-select (up to ~10 items). After selection → Step 3.

Step 3 — Preview & Metadata Screen

Full-screen, pushes in from right. Bottom nav hidden (immersive).

┌──────────────────────────────────┐
│  ×  Abbrechen      Hochladen →  │
├──────────────────────────────────┤
│                                  │
│  ┌────┐ ┌────┐ ┌────┐  →        │  ← horizontal scroll, tap to preview
│  │img │ │img │ │ ×  │           │    × on each thumbnail to remove
│  └────┘ └────┘ └────┘           │
│                                  │
│  Beschreibung (optional)         │
│  ┌────────────────────────────┐  │
│  │                            │  │  ← auto-focused
│  └────────────────────────────┘  │
│                                  │
│  # Schnell-Tags                  │
│  [#Feier] [#Spaß] [#Party] …   │  ← tap to append to caption
│                                  │
├──────────────────────────────────┤
│  ┌────────────────────────────┐  │
│  │      📤 Hochladen          │  │  ← sticky, disabled until ≥1 file
│  └────────────────────────────┘  │
└──────────────────────────────────┘

Step 4 — Background Upload + Feedback

  • Tapping "Hochladen" immediately returns to the feed (optimistic UX)
  • Slim progress bar above the bottom tab bar while queue is active
  • FAB gets a small spinning ring badge while uploads are in progress
  • On completion: brief toast near the bottom ("✓ Hochgeladen")
  • Rate-limit countdown banner anchored above the bottom bar (existing behavior)

4. Account Page

Single entry point for profile info and role-based dashboard navigation.

┌─────────────────────────────────────────┐
│              Mein Account               │
├─────────────────────────────────────────┤
│                                         │
│        ┌───────┐                        │
│        │  M    │   MaxMustermann        │
│        └───────┘   🏷 Gast              │
│                    Sommerfest 2025      │
│                    7 Uploads            │
│                                         │
├── Dashboards ───────────────────────────┤  (entire section absent for guests)
│                                         │
│  ⭐  Host-Dashboard                →    │  (host + admin only)
│  🛡  Admin-Dashboard               →    │  (admin only)
│                                         │
├── Konto ────────────────────────────────┤
│                                         │
│  ✏️  Anzeigename ändern             →    │
│  🔑  PIN ändern                     →    │
│  🚪  Event verlassen                →    │  (red text, confirm sheet)
│                                         │
└─────────────────────────────────────────┘
│  🏠 Feed  ·  [📷+]  ·  👤 Account       │
└─────────────────────────────────────────┘
  • "Dashboards" section is entirely absent in the DOM for plain guests — not just hidden
  • "Event verlassen" triggers a bottom-sheet confirmation before action
  • Avatar: colored circle with initial letter

5. Host Dashboard

Accessed via Account → Host-Dashboard. Full-screen page, bottom nav visible.

┌─────────────────────────────────────────┐
│  ←   🎉 Host-Dashboard                  │
├─────────────────────────────────────────┤
│                                         │
│  ── Statistiken ──────────────────────  │
│  ┌──────────┐  ┌──────────┐            │
│  │    24    │  │   156    │            │
│  │  Nutzer  │  │ Uploads  │            │
│  └──────────┘  └──────────┘            │
│                                         │
│  ── Event-Einstellungen ──────────────  │  ← collapsible section
│                                         │
│  Neue Uploads sperren                   │
│  ○────────────●  Gesperrt              │  ← toggle
│  Keine neuen Uploads möglich            │
│                                         │
│  ── Nutzerverwaltung ─────────────────  │  ← collapsible section
│                                         │
│  🔍  Nutzer suchen…                     │
│  ┌───────────────────────────────────┐  │
│  │  👤  MaxMustermann   Gast  [🚫]   │  │
│  │  👤  AnnaSchulz      Gast  [🚫]   │  │
│  │  👤  GesperrterNutzer      [↩]    │  │  ← banned: undo icon
│  └───────────────────────────────────┘  │
│                                         │
└─────────────────────────────────────────┘
│  🏠 Feed  ·  [📷+]  ·  👤 Account       │
└─────────────────────────────────────────┘
  • Sections have a chevron toggle to collapse/expand (helps on small phones)
  • Ban/unban: icon tap + bottom sheet confirmation ("Nutzer wirklich sperren?")
  • User list virtualized for large events

6. Admin Dashboard

Most complex page. Uses an inner tab bar directly below the header to divide the four functional areas. The inner tabs are independent of the bottom nav.

┌─────────────────────────────────────────┐
│  ←   🛡 Admin-Dashboard                 │
├─────────────────────────────────────────┤
│  [Stats] [Config] [Export] [Nutzer]     │  ← inner tab bar (scrollable if needed)
├─────────────────────────────────────────┤
│                                         │
│  [Tab content]                          │
│                                         │
└─────────────────────────────────────────┘
│  🏠 Feed  ·  [📷+]  ·  👤 Account       │
└─────────────────────────────────────────┘

Stats Tab

  ┌──────────┐  ┌──────────┐
  │  156     │  │  24      │
  │ Uploads  │  │ Nutzer   │
  └──────────┘  └──────────┘
  ┌──────────┐  ┌──────────┐
  │  2.1 GB  │  │  3       │
  │ Speicher │  │ Gesperrt │
  └──────────┘  └──────────┘

2×2 metric card grid. Values large and prominent. Optionally expandable to show time-series charts on tap.

Config Tab

  Upload-Limit / Nutzer
  ┌────────────────────────────────┐
  │  10                            │
  └────────────────────────────────┘

  Zeitfenster (Sek.)
  ┌────────────────────────────────┐
  │  60                            │
  └────────────────────────────────┘

  Max. Dateigröße (MB)
  ┌────────────────────────────────┐
  │  50                            │
  └────────────────────────────────┘

  ┌────────────────────────────────┐
  │        💾 Speichern            │  ← sticky at bottom of tab scroll area
  └────────────────────────────────┘

Each setting: full-width label + input. Save button always reachable without scrolling.

Export Tab

  ── Galerie ──────────────────────────
  [  🔓 Galerie freigeben  ]

  ── Export-Jobs ──────────────────────
  [  🔄 Aktualisieren  ]

  ┌───────────────────────────────────┐
  │  HTML-Viewer   ● Fertig  [↓ ZIP]  │
  │  JSON-Export   ⏳ Läuft…          │
  │  ZIP-Archiv    ✗ Fehler   [↺]     │
  └───────────────────────────────────┘

  [  + Neuer Export-Job  ]
  • Status chips: green (Fertig), amber (Läuft), red (Fehler)
  • Download button inline per completed job
  • Only the jobs list refreshes on "Aktualisieren" — no full page re-render

Nutzer Tab

Same structure as Host Nutzerverwaltung, with any additional admin-only actions (e.g. role assignment) added as extra controls per row.


Design Principles Summary

Principle Application
Thumb zone All primary actions in bottom ~20% of screen
One-hand operation FAB centered, bottom sheets dismissable with swipe
Minimal taps to upload Source → picker → preview → upload: 4 taps
Immediate feedback Optimistic return to feed, background upload
Progressive disclosure Caption/tags optional; CTA always reachable
No role clutter in nav Role links only in Account, bar stays clean
Collapsible sections Long management pages stay usable on small phones
Inner tabs for complex pages Admin dashboard split across 4 focused tabs