# Mobile-First UI/UX Redesign Concept > **Status: IMPLEMENTED (v0.15).** This document captures the design intent. The redesign > has shipped β€” see [BottomNav.svelte](../frontend/src/lib/components/BottomNav.svelte), > [UploadSheet.svelte](../frontend/src/lib/components/UploadSheet.svelte), > [CameraCapture.svelte](../frontend/src/lib/components/CameraCapture.svelte), > [feed/+page.svelte](../frontend/src/routes/feed/+page.svelte), > [account/+page.svelte](../frontend/src/routes/account/+page.svelte), > [host/+page.svelte](../frontend/src/routes/host/+page.svelte), > [admin/+page.svelte](../frontend/src/routes/admin/+page.svelte). Use this doc as the design > reference; treat code as the source of truth for current behaviour. ## Overview EventSnap is intended for mobile use at live events. This document describes the full mobile-first design 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 ``. Native camera opens. After capture β†’ Step 3. ### Step 2b β€” Gallery Triggers ``. 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. --- ## Touch gestures vs. desktop buttons (planned extension) Where a gesture is more ergonomic on mobile than a button, EventSnap prefers the gesture on touch and mirrors it as an explicit button on desktop. Inspired by Instagram, WhatsApp and Telegram β€” long-press for context, swipe to dismiss, double-tap to react. | Surface | Touch gesture | Desktop equivalent | |-----------------------------------------|-------------------------------------|------------------------------------------| | Post card | Long-press β†’ context bottom sheet | β‹― kebab in the card corner | | Comment row | Long-press β†’ bottom sheet | β‹― next to the comment timestamp | | User row (Host / Admin dashboards) | Long-press β†’ bottom sheet | Inline buttons (ban, promote, reset PIN) | | Lightbox | Swipe left / right | ←/β†’ arrow keys + on-screen chevrons | | Lightbox | Swipe down to close | Esc + βœ• button | | Bottom sheet | Swipe down to dismiss | Click backdrop or Γ— in the sheet header | | Feed | Pull to refresh | Refresh icon next to the view toggle | | Post (any) | Double-tap β†’ like | Click the heart icon | **Discoverability rule:** every gesture must have a visible button equivalent on the same page. Gestures are never the *only* path to an action. Helps with stylus users, accessibility, and people who don't know the gesture vocabulary. **Context bottom-sheet pattern** (used by every long-press above): ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β–¬ (drag handle) β”‚ β”‚ β”‚ β”‚ πŸ—‘ LΓΆschen β”‚ ← destructive action red β”‚ πŸ“₯ Original anzeigen β”‚ β”‚ πŸ”— Teilen β”‚ β”‚ 🚩 Melden β”‚ (only on others' content) β”‚ β”‚ β”‚ [ Abbrechen ] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` Each sheet is composed from a shared `` component (planned) with a single `actions: ContextAction[]` prop. Adding a new gesture context = define the actions array where needed. Drop-in, one file. ## 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 | | Gestures over chrome | Long-press for context menus, swipe to dismiss, double-tap to react β€” always with a button fallback for desktop and accessibility |