diff --git a/repositories/d-sports-engage-native.mdx b/repositories/d-sports-engage-native.mdx index e79c1b6..d9c50be 100644 --- a/repositories/d-sports-engage-native.mdx +++ b/repositories/d-sports-engage-native.mdx @@ -1,56 +1,71 @@ --- title: "d-sports-engage-native" -description: "Native iOS and Android app for D-Sports Engage. Expo 54, React Native, Clerk, RevenueCat, Thirdweb." +description: "Native iOS and Android app for D-Sports Engage. Expo 55, React Native 0.83, Clerk, RevenueCat, Thirdweb." icon: "smartphone" --- ## Overview -**d-sports-engage-native** (package name: `engage-native`) is the native mobile app for D-Sports. It mirrors the core PWA experience on iOS and Android: wallet, shop, leaderboard, locker room, and profile. +**d-sports-engage-native** (package name: `engage-native`, version **1.18.1**) is the native mobile app for D-Sports. It mirrors the core PWA experience on iOS and Android: wallet, shop, leaderboard, locker room, and profile. -- **Run:** `bunx expo start` or `bun run start` — then press `a` for Android or `i` for iOS, or scan the QR code with Expo Go. +- **Run:** `bunx expo start` — then press `a` for Android or `i` for iOS, or scan the QR code with Expo Go. +- **TypeScript check:** `bun tsc --noEmit` ## Tech stack -| Category | Technology | -| ---------- | ------------------------- | -| Framework | Expo 54, React Native 0.81, React 19 | -| Auth | Clerk (Expo) | -| Payments | RevenueCat (react-native-purchases) | -| Web3 | Thirdweb | -| State | Zustand | -| Storage | MMKV | -| UI | Lucide React Native | -| Navigation | Expo Router | -| Package | Bun | +| Category | Technology | +| ------------- | ----------------------------------------------- | +| Framework | Expo 55, React Native 0.83.4, React 19.2 | +| Auth | Clerk (`@clerk/clerk-expo`) | +| Payments | RevenueCat (`react-native-purchases`) | +| Web3 | Thirdweb SDK | +| State | Zustand 5 + MMKV persistence | +| Navigation | Expo Router 55 (file-based, typed routes) | +| Push | OneSignal (`react-native-onesignal`) | +| Monitoring | Sentry (`@sentry/react-native`) | +| Analytics | Vercel Analytics | +| UI | Lucide React Native | +| Animations | React Native Reanimated 4 | +| Package | Bun | ## Features -- **Wallet** — Tokens, holdings, pack opening, crypto checkout (via PWA backend) -- **Shop** — Collectibles, cart, coin bundles, checkout -- **Leaderboard** — Rankings and filters -- **Locker room** — Social feed and engagement -- **Profile** — User profile and settings -- **Theme** — Dark/light mode (default dark) - -## What changed since last docs sync - -- Team-aware experiences were expanded to align with backend team/favorites behavior. -- Quest and rewards surfaces were updated to support per-team progression and pass-aware eligibility. -- Pack opening and odds disclosure UX were upgraded with safer interactions and clearer status/error handling. -- Settings and account flows were expanded, including in-app account deletion and richer support/data controls. +- **Wallet** — token balances, holdings, pack opening, crypto checkout (Thirdweb + PWA backend) +- **Shop** — collectibles, 3D model viewer, cart, coin bundles, RevenueCat + crypto checkout +- **Leaderboard** — team-scoped rankings, quest hero icons, per-team quest sections +- **Locker room** — social feed, daily pick'em, spin wheel, guess the player, explore fans/teams +- **Profile** — achievement badges, milestone avatars, follow lists, points history +- **Settings** — account management, accessibility, appearance, notifications, support, changelog +- **Widgets** — iOS home screen and Live Activity widgets, Android home screen widget +- **Theme** — dark/light mode (default dark) + +## Environment variables + +The app uses `EXPO_PUBLIC_*` prefixed variables accessible at runtime: + +| Variable | Purpose | +| -------- | ------- | +| `EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY` | Clerk authentication | +| `EXPO_PUBLIC_API_URL` | Backend API base URL | +| `EXPO_PUBLIC_TW_CLIENT_ID` | Thirdweb client ID | +| `EXPO_PUBLIC_REVENUECAT_API_KEY` | RevenueCat API key | +| `EXPO_PUBLIC_REVENUECAT_APPSTORE_ID` | RevenueCat App Store ID | +| `EXPO_PUBLIC_REVENUECAT_ENTITLEMENT` | RevenueCat entitlement ID | +| `EXPO_PUBLIC_SUPABASE_URL` | Supabase project URL | +| `EXPO_PUBLIC_SUPABASE_KEY` | Supabase publishable key | ## Backend integration surfaces - Primary API source: `d-sports-api` under `/api/*`. - Native app consumes team, league, quest, reward, wallet, commerce, and social endpoints. -- Retry/caching logic and auth token injection are centralized in app API client modules. +- Retry/caching logic and auth token injection are centralized in `lib/api/client.ts` with MMKV cache fallback. +- Crypto checkout calls the PWA backend (`POST /api/checkout/crypto` and `/api/checkout/crypto/verify`), then signs on-chain via Thirdweb. ## Quest and pass UX integration -- Quest UI now reflects team-scoped eligibility and pass-gated progression where applicable. +- Quest UI reflects team-scoped eligibility and pass-gated progression where applicable. - Reward presentation differentiates free/unpaid states and claimability. -- Native progression state is expected to mirror backend eligibility and completion semantics. +- Native progression state mirrors backend eligibility and completion semantics. ## Team-aware experiences @@ -64,12 +79,36 @@ icon: "smartphone" ## Getting started -1. Clone the repository and run `bun install`. -2. Configure environment (Clerk, RevenueCat, Thirdweb, API base URL) per repo README. -3. Run `bunx expo start`. -4. For development builds: `bun run build:dev` (EAS) or run with Expo dev client. - -The app targets both native and web (responsive) and uses the same backend (d-sports-api) as the PWA for API and checkout flows. + + + ```bash + bun install + ``` + + + Copy `.env` and set your `EXPO_PUBLIC_*` keys for Clerk, RevenueCat, Thirdweb, and the API base URL. + + + ```bash + bunx expo start + ``` + Press `a` for Android, `i` for iOS, or scan the QR code with Expo Go. + + + ```bash + # Development build (all platforms) + bun run build:dev + + # Preview build (iOS only) + bun run build:preview:ios + + # Production build with App Store submission + bun run build:submit:ios + ``` + + + +The app targets both native and web (responsive) and uses the same backend (`d-sports-api`) as the PWA for API and checkout flows. ## Deep dives diff --git a/repositories/d-sports-engage-native/architecture.mdx b/repositories/d-sports-engage-native/architecture.mdx index af786e3..a92d343 100644 --- a/repositories/d-sports-engage-native/architecture.mdx +++ b/repositories/d-sports-engage-native/architecture.mdx @@ -3,28 +3,105 @@ title: "Native architecture" description: "Architecture overview for d-sports-engage-native application layers and platform behavior." --- -## App architecture +## Project structure -The native app is structured around Expo Router screens, feature-oriented components, shared hooks, and API modules. +```text +app/ +├── (auth)/ # Login/signup screens +├── (onboarding)/ # New user onboarding flow +├── (tabs)/ # Main tab navigation +│ ├── wallet.tsx # Wallet screen (JSX only — logic in hook) +│ ├── shop.tsx # Shop screen (JSX only — logic in hook) +│ ├── leaderboard/ # Leaderboard screens +│ ├── locker-room/ # Social feed +│ └── profile.tsx # User profile +├── settings/ # Settings pages with nested modals/tabs +└── _layout.tsx # Root layout with providers + auth protection -- Routing: `app/*` with grouped routes for tabs/auth/onboarding/settings. -- Feature logic: extracted hooks for wallet, shop, locker room, and settings. -- Shared contexts: user, collectibles, accessibility, and UI visibility/state controls. +components/ +├── wallet/ # Extracted wallet sub-components +├── shop/ # Extracted shop sub-components +├── locker-room/ # Locker room components +├── leaderboard/ # Leaderboard components +├── profile/ # Profile components +├── settings/ # Settings components +├── navigation/ # PillTabBar, tab config +├── layout/ # AppScreen wrapper (responsive web max-width) +├── ui/ # Reusable UI primitives +├── Icon/ # Icon wrapper (lucide-react-native) +└── theme-provider.tsx # Theme context (dark/light) -## State and context boundaries +hooks/ # Feature hooks (use-wallet-screen, use-shop-screen, etc.) +lib/api/ # API client modules with MMKV cache fallback +context/ # React Context providers (user, collectibles, navbar) +services/ # Zustand store, MMKV storage, types +theme/ # Brand colors, design tokens +types/ # Shared TypeScript types +constants/ # Shared constants +``` -- Local/ephemeral UI state lives near feature hooks and components. -- Cross-screen state is managed with context providers and persisted storage where required. -- User/session-sensitive state is coordinated with backend auth and profile sync endpoints. +## Routing -## API client and retry behavior +The app uses **Expo Router** with file-based routing and typed routes enabled. + +- **Route groups:** `(tabs)` for main navigation, `(auth)` for login/signup, `(onboarding)` for new users +- **Settings:** `settings/` directory contains settings pages with nested components, modals, and tabs +- **Auth protection:** `_layout.tsx` automatically redirects based on authentication and onboarding state +- **Path alias:** `@/*` maps to the project root + +## Screen pattern + +Screen files contain **only imports and JSX**. All state, effects, and handlers live in dedicated hooks: + +- `hooks/use-wallet-screen.ts` — wallet state, token fetch effects, PIN verification, transaction handlers +- `hooks/use-shop-screen.ts` — cart state, product queries, carousel auto-scroll, checkout logic +- `hooks/use-feed-section.ts` — locker room feed logic + +Sub-components are extracted into `components/wallet/`, `components/shop/`, etc. with barrel exports via `index.ts`. + +## Tab bar + +The tab bar implementation differs by platform: + +- **iOS:** uses `NativeTabs` from `expo-router/unstable-native-tabs` (system UIKit tab bar) with `systemChromeMaterialDark` material and gold selection accent (`#FFD700`). +- **Android + web:** uses a custom JS `PillTabBar` overlay with `expo-blur` (`BlurView`). The default system tab bar is hidden. +- **Shared config:** `components/navigation/tab-config.ts` defines tab order, SF Symbol pairs for iOS, and active-tab resolution logic. + +## State management + +| Layer | Technology | Location | +| ----- | ---------- | -------- | +| Global store | Zustand 5 + MMKV persistence | `services/store.ts`, `services/storage.ts` | +| Auth and user | React Context | `context/user-context.tsx` | +| Collectibles | React Context | `context/collectibles-context.tsx` | +| Navbar visibility | React Context | `context/navbar-visibility-context.tsx` | +| Local/ephemeral | Component state in hooks | `hooks/use-*-screen.ts` | + +## API client and caching - All network calls route through `lib/api/*` modules. -- Client wrappers handle auth token propagation, error normalization, and retry strategy. -- Quest/reward/team flows should consume backend eligibility as source of truth. +- `lib/api/client.ts` handles auth token injection (Clerk), error normalization, and retry strategy. +- `lib/api/cache.ts` provides `fetchWithCache()` with MMKV cache-first fetching. +- Domain modules: `wallet-api.ts`, `shop-api.ts`, `user-api.ts`, `quests-api.ts`, `leaderboard-api.ts`, `locker-room-api.ts`, `teams-api.ts`, `collectibles-api.ts`, `checkout-api.ts`, `games-api.ts`. + +## Checkout and payments + +| Method | Technology | Details | +| ------ | ---------- | ------- | +| Fiat (Apple IAP, Google Play, Stripe) | RevenueCat | `lib/revenuecat/provider.tsx` | +| Crypto (on-chain) | Thirdweb SDK | `lib/api/checkout-api.ts` calls `POST /api/checkout/crypto`, Thirdweb signs the transaction | + +Supported chains for crypto checkout: **Arbitrum** (default), Ethereum, Polygon. ## Platform-specific behavior -- iOS/Android platform differences are handled in native-specific components and runtime checks. -- Web-target support exists but mobile behavior is primary for interaction and performance design. -- Haptics, modal controls, and animation handling are implemented with platform-safe fallbacks. +- **iOS/Android:** platform differences are handled in native-specific layout files (e.g., `_layout.ios.tsx` vs `_layout.android.tsx`) and runtime checks. +- **Web:** responsive desktop layout via `AppScreen` wrapper (`maxWidth: 480px`), web hover states (`WebHoverWrapper`), PWA manifest with `display: standalone`. +- **Haptics:** `expo-haptics` with platform-safe fallbacks. +- **Animations:** React Native Reanimated 4 for scroll-based navbar hide/show and UI transitions. + +## Widgets + +- **iOS:** `RankOrPointsWidget` (small/medium) and `LiveStatusActivity` (Live Activity for score updates) via `expo-widgets`. +- **Android:** `RankOrPointsWidget` via `react-native-android-widget`, refreshes every 30 minutes. +- Widget data is prepared in `lib/widget-data.ts`.