Components¶
Every component lives under frontend/components/, grouped by feature (auth, chat, friends, ...) plus a shared ui/ primitive folder. Feature folders depend on ui/; they never reach into each other.
Folder map¶
| Folder | Purpose | Notable contents |
|---|---|---|
components/auth/ |
Login / register / OTP / passkey UI | Social-login buttons (Google, Apple, LINE), OTP input grid, password strength meter, complete-profile form |
components/chat/ |
DM + group chat surface | Message bubbles, composer, reaction picker, reply preview, typing indicator, klipy/GIF picker integration, message-actions sheet |
components/discover/ |
Discovery feed + filters | Feed card, filter chips, cluster expanders, near-you carousel |
components/forms/ |
Reusable form pieces | LocationAutocomplete (with .android.tsx Places-API variant), category picker, date/time picker, image picker tile |
components/friends/ |
Friend graph UI | Friend cards, request rows, accept/decline actions, friends list, suggestions |
components/horizon/ |
Personal timeline UI | Event/voyage/waypoint cards, timeline sectioning, empty states |
components/layout/ |
App chrome | AppNav (bottom dock on mobile, sidebar on desktop), PageHeader, safe-area wrappers |
components/location/ |
Location-sharing UI | Permission prompts, location sharing toggles, status badges |
components/map/ |
Map view (platform-split) | react-native-maps on .ios.tsx / .android.tsx, react-leaflet on .web.tsx; shared marker, cluster, and popup logic |
components/modals/ |
Full-screen modals | CreateEventModal (mounted once at the root layout), share modal, report modal, image viewer |
components/profile/ |
Profile + settings UI | Profile header, stat row, edit forms, theme picker, account/security/security forms |
components/ui/ |
Theme-aware primitives | Button, Input, Chip, Toast, GlassView, GroupAvatar, GalleryCard, NavBottomSheet, SnapBottomSheet… (~20 files; see Design System) |
components/website/ |
Public marketing pages (web-only) | Landing hero, feature sections, decorative voxel/anim components |
Platform splits¶
Two folders contain genuinely divergent platform code:
components/map/¶
| Bundle | Library | Why |
|---|---|---|
*.web.tsx |
leaflet + react-leaflet (over OSM tiles) |
react-native-maps doesn't ship a web target; Leaflet runs natively in the DOM |
*.tsx (native) |
react-native-maps (Google Maps SDK) |
Native rendering, gestures, and clustering |
Metro picks .web.tsx for the web bundle and the un-suffixed (or .android.tsx / .ios.tsx) variant for native. The two implementations share the same prop contract so screen-level code is platform-agnostic.
components/forms/LocationAutocomplete*¶
| File | Behavior |
|---|---|
LocationAutocomplete.android.tsx |
Calls Google Places API directly (needs a backend proxy — see frontend/ANDROID_SETUP.md TODOs) |
LocationAutocomplete.tsx |
Plain TextInput fallback on iOS and web (no Places API costs) |
components/website/¶
The marketing website renders only inside the web bundle. On native, these files are never imported (the route exists only on the web target). They lean on web-native primitives — CSS animations, hover states, scroll observers via ScrollRevealView.
Composition rules¶
ui/is the only shared dependency. Feature folders import fromcomponents/ui/and fromservices//contexts//utils/— never from each other.- Routes are thin. A route file in
app/typically composes 2–4 feature components plus layout chrome. - State stays high. Cross-cutting state lives in
contexts/; intra-feature state is local to the feature folder. - Theme reads happen once. Every component reads
useTheme()at the top and feedsthemeinto a memoizedmakeStyles(theme)factory.
Cross-links¶
- Design System — what's inside
components/ui/ - Architecture — how components fit into the layered model
- Routing — which routes consume which feature folders