106 lines
5.9 KiB
Markdown
106 lines
5.9 KiB
Markdown
# Yaltopia Tickets App — Agent Guide
|
|
|
|
## First Read
|
|
|
|
Read these before writing any code:
|
|
- `app/_layout.tsx` — root stack, guards, heartbeat, fonts, theme
|
|
- `lib/api.ts` — API services & endpoint definitions
|
|
- `lib/api-middlewares.ts` — auth injection + token refresh logic
|
|
- `lib/routes.ts` — all route definitions with guard metadata
|
|
- `lib/auth-store.ts` — zustand persisted auth state
|
|
|
|
## Commands
|
|
|
|
```
|
|
npm run start # expo start
|
|
npm run android # expo run:android
|
|
npm run ios # expo run:ios
|
|
npm run web # expo start --web
|
|
```
|
|
|
|
No lint, typecheck, or test scripts exist. No `postinstall` hook beyond `patch-package`.
|
|
|
|
## Project Structure
|
|
|
|
- **`app/`** — expo-router file-based screens; entry point is `expo-router/entry` (set in `package.json` `main`)
|
|
- **`app/(tabs)/`** — 5 bottom tabs: index (Home), payments, scan, proforma, news
|
|
- **`lib/`** — API client (`api.ts`), middleware (`api-middlewares.ts`), stores, guards, routes, permissions, theme, utils
|
|
- **`components/`** — shared UI; `components/ui/` has shadcn-style primitives (button, text, card)
|
|
- **Path alias**: `@/` → project root (tsconfig paths)
|
|
|
|
## Key Conventions
|
|
|
|
- **Navigating**: `useSirouRouter<AppRoutes>().go("routeName", { params })` — NOT expo-router's `router.push`. Import `AppRoutes` from `@/lib/routes`.
|
|
- **API calls**: Use the `@simple-api` client (`api.{service}.{endpoint}({ body, params, query, headers })`). For file uploads (scan), use raw `fetch` with FormData.
|
|
- **Auth tokens**: Never manually inject Bearer. `authMiddleware` does it automatically + proactively refreshes near-expiry tokens via `refreshTokens()` singleton promise.
|
|
- **Phone numbers**: Ethiopian `+251` is auto-prepended. Input fields accept the 9-digit number without prefix.
|
|
- **Toast**: `import { toast } from "@/lib/toast-store"` then `toast.success("Title", "Message")`, `.error()`, `.warning()`, `.info()`.
|
|
- **Form screens** use inline `StyleSheet.create` for input styles and `useInputColors()` custom hook for theming. No form validation library.
|
|
|
|
## UI Patterns (look at existing screens)
|
|
|
|
- **Tab bar**: Floating pill, `absolute`, `bottom: 25`, `marginHorizontal: 20`, `borderRadius: 32` (see `app/(tabs)/_layout.tsx`)
|
|
- **Primary color**: `#ea580c` (orange) — used as `text-primary`, `bg-primary`, `color="#ea580c"`
|
|
- **Cards**: `<Card>` + `<CardContent>` from `@/components/ui/card`, often wrapped in `<ShadowWrapper level="xs">`
|
|
- **Text**: `<Text variant="h1|h2|h3|h4|p|muted|small">` from `@/components/ui/text`
|
|
- **Buttons**: `<Button variant="default|outline|destructive|ghost|secondary" size="default|sm|lg|icon">`
|
|
- **Status badges**: `text-[9px] font-semibold uppercase tracking-widest` with semi-transparent bg
|
|
- **Section labels**: `font-bold text-xs uppercase tracking-widest`
|
|
- **Filter pills**: `rounded-[4px] px-4 py-1.5`
|
|
- **Bottom sheet pickers**: `<PickerModal>` + `<SelectOption>` from `@/components/PickerModal`
|
|
- **Confirmation modals**: `<ActionModal>` from `@/components/ActionModal`
|
|
- **Empty states**: `<EmptyState>` with `previewLines`, `actionLabel`, `onActionPress`
|
|
- **No gradients** anywhere (enforced by AGENTS.md). Use solid colors.
|
|
|
|
## State Stores (zustand)
|
|
|
|
| Store | File | Persisted? | Key |
|
|
|---|---|---|---|
|
|
| `useAuthStore` | `lib/auth-store.ts` | Yes (AsyncStorage) | `yaltopia-auth-storage` |
|
|
| `useLanguageStore` | `lib/language-store.ts` | Yes (AsyncStorage) | `app-language` |
|
|
| `useToast` | `lib/toast-store.ts` | No | — |
|
|
|
|
Theme is persisted via `saveTheme()`/`loadTheme()` in `lib/theme.ts` using AsyncStorage key `app_theme_preference`. Not a zustand store.
|
|
|
|
## API Endpoints (lib/api.ts)
|
|
|
|
`BASE_URL = https://api.yaltopiaticket.com/`
|
|
|
|
Services: `auth`, `invoices`, `payments`, `proforma`, `scan`, `users`, `company`, `news`, `notifications`, `rbac`, `support`, `faq`
|
|
|
|
Middleware pipeline: logger → transformer → refresh (401 retry) → auth (Bear token + proactive refresh)
|
|
|
|
## Route Guards (@sirou)
|
|
|
|
Routes are defined in `lib/routes.ts` with guards metadata (strings `"auth"` or `"guest"`). Guards are pure functions in `lib/auth-guards.ts`. `GlobalGuard` in `app/_layout.tsx` runs supplementary auth/guest checks.
|
|
|
|
## Scan Flow
|
|
|
|
Camera → capture → preview → press "Extract" → raw `fetch` POST to `/scan/invoice` or `/scan/payment-receipt` with FormData → parse OCR result → `api.invoices.create()` with mapped data → navigate to detail.
|
|
|
|
## Notes
|
|
|
|
- **Google Sign-In** is lazy-loaded in a try/catch block — native module may not be available in Expo Go.
|
|
- **SMS scanning** (`react-native-get-sms-android`) is Android-only and also lazy-loaded.
|
|
- **No local database** — pure API-consumed app.
|
|
- RBAC permissions in `lib/permissions.ts` — roles: ADMIN, BUSINESS_OWNER, EMPLOYEE, ACCOUNTANT, CUSTOMER_SERVICE, AUDITOR, VIEWER.
|
|
- CSS variables in `global.css` power NativeWind theme. `darkMode: "class"` in tailwind config.
|
|
|
|
## Design Context
|
|
|
|
Before any UI work, read these two files for design strategy + visual system:
|
|
- **`PRODUCT.md`** — register, users, brand personality, design principles, anti-references
|
|
- **`DESIGN.md`** — colors, typography, components, elevation, do's and don'ts
|
|
- **`.impeccable/design.json`** — machine-readable design tokens with tonal ramps and component snippets
|
|
|
|
Key rules:
|
|
- Primary orange `#E46212` on ≤20% of surfaces. Flat-by-default (no shadows on cards/buttons). One typeface (DM Sans, weight creates hierarchy). True white backgrounds, not tinted.
|
|
|
|
## UI Build Process
|
|
|
|
When building UI, ALWAYS use both skills together:
|
|
1. **yimpeccable** (`.agents/skills/yimpeccable/`) — run `$impeccable <command>` per its reference. Provides design guidance, register context, color/typography/layout rules.
|
|
2. **ui-ux-pro-max** (`.opencode/skills/ui-ux-pro-max/`) — run `python3 .opencode/skills/ui-ux-pro-max/scripts/search.py "<query>" --design-system` or domain-specific searches. Provides design system recommendations, color palettes, font pairings, UX guidelines.
|
|
|
|
Always load both skill files and follow their workflows on any UI task.
|