Patterns

Patterns

The flows members go through again and again, and the rules each one keeps. Every pattern is built in the app today; the screen guide shows each screen in full.

app/(setup)/consent-read.tsx app/(setup)/consent-choose.tsx app/screens/review.tsx app/screens/recording-detail.tsx app/screens/privacy.tsx

The same four choices appear in four places. Wherever they appear, they look the same, use the same words, and save a record that is never edited.

Read the AgreementThe agreement in sections. Continue unlocks once every section is opened and the text is scrolled to the end.
Starting choiceWho Can Use Your Recordings. "Nzinga's models" is marked Suggested. I Agree saves it with the agreement's version and hash.
Every recordingReview asks again, starting from the member's usual choice.
Change or withdrawOn Recording Detail, from a sheet. The history of choices is shown in order.

Who Can Use Your Recordings

Your starting choice. You can change it on every recording.

Setup, step 5 of 6.

Who can use this recording?
Every change is added to the list below the recording, never erased.

The change sheet on Recording Detail, here with sharing paused, so only "Only me" is enabled.

  1. Always all four choices, in order, with their exact names and one line each with a short pay tag.
  2. Who can use each recording is visible without opening it: the Library row and the recording's header say it.
  3. Pause all sharing keeps new recordings with the member; it never changes past choices.
  4. Withdrawing is never more than two taps away, and its sheet says what cannot be undone.

Invite and Join

app/(join)/* app/invite/[code].tsx packages/core/src/invites.ts apps/mobile/CLAUDE.md §6

WelcomeThree slides, then Sign in or I have an invite.
Phone NumberThe number the member already has, with a country picker inside the field.
Sign-In CodeSix boxes, one-time-code autofill, checks itself at six digits.
Invite CodeOnly for a new number. "Nzinga Is Invite-Only".
SetupSix 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.

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.

Recording Flow

app/screens/record.tsx recording.tsx review.tsx saved.tsx app/contexts/RecorderContext.tsx

RecordLanguage chips, today's idea, the record button.
RecordingLive pill in magenta, a large timer, a level meter. Pause, Done, Discard.
ReviewTitle, playback, Record again, who can use it, what happens next with the estimated earning.
SavedSent For Review or Saved Privately, the steps that follow, Record another.
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.

Review and Rejection

app/screens/recording-detail.tsx lib/recordings.ts apps/api/src/app.ts (review) SPEC.md §5

  • 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.

Payout

app/screens/payout.tsx payout-method.tsx lib/payouts.ts packages/core/src/ledger.ts

AmountAll or the minimum, with checks. Below the minimum the screen explains instead.
MethodThe saved mobile money or bank account, or add one.
ReviewDetail rows and a reference. The button names the amount.
RequestedTrack the payout: requested, checked, confirmed by SMS, paid.
  • 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.

Empty, Loading and Error States

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.

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.

KindTitleSubtitle
EmptyNo recording to reviewRecord a voice note first.
PermissionMicrophone is offNzinga needs the microphone to record. Turn it on for Nzinga in your phone's settings.
ErrorCould not load your walletFrom errorMessage(): "No connection. Check your internet and try again."
ErrorCould not load your progressYour progress is kept on this phone. Try again in a moment.