diff --git a/repositories/d-sports-engage-native.mdx b/repositories/d-sports-engage-native.mdx index e79c1b6..48c860c 100644 --- a/repositories/d-sports-engage-native.mdx +++ b/repositories/d-sports-engage-native.mdx @@ -6,51 +6,72 @@ 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.17.4**) 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 54, React Native 0.81, React 19 | +| Auth | Clerk (`@clerk/clerk-expo`) | +| Payments | RevenueCat (`react-native-purchases`) | +| Web3 | Thirdweb | +| State | Zustand 5 | +| Storage | MMKV | +| UI | Lucide React Native | +| Navigation | Expo Router 6 | +| Push | OneSignal (`react-native-onesignal`) | +| Error tracking | Sentry (`@sentry/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** — Tokens, holdings, pack opening, send/receive, crypto checkout (via PWA backend) +- **Shop** — Collectibles, cart, coin bundles, fiat (RevenueCat) and crypto checkout +- **Leaderboard** — Per-team and global rankings with team-slug routes +- **Locker room** — Social feed, quest center, and mini-games (Daily Spin Wheel, Guess the Player, Daily Pick'em) +- **Profile** — User profile, milestone avatar rings, achievements, follower/following lists, points history +- **Settings** — Account, accessibility, appearance, notifications, support, legal, and in-app account deletion +- **Theme** — Dark mode default (base `#0a0e1a`, gold `#F5C842`, blue `#4169E1`) + +## Environment variables + +The app reads `EXPO_PUBLIC_*` environment variables at runtime. You need to set these in a `.env` file at the repo root: + +| Variable | Purpose | +| -------- | ------- | +| `EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY` | Clerk authentication | +| `EXPO_PUBLIC_API_URL` | Backend API base URL (e.g. `https://api.d-sports.org`) | +| `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 identifier | +| `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`. + +## EAS builds and OTA updates + +The repo includes EAS build profiles in `eas.json` and a GitHub Actions workflow (`.github/workflows/eas-update.yml`) for OTA updates: + +- Pushes to `develop` publish an OTA update to the **develop** branch. +- Pushes to `main` publish an OTA update to the **main** branch. +- Build commands: `bun run build:dev`, `bun run build:preview`, `bun run build:prod` (all via `eas-cli`). ## 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 @@ -65,9 +86,10 @@ icon: "smartphone" ## Getting started 1. Clone the repository and run `bun install`. -2. Configure environment (Clerk, RevenueCat, Thirdweb, API base URL) per repo README. +2. Create a `.env` file with the required environment variables listed above. 3. Run `bunx expo start`. 4. For development builds: `bun run build:dev` (EAS) or run with Expo dev client. +5. For native builds: `expo run:ios` or `expo run:android`. The app targets both native and web (responsive) and uses the same backend (d-sports-api) as the PWA for API and checkout flows. diff --git a/repositories/d-sports-engage-native/architecture.mdx b/repositories/d-sports-engage-native/architecture.mdx index af786e3..22061fb 100644 --- a/repositories/d-sports-engage-native/architecture.mdx +++ b/repositories/d-sports-engage-native/architecture.mdx @@ -7,24 +7,82 @@ description: "Architecture overview for d-sports-engage-native application layer The native app is structured around Expo Router screens, feature-oriented components, shared hooks, and API modules. -- 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. +- **Routing:** `app/*` with grouped routes — `(tabs)` for main navigation, `(auth)` for login/signup, `(onboarding)` for new users, and `settings/` for nested settings pages. +- **Feature logic:** extracted hooks (`hooks/use-wallet-screen.ts`, `hooks/use-shop-screen.ts`, etc.) keep screen files as thin JSX render shells. +- **Shared contexts:** `UserContext` (auth, profile, team membership), `CollectiblesContext` (owned packs/items), `NavBarVisibilityContext`, and `CreateActionContext`. + +## Project structure + +``` +app/ +├── (auth)/ # Login/signup (Clerk email+password, Apple, Google) +├── (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 with [teamSlug] routes +│ ├── locker-room/ # Social feed with game routes +│ └── profile.tsx # User profile +├── settings/ # Settings pages with nested modals/tabs +└── _layout.tsx # Root layout with providers + auth protection + +components/ +├── wallet/ # 9 wallet sub-components with barrel export +├── shop/ # 7 shop sub-components +├── locker-room/ # Locker room + game components +├── leaderboard/ # Leaderboard components +├── profile/ # Profile, achievements, milestones +├── settings/ # Settings sections, modals, tabs +├── ui/ # Reusable primitives (Button, TextField, etc.) +└── Icon/ # Icon wrapper using lucide-react-native + +hooks/ # Feature hooks (use-wallet-screen, use-shop-screen, etc.) +lib/api/ # API client modules (wallet, shop, user, quests, etc.) +types/ # Shared types (wallet, shop, checkout, api) +constants/ # Shared constants (wallet, shop, locker room) +context/ # React context providers +services/ # Zustand store, MMKV storage, core types +theme/ # Colors, fonts, spacing, typography +``` ## State and context boundaries - Local/ephemeral UI state lives near feature hooks and components. - Cross-screen state is managed with context providers and persisted storage where required. +- **Zustand** store in `services/store.ts` with MMKV persistence for theme, cart, and points. - User/session-sensitive state is coordinated with backend auth and profile sync endpoints. ## API client and retry behavior -- All network calls route through `lib/api/*` modules. +- All network calls route through `lib/api/*` modules with a base client in `lib/api/client.ts`. +- `lib/api/index.ts` exposes a `useApi()` hook for all API modules (wallet, shop, user, quests, leaderboard, locker room, teams, collectibles, checkout). +- `lib/api/cache.ts` provides `fetchWithCache()` for MMKV cache-first fetching. - Client wrappers handle auth token propagation, error normalization, and retry strategy. -- Quest/reward/team flows should consume backend eligibility as source of truth. + +## Platform-specific tab bar + +The tab navigation uses different implementations per platform: + +- **iOS:** `app/(tabs)/_layout.ios.tsx` uses `NativeTabs` from `expo-router/unstable-native-tabs` (system UIKit tab bar). Uses `systemChromeMaterialDark` with gold selection tint (`#FFD700`). +- **Android and web:** `app/(tabs)/_layout.tsx` uses JS `Tabs` with a hidden default bar and a custom `PillTabBar` overlay. Android uses `expo-blur` for the blur surface. +- **Shared config:** `app/(tabs)/tab-config.ts` defines tab order, SF Symbol pairs, and active-tab pathname resolution. + +## Checkout and payments + +- **Fiat:** RevenueCat (`lib/revenuecat/provider.tsx`) handles Apple IAP (native), Google Play (native), and Stripe (web). +- **Crypto:** `lib/api/checkout-api.ts` calls the PWA backend (`POST /api/checkout/crypto`). On-chain transactions use Thirdweb SDK via `lib/crypto/send-transaction.ts`. Supported chains: Arbitrum (default), Ethereum, Polygon. + +## Push notifications + +OneSignal is integrated via `react-native-onesignal` and the `onesignal-expo-plugin`. Subscription management is in `lib/onesignal-subscription.ts`. + +## Error monitoring + +Sentry (`@sentry/react-native`) is configured via the Expo plugin in `app.json`. Runtime initialization happens in `app/_layout.tsx`. ## 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. +- iOS/Android platform differences are handled in native-specific component files (e.g. `_layout.ios.tsx`). +- Web-target support exists with responsive layout (`components/layout/AppScreen.tsx`, max width 480px) and web hover states. - Haptics, modal controls, and animation handling are implemented with platform-safe fallbacks. +- Path alias `@/*` maps to the project root for all imports. diff --git a/repositories/d-sports-engage-native/feature-mapping.mdx b/repositories/d-sports-engage-native/feature-mapping.mdx index 27fbcd7..e0434f8 100644 --- a/repositories/d-sports-engage-native/feature-mapping.mdx +++ b/repositories/d-sports-engage-native/feature-mapping.mdx @@ -10,6 +10,7 @@ description: "Native feature coverage and parity mapping against backend/PWA beh ## Wallet and pack opening - Wallet screens consume balances, token data, and secure key/pin flows from backend APIs. +- **Send and receive** — send on-chain transactions via `lib/crypto/send-transaction.ts`; receive modal shows wallet address with copy and QR code. - Pack browsing, purchase, and open flows use backend-driven states and inventory refresh behavior. - Odds-disclosure surfaces read backend-provided probability payloads. @@ -18,9 +19,38 @@ description: "Native feature coverage and parity mapping against backend/PWA beh - Quest UI supports team-aware progression and pass-gated eligibility. - Reward states and claim flows follow backend quest/reward APIs. - Global pass and event pass effects are reflected in native quest visibility/completion UX. +- Quest center uses MMKV cache with TTL-based invalidation and refetches on tab focus. ## Team and leaderboard integration - Teams and leagues metadata are consumed from backend `/api/teams` and `/api/leagues`. -- Leaderboard displays and team-scoped ranking views align with backend leaderboard contracts. +- Leaderboard displays use per-team stack routes (`/leaderboard/[teamSlug]`) and team-scoped ranking views. - Favorite-team interactions influence quest and leaderboard context where backend eligibility requires it. +- Team logos are resolved through `lib/team-logo-utils.ts` with protocol normalization and error fallbacks. + +## Locker room and mini-games + +- Social feed with post creation, comments, and user-generated content moderation (report, hide). +- **Daily Spin Wheel** (`components/locker-room/DailySpinWheelGame.tsx`) — daily reward spin with segment/outcome alignment and claim flows. +- **Guess the Player** (`components/locker-room/GuessThePlayerGame.tsx`) — player identification game. +- **Daily Pick'em** (`components/locker-room/DailyPickEmGame.tsx`) — daily prediction game. +- Featured games carousel with dedicated stack routes (`/locker-room/wheel-spin`, `/locker-room/player-guess`). +- Explore teams and explore fans carousels with web drag support. + +## Profile and achievements + +- User profile with milestone avatar rings (tier-colored SVG ring based on reward milestones). +- Achievement cards, chips, and detail modals with rarity styling. +- Points history modal with chronological breakdown by kind (quest, game, onboarding, other). +- Follower/following lists with follow/unfollow from public profiles. + +## Authentication + +- Clerk email and password sign-in with OTP email verification for new users. +- Two-factor authentication support (authenticator app, SMS, backup code). +- OAuth via Apple and Google. + +## Notifications + +- Push notifications via OneSignal with subscription management in `lib/onesignal-subscription.ts`. +- In-app notification screen at `app/notifications.tsx`.