Skip to content

VNEXT-83184: Redesign checkout coupon UI - #1439

Open
abansal2-godaddy wants to merge 12 commits into
godaddy:mainfrom
abansal2-godaddy:VNEXT-83184
Open

abansal2-godaddy wants to merge 12 commits into
godaddy:mainfrom
abansal2-godaddy:VNEXT-83184

Conversation

@abansal2-godaddy

@abansal2-godaddy abansal2-godaddy commented Aug 24, 2026

Copy link
Copy Markdown

Summary

Implements VNEXT-83184: redesign the checkout coupon / promotion code UI (default → filled → success → error).

Where this lives: @godaddy/react DiscountStandalone (used by Bruce when enablePromotionCodes is on).

Design

  1. Combined bordered row (h-12, theme tokens) — input + Apply (or clear on error)
  2. Compact helper text under the field for errors
  3. Full-width applied bar — check + code + amount + remove (accent surface, foreground text)
  4. One coupon at a time — entry field hidden while a code is applied
  5. Coupon heading is host-owned via checkout.summary.discount.before / .after (not shipped in the package)

Error copy

Maps GraphQL codes via apiErrors, falls back to failedToApply (does not claim every failure is an “invalid” code).

What changed

  • discount-standalone.tsx / discount-applied-bar.tsx
  • Targets: checkout.summary.discount.before|after
  • Existing locale keys only (placeholder, enterCode, apply, …) — no new en-US-only strings
  • Unit tests + changeset

Test plan

  • Discount unit tests pass locally
  • After publish + Bruce bump: default / filled / success / error on checkout
  • Host injects heading via checkout.summary.discount.before if desired
  • Applied bar readable under default theme; remove restores input

abansal2-godaddy and others added 2 commits August 24, 2026 13:30
Implement combined coupon input states (default, filled, success, error)
in DiscountStandalone, add DiscountAppliedBar, and extend enUs discounts
strings for GOLF to translate into other locales.

Co-authored-by: Cursor <cursoragent@cursor.com>
Versioning can be handled in the release workflow; the coupon redesign does not need a local changeset.

Co-authored-by: Cursor <cursoragent@cursor.com>
@abansal2-godaddy
abansal2-godaddy requested a review from a team as a code owner August 24, 2026 08:10
@changeset-bot

changeset-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8475b7a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@godaddy/localizations Patch
@godaddy/react Patch
nextjs Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Bump @godaddy/react and @godaddy/localizations so the Version Packages workflow can publish after merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
@abansal2-godaddy
abansal2-godaddy marked this pull request as draft August 24, 2026 09:44
abansal2-godaddy and others added 2 commits August 24, 2026 15:19
Clarify in DiscountStandalone and DiscountAppliedBar that the redesign cannot reuse the old input/button/chip composition, so those imports were dropped from this path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the explanation in the PR description and review comments instead.

Co-authored-by: Cursor <cursoragent@cursor.com>

@abansal2-godaddy abansal2-godaddy left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer notes (also in the PR description): why the layout changed, and why the old discount imports were dropped from — without leaving that rationale in the source files.

import { eventIds } from '@/tracking/events';
import { TrackingEventType, track } from '@/tracking/track';
import { Discounts } from './discounts';
import type { DiscountFormProps } from './types';

@abansal2-godaddy abansal2-godaddy Aug 24, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these imports changed / why the old ones are gone from this file

Previously this file composed:

  • DiscountInput
  • DiscountApplyButton
  • DiscountErrorList
  • Discounts / DiscountTag

Those matched the old UX (separate input + button, large alert errors, chip tags with code only).

VNEXT-83184 needs a different UX, so those imports were removed from this path:

  • Input + Apply (or clear) must live in one bordered row → not standalone DiscountInput / DiscountApplyButton
  • Errors are a short helper under the field → not DiscountErrorList
  • Success needs code + formatted amount + remove in a full-width bar → not chip DiscountTags

The old modules are still in the package/exported for now; they just are not used by DiscountStandalone anymore. Cleanup can be a follow-up.

