Reseller app
Who uses the HOCO reseller app, how it is navigated, the behaviours every screen shares (guest mode, pricing, live updates, WhatsApp support), its deep links and the list of its 41 screens.
The reseller app (application revendeur) is the Flutter app through which a point of sale orders HOCO, ACEFAST and BOROFONE accessories, follows its orders live, handles invoices, payments, returns and after-sales claims, and talks to HOCO (cahier §5, §14.1). Imad builds it in hoco-mobile/apps/reseller (application id dz.hoco.reseller); Akram designs it on days 6 to 10 of the design plan, the V2 screens in DES-30. The reseller web is its responsive twin on the same API.
This page holds what every screen shares. The section pages hold one specification per screen.
Who uses it and how
Users.
- Resellers (revendeurs): the owner or counter staff of a phone-accessory shop anywhere in Algeria's 58 wilayas (provinces). Today they order by phone or WhatsApp from their délégué commercial (field sales delegate) or HOCO's office. One account per shop; the shop's main mobile number is the login (cahier §4.2). Each reseller has a customer type — Super-gros, Demi-gros or Détail — that selects their price for every product (PRC-02, AUTH-11).
- Guests: shop owners who installed the app from a store listing, a flyer or a delegate's QR code and have no account yet. They browse the catalog, products and promotions without prices and can write to HOCO on WhatsApp (AUTH-10).
Context of use.
- In the shop, between customers. Sessions are short and interrupted. The cart lives on the server and forms keep drafts, so nothing is lost when the reseller switches app or the phone locks.
- Mid-range Android on mobile data (cahier §9, NFR-04). The app opens and returns search results in under 3 seconds on a normal connection (NFR-01). Lists show skeletons, never a blank screen.
- B2B quantities. Lines of 10, 50 or 100 pieces are normal. Quantities can be typed, not only tapped with +/−.
- Onboarding often happens with a delegate standing next to the reseller. The delegate shows an invitation QR code; the reseller installs, signs up, and the delegate may prepare a first order that the reseller confirms (cahier §6.6, §6.7). Sign-up must take less than three minutes.
- Trust. Prices are always the reseller's own, totals always come from the server, every order waits for HOCO's explicit confirmation (ORD-14), and every status change shows up live and as a notification (ORD-15).
Scope. V1: guest browsing, account, catalog with advanced filters, cart, ordering, live order tracking, returns and after-sales claims, simple promotions, finance view, notifications, support and regional WhatsApp (cahier §14.1 and the team decisions of 17 Oct 2026 recorded in the decision register). V2: loyalty points and levels, rewards, profitable packs (cahier §14.2) — RA-37 to RA-39.
How to read a screen spec
Every screen on the section pages follows the same template:
| Block | What it holds |
|---|---|
| Fields table | Screen name, French title, release, design day, Flutter build task, requirements, client reference screen |
| Purpose | Why the screen exists |
| Entry points & exits | Where the user comes from and where they can go, by screen id |
| Layout | Blocks from top to bottom with the design-system components used |
| Data | Every field shown and its source, written op → field.path — for example cart.get → totals.totalTtc |
| Actions | Every interaction, the operation it calls, idempotency, optimistic update, loading and disabled rules, feedback |
| Rules | Business rules with requirement ids |
| States | Loading, empty, error (with error codes and French messages), offline, guest and status-gated, edge cases |
| Copy | Key French strings; {name} marks a placeholder (ARB syntax) |
| Analytics | Events worth logging |
| Acceptance criteria | Testable statements used by design QA (DQA-02) and the functional campaign (QA-03) |
The API contract wins
Field paths follow the API reference: the Me object of auth, the public settings of appConfig.get and the shared schemas (Price, Totals, ProductCard, Issue, Address). Error codes and order rules follow lifecycles and statuses. Once SRV-03 publishes the OpenAPI document it is authoritative: if a field differs, build against the contract and fix this page in the same pull request.
Component names come from the mobile component library (DES-03): AppBar, TabRootHeader (store greeting + bell), SearchField, BottomNav, Button (primary, secondary, text, destructive), IconButton, TextField, PhoneField, PasswordField, OtpField, Select, QuantityStepper, Chip, FilterChip, RangeSlider, StatusBadge, StockBadge, PriceTag, PriceLock, ProductCard, CartLine, OrderCard, ProgressTracker, Timeline, KpiTile, ListRow, SectionHeader (title + « Voir tout »), Tabs, Carousel, Countdown, RadioCard, AddressCard, SummaryCard, StickyFooter, WhatsAppButton, Banner (info, warning, error, success), BottomSheet, Dialog, Snackbar, Skeleton, EmptyState, ErrorState, Uploader, ImageGallery. If Akram names a component differently in Claude Design, Claude Design wins.
Formatting rules
These rules apply to every screen; the specs do not repeat them.
| Data | Rule | Example |
|---|---|---|
| Money | The API sends integer centimes of DZD. Format with the fr locale: narrow no-break space between thousands, comma before decimals, then « DA ». Totals, order lines, invoices, payments, credit notes and credit always show two decimals. Price tags on product cards, home tiles and promotion cards drop ,00 (as on the reference screens). | 125000 → « 1 250,00 DA » · card « 1 250 DA » |
| Which price | Price carries ht and ttc; the large figure follows the public setting settings.pricing.priceDisplay (TTC by default, decision to confirm) with the suffix « TTC » or « HT ». Summaries always show the fiscal breakdown HT / TVA / TTC. | « 2 490 DA TTC » |
| Discounts | True minus sign, success tone | « −4 500,00 DA » |
| Free delivery | A delivery fee of 0 reads « Offerts » in success tone | — |
| Dates | Converted from UTC to Africa/Algiers. Lists: « 14 nov. 2026 à 10:32 »; same day « Aujourd'hui à 10:32 », previous day « Hier à 16:45 ». Date-only fields: « 30 nov. 2026 ». Relative times (« il y a 5 min ») only in the notification inbox | — |
| Countdowns | Below 24 h « 12 h 45 min 30 s »; above « 2 j 5 h ». Computed against appConfig.get → serverTime, not the device clock | — |
| Phones | Stored E.164, shown national | +213555123456 → « 0555 12 34 56 » |
| Counts | « 3 articles » counts lines; « 12 pièces » counts units | — |
| Business numbers | Shown as issued, long-press to copy | « CMD-2026-000158 » |
| Percentages | Narrow no-break space before % | « −30 % » |
Prices and customer type. A signed-in reseller sees, for every variant, the price of their customer type (Super-gros (SUPER_GROS), Demi-gros (DEMI_GROS) or Détail (DETAIL)), with active promotions applied on top (PRC-01, PRC-02). The type is never chosen per order and only the back-office changes it after sign-up. When it changes, the server pushes account.customer_type_changed; the app refreshes Me, the catalog and the cart (lines show « Prix mis à jour »).
Price lock. When ProductCard.price is null and priceLocked is true — guests, and pending resellers when settings.catalog.pricesVisibleBeforeValidation is false — every PriceTag is replaced by the PriceLock component: a lock icon and « Créez un compte pour voir les prix » (guest) or « Prix visibles après validation de votre compte » (pending). Tapping it opens the sign-up prompt of RA-41 for guests. No price, discount amount, margin or price filter may appear anywhere in a locked state; a promotion keeps its label and percentage badge.
Stock is availability only. Resellers and guests see exactly two states, never a quantity (STK-07): StockBadge En stock (IN_STOCK) (success tone) or En rupture (OUT_OF_STOCK) (danger tone). No screen, helper or error message says « Plus que N pièces » or reveals a quantity; stock problems read « Stock insuffisant pour cette quantité ».
Quantity stepper. Every QuantityStepper (product detail, cart, scanner sheet, return and claim forms) obeys the variant's limits from the API: valid quantities are minQty, minQty + qtyStep, minQty + 2 × qtyStep… up to maxQtyPerOrder (ORD-02). Available stock is not known by the app; the server checks it.
- − is replaced by a trash icon when the quantity equals
minQty(cart only; on product detail it is disabled). - + is disabled at the maximum, with the helper « Maximum 20 pièces par commande ».
- Tapping the number opens a numeric keypad. A typed value is snapped down to the nearest valid quantity with an explanation (« Par multiples de 5 — quantité ajustée à 45 »).
- Long-press on +/− repeats every 150 ms.
Navigation model
Five bottom tabs, as on the reference screens:
| Tab | Icon | Root screen (signed in) | Guest | Badge |
|---|---|---|---|---|
| Accueil | house | RA-09 | RA-09 without prices | none |
| Catalogue | grid | RA-12 | RA-12 without prices | none |
| Panier | cart | RA-17 | Sign-up prompt (RA-41) | number of cart lines, cart.get → itemsCount; hidden at 0, « 99+ » above 99 |
| Commandes | clipboard | RA-21 | Sign-up prompt (RA-41) | assisted orders waiting for the reseller's confirmation, orders.summary → awaitingConfirmation; hidden at 0 |
| Compte | person | RA-27 | Sign-up prompt with « Se connecter » and « Créer mon compte » | none |
- Each tab keeps its own navigation stack (go_router
StatefulShellRoute). Re-tapping the active tab pops to its root, or scrolls the root to the top when already there. - Tab roots Accueil, Catalogue and Commandes use the
TabRootHeader: store logo, « Bonjour, » and the store name, and the notification bell with the unread badge (notifications.unreadCount→count, « 9+ » above 9). Guests see the HOCO logo, « Bienvenue sur HOCO » and a « Se connecter » text button instead of the bell. Panier and Compte use anAppBarwith a title. - Android back pops the current stack; on a tab root other than Accueil it goes to Accueil; on Accueil it exits the app.
- Full-screen flows hide the bottom navigation: onboarding (RA-02 to RA-08), the scanner (RA-11), checkout to confirmation (RA-18 to RA-20), the image viewer, and the forms of RA-19, RA-31, RA-33 and RA-40.
- Badges refresh after every cart mutation (from its response), on live events, when the app returns to the foreground, when a push arrives, and on pull-to-refresh.
WhatsApp support button (SUP-05). A fixed WhatsAppButton (56 dp round button, WhatsApp green, glyph and the accessible label « Contacter HOCO sur WhatsApp ») floats bottom-right, 16 dp above the bottom navigation, on Accueil, Catalogue, Commandes and Compte roots, on RA-24, RA-25, RA-32, RA-02 and every guest screen. It is hidden where it would cover a sticky footer or a form (cart, checkout, scanner, forms, image viewer); RA-14 and RA-22 carry a WhatsApp icon in their AppBar instead, with a prefilled message naming the product or the order. One tap opens WhatsApp on the number of the user's support region:
- Signed in:
Me.supportRegion.whatsappNumber(region of the wilaya declared in the account) — no call needed. - Signed in without a region (
supportRegion: null):settings.support.whatsappfromappConfig.get. - Guest:
support.whatsappwith the device position when the location permission is granted (nearest commune → wilaya → region); without permission, the first tap opens aBottomSheet« Votre wilaya » (searchable list, plus « Utiliser ma position »), the choice is stored on the device and sent aswilayaCode; failing that, the default number.
The link is https://wa.me/<number without +>?text=<message>. Prefilled messages: signed in « Bonjour HOCO, je suis {storeName} ({resellerNumber}). »; guest « Bonjour HOCO, je souhaite des informations sur vos produits. »; from a product « … Ma question concerne {productName} (réf. {sku}). »; from an order « … Ma question concerne la commande {orderNumber}. ». Region name and hours are shown on RA-32.
Navigation map
Launch, guest browsing and onboarding:
Main navigation (tabs and the screens they lead to):
Global behaviours
Launch and session restore
- RA-01 reads the session token from secure storage and calls
appConfig.getand, when a token exists,me.getin parallel. - The version policy is applied first (see below). Then the route: no token and first launch → RA-02; no token and the user already chose to browse as a guest → RA-09 in guest mode; token valid → RA-09 or the pending deep link (a pending account lands on RA-06 once, right after sign-up);
401 UNAUTHENTICATED→ token cleared, guest mode with the banner « Votre session a expiré. Reconnectez-vous. » Me.mustChangePasswordtrue → the change-password form of RA-35 opens first; every other call answers403 PASSWORD_CHANGE_REQUIREDuntil it is done.Me.consents.termsVersiondiffers fromsettings.legal.termsVersion→ a blockingDialogasks to accept the new terms (link to the text), saved withme.update.- Sessions last 30 days and slide with activity (AUTH-06): a reseller who opens the app at least once a month never signs in again. Signing out (
auth.logout) clears the token and the cachedMe, keeps the catalog cache and returns to guest browsing. - Offline at launch with a stored token: the app opens on cached data with the offline banner and checks the session when the network returns. Offline at the very first launch: RA-36 offline state.
- On the first launch only, the Play install referrer is read and sent with
invitations.attributeso that an installation from an invitation link is attributed to the delegate (IVT-03, IVT-04).
What each kind of user can do
The server enforces these rules (403 ACCOUNT_PENDING_VALIDATION, 403 ACCOUNT_SUSPENDED, 403 RESELLER_SUSPENDED); the app never offers an action the server will refuse (ACL-05). The state comes from Me.status and Me.reseller.validationStatus (AUTH-08).
| Capability | Guest (no account) | PENDING_VALIDATION | ACTIVE | SUSPENDED / DISABLED |
|---|---|---|---|---|
| Catalog, search, filters, product detail, promotions | Yes, without prices, no price filter | Yes, with the prices of the declared type (setting catalog.pricesVisibleBeforeValidation, default true; else price lock) | Yes | — |
| WhatsApp support | Yes (region from position or chosen wilaya) | Yes (declared region) | Yes | Number shown on the refusal message |
| Favorites, cart | No — sign-up prompt | Yes | Yes | — |
| Checkout | No | No — banner « Votre compte doit être validé par HOCO avant de commander » | Yes | — |
| Confirm an assisted order (RA-23) | No | No — HOCO confirms it by phone in the back-office | Yes | — |
| Orders, returns, after-sales claims | No | Orders list (assisted orders only) | Yes | — |
| Finance (RA-29 to RA-31) | No | Read only; no payment declaration | Yes | — |
| Store profile and documents (RA-28) | No | Yes — encouraged, it speeds up validation | Yes | — |
| Notifications, settings, support tickets | No | Yes | Yes | — |
| Sign in | — | Yes | Yes | Refused with an explicit message (RA-07) |
- A pending reseller has the full shell; the Compte tab shows the RA-06 status card at the top and checkout shows the validation banner.
- SUSPENDED and DISABLED accounts lose their sessions server-side; the next call answers
403 ACCOUNT_SUSPENDEDand the app signs out locally. - Ordering blocks on an active account. Reseller lifecycle status Suspendu (
SUSPENDED) (unpaid, fraud, closure): blocking issueRESELLER_SUSPENDEDincart.get→issues, banner on Accueil and Panier « Les commandes sont suspendues sur votre compte. Contactez HOCO. », checkout disabled — everything else, including invoices and payments, stays available. A credit account blocked by finance only disables the Crédit payment method. An order belowsettings.orders.minAmountdisables checkout until the minimum is reached.
Version policy, forced update and maintenance
appConfig.get (called with app=RESELLER_APP, platform=android and version) returns minVersion, latestVersion, forceUpdate, updateAvailable, storeUrl, releaseNotes, maintenance and serverTime (ADM-07).
forceUpdatetrue, or any call answering426 UPGRADE_REQUIRED: blocking RA-36 « Mise à jour requise »; the only action opensstoreUrl.updateAvailabletrue: a dismissible dialog once per new version withreleaseNotes.maintenance.enabled, or any call answering503 MAINTENANCE: blocking maintenance state withmaintenance.messageand « Retour prévu vers 14:30 » whenmaintenance.untilis set; « Réessayer » callsappConfig.getagain.appConfig.getis called at launch, when the app returns to the foreground after more than one hour, and after any426or503 MAINTENANCE.
Live updates
Order screens are live (ORD-15, SYN-07). While the app is in the foreground and signed in, it keeps one Server-Sent Events connection to events.stream (GET /v1/events, heartbeat every 25 s).
| Event | Effect in the app |
|---|---|
order.status_changed | The order's card on RA-21, the counters, the tracker and timeline of RA-22 update in place (tracker step animates); in-app Banner « Commande CMD-2026-000158 : Validée » with « Voir » when the user is elsewhere |
order.modified | RA-22 reloads and shows the « Commande modifiée par HOCO » banner |
assisted_order.awaiting_confirmation | Commandes badge +1, home banner, RA-21 pinned card |
return.status_changed | RA-40 detail and the order's return block update |
ticket.replied | RA-34 appends the message; RA-32 list re-sorts |
ticket.resolved | RA-34 shows the resolution (replacement order, return, credit note, repair or rejection); the linked order or return refreshes |
notification.created | Bell badge set to unread; RA-26 prepends the item; no system banner (the push is suppressed in the foreground) |
resync | The replay window (10 minutes) was exceeded: refetch the visible screen and the unread count |
- The connection opens after sign-in and when the app comes to the foreground, and closes when it goes to the background (push takes over). Mobile has no browser
EventSource: the client sends the bearer token and, on reconnection,Last-Event-IDitself, with backoff from 1 s to 30 s; silence for 60 s (the server pings every 25 s) means reconnect. Event ids already processed are ignored (at-least-once delivery). - On return to the foreground the app reloads the screen it shows — events that happened in the background are not replayed, the inbox holds them.
- Every event that matters is also a notification (push + inbox), so nothing depends on the stream (notifications matrix).
Online-first, cached catalog, offline banner
The reseller app is online-first. Unlike the delegate app it has no outbox: an order, a confirmation, a payment declaration, a return or a claim is never queued offline, because prices, stock and credit must be re-validated when it is submitted (PRC-05).
- Cached on the device for offline reading (kept 7 days; the account data is cleared at sign-out, the public catalog is kept): the last home aggregate, categories, brands and facets, catalog pages and product details viewed in the last 24 hours, favorites, the last cart snapshot, the first page of orders and every order detail viewed, invoices list, the first page of notifications, the store profile. Product images use the image cache (200 MB cap).
- Offline banner. After 3 seconds without connectivity a
Bannerappears under the header: « Hors connexion — données du 14 nov. à 10:32 ». Cached screens stay readable; every action that writes is disabled with « Connexion requise pour cette action ». When the network returns the banner turns into the snackbar « Connexion rétablie », the visible screen refreshes and the live connection reopens. - Prices shown offline may be stale; the cart and checkout always re-validate them.
Errors and retries
| Situation | Behaviour |
|---|---|
| Network unreachable or timeout on a read | Two automatic retries (after 1 s and 3 s), then cached data with the offline banner, or ErrorState |
| Timeout on a write | Operations that take an Idempotency-Key are retried with the same key; others show the error with « Réessayer » |
401 UNAUTHENTICATED | Session cleared; guest mode with « Votre session a expiré » and RA-07; the current route is reopened after sign-in |
403 ACCOUNT_SUSPENDED | Local sign-out, RA-07 with the suspension message |
403 ACCOUNT_PENDING_VALIDATION | Validation banner, me.get refreshed |
403 RESELLER_SUSPENDED | Ordering-blocked banner |
404 NOT_FOUND | « Ce contenu n'est plus disponible » and back to the parent list |
409 IDEMPOTENCY_IN_PROGRESS | Wait 1 s and resend with the same key, at most three times |
426 UPGRADE_REQUIRED · 503 MAINTENANCE | RA-36 blocking states |
429 RATE_LIMITED | « Trop de tentatives. Réessayez dans {seconds} s. » from Retry-After |
500, 502, 504 | ErrorState « Une erreur est survenue » with « Réessayer » and the requestId in small type for support |
When a screen has no specific copy for an error code, it shows the server's error.message, which is localised and safe to display. Codes are listed in the error registry.
Push notifications
- The device registers its FCM token with
me.devices.registerafter sign-in, when FCM rotates the token and after an app update;auth.logoutunregisters it (AUTH-09, NOT-02). Guests receive no push. - Android 13+ notification permission is requested with a pre-prompt at the moments it makes sense — on RA-06 (« Soyez prévenu dès la validation de votre compte ») and on RA-20 (« Suivez la confirmation de votre commande ») — never at first launch.
- A push received in the foreground shows an in-app banner with « Voir » (unless the live stream already showed it) and refreshes the badges. A tap on a push opens its route (table below) and marks it read with
notifications.markRead. Signed out, the route is kept and opened after sign-in; if the target is gone or out of scope, the parent list opens with « Ce contenu n'est plus disponible ».
Data freshness
| Data | Refreshed |
|---|---|
| Cart and its badge | After each cart mutation (from the response); on Panier focus; on return to foreground — the cart is shared with the web (ORD-01) |
| Home aggregate | On return to foreground when older than 5 minutes; pull-to-refresh |
| Catalog lists and facets | On open, cached 10 minutes; pull-to-refresh |
| Product detail, checkout options, finance | Every time the screen opens |
| Orders, order detail, returns, tickets | Live events while open; on focus; on push; pull-to-refresh |
| Unread count | Live notification.created; on return to foreground; after reading |
Accessibility and localisation
- Touch targets at least 48 × 48 dp; text contrast WCAG AA (4.5:1); statuses always carry text, never colour alone; every icon button has a semantic label (NFR-07).
- Layouts survive a 130 % system text scale without truncating prices, totals or statuses (they wrap to two lines).
- French only in V1, Arabic (RTL) and English prepared (NFR-06): no text inside images, directional icons mirror, all strings in ARB files (MOB-07). Banner images carry no text that matters — titles and calls to action are separate fields.
Analytics
Events are snake_case, logged through one analytics wrapper (provider to confirm; Firebase Analytics is the natural choice as Firebase already serves push). Every event carries screenId, appVersion, platform, userKind (guest, pending, active) and, when signed in, customerType; the reseller is identified by its UUID only — no name, phone or address (Law 18-07). Screen views are logged by the router observer with the screen id (RA-18). Per-screen events are listed in each spec.
Deep links
The app, its push notifications and the reseller web share one URL space under https://app.hoco.dz (domain to confirm). Android App Links open the app when it is installed, else the same path on the web. Push payloads carry notificationId, category, event and route. Event keys are those of the notifications matrix; the ones below are the reseller-facing events.
| Route | Screen | Opened by these events | Notes |
|---|---|---|---|
/ | RA-09 | account.approved, account.customer_type_changed | Also the target when a route cannot be resolved |
/i/{code} | RA-02 then RA-03 | — (invitation link, QR) | Signed in: ignored with « Vous êtes déjà connecté » |
/signin · /signup · /forgot-password | RA-07 · RA-03 · RA-08 | — | — |
/account/pending | RA-06 | account.rejected | — |
/search?q= | RA-10 | — | — |
/catalog?… | RA-12 with RA-13 state | — | Same query parameters as the web URL (see RA-13); banner targets |
/products/{productId}?variant= | RA-14 | — | Shared product links; guests allowed |
/products/{productId}/specs | RA-15 | — | — |
/favorites | RA-16 | — | — |
/cart | RA-17 | — | — |
/checkout | RA-18 | — | Never a push target; opened from the cart only |
/orders?status= | RA-21 | — | — |
/orders/{orderId} | RA-22 | order.submitted, order.validated, order.refused, order.status_changed (on hold, En préparation, Prête, Expédiée, Livrée, Retournée), order.modified, order.cancelled, delivery.failed, assisted_order.confirmed (by HOCO), assisted_order.expired | Every status change notifies |
/orders/{orderId}/confirm | RA-23 | assisted_order.awaiting_confirmation, assisted_order.reminder (24 h before expiry) | Falls back to RA-22 when no longer awaiting confirmation |
/orders/{orderId}/return · /returns · /returns/{returnId} | RA-40 | return.requested, return.approved, return.rejected, return.received | — |
/promotions · /promotions/{promotionId} | RA-24 · RA-25 | daily_offer.published · promotion.started | Guests allowed (no push for guests) |
/notifications | RA-26 | announcement.published (opens the announcement) | — |
/account · /account/store · /account/addresses | RA-27 · RA-28 · RA-19 | — | — |
/finance | RA-29 | — | — |
/finance/invoices · /finance/invoices/{invoiceId} | RA-30 | invoice.issued | Credit notes are announced by return.received and ticket.resolved |
/finance/payments · /finance/payments/declare?invoiceId=&orderId= | RA-31 | payment.confirmed, payment.rejected | — |
/support · /support/new?orderId=&type= · /support/tickets/{ticketId} | RA-32 · RA-33 · RA-34 | ticket.created, ticket.replied, ticket.status_changed, ticket.resolved, ticket.rejected | type=AFTER_SALES opens the claim form |
/settings | RA-35 | security.new_device, security.password_changed | — |
V2: /packs/{packId} · /loyalty · /loyalty/rewards | RA-37 · RA-38 · RA-39 | loyalty.points_earned, loyalty.level_up | V2 |
Screen list
| ID | Screen | UI title | Section | Release | Design | Build |
|---|---|---|---|---|---|---|
RA-01 | Splash & version check | Démarrage | Onboarding & account | V1 | Day 6 | MOB-05 |
RA-02 | Welcome (sign in, sign up, browse as guest) | Bienvenue | Onboarding & account | V1 | Day 6 | MOB-06 |
RA-03 | Sign-up — phone & invitation code | Inscription — téléphone | Onboarding & account | V1 | Day 6 | MOB-06 |
RA-04 | OTP verification | Vérification du code | Onboarding & account | V1 | Day 6 | MOB-06 |
RA-05 | Sign-up — store details, customer type & password | Inscription — magasin | Onboarding & account | V1 | Day 6 | MOB-06 |
RA-06 | Account pending validation / rejected | Compte en attente | Onboarding & account | V1 | Day 6 | MOB-06 |
RA-07 | Sign in | Connexion | Onboarding & account | V1 | Day 6 | MOB-06 |
RA-08 | Forgot password | Mot de passe oublié | Onboarding & account | V1 | Day 6 | MOB-06 |
RA-09 | Home | Accueil | Shopping | V1 | Day 7 | MRA-01 |
RA-10 | Search | Recherche | Shopping | V1 | Day 7 | MRA-02 |
RA-11 | Barcode scanner | Scanner | Shopping | V1 | Day 7 | MRA-02 |
RA-12 | Catalog | Catalogue | Shopping | V1 | Day 7 | MRA-02 |
RA-13 | Advanced filters & sort (price range, category/sub-category, brand, attributes…) | Filtres avancés et tri | Shopping | V1 | Day 7 | MRA-02 |
RA-14 | Product detail | Détail produit | Shopping | V1 | Day 8 | MRA-03 |
RA-15 | Full specifications | Caractéristiques | Shopping | V1 | Day 8 | MRA-03 |
RA-16 | Favorites | Favoris | Shopping | V1 | Day 8 | MRA-03 |
RA-17 | Cart | Panier | Ordering | V1 | Day 8 | MRA-04 |
RA-18 | Checkout | Validation de commande | Ordering | V1 | Day 8 | MRA-04 |
RA-19 | Address book & address form | Adresses de livraison | Ordering | V1 | Day 8 | MRA-04 |
RA-20 | Order confirmation | Commande envoyée | Ordering | V1 | Day 8 | MRA-04 |
RA-21 | Orders | Commandes | Orders | V1 | Day 9 | MRA-05 |
RA-22 | Order detail & tracking | Suivi de commande | Orders | V1 | Day 9 | MRA-05 |
RA-23 | Assisted order confirmation | Commande assistée à confirmer | Orders | V1 | Day 9 | MRA-05 |
RA-24 | Promotions & daily offers | Promotions | Promotions | V1 | Day 10 | MRA-06 |
RA-25 | Promotion detail | Détail de l'offre | Promotions | V1 | Day 10 | MRA-06 |
RA-26 | Notifications | Notifications | Account | V1 | Day 10 | MRA-08 |
RA-27 | Account hub | Compte | Account | V1 | Day 10 | MRA-07 |
RA-28 | Store profile & documents | Mon magasin | Account | V1 | Day 10 | MRA-07 |
RA-29 | Balance & credit | Solde et crédit | Finance | V1 | Day 9 | MRA-07 |
RA-30 | Invoices | Factures | Finance | V1 | Day 9 | MRA-07 |
RA-31 | Payments & payment declaration | Paiements | Finance | V1 | Day 9 | MRA-07 |
RA-32 | Support: tickets, after-sales claims & WhatsApp | Assistance | Support | V1 | Day 10 | MRA-08 |
RA-33 | New ticket / after-sales claim | Nouvelle demande | Support | V1 | Day 10 | MRA-08 |
RA-34 | Ticket conversation | Conversation | Support | V1 | Day 10 | MRA-08 |
RA-35 | Settings | Paramètres | Account | V1 | Day 10 | MRA-07 |
RA-36 | System states (offline, maintenance, forced update, errors, empty) | États système | System | V1 | Day 10 | MOB-05 |
RA-37 | Packs list & detail | Packs rentables | V2 | V2 | DES-30 | MRA-20 |
RA-38 | Loyalty: points, level, history | Fidélité | V2 | V2 | DES-30 | MRA-20 |
RA-39 | Rewards & redemption | Récompenses | V2 | V2 | DES-30 | MRA-20 |
RA-40 | Return request | Demande de retour | Orders | V1 | Day 9 | MRA-10 |
RA-41 | Guest mode — price lock and sign-up prompts | Mode invité | System | V1 | Day 6 | MOB-06 |
Section pages
Onboarding & account
Shopping
Ordering
Orders
Promotions
Finance
Account & support
System, returns, guest mode & V2
Screen inventory
Every screen of the four interfaces with its release, design day and build task — the list Akram, Imad and Anis validate on Day 5, the back-office template strategy, the navigation map of each app and the coverage check.
Onboarding & account
Screen specifications RA-01 to RA-08 of the reseller app — launch and version check, welcome with guest entry, sign-up with OTP, customer type and account claim, pending validation, sign-in and password reset.