Nzinga mosaic in magenta, flame and Volt
Design
/
Patterns

Patterns

The flows members go through again and again, and the rules each one keeps.

Phone App
Expo SDK 58

Every pattern is built in the app today; the screen guide shows each screen in full.

02

Invite and Join

Source
app/(join)/* · app/invite/[code].tsx · packages/core/src/invites.ts · apps/mobile/CLAUDE.md §6
01
Welcome
Three slides, then Sign in or I have an invite.
02
Phone Number
The number the member already has, with a country picker inside the field.
03
Sign-In Code
Six boxes, one-time-code autofill, checks itself at six digits.
04
Invite Code
Only for a new number. "Nzinga Is Invite-Only".
05
Setup
Six steps, one progress line: name and photo, languages, about you, agreement, choice, permissions.
  • I have an invite collects the invite first, so a new member needs only one sign-in code.
  • Codes are forgiving: spaces and dashes are ignored, and I, L and O are read as 1, 1 and 0.
  • Invites are sent by the member through the phone's share sheet with the code and a link; nzinga://invite/CODE opens the invite screen with the code filled in.
  • The invite screen is open about the inviter's bonus.
Example
Live component

Enter the Code

Sent to your number. It expires in 10 minutes.

482

Sign-In Code. The first three digits are typed; the caret is Volt.

Nzinga Is Invite-Only

Enter the code from the person who invited you. Invite links fill this in automatically.

Invite code
K7Q2-M8XA

Each code works once and can't be bought or sold. The member who invited you earns a small bonus when your first recording is accepted.

Invite Code, with the inviter's bonus said openly.

03

Recording Flow

Source
app/screens/record.tsx · recording.tsx · review.tsx · saved.tsx · app/contexts/RecorderContext.tsx
01
Record
Language chips, today's idea, the record button.
02
Recording
Live pill in magenta, a large timer, a level meter. Pause, Done, Discard.
03
Review
Title, playback, Record again, who can use it, what happens next with the estimated earning.
04
Saved
Sent For Review or Saved Privately, the steps that follow, Record another.
Example
Live component
Recording
Swahili
1:17

Describe your favourite dish and how it is cooked

Recording: magenta says it is live; Volt marks the one action, Done.

Review
Directions from the market
Who can use this recording?

Review: playback, the choice, then one Volt action.

  • One recorder for the whole app; a recording still running shows a magenta card that leads back to it.
  • Calls and leaving the app pause the recording and say so. Discard always asks first.
  • The audio stays on the phone. Only the details and the member's choice are sent.
04

Review and Rejection

Source
app/screens/recording-detail.tsx · lib/recordings.ts · apps/api/src/app.ts · SPEC.md (review) §5
Example
Live component
  • A native speaker reviews each recording, usually within about three days. The member is told either way.
  • On acceptance, each speaker who chose "Nzinga's models" or wider is paid for their own accepted seconds.
  • A rejected recording says why in plain words and offers Record it again. The server does not send a reason yet, so the app names the usual ones honestly rather than inventing a specific one.
  • Quality and fraud checks (language identification, duplicates, synthetic or replayed audio) are planned in the spec.
Do
"Not accepted. Usually this means background noise, a very short recording, or speech in a different language from the one chosen."
Don't
"Rejected: low quality."
Blames without helping, and offers no way forward.
05

Payout

Source
app/screens/payout.tsx · payout-method.tsx · lib/payouts.ts · packages/core/src/ledger.ts
01
Amount
All or the minimum, with checks. Below the minimum the screen explains instead.
02
Method
The saved mobile money or bank account, or add one.
03
Review
Detail rows and a reference. The button names the amount.
04
Requested
Track the payout: requested, checked, confirmed by SMS, paid.
Example
Live component
  • One open request at a time; cancel it any time until it is paid.
  • The name on the account must match. Nzinga confirms every payout by SMS before money moves.
  • Payout methods and requests are kept on this phone until the server has a payout endpoint, and every payout screen says so.
  • A payout never takes the balance below zero.
06

Empty, Loading and Error States

Source
components/Placeholder.tsx · components/SkeletonLoader.tsx · app/hooks/useLoad.ts · SCREENS.md (design rules)

Every list has all three. Lists reload when the screen comes back into focus, so they are fresh after a save.

Example
Live component
Nothing recorded yet
Your first recording takes about a minute. Start with today's idea.

Empty: what will be here, and the first step.

Loading: the shape of the content, not a spinner.

Could not load your recordings
No connection. Check your internet and try again.

Error: what failed, why, and Try again.

Kind
Title
Subtitle
Empty
No recording to review
Record a voice note first.
Permission
Microphone is off
Nzinga needs the microphone to record. Turn it on for Nzinga in your phone's settings.
Error
Could not load your wallet
From errorMessage(): "No connection. Check your internet and try again."
Error
Could not load your progress
Your progress is kept on this phone. Try again in a moment.