Comment thread packages/react/src/components/checkout/discount/discount-standalone.tsx Outdated
inputInMinorUnits = true,
onRemove,
isRemoving,
}: DiscountAppliedBarProps) {

@abansal2-godaddy abansal2-godaddy Aug 24, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a new DiscountAppliedBar instead of tweaking DiscountTag

DiscountTag is a small chip (tag icon + code + X) and has no amount. The success state in the design is a full-width green bar: check + code + – $amount + remove.

That is a different component shape, so we added this bar for DiscountStandalone rather than overloading the chip. DiscountTag / Discounts remain in the package unused by this path until a cleanup PR.

@abansal2-godaddy
abansal2-godaddy marked this pull request as ready for review August 24, 2026 09:53
@abansal2-godaddy

Copy link
Copy Markdown
Author

Reviewer note: layout vs old imports

Details are on the Files changed tab (inline comments) and in the updated PR description.

Short version

  • New design is a combined input+Apply row, compact error helper, and a success bar with amount — not the old separate input/button/alert/chip composition.
  • That is why DiscountStandalone dropped DiscountInput / DiscountApplyButton / DiscountErrorList / Discounts / DiscountTag and why DiscountAppliedBar was added.
  • Rationale is documented in the PR only (not as source comments).

…c intact.

Preserve the original code collection and handlers; limit the change to the new coupon UI, amount lookup for the success bar, and error helper copy.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pbennett1-godaddy

pbennett1-godaddy commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

@abansal2-godaddy - is the main goal here to show each coupon codes value instead of a single discount total? I'd prefer not to make huge design changes if possible. We currently follow a similar pattern to other checkouts so I don't think it would be confusing users thinking it's mandatory.

@abansal2-godaddy

abansal2-godaddy commented Aug 27, 2026

Copy link
Copy Markdown
Author

@abansal2-godaddy - is the main goal here to show each coupon codes value instead of a single discount total? I'd prefer not to make huge design changes if possible. We currently follow a similar pattern to other checkouts so I don't think it would be confusing users thinking it's mandatory.

No @pbennett1-godaddy ,It's more of a UI and experience change only with proper error states and intent when a C1 applies a coupon.
Also how can I test these changes on bruce storefront on dev/test environment?
Screenshot 2026-08-27 at 11 33 59 AM

@pbennett1-godaddy

Copy link
Copy Markdown
Contributor

No @pbennett1-godaddy ,It's more of a UI and experience change only with proper error states and intent when a C1 applies a coupon. Also how can I test these changes on bruce storefront on dev/test environment?

you can use the nextjs sample app in this repo to test against a dev/test env store. Can you look into what discount GPAs actually return on failure? I don't think we should have a default of "Coupon isn't valid" cause I think there is basically only a single error of "coupon code failed to apply" from the BE. Invalid would lead customers to believe the coupon they tried to use even if there was an error was an invalid code.

@abansal2-godaddy

Copy link
Copy Markdown
Author

No @pbennett1-godaddy ,It's more of a UI and experience change only with proper error states and intent when a C1 applies a coupon. Also how can I test these changes on bruce storefront on dev/test environment?

you can use the nextjs sample app in this repo to test against a dev/test env store. Can you look into what discount GPAs actually return on failure? I don't think we should have a default of "Coupon isn't valid" cause I think there is basically only a single error of "coupon code failed to apply" from the BE. Invalid would lead customers to believe the coupon they tried to use even if there was an error was an invalid code.

Yes you are right, I'll check what we get as response under various cases from BE and have the error state render the intended failure

abansal2-godaddy and others added 5 commits September 14, 2026 17:13
…s copy.

Keeps one-coupon UX aligned with design and avoids calling codes "invalid" when checkout-api only returns DISCOUNT_APPLICATION_FAILED.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Match h-12 checkout fields, drop package-owned coupon heading keys, and expose checkout.summary.discount before/after slots for hosts.

Co-authored-by: Cursor <cursoragent@cursor.com>
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