HOCO B2B
DesignScreen specificationsReseller web

Reseller web

Screen specifications RW-01 to RW-15 of the reseller web — what changes from the reseller app at desktop and tablet widths, which app screens each page mirrors, and the web-only concerns: invitation landing, session cookie, live updates, breakpoints, keyboard.

The reseller web (@hoco/web, Next.js 16, at https://app.hoco.dz, domain to confirm) is the responsive web version of the reseller app — a team decision (RWA-01), not in the cahier. It is part of V1: built by Anis in the V1 build phase (WEB-01 to WEB-05) and deployed with the rest before acceptance and the pilot — see the timeline. Akram designs its desktop and tablet layouts on day 20; phone widths reuse the mobile designs.

One product, two shells. Same account, same server-side cart, same orders, same rules, same API — no web-only rule (RWA-02). Every behaviour, rule, error code and French string of the RA specifications applies unchanged; this page only lists what differs. Shopkeepers who have a computer at the counter get bigger tables and keyboard entry; everyone else uses the app.

IDScreenSectionReleaseDesignBuild
RW-01Sign in, sign-up (with customer type), OTP, password reset — and guest browsingAccountV1Day 20WEB-01
RW-02HomeShoppingV1Day 20WEB-02
RW-03Catalog with advanced sidebar filters & searchShoppingV1Day 20WEB-02
RW-04Product detailShoppingV1Day 20WEB-02
RW-05FavoritesShoppingV1Day 20WEB-02
RW-06CartOrderingV1Day 20WEB-03
RW-07Checkout & confirmationOrderingV1Day 20WEB-03
RW-08Orders listOrdersV1Day 20WEB-04
RW-09Order detail, tracking & assisted-order confirmationOrdersV1Day 20WEB-04
RW-10Promotions & daily offersPromotionsV1Day 20WEB-05
RW-11NotificationsAccountV1Day 20WEB-05
RW-12Profile, store, addresses & settingsAccountV1Day 20WEB-05
RW-13Invoices, payments & creditFinanceV1Day 20WEB-04
RW-14Support: tickets, after-sales claims, returns & WhatsAppSupportV1Day 20WEB-05
RW-15Loyalty, rewards & packsV2V2DES-30WEB-20

What is shared and what is web-only

TopicRule on the web
Behaviour, copy, error codesExactly as the mirrored RA screen
Guest modeSame as RA-41: catalog, product pages, promotions and WhatsApp without an account, prices locked; sign-up prompts in a modal (desktop) or bottom sheet (phone)
SessionhttpOnly cookie hoco.session_token set by the API on Domain=.hoco.dz, Secure, SameSite=Lax, 30 days sliding (Max-Age=2592000); no token in JavaScript. A 401 sends to /signin?next=<path>. Server components forward the cookie to the API; client calls use credentials: "include". Mutations are protected by SameSite=Lax plus the API's Origin check (Assumption, see auth)
App configappConfig.get with app=RESELLER_WEB&platform=web: maintenance page and public settings; no version policy
Live updatesnew EventSource("https://api.hoco.dz/v1/events", { withCredentials: true }) while a tab is visible (events.stream); the browser resends Last-Event-ID; data also refetches on window focus (TanStack Query refetchOnWindowFocus). Same events and effects as the app
NotificationsIn-app inbox only — no web push in V1 (NOT-02 is mobile). The bell badge updates from live notification.created
WhatsAppThe fixed button (bottom-right, 56 px, label « WhatsApp » on hover) opens https://wa.me/… in a new tab (WhatsApp Web or Desktop). Signed in: Me.supportRegion; guest: support.whatsapp with the browser position if allowed, else the wilaya chooser
Barcode scanner (RA-11)Not on the web. A USB barcode reader typing into the search box works, because search matches barcodes exactly
FilesDrag and drop and paste (Ctrl+V of a screenshot) on every uploader, plus the file picker; same purposes and limits
PDFsInvoices, delivery notes and credit notes open in a new tab from a fresh signed URL (valid 5 minutes)
IdempotencyKeys of pending writes (checkout, declarations, claims, returns) are kept in sessionStorage until success, so a reload or a double click cannot duplicate them
SEONot needed: every page sends noindex, robots.txt disallows all. The only page made for sharing is the invitation landing, which carries Open Graph tags for WhatsApp and SMS previews (still noindex, the codes are personal)
AnalyticsSame events as the app with platform: "web"

Layout system

Breakpoints (Tailwind defaults):

WidthLayout
below 768 px (phone)The mobile designs of the RA screens: bottom tab bar (Accueil, Catalogue, Panier, Commandes, Compte), bottom sheets, sticky footers
768–1023 px (tablet)Top header with search and cart; navigation in a left drawer (hamburger); catalog filters in a drawer; product grids of 3 columns; forms in one centred column of 640 px
1024 px and above (desktop)The layouts described on this page; content centred, max width 1 280 px; grids of 4 columns from 1 280 px (3 below)

Desktop shell (≥ 1024 px):

  1. Header (64 px, sticky): logo « HOCO B2B » (→ /); search field in the centre (40 % of the width) with the type-ahead panel of RA-10 as a dropdown; right side: bell with badge and a dropdown of the 10 latest notifications, cart icon with the line count and a mini-cart popover (last lines, total, « Voir le panier »), account menu (store name, « Demi-gros », Mon compte, Mes commandes, Factures, Se déconnecter). Guests: « Se connecter » and « Créer un compte » instead of bell, cart and account.
  2. Navigation bar (48 px): Catalogue (mega-menu of categories and sub-categories), Nouveautés, Promotions, Mes commandes, Assistance.
  3. Banners slot under the navigation for the pending-validation, ordering-blocked and assisted-order banners of the app.
  4. Footer: support phone and hours, WhatsApp link of the region, legal links, app download badge.
  5. Fixed WhatsAppButton bottom-right.

Keyboard and accessibility (NFR-07):

  • A « Aller au contenu » skip link; logical tab order; visible focus ring (2 px, brand colour, 2 px offset) on every interactive element.
  • / focuses the search field; in the type-ahead (ARIA combobox) ↑/↓ move, Enter opens, Esc closes.
  • Quantity inputs accept digits; ↑/↓ change by qtyStep; the value is validated on Enter or blur with the same snapping message as the app.
  • Dialogs and drawers trap focus, close with Esc and return focus to their trigger. Toasts are announced (aria-live="polite"); errors under fields are linked with aria-describedby.
  • Range sliders work with arrow keys (one step) and PageUp/PageDown (ten steps), each thumb labelled (« Prix minimum », « Prix maximum »).
  • Tables use real <table> semantics with sortable headers as buttons; status pills carry text.
  • Contrast WCAG AA; layouts hold at 200 % browser zoom (they switch to the tablet or phone layout).

Routes

The web uses the same paths as the app's deep links (overview › deep links), so one link works everywhere: /, /i/{code}, /signin, /signup, /forgot-password, /account/pending, /search?q=, /catalog?…, /products/{productId}, /favorites, /cart, /checkout, /checkout/confirmation/{orderId}, /orders, /orders/{orderId}, /orders/{orderId}/confirm, /orders/{orderId}/return, /returns, /returns/{returnId}, /promotions, /promotions/{promotionId}, /notifications, /account, /account/store, /account/addresses, /settings, /finance, /finance/invoices/{invoiceId}, /finance/payments, /finance/payments/declare, /support, /support/new, /support/tickets/{ticketId}. Android App Links (/.well-known/assetlinks.json served by this app with the reseller app's signing certificate) make the same URLs open the app when it is installed.

