Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export const SET_CURRENT_PROMO_CODE = 'SET_CURRENT_PROMO_CODE';
export const CLEAR_CURRENT_PROMO_CODE = 'CLEAR_CURRENT_PROMO_CODE';
export const VALIDATE_PROMO_CODE = 'VALIDATE_PROMO_CODE';
export const VALIDATE_PROMO_CODE_SUCCESS = 'VALIDATE_PROMO_CODE_SUCCESS';
export const VALIDATE_PROMO_CODE_ERROR = 'VALIDATE_PROMO_CODE_ERROR';
export const DISCOVER_PROMO_CODES = 'DISCOVER_PROMO_CODES';
export const DISCOVER_PROMO_CODES_SUCCESS = 'DISCOVER_PROMO_CODES_SUCCESS';

Expand Down Expand Up @@ -230,9 +229,11 @@ export const removePromoCode = () => (dispatch, getState) => {
}

/**
* Validates promo code for a specific ticket selection.
* Stores allows_to_reassign in Redux state.
* Returns response or throws error - caller handles UI concerns.
* Validates the applied promo code for a ticket selection. Resolves with the
* API response (usePromoCode reads allows_to_reassign from it) or rejects;
* the caller owns all UI concerns. The two actions dispatched below reach no
* reducer; they are devtools breadcrumbs, and getRequest requires a receive
* action to deliver the response.
*/
export const validatePromoCode = (ticketData) => async (dispatch, getState, { apiBaseUrl, getAccessToken }) => {
const { registrationLiteState: { settings: { summitId }, promoCode: currentPromoCode } } = getState();
Expand Down
11 changes: 6 additions & 5 deletions src/hooks/usePromoCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ const usePromoCode = ({
const isDiscoveredCode = isApplied && discoveredPromoCode?.code === promoCode;

// --- Canonical signals ---
// The raw Redux signals can overlap (e.g. a stale promoCodeVerified=false
// persists while a re-validation is in flight), so precedence is encoded
// here, once, rather than in each consumer.
// The raw signals can overlap (a rejection stays recorded while a
// re-validation runs), so precedence is encoded here, once, rather than
// in each consumer.

// Something genuinely in flight: applying the code, validating it against
// a ticket, or waiting on the code-filtered ticket list with no settled
// answer to show in the meantime.
// a ticket, or -- for an anonymous user who applies a code while the
// initial ticket list is still loading -- waiting for that list, with no
// settled answer to show in the meantime.
const isBusy = applyingCode || validatingCode
|| (isApplied && promoCodeVerified == null && !ticketDataLoaded);

Expand Down
Loading