initial
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user