RW-01 — Sign in, sign-up, OTP, password reset and guest browsing

FieldValue
ScreenSign in, sign-up (with customer type), OTP, password reset — and guest browsing · Account
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-01
RequirementsAUTH-03 · AUTH-04 · AUTH-05 · AUTH-10 · AUTH-11
Reference screenNone — follow the design system

Mirrors — RA-02, RA-03, RA-04, RA-05, RA-06, RA-07, RA-08, RA-41. No splash (RA-01): the server renders the first page; maintenance comes from appConfig.get.

Desktop layout — Two columns: a brand panel on the left (45 %: illustration, the three value lines of RA-02, the invitation card when a code is present) and the form on the right (max 440 px). Sign-up is one page with a three-step stepper at the top (« Téléphone » → « Code » → « Magasin ») — the customer-type RadioCards sit side by side in one row. Password reset is the same two-step page. The pending and rejected states of RA-06 are a centred card at /account/pending, also shown at the top of /account.

Behaviour — Identical to the app: OTP rules, claim of a field prospect, customer type required, terms acceptance, 401/403 messages. auth.login is sent with app: "RESELLER" from a browser: the API answers in cookie mode (no token in the body). After sign-in or sign-up the user returns to next (or the page they were on as a guest), now with prices.

Invitation landing /i/{code} (web-only, invitations.landing, IVT-04):

