ProcureGlobal · Round 2B · Mobile-first

Cart drawer & full cart page — bundle-aware, RN-portable

Two cart surfaces that share the same line-item vocabulary. The drawer is a bottom sheet on mobile and a slide-from-right panel on desktop. The dedicated cart page is the same line-item rendering with breathing room, plus shipping selector, totals breakdown, and the B2B quote-request entry. Both render fixed bundles as parent + indented children with rolled-up pricing, and configurable bundle add-ons as tagged children. No B2B order-approval gate — that was an earlier misroute and stays out of the cart flow.

round 2B surfaces drawer + page platform web · iOS · Android bundle-aware per Q-PDP-3 draft touch min 48px
2B · A Cart drawer (bottom sheet) opens over the PDP, no route change
9:41

Hisense 55" 4K UHD…

GHS 6,499
Cart3 items
Hisense 55" 4K UHD Smart TV — A6
55" Configurable
1
GHS 6,499
Universal Wall Mount 32–65"
Add-on + GHS 249
Configurable bundle · 2 items GHS 6,748
Office Starter Pack — Chair + Desk + Monitor Stand
Black / Walnut Fixed bundle Save GHS 480
1
GHS 3,899
Ergonomic Mesh Chair · Black
Included Bundled
Standing Desk 120cm · Walnut
Included Bundled
Aluminium Monitor Stand
Included Bundled
Fixed bundle · 3 items GHS 3,899 −GHS 480 saved
Indomie Instant Noodles Carton — 40 × 70g
Chicken
2
GHS 360
Spend GHS 1,252 more for free express delivery to Accra · East Legon
Subtotal · before tax & shipping GHS11,007
Tax & shipping calculated at checkout
Drawer over PDP · 78% sheet height

Drawer rationale

The drawer is the instant-feedback affordance — tap "Add to cart" on a PDP and the sheet slides up so you can confirm the addition without losing your place. No route change, no scroll loss. Two CTAs out: "View cart" goes to the full page; "Checkout" jumps straight into the three-step flow.

Mechanics

  • Bottom sheet at 78% screen height — leaves the PDP visible behind the dimmed scrim so context is preserved. Drag-down dismiss. Snap points at 40% (collapsed preview), 78% (default), and 96% (immersive).
  • Slides in over content — does not push or scroll the page underneath. Background is dimmed with a rgba(28,26,71,0.55) scrim and a faint blur to denote modal context.
  • Desktop equivalent — same component, different layout primitive: slides in from the right at 420px width, full viewport height, with the same scrim over the page.
  • Drag handle at the top is the platform-standard "this is a sheet you can drag" affordance — iOS and Android both render it the same way; web uses identical markup.

Line item vocabulary

  • Three shapes in one component: plain item, bundle parent (with lavender wash + indented children + rolled-up footer), bundle child (smaller thumb, indented, dimmed price, connector lines on the left).
  • Bundle children show no individual price — for fixed bundles they're "Bundled" (free, included). Total comes from the parent's rolled-up footer line, which also displays the savings versus the sum of components' list prices.
  • Configurable bundles (the TV + Wall mount case) render the add-on as a child with a "+ GHS 249" delta — visible cost, distinct from a fixed bundle's free children. The bundle-end footer rolls them up to the combined line price.
  • Variant chips inline — e.g., "55"", "Black / Walnut" — keep the variant visible without an "edit" dive. Tapping the variant opens a bottom sheet to change it without leaving the cart.
  • Quantity stepper inline at 32×32 with 32px label — total reach is just inside the 48px floor at the tap zone of the button cores, with adequate spacing.
Bundle rendering wired to Q-PDP-3 schema Drawer reads cart_items and joins cart_item_components for each item where the parent product has is_bundle = true. Fixed-bundle children render with line-price free; configurable bundle children render with delta pricing per the price_strategy on each bundle_items row. Bundle-end footer is the sum of selected components, displayed as the bundle's effective cart price.

Incentive strip

  • "Spend X more for free delivery" — midnight strip with aqua highlight, sits between the items and the totals. Source: nearest free-delivery threshold from shipping_rates, computed server-side. When the threshold is crossed, the strip swaps to "Free express delivery unlocked".
  • No urgent coral here — coral is reserved for flash sales and stockouts per the brand system. The promo strip uses aqua-on-midnight as a positive nudge.

Open questions for Ekow

  • Configurable bundle: edit-in-cart vs back-to-PDP? Currently the child add-on row has no inline edit affordance — to remove the wall mount, the customer taps the parent and goes back to the PDP. Alternative: a small "×" on the child row removes just the add-on, leaving the parent. Which? Q-2B-1
  • Drawer snap points. 40 / 78 / 96 % proposed. Confirm or override. Q-2B-2
  • Free-delivery threshold needs to be a real number. Is GHS 12,000 the floor for free Accra express, or does it vary by region / courier? Q-2B-3
2B · B Full cart page dedicated route · same line vocabulary
9:41
Your cart · 3 items

Your cart

