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

421 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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"
---
## 2. Feed / Gallery Page
### 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.
### Step 2b — Gallery
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 |