# CasaDoc — mobile app Mobile client for the CasaDoc property-document platform, for iOS and Android from a single codebase. **Stack:** Expo SDK 52 · React Native 0.76 · expo-router · TypeScript · React Query · expo-secure-store · i18n-js. The app can run against the PHP backend or against in-memory demo data; the choice is one constant in `src/api/config.ts`. --- ## Features **Account** - Login with email and password, bearer token kept in SecureStore, auto-login on next launch. - Registration with e-mail code verification. - Password recovery (request a code, set a new password) and password change from inside the app. - Profile editing, avatar, account deletion. - Interface in Italian and English, following the device language, with a manual override in the profile. **Properties** - List with cover image, address and document counters. - Detail screen with document categories as folders and recent documents. - Create and edit, including a map picker for the address (react-native-maps). **Documents** - Per-property list, filtered by category and by status. - Search across every document of every property. - Expiry tracking: valid, expiring and expired badges, warning banners, and a dedicated tab listing everything that needs attention. - Detail screen with an inline preview for images and a card that hands PDFs to the phone's own viewer; sharing and deletion. - Editing of name, category and expiry date. **Adding a document** - From the file picker, from the photo library, or with the built-in scanner. - The scanner uses the native document scanner (ML Kit on Android, VisionKit on iOS) with edge detection and perspective correction, captures several pages and combines them into one PDF (`src/scanner/scanToPdf.ts`). **Offline** - Responses are cached and persisted, so a previously opened screen still shows its content without a connection; a banner appears while the device is offline and the data refreshes as soon as it is back. --- ## Getting started ```bash npm install ``` The scanner, the maps and the file viewer are native modules, so the app needs a development build rather than Expo Go: ```bash npx expo run:ios # or: npx expo run:android npm start # subsequent runs ``` With EAS instead of a local build: ```bash npx eas build --profile development --platform ios # or android ``` `npm run prebuild` regenerates the native projects (`expo prebuild --clean`); `ios/` and `android/` are not kept in the repository because everything native is declared by config plugins in `app.json`, and `npm install` applies `patches/` through `patch-package`. When the phone is connected over USB, `npm run reverse` forwards the Metro and backend ports to it. --- ## Pointing the app at a backend Everything goes through `src/api/config.ts`: ```ts export const USE_MOCK = false; // true -> in-memory demo data, no server ``` - `USE_MOCK = true` uses `src/api/mock.ts`: every flow works offline on demo data, and any credentials are accepted at login. - `USE_MOCK = false` uses `src/api/real.ts`, mapped to the endpoints in `openapi.yaml`. The address of the server comes from two places: `DEV_HOST` in the same file for development builds, and `expo.extra.apiUrl` in `app.json` for release builds. A release build must use `https`, because both platforms block plain HTTP traffic outside development. The screens import `api` from `@/api` and never know which of the two is active. ### How documents map to the backend The screens work with a flat model: a property owns documents, each with a category and an optional expiry date. The backend nests the same data one level deeper, as page (slug) → section → document requirement → uploaded files. `src/api/real.ts` holds that mapping. Reads flatten the structure for display; writes stay faithful, because the upload screen has the user pick a real requirement and sends its id. Two consequences are worth knowing: - A property's documents are gathered with one request per category page, since the endpoint serves a single page at a time. The properties list does not pay that cost — it uses the counters `homes.php` returns. - There is no endpoint for a single file's metadata, so document screens read from the list they were opened from. --- ## Project structure ``` app/ expo-router routes _layout.tsx providers, auth gate (auth)/ login, register, verify, forgot, reset (tabs)/ properties · search · expiring · profile property/[id].tsx property detail property/add.tsx new property property/edit/[id].tsx edit property property/location.tsx map picker for the address documents/[propertyId].tsx documents of a property document/[id].tsx document detail and viewer document/edit/[id].tsx edit a document profile/edit.tsx profile profile/password.tsx change password upload.tsx add a document: file, gallery or scan src/ api/ config.ts (backend switch), http.ts, types.ts, mock.ts, real.ts auth/ AuthContext, token in SecureStore i18n/ en.ts, it.ts, locale detection and override scanner/ scanToPdf.ts theme/ design tokens (colours, spacing, radii, typography) components/ ui.tsx, domain.tsx, forms, AppBar, PdfView, OfflineBanner lib/ formatting, permissions, files, network, query client ``` --- ## Scripts | | | |---|---| | `npm start` | Metro for a development build | | `npm run ios` / `npm run android` | build and install on device or simulator | | `npm run prebuild` | regenerate `ios/` and `android/` | | `npm run typecheck` | TypeScript, no emit | | `npm run lint` | ESLint | | `npm run reverse` | forward ports 8081 and 8080 to a USB-connected Android device | --- ## Notes - Design tokens live in `src/theme/tokens.ts` and are the single source for colours, spacing, radii and typography. Typography currently maps to the system font; loading Space Grotesk and Inter through `expo-font` is a change in that one file. - Sharing between owners, ownership transfer and reports exist in the backend contract but are outside the scope of this app.