3 items · ready to check out · delivering to Accra · East Legon
In your cart
Hisense 55" 4K UHD Smart TV — A6
55" Configurable
1
GHS 6,499
Universal Wall Mount 32–65"
Add-on + GHS 249
Configurable bundle · 2 items GHS 6,748
Office Starter Pack — Chair + Desk + Stand
Black / Walnut Fixed bundle Save GHS 480
1
GHS 3,899
Ergonomic Mesh Chair · Black
Included Bundled
Standing Desk 120cm · Walnut
Included Bundled
Aluminium Monitor Stand
Included Bundled
Fixed bundle · 3 items GHS 3,899 −GHS 480 saved
Indomie Instant Noodles Carton — 40 × 70g
Chicken
2
GHS 360
Delivery to Accra · East Legon
Speedaf · Standard
1–3 days
GHS 35
Bolt courier · Same-day
Order by 2pm · Accra metro
GHS 80
Store pickup · East Legon
Ready in 2 hours
Free
Subtotal · 3 items GHS 11,007
Bundle savings − GHS 480
Shipping · Speedaf Standard GHS 35
Tax · inclusive GHS 1,650
VAT 15% GHS 1,432
NHIL · GETFund · COVID GHS 218
Total GHS11,042
USD presentment USD 722.66 @ 15.28
For business

Buying for an organisation?

Turn this cart into a B2B quote — volume pricing, NET 30 terms (v1.1), and a PO workflow for your team.

Total
GHS 11,042
Cart page · /cart route

Full cart page rationale

The page is for the long stare — promo codes, shipping choices, tax transparency, and the B2B off-ramp. Same line-item vocabulary as the drawer; everything else is page-level chrome.

Structure

  • Items first. Highest information value, top of the page. Promo, shipping, and totals stack below.
  • "Clear cart" is a destructive action behind a confirm modal — kept visible but de-emphasised in coral text only.
  • Promo code as plain input + Apply button. Monospace placeholder keys the input as machine-shaped data. Success state replaces the row with a "Promo applied: BACKTOSCHOOL10 · −GHS 200" pill.

Shipping selector

  • Radio rows, not a dropdown. Customer needs to compare options at a glance — price, ETA, courier name. Speedaf / Bolt / DHL named per locked PRD §6.10.
  • Address chip at the top with "Change" — opens an inline form for region + GhanaPost GPS code. Saved addresses appear as cards above the form for authenticated users.

Totals breakdown

  • Tax shown inclusive of all four levies per PRD §7.4. Sub-rows (VAT, NHIL/GETFund/COVID) shown in DM Mono, indented and muted — present for transparency but not the headline.
  • Bundle savings as a positive line in the success colour — communicates the discount earned, not just the totals.
  • Grand total in a lavender/aqua wash, large Bricolage display. Always GHS primary.
  • USD presentment sits below the grand total in lavender mist — for diaspora buyers; FX rate visible. Refreshes on currency switcher change.

B2B off-ramp

  • "Buying for an organisation?" dark card mirrors the PDP B2B prompt — the same affordance reappears in the cart so a customer who arrived as B2C can convert mid-cart. Tap routes the cart contents into a new draft quote (PRD §6.3 lifecycle: draft → submitted → under_review).
  • Quote is staff-approved per PRD §6.3 — but that approval gate sits in the quote flow, NOT in the regular order checkout. B2C and B2B-buying-as-B2C checkouts auto-confirm.

Sticky action bar

  • Mini total + Checkout primary. Same pattern as the PDP, single primary CTA — no wishlist on the cart page, the surface is already committed.
  • "Continue shopping" as a tertiary text link above the action bar — out of the way but discoverable.

Web ↔ React Native primitive map

One cart model, two render targets. The drawer and page share their item-list component (CartLineList). The drawer mounts it inside BottomSheet (web) / @gorhom/bottom-sheet (RN). The page mounts it inside a scrolling layout. Same JSON in, same component, two enclosures.
Bottom-sheet drawer@gorhom/bottom-sheet · snap [0.4, 0.78, 0.96]
Cart line listFlatList · ItemSeparatorComponent
Bundle parent + childrenSectionList by bundle_id (header + footer roll-up)
Quantity stepperPressable + Animated.View
Shipping radio rowsRadioGroup (custom Pressable) — no native picker
Promo code input + applyTextInput autoCapitalize="characters"
Free-delivery progress stripView + ProgressBar (Animated.Value)
Sticky bottom action barAbsolute View + useSafeAreaInsets()
Currency presentment rowSame component, useLocale() for FX

Open questions for Ekow

  • Promo code policy. Does a promo stack with bundle savings, or are they mutually exclusive? Today both render, but the policy needs confirming. Q-2B-4
  • "Save for later" affordance on cart items — common e-commerce pattern. Include for v1.0 or defer? Q-2B-5
  • Bulk pricing trigger for B2C customers. The PDP showed "Bulk pricing from 5 units" but the cart doesn't yet surface a per-line bulk tier table. Show it inline when qty crosses the threshold, or keep it PDP-only? Q-2B-6
  • Address picker UX — inline form vs full-page route vs bottom-sheet. Today's mock implies inline; checkout (Round 3) is the real address editor. Confirm. Q-2B-7

What's next

  • Round 3 — three-step checkout (address → shipping → payment), guest + authenticated flows, currency switcher persistence. Customer account dashboard (orders, addresses, saved methods, B2B sub-user view).
  • Round 4 — B2B quote flow (cart-to-quote, status timeline, accept/decline), admin shell, customer 360, reviews moderation queue (per Q-PDP-4 spec).
  • Round 5 — Native-specific patterns: tab bar nav, native modals, share sheets, push permission flows, biometric unlock.
  • System extras — Email templates (React Email), empty states (incl. empty cart), loading skeletons, error pages (incl. payment failed, out of stock).