VisitorWhat happens
Android phone with the app installedThe App Link opens the app directly; the landing is never shown
Android phone without the appLanding card « Yacine, délégué HOCO, vous invite à rejoindre HOCO B2B » (invitations.resolve → delegateFirstName, storeName); the page redirects after 300 ms to the Play Store with referrer=inv%3DAB12CD34%26t%3D<token> (button « Installer l'application » as fallback), so the first launch attributes the install; secondary « Continuer sur le web » → /signup?code=AB12CD34
iPhone (no iOS app in V1 unless HOCO decides so)« Créer mon compte sur le web » first; the store button only if an iOS app exists
Computer« Créer mon compte » (web sign-up with the code) and a QR code of the same link: « Scannez pour installer l'application sur votre téléphone »
Invalid or expired code« Ce lien d'invitation n'est plus valable. » with « Créer un compte » and the WhatsApp button
Already signed inRedirect to / with « Vous êtes déjà connecté »

Desktop visitors are redirected to the web sign-up with the code prefilled (it also shows the QR code). Open Graph tags are generic (« Invitation HOCO — rejoignez le réseau des revendeurs ») so WhatsApp previews never show the store name; full behaviour on invitations.landing.

Acceptance criteria — A web sign-up with an invitation code is attributed to the inviting delegate like an app sign-up; on an Android phone without the app, « Installer l'application » leads to an install whose first launch prefills the code; a guest who signs in from a product page returns to it with prices.

RW-02 — Home

FieldValue
ScreenHome · Shopping
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-02
RequirementsCAT-11 · PRM-05 · FIN-10 · NOT-09 · NOT-10
Reference screenNone — follow the design system

Mirrors — RA-09.

Desktop layout — First row: the banner carousel with the daily offer (two thirds, with arrows and dots) and, on the right third, the account card (balance, available credit, assisted order to confirm, orders waiting for HOCO's confirmation) — or, for guests, the sign-up card. Second row: the quick tiles as four cards. Then « Catégories populaires » as a grid of 8 tiles and « Produits recommandés » as a 5-column carousel with arrows. The announcement card sits under the account card.

Behaviour — Same data (catalog.home) and rules as the app, server-rendered for the first paint with the session cookie; live events update the account card. Keyboard: carousel arrows are buttons, auto-advance pauses on hover and focus.

Notification Centre (change request 03) — NOT-09, WEB-06. The announcement card under the account card becomes the « Centre de notifications » card: group chips with their unread counts (notifications.unreadCount → byGroup), then the 3 latest unread items, each with its action button. A chip opens /notifications?group=. Live notification.created updates it. There are no pop-ups. Active flash sales follow the daily offer in the carousel, with their countdown.

RW-03 — Catalog with advanced sidebar filters & search

FieldValue
ScreenCatalog with advanced sidebar filters & search · Shopping
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-02
RequirementsCAT-07 · CAT-12 · CAT-13
Reference screenNone — follow the design system

Mirrors — RA-10 (search), RA-12 (catalog), RA-13 (filters and sort). The full filter specification — facets, widgets, counts, combination rules, guests — is RA-13.

Desktop layout

  1. Breadcrumb (« Catalogue › Chargeurs › Chargeurs muraux ») and the title with the count « 36 produits ».
  2. Left sidebar (272 px, sticky, scrolls on its own): the filter sections of RA-13 in the same order — category tree (expanded on the current branch), price slider with its two inputs (signed-in) or the lock (guest), brands, the category's attributes, availability, offers. Each section collapsible; « Réinitialiser » at the top. Filters apply immediately on the web (no « Afficher … » button): every change updates the URL, the counts and the grid (debounced 300 ms).
  3. Above the grid: active filter chips with × and « Tout effacer »; on the right, the tabs « Nouveautés · Populaires · Promotions » and the sort Select.
  4. Grid of product cards (3 or 4 columns) with the price or the lock, availability pill, heart and « Ajouter » button with a small quantity input (signed-in).
  5. Pagination: « Charger plus » button (cursor) instead of infinite scroll, and « 36 produits affichés sur 36 ».
  6. Tablet: the sidebar becomes a « Filtres » drawer with the app's apply button.

URL state — The whole filter state lives in the query string, so links are shareable, the back button undoes a filter and a reload keeps it: /catalog?category=chargeurs-muraux&brand=hoco&brand=acefast&priceMin=100000&priceMax=500000&attr.power=20..65&attr.connector=USB_C&availability=IN_STOCK&promotion=true&new=true&sort=price_asc&q=chargeur. Category and brand use their slugs (CategoryNode.slug, BrandView.slug), mapped to ids before calling catalog.products.list and catalog.facets; every other parameter is passed as is. Unknown parameters are dropped from the URL. Pushing history: one entry per applied change (debounced), replaceState while a slider is dragged.

Search — The header search shows the grouped suggestions of catalog.products.suggest in a dropdown; Enter goes to /catalog?q=…; recent searches are kept in localStorage (10).

Acceptance criteria — Copying the URL of a filtered catalog into another browser (signed in) shows the same products; the browser back button removes the last filter; a guest URL never contains price parameters (they are dropped).

RW-04 — Product detail

FieldValue
ScreenProduct detail · Shopping
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-02
RequirementsCAT-08
Reference screenNone — follow the design system

Mirrors — RA-14, RA-15.

Desktop layout — Two columns: gallery on the left (main image with click-to-zoom lightbox, vertical thumbnails), information on the right (name, reference, category, variant chips, price block or lock, recommended price and margin, availability, quantity input with −/+, « Ajouter au panier » and « Commander maintenant », WhatsApp link « Une question sur ce produit ? »). Below, full width: tabs « Description », « Caractéristiques » (the full grouped table of RA-15, inline — no separate page), « Garantie »; then similar and complementary products as carousels.

Web-only — Share: « Copier le lien » (and the Web Share API when the browser has it). Quantity typed with the keyboard as described above.

RW-05 — Favorites

FieldValue
ScreenFavorites · Shopping
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-02
RequirementsCAT-09
Reference screenNone — follow the design system

Mirrors — RA-16.

Desktop layout — /favorites in the account area (side navigation of RW-12): grid of cards with « Ajouter au panier »; removing shows an undo toast. Same API and rules.

RW-06 — Cart

FieldValue
ScreenCart · Ordering
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-03
RequirementsORD-01 · ORD-02
Reference screenNone — follow the design system

Mirrors — RA-17.

Desktop layout — Two columns. Left: the lines as a table — image, product (name, variant, reference, line issue under it), unit price (promotional price and struck base price), quantity input with −/+, line total, remove (×). Right: a sticky summary panel (320 px) — « Sous-total », « Remises », « Frais de livraison », « Total TTC », « dont TVA », the minimum-amount and free-delivery progress bars, applied promotions, and the primary « Passer la commande » with its blocking reason. Cart-level banners above the table.

Behaviour — Same CartView, issues, fixes and undo as the app. The cart is shared: the page refetches on window focus, so a line added on the phone appears when the reseller comes back to the tab. Quantity changes from the keyboard are sent on Enter or blur (and debounced while clicking −/+).

RW-07 — Checkout & confirmation

FieldValue
ScreenCheckout & confirmation · Ordering
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-03
RequirementsORD-03 · FIN-02 · FIN-05
Reference screenNone — follow the design system

Mirrors — RA-18, RA-19 (address choice and form), RA-20.

Desktop layout — Two columns. Left, the numbered sections of RA-18: addresses as selectable cards in a grid of two (with « Ajouter une adresse » opening the form of RA-19 in a dialog), payment methods as radio cards with their instructions and the credit box, the note. Right, the sticky summary with the collapsible lines, the totals and « Valider la commande ». Confirmation at /checkout/confirmation/{orderId}: the content of RA-20 in a centred card (« Commande envoyée ! », number, Envoyée — en attente de confirmation par HOCO, summary, « Suivre ma commande »), updated live if HOCO confirms while it is open.

Web-only — The Idempotency-Key of the pending checkout is kept in sessionStorage with the body fingerprint: a double click, a reload during the request or the browser back button after a timeout replays the same key; the button is disabled from the first click. Leaving the page while the request runs shows the browser's « Quitter la page ? » prompt. After success, /checkout redirects to /orders (the cart is empty).

Acceptance criteria — Double-clicking « Valider la commande » or reloading during the request creates one order; the confirmation shows Envoyée and never Validée before HOCO confirms.

RW-08 — Orders list

FieldValue
ScreenOrders list · Orders
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-04
RequirementsORD-07
Reference screenNone — follow the design system

Mirrors — RA-21.

Desktop layout — The five status tiles in one row (clickable filters), the pinned « À confirmer » assisted order, then a table: N°, Date, Canal, Articles, Total TTC, Statut (pill with the step label), Paiement (invoice status), and actions (Voir, Recommander, invoice PDF icon when issued). Filters above the table: search, status, period, channel; « Charger plus » pagination. Rows update live (pill and tracker), with a brief highlight.

RW-09 — Order detail, tracking & assisted-order confirmation

FieldValue
ScreenOrder detail, tracking & assisted-order confirmation · Orders
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-04
RequirementsORD-06 · ORD-07 · ORD-08 · ORD-15 · ORD-13
Reference screenNone — follow the design system

Mirrors — RA-22, RA-23, and the return form of RA-40 (/orders/{orderId}/return).

Desktop layout — Two columns. Left: status header and banner, horizontal five-step tracker with dates, items table, history timeline. Right (sticky): totals, payment card (with « Déclarer un paiement »), delivery card, documents, the « Retours et SAV » block, and the allowed actions (Recommander, Annuler la commande, Contacter l'assistance). For an assisted order awaiting the reseller, the right column becomes the confirmation panel of RA-23 (countdown, address, payment method, note, « Confirmer la commande », « Refuser »); /orders/{orderId}/confirm scrolls to it. The return request opens as a page with the form of RA-40 (lines table with quantity inputs, reason, comment, photo drop zone).

Behaviour — Live via events.stream (order.status_changed, order.modified, return.status_changed): the tracker and timeline update without reload. Same rules, windows and errors as the app.

RW-10 — Promotions & daily offers

FieldValue
ScreenPromotions & daily offers · Promotions
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-05
RequirementsPRM-01 · PRM-05 · PRM-07
Reference screenNone — follow the design system

Mirrors — RA-24, RA-25.

Tabs (change request 03) — Tabs « Promotions » and « Ventes flash » as in the app (V2 « Offres exclusives »), as the ?tab= query so the back button and shared links work. Flash sales are a 3-column grid of FlashSaleCard with live countdowns from the server time (PRM-07, WEB-06).

Desktop layout — Daily offers as a wide carousel with countdowns, then the promotions as a 3-column card grid with brand filter chips; the promotion page shows the conditions in a side card and the eligible products as a catalog grid (with the catalog's filters). Guests see everything with the price lock.

RW-11 — Notifications

FieldValue
ScreenNotifications · Account
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-05
RequirementsNOT-01 · NOT-09 · NOT-10
Reference screenNone — follow the design system

Mirrors — RA-26.

Groups and actions (change request 03) — The dropdown and the full page group items by NotificationGroup. The page has a left column of groups with unread counts; the dropdown has a « Toutes / Urgent » toggle. Every item shows its action button. The group push switches live on RW-12 and apply to the app, since the reseller web has no web push (WEB-06).

Desktop layout — The header bell opens a 380 px dropdown with the 10 latest items, « Tout marquer comme lu » and « Voir toutes les notifications » → /notifications, a full page with the filter chips of the app and the announcement detail in a dialog. No web push: the badge is kept current by live notification.created events while a tab is open, and by notifications.unreadCount on focus.

RW-12 — Profile, store, addresses & settings

FieldValue
ScreenProfile, store, addresses & settings · Account
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-05
RequirementsCRM-01 · NOT-06
Reference screenNone — follow the design system

Mirrors — RA-27, RA-28, RA-19 (management), RA-35.

Desktop layout — Account area with a left side navigation (240 px): Tableau de bord du compte (identity card, customer type, delegate, money tiles — RA-27), Mon magasin (RA-28, form in two columns, document list with a drop zone), Adresses (cards grid, form in a dialog), Favoris (RW-05), Mes retours, Notifications (preferences), Sécurité (password, connected devices — the current browser shows as « Web revendeur · Chrome sur Windows », phone change), Informations (legal, account deletion request). The finance pages (RW-13) and support (RW-14) are entries of the same navigation.

RW-13 — Invoices, payments & credit

FieldValue
ScreenInvoices, payments & credit · Finance
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-04
RequirementsFIN-01 · FIN-03 · FIN-10
Reference screenNone — follow the design system

Mirrors — RA-29, RA-30, RA-31.

Desktop layout — /finance: a row of summary cards (balance due, overdue, available credit with its bar, declarations under verification, available credit notes), then tabs « Factures » · « Avoirs » · « Paiements » with tables (number, dates, order, amounts, remaining, status, PDF). The invoice detail opens in a right-side drawer. « Déclarer un paiement » opens the declaration form in a drawer (600 px): method cards with HOCO's payment details and copy buttons, amount, date, reference, invoices to pay as a checkbox table with remaining amounts, proof drop zone (drag and drop, paste, or browse; PDF or image up to 10 MB), comment. Same API, rules and verification flow as RA-31.

RW-14 — Support: tickets, after-sales claims, returns & WhatsApp

FieldValue
ScreenSupport: tickets, after-sales claims, returns & WhatsApp · Support
French title—
ReleaseV1
Design dayDay 20 — DES-20
Build taskWEB-05
RequirementsSUP-01 · SUP-04 · SUP-05 · ORD-13
Reference screenNone — follow the design system

Mirrors — RA-32, RA-33, RA-34, and the returns list and detail of RA-40.

Desktop layout — /support: the regional WhatsApp card and phone at the top (region name, number, hours, « Écrire sur WhatsApp » opening WhatsApp Web), the FAQ, then a two-pane view — requests list on the left (tabs « Toutes · SAV · Autres », status pills), the selected conversation on the right with the resolution card of a claim and the composer (Enter sends, Shift+Enter new line, drop zone for attachments). « Nouvelle demande » and « Réclamation SAV » open the forms of RA-33 as pages: the claim form shows the order's lines as a table with checkboxes and quantity inputs, the issue cards in a row, and a photo drop zone. Mes retours lists the return requests with their status and opens the return detail of RA-40.

Behaviour — Live ticket.replied, ticket.resolved and return.status_changed update the open pane. Same windows (30 days for claims, 7 for returns) and errors as the app.

RW-15 — Loyalty, rewards & packs

FieldValue
ScreenLoyalty, rewards & packs · V2
French title—
ReleaseV2
Design dayDES-30 — V2 designs (no fixed day)
Build taskWEB-20
RequirementsLOY-03 · LOY-04 · PRM-06
Reference screenNone — follow the design system

V2 — designed in DES-30, built in WEB-20. Mirrors — RA-37, RA-38, RA-39.

Desktop layout — Loyalty page with the points card, the level track and the history table side by side; rewards as a card grid with a confirmation dialog; packs as a grid on the promotions page and a pack detail page with the items table and « Ajouter le pack au panier ». Same API and rules as the app.

On this page