Skip to content

Empty + Error + Loading + Offline State Audit — Ideony Mobile

Empty + Error + Loading + Offline State Audit — Ideony Mobile

Section titled “Empty + Error + Loading + Offline State Audit — Ideony Mobile”

Date: 2026-04-20 Scope: apps/mobile/app/ — 44 content screens (excluding _layout.tsx)


State✅ Full🟡 Partial/inline❌ MissingN/A
Loading626012
Empty510029
Error63422
Offline00440

Full EmptyState component usage: only 5 screens — results.tsx, dashboard.tsx, requests.tsx, (professional)/credentials.tsx, (admin)/credentials.tsx. Full ErrorState component usage: only 6 screens (same 5 + professional/[id].tsx). Full Skeleton loading: only 3 screens (results, professional/[id], dashboard). NetInfo usage: zero — offline detection absent entirely.


ScreenLoadingEmptyErrorOffline
tour.tsxN/A (delegates to WelcomeTour)N/AN/A
continue.tsx🟡 button ActivityIndicator onlyN/A🟡 inline colors.error Text
ScreenLoadingEmptyErrorOffline
sign-in.tsxN/A (Clerk component)N/AN/A
sign-up.tsxN/A (Clerk component)N/AN/A
ScreenLoadingEmptyErrorOffline
index.tsx🟡 ActivityIndicator; no skeletonN/A✅ inline Text + Button retry; 3-retry logic
ScreenLoadingEmptyErrorOffline
index.tsx🟡 ActivityIndicator🟡 inline Text
search.tsx🟡 ActivityIndicator🟡 inline “no results” Text🟡 inline Text
bookings.tsx🟡 ActivityIndicator🟡 EmptyState partial — custom inline🟡 inline Text
profile.tsx🟡 ActivityIndicatorN/A🟡 inline Text
triage.tsxN/A (form)N/A🟡 inline Text
sos.tsx🟡 ActivityIndicatorN/A🟡 inline Text
ScreenLoadingEmptyErrorOffline
book/[professionalId].tsx🟡 ActivityIndicatorN/A🟡 inline Text
booking/[id].tsx🟡 ActivityIndicatorN/A🟡 inline Text
professional/[id].tsx✅ Skeleton componentsN/A✅ ErrorState component
results.tsx✅ SkeletonList/SkeletonProfessionalCard✅ EmptyState component✅ ErrorState component
compare.tsx🟡 ActivityIndicatorN/A🟡 inline Text
quotes/[id].tsx🟡 ActivityIndicatorN/A🟡 inline Text
quotes/new.tsxN/A (form)N/A🟡 inline Text
review/[bookingId].tsxN/A (form)N/A🟡 inline Text
portfolio/index.tsx🟡 ActivityIndicator🟡 custom inline “no images”🟡 inline Text
chat/[bookingId].tsx🟡 ActivityIndicator🟡 custom inline “no messages”🟡 inline Text
settings.tsxN/AN/A🟡 inline
stripe-onboarding.tsxN/A (action screen)N/A🟡 Alert.alert
verification/index.tsx🟡 ActivityIndicator; RefreshControl present🟡 custom inline Text❌ isError not destructured
verification/submit.tsxN/A (form)N/A🟡 Alert.alert for upload; inline Text for piva
ScreenLoadingEmptyErrorOffline
sos/index.tsxN/A (action)N/A🟡 inline Text
sos/[id]/countdown.tsx🟡 ActivityIndicatorN/A🟡 inline Text
sos/[id]/tracking.tsx🟡 ActivityIndicatorN/A🟡 inline Text
sos/[id]/complete.tsxN/AN/AN/A
sos/[id]/cancelled.tsxN/AN/AN/A
ScreenLoadingEmptyErrorOffline
dashboard.tsx✅ Skeleton components✅ EmptyState component✅ ErrorState component
requests.tsx✅ SkeletonBookingCard✅ EmptyState component✅ ErrorState component
earnings.tsx🟡 ActivityIndicator; RefreshControl🟡 custom inline “no earnings”❌ isError not destructured
calendar.tsx🟡 ActivityIndicator🟡 custom inline “no events”🟡 inline Text
credentials.tsx✅ Skeleton✅ EmptyState component✅ ErrorState component

