5.8 KiB
5.8 KiB
07a — Guest PWA Routes & Components
This scaffold describes recommended routes, guards, directories, and components for the Guest PWA. It is framework-leaning (React Router v6 + Vite), but adaptable.
Routing Principles
- Event routes require an event token (from QR/PIN). Guard redirects to Landing when missing/invalid.
- Use route-level code splitting for camera/lightbox/slideshow.
- Prefer modal routes (photo detail) layered over the gallery.
Route Map (proposed)
/— Landing (QR/PIN input; deep-link handler)/setup— Profile Setup (name/avatar; skippable)/e/:slug— Home/Feed (default gallery view + info bar)/e/:slug/tasks— Task Picker (random/emotion)/e/:slug/tasks/:taskId— Task Detail (card)/e/:slug/upload— Upload Picker (camera/library + tagging)/e/:slug/queue— Upload Queue (progress/retry)/e/:slug/gallery— Gallery index (alias of Home or dedicated page)/e/:slug/photo/:photoId— Photo Lightbox (modal over gallery)/e/:slug/achievements— Achievements (optional)/e/:slug/slideshow— Slideshow (optional, read-only)/legal/:page— Legal pages (imprint/privacy/terms)*— NotFound
Note: The settings experience is handled via the header sheet (no dedicated route; legal pages stay routable under /legal/:page).
Guards & Loaders
EventGuard— verifies event token in storage; attempts refresh; otherwise redirects to/.PrefetchEvent— loads event metadata/theme on:slugroutes.OfflineFallback— surfaces offline banner and queues mutations.
Suggested Directory Structure
apps/guest-pwa/
src/
routes/
index.tsx // router config + guards
pages/
LandingPage.tsx
ProfileSetupPage.tsx
HomePage.tsx
TaskPickerPage.tsx
TaskDetailPage.tsx
UploadPage.tsx
UploadQueuePage.tsx
GalleryPage.tsx
PhotoLightbox.tsx // modal route
AchievementsPage.tsx
SlideshowPage.tsx
SettingsSheet.tsx
LegalPage.tsx
NotFoundPage.tsx
components/
Header.tsx
InfoBar.tsx
BottomNav.tsx
QRPinForm.tsx
CTAButtons.tsx
EmotionPickerGrid.tsx
TaskCard.tsx
CameraPicker.tsx // photos only; no video capture
UploadPreviewList.tsx
UploadQueueList.tsx
GalleryMasonry.tsx
PhotoCard.tsx
FiltersBar.tsx
Toast.tsx
stores/
useEventStore.ts // tenant/event token, theme
useProfileStore.ts // name/avatar (local)
useUploadQueue.ts // IndexedDB-backed queue
services/
apiClient.ts // fetch wrapper + trace id
eventsApi.ts // GET event meta
photosApi.ts // list/finalize/like
uploadService.ts // request signed URL, do PUT, finalize; photo only
sw.ts // service worker register helpers
hooks/
useOnline.ts
useA2HS.ts
usePollStats.ts // polls /events/:slug/stats every 10s
usePollGalleryDelta.ts // polls /events/:slug/photos?since=...
i18n/
de.json
en.json
main.tsx
App.tsx
Router Sketch (React Router v6)
import { createBrowserRouter } from 'react-router-dom';
import EventGuard from './routes/EventGuard';
import PrefetchEvent from './routes/PrefetchEvent';
export const router = createBrowserRouter([
{ path: '/', element: <LandingPage /> },
{ path: '/setup', element: <ProfileSetupPage /> },
{
path: '/e/:slug',
element: (
<EventGuard>
<PrefetchEvent>
<HomeLayout />
</PrefetchEvent>
</EventGuard>
),
children: [
{ index: true, element: <HomePage /> },
{ path: 'tasks', element: <TaskPickerPage /> },
{ path: 'tasks/:taskId', element: <TaskDetailPage /> },
{ path: 'upload', element: <UploadPage /> },
{ path: 'queue', element: <UploadQueuePage /> },
{ path: 'gallery', element: <GalleryPage /> },
{ path: 'photo/:photoId', element: <PhotoLightbox /> },
{ path: 'achievements', element: <AchievementsPage /> },
{ path: 'slideshow', element: <SlideshowPage /> },
],
},
// Settings sheet is rendered inside Header; no standalone route.
{ path: '/legal/:page', element: <LegalPage /> },
{ path: '*', element: <NotFoundPage /> },
]);
Component Checklist
- Layout
Header,InfoBar(X Gäste online • Y Aufgaben gelöst),BottomNav,Toast.
- Entry
QRPinForm(QR deep link or PIN fallback),ProfileForm(name/avatar).
- Home/Feed
HeroCard(Willkommensgruess + Eventtitel) undStatTiles(online Gaeste, geloeste Aufgaben, letztes Upload).CTAButtons(Aufgabe ziehen, Direkt-Upload, Galerie) +UploadQueueLinkfuer Warteschlange.EmotionPickerGridundGalleryPreviewals inhaltlicher Einstieg.
- Tasks
EmotionPickerGrid,TaskCard(shows duration, group size, actions).
- Capture/Upload (photos only)
CameraPicker,UploadPreviewList,UploadQueueList.
- Photo View
PhotoLightbox(modal), like/share controls, emotion tags.
- Settings & Legal
SettingsSheet(Header-Overlay mit Namenseditor, eingebetteten Rechtsdokumenten, Cache-Leeren),LegalPageRenderer.
State & Data
- TanStack Query for server data (events, photos); optimistic updates for likes.
- Zustand store for local-only state (profile, queue, banners).
- IndexedDB for upload queue; CacheStorage for shell/assets.
- Polling: focus-aware intervals (10s stats, 30s gallery); use document visibility to pause; backoff on failures.
Accessibility & Performance
- Focus management on modal open/close; trap focus.
- Color contrast and minimum tap target sizes (44px).
- Code-split camera/lightbox/slideshow; prefetch next gallery page.
Out of Scope
- Video capture/upload is not supported.