Clients
Mobile app & interfaces
One Expo React Native codebase for Android and iOS. Drivers and hosts use the same app; host features appear once an account becomes a host.
Interfaces#
The four core screens, recreated in HTML for the web (the same previews as on our home page).
Indiranagar Metro Hub
100 Feet Rd, HAL 2nd Stage
Explore
Map and list of nearby spots with price, distance and free slots
Indiranagar Metro Hub
₹40/hr100 Feet Rd, HAL 2nd Stage, Bengaluru
Today, 2:00 PM – 5:00 PM
3 Hours Duration
Book
Server-quoted price breakdown, then pay or pay at the venue
You’re parked
Until 5:00 PM today. Bay A-04 at Indiranagar Metro Hub.
or tell the host your PIN
Access pass
Live QR code that refreshes itself, plus the offline PIN
Host
3 live spots
Bay 1 (Driveway)
Standard · ₹40/h
Bay 2 (EV Port)
Fast DC 50kW · ₹75/h
Host
Earnings, requests to approve and the gate scanner
Screen map#
Routes are files (Expo Router). Groups in parentheses share a layout without adding to the URL.
(auth)/ sign-in · sign-up · forgot-password # email + password, or Google via Clerk(app)/(tabs)/ index (explore) · bookings · host · account(app)/listing/[id] listing detail, reviews, book(app)/booking/[id] booking detail, payment, live QR pass, extend, check-out(app)/report/[id] dispute with photos(app)/host/ new-listing · listing/[id] · bookings · scan (camera)(app)/account/ profile · password · delete(app)/notifications in-app inboxlegal/[doc] · support · verify-email · sso-callbackTalking to the API#
| Concern | How the app handles it |
|---|---|
| Server state | TanStack Query caches responses, refetches live screens (the booking screen every 20 s while a session is active) |
| Auth | Access token in memory only; refresh token in the Keychain / Keystore (SecureStore) |
| Expired token | On a 401 the client refreshes once (concurrent requests share one refresh) and retries |
| Errors | Every API error has the same JSON shape, so screens show the server's message and field errors |
| Slow starts | 60 s request timeout: the hosted API sleeps when idle and can take ~55 s to wake |
| Rules | Prices, GST and booking limits come from GET /v1/config, never hard-coded in the app |
| Device | A random per-install id sent only when signing in, so a known phone gets less friction |
/** Concurrent 401s share one refresh call. */private refreshOnce(): Promise<string | null> { if (!this.tokens) return Promise.resolve(null); this.refreshing ??= this.tokens.refresh().finally(() => { this.refreshing = null; }); return this.refreshing;}Photo uploads go straight to storage#
Swipe sideways to see the whole figure.
Builds and quality checks#
- Android APKs are built on EAS; API keys live in EAS environment variables, not in the repository.
- Every change passes
tsc --noEmit(strict TypeScript), ESLint andexpo-doctor(21/21 checks). - Payments use the native Razorpay SDK, so they need the real app build; in Expo Go the app explains this instead of crashing.