(professional)/onboarding/ group (9 screens)

Section titled “(professional)/onboarding/ group (9 screens)”

All of index, area, profile, stripe, identity, credentials, pricing, portfolio, complete:

  • Loading: 🟡 ActivityIndicator on buttons; no skeleton — appropriate for wizard steps
  • Empty: 🟡 where applicable (credentials/portfolio use custom inline views, not EmptyState component)
  • Error: 🟡 universally (inline colors.error Text; no ErrorState component)
  • Offline: ❌ universally
ScreenLoadingEmptyErrorOffline
(admin)/credentials.tsx✅ Skeleton✅ EmptyState component✅ ErrorState component

Token usage:

  • Semantic colors.* tokens: ✅ nearly universal. Exception: onboarding/portfolio.tsx hardcodes "rgba(0,0,0,0.5)" and "#fff" on delete overlay button.
  • @ideony/design-tokens shadows.sm/shadows.md: used in verification/index.tsx, stripe-onboarding.tsx, professional/[id].tsx — not universal.

Icon consistency split:

  • Lucide React Native: dominant everywhere except onboarding wizard
  • Phosphor React Native: ALL (professional)/onboarding/ steps exclusively
  • This split is intentional/consistent within each group — not a defect per se

i18n coverage on state messages:

  • ✅ fully wrapped: all screens except (welcome)/continue.tsx
  • 🟡 (welcome)/continue.tsx: Italian string fallbacks pattern (t("key", "Fallback italiano")) — strings work but circumvent translation pipeline

Offline:zero NetInfo usage anywhere in the codebase.

ErrorState component usage: only 6 screens: results.tsx, professional/[id].tsx, dashboard.tsx, requests.tsx, (professional)/credentials.tsx, (admin)/credentials.tsx

EmptyState component usage: only 5 screens: results.tsx, dashboard.tsx, requests.tsx, (professional)/credentials.tsx, (admin)/credentials.tsx

verification/index.tsx specific issue: isError not destructured from useQuery — if the /verification/me fetch fails, user sees a blank screen (only isLoading and data are used). RefreshControl passes refreshing={isLoading} which is always false after initial load (should be isRefetching).

earnings.tsx specific issue: Same pattern — isError not destructured, silent failure.


  1. verification/index.tsxisError unhandled → blank screen on network failure; also RefreshControl bug (isLoadingisRefetching). High impact: professional verification is a trust-critical flow.

  2. earnings.tsxisError unhandled → blank screen on failure. High impact: earnings data drives professional payout decisions.

  3. (consumer)/bookings.tsx — no EmptyState/ErrorState components; loading is ActivityIndicator only. High impact: core consumer screen.

  4. (consumer)/index.tsx (home feed) — no empty state at all; no skeleton loading. High impact: first screen a consumer sees after login.

  5. chat/[bookingId].tsx — no ErrorState; custom inline empty. High impact: real-time communication feature, errors must surface clearly.

  6. portfolio/index.tsx — no ErrorState; custom inline empty. Impact: professional’s portfolio showcase.

  7. (professional)/onboarding/credentials.tsx and onboarding/portfolio.tsx — custom inline empty views instead of EmptyState component; error states inline only. Impact: onboarding completion rate.

  8. (consumer)/search.tsx — no skeleton during initial load; no ErrorState. High impact: primary discovery surface.

  9. booking/[id].tsx — no ErrorState. Impact: booking management critical for both roles.

  10. (welcome)/continue.tsx — Italian string fallbacks bypass translation pipeline; error is inline (no ErrorState). Impact: first auth experience for all users.


NetInfo is absent from the entire codebase. Recommend: single useNetworkStatus hook (wrap @react-native-community/netinfo) + global OfflineBanner component rendered in _layout.tsx → one fix covers all 44 screens.