HOCO B2B
DesignScreen specificationsReseller app

Promotions

Screen specifications RA-24 and RA-25 of the reseller app — daily offers with countdown, the list of promotions targeting the reseller, and a promotion's conditions and eligible products.

Cahier §4.6 and §5.5: daily offers, scheduled promotions and temporary discounts on products, categories or brands, targeted by wilaya, segment, level, brand or volume; « Une promotion doit respecter ses dates, son stock et sa cible ». V1 has simple promotions only (PRM-01); packs and loyalty are V2 (RA-37 to RA-39). Designed on day 10, built in MRA-06. Promotions apply automatically in the cart — there is no code to type.

IDScreenUI titleSectionReleaseDesignBuild
RA-24Promotions & daily offersPromotionsPromotionsV1Day 10MRA-06
RA-25Promotion detailDétail de l'offrePromotionsV1Day 10MRA-06

Guests. Guests see promotions and banners — label, percentage badge, dates, conditions and eligible products — but no price and no amount (PriceLock); « −30 % » badges stay. promotions.list, promotions.get and banners.list accept calls without a session (auth: optional) and then return untargeted, public promotions only.

Client reference — promotions and loyalty: daily flash offer with countdown, profitable packs, loyalty points, level and rewards. V1 covers the daily offers; packs and loyalty are V2.
Client reference — promotions and loyalty: daily flash offer with countdown, profitable packs, loyalty points, level and rewards. V1 covers the daily offers; packs and loyalty are V2. — client reference (cahier des charges)

RA-24 — Promotions & daily offers

FieldValue
ScreenPromotions & daily offers · Promotions
French titlePromotions
ReleaseV1
Design dayDay 10 — DES-10
Build taskMRA-06
RequirementsPRM-01 · PRM-05 · PRM-07
Reference screenreseller-06-promotions-loyalty

Purpose — Show today's offers and every promotion currently available to the reseller, so they can act before it ends (PRM-01, PRM-05).

Entry points & exits — Promotions quick tile and the daily offer on RA-09; notifications daily_offer.published and promotion.started; /promotions. Exits to RA-25, RA-14 (product of a daily offer), RA-12 on the Promotions tab (« Voir tous les produits en promotion »), WhatsApp.

