Skip to content

feat(CP-2836): enforce free product options before quick checkout - #1022

Closed
aelzakzouk wants to merge 6 commits into
masterfrom
feature/CP-2836-enforce-free-product-options-quick-checkout
Closed

feat(CP-2836): enforce free product options before quick checkout#1022
aelzakzouk wants to merge 6 commits into
masterfrom
feature/CP-2836-enforce-free-product-options-quick-checkout

Conversation

@aelzakzouk

Copy link
Copy Markdown
Contributor

No description provided.

…illed

Add salla-add-product-button validate hook that scrolls to the options
section and shows a soft info hint when optional options are unselected;
checkout is not blocked (required options are validated server-side).
Add optional_options_hint i18n key in Arabic and English.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sallainternalbot
sallainternalbot Bot marked this pull request as draft August 4, 2026 14:26
@codacy-production

codacy-production Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Not up to standards ⛔

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🔴 Metrics 4 duplication

Metric Results
Duplication ⚠️ 4 (≤ 2 duplication)

View in Codacy

AI Reviewer: run a review on demand. To trigger the first review automatically, go to your organization or repository integration settings. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@aelzakzouk
aelzakzouk force-pushed the feature/CP-2836-enforce-free-product-options-quick-checkout branch from 1101c24 to 55d1489 Compare August 6, 2026 13:45
aelzakzouk and others added 5 commits August 8, 2026 05:55
…heckout

- Two-path gate on salla-add-product-button validate hook:
  PDP: blocks + scrolls when required advance=0 options are missing; injects
       filled selections into cart::before.add.item
  Non-PDP: calls product/options API, opens salla-order-options-modal with free
           options as steps (product preview + options form); blocks on dismiss
- Add cart::before.add.item listener to inject _pendingFreeOptions as `options`
- Add required_free_options_message locale key (AR + EN)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ick buy

- Always call product/options API before quick buy (even on PDP page)
- Priority 1: if offer_options returned (Y has required options) → open modal
  showing Y's thumbnail + name + options as steps
- Priority 2: if X itself has free options → PDP: validate in-place,
  non-PDP: open modal for X
- _pendingOfferFreeOptions injected as free_product_options[Y.id] in
  cart::before.add.item so backend receives Y's selections alongside X

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…k checkout

- Fix API key: read advance_free_product (array) instead of offer_options
- Replace single-offer handler with _handleOfferFreeOptionsSteps that loops
  each entry sequentially, opening one salla-order-options-modal per Y
- Pending offer options stored as [{productId, options}] array instead of
  single object
- Cart injection promotes X to products[0] and appends each Y as products[N]
  with bracket-notation keys so MiniCheckoutRequest parses them correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… DOM

The modal is injected by salla-add-product-button at runtime, so
querySelector returns null when our hook fires. Create and attach it
ourselves, then await customElements.whenDefined() before calling open().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@momen-mahmoud-mahmoud

Copy link
Copy Markdown
Contributor

Closing as superseded by https://github.com/SallaApp/twilight/pull/2191, which implements this behaviour in salla-order-options-modal / OrderOptionsGate instead of in the theme.

The reasoning, so it's on the record:

  • The storefront gate now lives in Twilight, so every theme gets it rather than Raed alone. That matters because the server-side check in MiniCheckoutRequest applies to all themes — a merchant on any other theme would otherwise hit a validation error with no UI to satisfy it.
  • The Twilight branch already carried the wizard, product card, offer badge and RTL work (af744d5b7..5923a7594), so this behaviour was effectively moved out of the theme on 2026-08-08..10 and this PR is the earlier attempt at the same thing.
  • Shipping both would mean two gates on one storefront, each with its own cart::before.add.item handler rewriting the same payload.

One thing deliberately not carried over: pages.products.optional_options_hint (the nudge when optional options are left blank) has no Twilight equivalent. It never fired in practice — _handlePdpFreeOptions reads optionsEl.optionsData, a private Stencil @State that isn't readable from the host element — but if that nudge is wanted as a feature, it belongs in salla-product-options and is worth its own ticket. required_free_options_message is covered: the modal reports required-option failures via blocks.order_options.required_message, and PDP validation goes through validateAndScroll().

Reopen if you disagree — happy to be wrong here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants