6.2 KiB
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
npm install
The scanner, the maps and the file viewer are native modules, so the app needs a development build rather than Expo Go:
npx expo run:ios # or: npx expo run:android
npm start # subsequent runs
With EAS instead of a local build:
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:
export const USE_MOCK = false; // true -> in-memory demo data, no server
USE_MOCK = trueusessrc/api/mock.ts: every flow works offline on demo data, and any credentials are accepted at login.USE_MOCK = falseusessrc/api/real.ts, mapped to the endpoints inopenapi.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.phpreturns. - 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.tsand are the single source for colours, spacing, radii and typography. Typography currently maps to the system font; loading Space Grotesk and Inter throughexpo-fontis 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.