Layout

  1. AppBar « Promotions » with back and a search icon (→ RA-10).
  2. « Offres du jour » with « Voir tout »: Carousel of daily offers as on the reference — label « OFFRE FLASH » or « OFFRE DU JOUR », title (« Jusqu'à −30 % »), subtitle (« sur une sélection de produits HOCO »), image, discount badge, Countdown « Se termine dans 12 h 45 min 30 s », dots.
  3. Filter chips: « Toutes », « Se termine bientôt » (under 48 h), « HOCO », « ACEFAST », « BOROFONE ».
  4. « Toutes les promotions »: list of promotion cards — image or brand logo, title, type label (Remise en %, Remise en montant, Prix promotionnel, Livraison offerte), scope line (« Sur les chargeurs HOCO », « Sur toute la marque ACEFAST »), validity « Jusqu'au 30 nov. », and « Quantité limitée » when a stock cap applies (never the remaining number).
  5. Text link « Voir tous les produits en promotion » → RA-12, tab Promotions.
  6. WhatsAppButton (floating). Packs and loyalty sections of the reference come in V2.

Data

ShownSource
Daily offers and promotionspromotions.list → items[].id, title, subtitle, type (PromotionType), badgeLabel, imageUrl, scopeLabel, brandId, startsAt, endsAt, isDailyOffer, hasStockCap
Carousel extra slidesbanners.list ?placement=PROMOTIONS → items[].imageUrl, title, route
Server clockappConfig.get → serverTime (countdowns)

Actions — Card or slide → RA-25 (a daily offer on a single product may open RA-14 directly). Chips filter locally. Pull-to-refresh. A countdown reaching zero turns its card into « Offre terminée » and the card disappears at the next refresh.

Rules

  • Only active promotions targeting the reseller are returned — dates, stock cap and target are applied server-side (PRM-02, PRM-04); scheduled promotions are not shown in V1.
  • Discounts are computed on the reseller's customer-type price; stacking follows the configured rules (PRM-03).
  • A promotion's remaining stock cap is never shown as a number (consistent with STK-07): « Quantité limitée ».

States — Loading: carousel and card skeletons. Empty: « Aucune promotion en cours — revenez demain pour les offres du jour. » with « Voir le catalogue ». Error: ErrorState. Offline: cached list with the offline banner; countdowns keep running on cached endsAt. Guest: same screen, amounts locked.

Copy — « Promotions » · « Offres du jour » · « OFFRE FLASH » · « Se termine dans {remaining} » · « Toutes » · « Se termine bientôt » · « Toutes les promotions » · « Jusqu'au {date} » · « Quantité limitée » · « Offre terminée » · « Voir tous les produits en promotion » · « Aucune promotion en cours — revenez demain pour les offres du jour. »

Analytics — promotions_viewed with count, userKind; promotion_clicked with promotionId, position, isDailyOffer.

Tabs and flash sales (change request 03) — PRM-07, designed in DES-23, built in MRA-11.

  • Under the app bar, TabBar with « Promotions » and « Ventes flash ». V2 adds « Offres exclusives » (PRM-08). A tab without content is hidden. The screen opens on « Ventes flash » when a flash sale is active, else on « Promotions »; the routes are /promotions?tab=promotions and /promotions?tab=flash.
  • Promotions holds today's layout (daily offers and normal promotions that last several days or until the stock runs out).
  • Ventes flash lists the isFlashSale offers sorted by end time. Each card is a FlashSaleCard (DES-23): image, label « VENTE FLASH », discount badge, title, and a countdown that is prominent under 24 h (« Plus que 05:12:45 », ticking every second, from serverTime) and a date line from 24 h (« Se termine dans 2 jours »). The primary button « Commander maintenant » opens RA-25 or the single product on RA-14. At zero the card turns « Offre terminée » and greys out.
  • The push flash_sale.started opens RA-25 of that sale; the chip « Se termine bientôt » stays on the Promotions tab.

Acceptance criteria

  • A promotion targeted at another wilaya or segment is not listed (cahier §12 Promotion scenario).
  • A countdown reaches zero at the promotion's endsAt (server time), not the phone's clock.
  • No remaining-quantity number appears.

RA-25 — Promotion detail

FieldValue
ScreenPromotion detail · Promotions
French titleDétail de l'offre
ReleaseV1
Design dayDay 10 — DES-10
Build taskMRA-06
RequirementsPRM-01 · PRM-04
Reference screenNone — follow the design system

Purpose — Explain a promotion — what, on which products, until when, under which conditions — and let the reseller add eligible products to the cart (PRM-01, PRM-04).

Entry points & exits — Cards and slides of RA-24, the daily offer of RA-09, the promotion link on RA-14, notifications daily_offer.published and promotion.started, /promotions/{promotionId}. Exits to RA-14, RA-17 (snackbar), RA-41 (guest lock).

Layout

  1. Hero image with back and share; badge « −30 % ».
  2. Title, scope line, validity « Du 10 au 30 nov. 2026 » or a Countdown under 24 h.
  3. « Conditions » list, built from the promotion fields:
    • « Remise de 30 % sur une sélection de produits HOCO » (type and value);
    • « Valable du 10 nov. au 30 nov. 2026 »;
    • « Dans la limite des stocks alloués à l'offre » (when a stock cap exists);
    • « Minimum 5 pièces par article » (when a minimum quantity applies);
    • « Non cumulable avec d'autres offres » (stacking rule);
    • « Appliquée automatiquement dans votre panier ».
  4. « Produits concernés »: grid of ProductCard with the promotional price and the struck-through base price (or the lock), cart icons, infinite scroll.
  5. For Livraison offerte: no grid — « Livraison offerte sur toute commande à partir de 20 000,00 DA » and « Voir le catalogue ».

Data

ShownSource
Promotionpromotions.get → title, type, value, badgeLabel, scopeLabel, imageUrl, startsAt, endsAt, hasStockCap, minQty, stackable, minOrderAmount (free delivery)
Eligible productscatalog.products.list ?promotionId=&cursor= → items[] (ProductCard with promotion.price)

Actions — Product card → RA-14; quick add as on the catalog; share → « Offre HOCO : −30 % sur une sélection de produits HOCO jusqu'au 30 nov. » with the link /promotions/{promotionId} (no price).

Rules — The promotion applies to the eligible products only, within its dates, stock cap and target (PRM-04); the cart shows it on each line (RA-17) and its amount in the summary. An ended, paused or untargeted promotion is not served.

States — 404 NOT_FOUND (ended, paused or not targeted): « Cette offre est terminée » with « Voir les promotions en cours » → RA-24. No eligible product left: « Tous les produits de cette offre sont en rupture. » Offline: cached detail. Guest: amounts locked; conditions visible.

Copy — « Conditions » · « Remise de {value} sur {scope} » · « Valable du {start} au {end} » · « Dans la limite des stocks alloués à l'offre » · « Minimum {minQty} pièces par article » · « Non cumulable avec d'autres offres » · « Appliquée automatiquement dans votre panier » · « Produits concernés » · « Cette offre est terminée ».

Analytics — promotion_viewed with promotionId, type, userKind; add_to_cart with source: "promotion", promotionId.

Acceptance criteria

  • A product added from this screen shows the promotional price in the cart, and the cart total applies the promotion correctly (cahier §5.5).
  • After endsAt, the deep link shows « Cette offre est terminée ».
  • Conditions shown match those entered in the promotion editor (BO-50).

On this page