Skip to content
Open
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
6 changes: 6 additions & 0 deletions src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ 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 STRIPE_READY = 'STRIPE_READY';

export const startWidgetLoading = createAction(START_WIDGET_LOADING);
export const stopWidgetLoading = createAction(STOP_WIDGET_LOADING);

Expand Down Expand Up @@ -512,3 +514,7 @@ export const getMyInvitation = (summitId) => async (dispatch, getState, { apiBas
export const updateClock = (timestamp) => (dispatch) => {
dispatch(createAction(UPDATE_CLOCK)({ timestamp }));
};

export const setStripeReady = () => (dispatch) => {
dispatch(createAction(STRIPE_READY)({}));
};
20 changes: 13 additions & 7 deletions src/components/button-bar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
**/

import React from 'react';

import T from 'i18n-react';
import styles from "./index.module.scss";
import { isInPersonTicketType } from "../../actions";
import { STEP_COMPLETE, STEP_PAYMENT, STEP_PERSONAL_INFO, STEP_SELECT_TICKET_TYPE } from '../../utils/constants';

const ButtonBarComponent = ({ step, changeStep, validatePromoCode, onValidateError, formValues, removeReservedTicket, inPersonDisclaimer }) => {
const ButtonBarComponent = ({ step, changeStep, validatePromoCode, onValidateError, formValues, removeReservedTicket, inPersonDisclaimer, stripeReady }) => {
const { ticketType, ticketQuantity, promoCode } = formValues || {};

const nextButtonText = inPersonDisclaimer && ticketType && isInPersonTicketType(ticketType) ? 'Accept' : 'Next';
Expand All @@ -32,13 +32,19 @@ const ButtonBarComponent = ({ step, changeStep, validatePromoCode, onValidateErr
</div>
<div className={styles.actions}>
{/* Back Button */}
{step !== STEP_SELECT_TICKET_TYPE && step !== STEP_PAYMENT && <button className={`${styles.button} button`} onClick={() => changeStep(step - 1)}>&lt; Back</button>}
{step !== STEP_SELECT_TICKET_TYPE && step === STEP_PAYMENT && <button className={`${styles.button} button`} onClick={() => removeReservedTicket()}>&lt; Back</button>}
{step !== STEP_SELECT_TICKET_TYPE && step !== STEP_PAYMENT && <button className={`${styles.button} button`} onClick={() => changeStep(step - 1)}>&lt; {T.translate("bar_button.back")}</button>}
{step !== STEP_SELECT_TICKET_TYPE && step === STEP_PAYMENT && <button className={`${styles.button} button`} onClick={() => removeReservedTicket()}>&lt; {T.translate("bar_button.back")}</button>}
{/* Next Button */}
{step === STEP_SELECT_TICKET_TYPE && <button disabled={!ticketType} className={`${styles.button} button`} onClick={() => validatePromoCode({ ...ticketType, ticketQuantity, promoCode }, onValidateError)}>{nextButtonText}</button>}
{step === STEP_PERSONAL_INFO && ticketType?.cost === 0 && <button className={`${styles.button} button`} type="submit" form="personal-info-form">Get Ticket</button>}
{step === STEP_PERSONAL_INFO && ticketType?.cost > 0 && <button className={`${styles.button} button`} type="submit" form="personal-info-form">Next</button>}
{step === STEP_PAYMENT && <button className={`${styles.button} button`} id="payment-form-btn" type="submit" form="payment-form">Pay Now</button>}
{step === STEP_PERSONAL_INFO && ticketType?.cost === 0 && <button className={`${styles.button} button`} type="submit" form="personal-info-form">{T.translate("bar_button.get_ticket")}</button>}
{step === STEP_PERSONAL_INFO && ticketType?.cost > 0 && <button className={`${styles.button} button`} type="submit" form="personal-info-form">{T.translate("bar_button.next")}</button>}
{step === STEP_PAYMENT && <button className={`${styles.button} button`} id="payment-form-btn" type="submit" disabled={!stripeReady} form="payment-form">
{stripeReady ?
T.translate("bar_button.pay_now")
:
T.translate("bar_button.loading")
}
</button>}
</div>
</div>
</>
Expand Down
3 changes: 3 additions & 0 deletions src/components/button-bar/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
display: flex;
button {
margin-left: 10px;
&:disabled {
cursor: not-allowed !important;
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/components/payment/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Helmet } from 'react-helmet';
import { PAYMENT_PROVIDER_LAWPAY, PAYMENT_PROVIDER_STRIPE } from '../../utils/constants';


const PaymentComponent = ({ isActive, userProfile, reservation, payTicket, providerKey, provider, providerOptions, successfulPaymentReturnUrl, timestamp, hidePostalCode, onError }) => {
const PaymentComponent = ({ isActive, userProfile, reservation, payTicket, providerKey, provider, providerOptions, successfulPaymentReturnUrl, timestamp, hidePostalCode, onError, onStripeReady }) => {

const [ref, { height }] = useMeasure();

Expand Down Expand Up @@ -55,6 +55,7 @@ const PaymentComponent = ({ isActive, userProfile, reservation, payTicket, provi
stripeReturnUrl={successfulPaymentReturnUrl}
hidePostalCode={hidePostalCode}
onError={onError}
onStripeReady={onStripeReady}
/>
}
{provider === PAYMENT_PROVIDER_LAWPAY &&
Expand Down
11 changes: 9 additions & 2 deletions src/components/registration-lite.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import {
loadProfileData,
removePromoCode,
applyPromoCode,
validatePromoCode
validatePromoCode,
setStripeReady
} from '../actions';

import AjaxLoader from "openstack-uicore-foundation/lib/components/ajaxloader";
Expand Down Expand Up @@ -161,6 +162,8 @@ const RegistrationLite = (
removePromoCode,
applyPromoCode,
validatePromoCode,
setStripeReady,
stripeReady,
...rest
}) => {

Expand Down Expand Up @@ -443,6 +446,7 @@ const RegistrationLite = (
providerOptions={providerOptions}
hidePostalCode={hidePostalCode}
onError={onError}
onStripeReady={setStripeReady}
successfulPaymentReturnUrl={successfulPaymentReturnUrl}
/>
</div>
Expand Down Expand Up @@ -488,6 +492,7 @@ const RegistrationLite = (
onError: (err, res) => setFormErrors(res.body.errors)
}}
changeStep={changeStep}
stripeReady={stripeReady}
/>
Comment on lines +495 to 496
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate ButtonBar implementation =="
button_file="$(fd "index.js" src/components/button-bar | head -n 1 || true)"
if [[ -z "${button_file}" ]]; then
  echo "ButtonBar file not found under src/components/button-bar"
  exit 0
fi
echo "Found: ${button_file}"

echo
echo "== Inspect ButtonBar disabled logic and stripeReady usage =="
rg -n -C4 "stripeReady|disabled|STEP_PAYMENT|PAYMENT_PROVIDER|onClick|pay" "${button_file}"

echo
echo "== Confirm props provided by RegistrationLite =="
rg -n -C3 "<ButtonBarComponent|stripeReady|provider=" src/components/registration-lite.js

Repository: fntechgit/summit-registration-lite

Length of output: 4627


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find stripeReady initialization and state management =="
rg -n "stripeReady.*=" src/components/registration-lite.js | head -20

echo
echo "== Find STEP_PAYMENT usage in registration-lite.js =="
rg -n "STEP_PAYMENT" src/components/registration-lite.js | head -20

echo
echo "== Look for payment provider logic and flow =="
rg -n -B5 -A5 "changeStep.*STEP_PAYMENT\|provider.*STEP_PAYMENT\|payTicket" src/components/registration-lite.js | head -50

echo
echo "== Check if stripeReady is initialized based on provider =="
rg -n -B10 "setStripeReady" src/components/registration-lite.js | head -30

Repository: fntechgit/summit-registration-lite

Length of output: 411


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find where step changes to STEP_PAYMENT =="
rg -n -B3 -A3 "STEP_PAYMENT" src/components/registration-lite.js

echo
echo "== Search for payment component usage in registration-lite.js =="
rg -n -C5 "payment-component\|PaymentComponent\|step === STEP_PERSONAL_INFO" src/components/registration-lite.js | head -80

echo
echo "== Look for provider conditional logic =="
rg -n "provider.*==\|provider.*Stripe" src/components/registration-lite.js | head -20

Repository: fntechgit/summit-registration-lite

Length of output: 999


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for validatePromoCode implementation and step transitions =="
rg -n "validatePromoCode" src/components/registration-lite.js -A5 -B2 | head -80

echo
echo "== Look for all step changes in the file =="
rg -n "changeStep\|setStep\|step =" src/components/registration-lite.js | head -30

echo
echo "== Check entire registration-lite file structure (first 200 lines) =="
head -200 src/components/registration-lite.js | tail -100

Repository: fntechgit/summit-registration-lite

Length of output: 1580


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find actions/validatePromoCode =="
fd "index.js" src/actions | head -1 | xargs -I {} sh -c 'echo "Searching in: {}"; rg -n "validatePromoCode" {} -A20 | head -60'

echo
echo "== Alternative: look for actions files =="
find src/actions -name "*.js" -type f 2>/dev/null | head -5

echo
echo "== Search validatePromoCode across actions directory =="
rg -n "validatePromoCode" src/actions/ -A10 | head -80

Repository: fntechgit/summit-registration-lite

Length of output: 230


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Explore src/ directory structure =="
find src -type d -name "*action*" -o -name "*reducer*" 2>/dev/null | head -10

echo
echo "== List all JS files in src/ =="
find src -maxdepth 2 -name "*.js" -type f 2>/dev/null | head -30

echo
echo "== Search for validatePromoCode definition across entire src =="
rg -n "export.*validatePromoCode\|const validatePromoCode\|function validatePromoCode" src/ 2>/dev/null | head -20

echo
echo "== Search for where step transitions happen =="
rg -n "STEP_PAYMENT\|STEP_PERSONAL_INFO" src/ | grep -v "node_modules\|registration-lite.js" | head -30

Repository: fntechgit/summit-registration-lite

Length of output: 579


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find validatePromoCode in actions.js =="
rg -n "validatePromoCode" src/actions.js -A30 | head -80

echo
echo "== Find step transitions in actions.js =="
rg -n "STEP_PAYMENT\|STEP_PERSONAL_INFO\|changeStep" src/actions.js | head -30

echo
echo "== Look for provider-specific logic in actions.js =="
rg -n "provider\|Stripe" src/actions.js | head -30

Repository: fntechgit/summit-registration-lite

Length of output: 1852


🏁 Script executed:

#!/bin/bash
set -euo zipefail

echo "== Get full validatePromoCode implementation (lines 196-260) =="
sed -n '196,260p' src/actions.js

echo
echo "== Search for changeStep action =="
rg -n "changeStep|CHANGE_STEP" src/actions.js -A5 | head -40

echo
echo "== Search for step changes related to payment =="
rg -n "dispatch.*step\|STEP_PAYMENT\|SET_STEP" src/actions.js | head -30

Repository: fntechgit/summit-registration-lite

Length of output: 131


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Get full validatePromoCode implementation (lines 196-260) =="
sed -n '196,260p' src/actions.js

echo
echo "== Search for changeStep action =="
rg -n "changeStep|CHANGE_STEP" src/actions.js -A5 | head -40

echo
echo "== Search for step changes related to payment =="
rg -n "dispatch.*step\|STEP_PAYMENT\|SET_STEP" src/actions.js | head -30

Repository: fntechgit/summit-registration-lite

Length of output: 4399


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Get reserveTicket implementation around line 326 =="
sed -n '255,380p' src/actions.js

echo
echo "== Search for other step changes to STEP_PAYMENT =="
rg -n "changeStep.*STEP_PAYMENT" src/actions.js

Repository: fntechgit/summit-registration-lite

Length of output: 5184


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find payTicketWithProvider implementation =="
rg -n "payTicketWithProvider" src/actions.js -A30 | head -100

echo
echo "== Check stripeReady in reducer =="
rg -n "stripeReady\|STRIPE_READY" src/reducer.js -B3 -A3 | head -60

echo
echo "== Find setStripeReady action =="
rg -n "setStripeReady\|SET_STRIPE_READY" src/actions.js -B2 -A5 | head -40

Repository: fntechgit/summit-registration-lite

Length of output: 2426


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check stripeReady initialization in reducer =="
rg -n "stripeReady" src/reducer.js -B5 -A5

echo
echo "== Find SET_STRIPE_READY or similar constants =="
rg -n "STRIPE_READY" src/

echo
echo "== Look for Stripe provider setup in PaymentComponent or payment logic =="
rg -n "setStripeReady" src/components/registration-lite.js -B5 -A5

Repository: fntechgit/summit-registration-lite

Length of output: 3152


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find where STRIPE_READY is dispatched (line 519) =="
sed -n '510,530p' src/actions.js

echo
echo "== Search for setStripeReady and STRIPE_READY dispatch =="
rg -n "STRIPE_READY\|dispatch.*STRIPE_READY" src/actions.js -B5 -A2

echo
echo "== Check if PaymentComponent or payment provider calls onStripeReady =="
rg -n "onStripeReady" src/

Repository: fntechgit/summit-registration-lite

Length of output: 453


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find PaymentComponent file =="
find src -name "*.js" | xargs grep -l "onStripeReady" | head -5

echo
echo "== Check where PaymentComponent is imported =="
rg -n "import.*PaymentComponent\|from.*payment" src/components/registration-lite.js

echo
echo "== Search for PaymentComponent definition in codebase =="
find src -type f -name "*.js" | xargs grep -l "export.*PaymentComponent\|const PaymentComponent" 2>/dev/null | head -5

Repository: fntechgit/summit-registration-lite

Length of output: 303


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Examine PaymentComponent implementation =="
cat src/components/payment/index.js | head -100

echo
echo "== Search for onStripeReady usage in payment component =="
rg -n "onStripeReady\|provider" src/components/payment/index.js | head -40

echo
echo "== Check StripeComponent and how it uses onStripeReady =="
rg -n "onStripeReady" src/components/stripe-form/index.js -B5 -A5 | head -50

Repository: fntechgit/summit-registration-lite

Length of output: 4013


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check LawpayForm implementation for ready callback =="
head -100 src/components/lawpay-form/index.js

echo
echo "== Search for any ready/onReady callback in lawpay-form =="
rg -n "onReady\|ready\|onError" src/components/lawpay-form/index.js | head -20

echo
echo "== Verify ButtonBar disabled logic one more time =="
sed -n '38,47p' src/components/button-bar/index.js

Repository: fntechgit/summit-registration-lite

Length of output: 3434


Pay button remains disabled for non-Stripe providers (e.g., LawPay) at the payment step.

The disabled={!stripeReady} check on the Pay button (ButtonBar line 41) blocks all payment providers, but stripeReady is only set by the Stripe provider's ready callback. LawpayForm does not trigger any ready callback, leaving the button permanently disabled for LawPay payments.

The variable name and gating logic are Stripe-specific and should be provider-agnostic. Either:

  • Rename stripeReady to paymentReady and have all payment providers (Stripe, LawPay, etc.) trigger the callback when ready, or
  • Check the provider type in ButtonBar's disabled condition instead of relying on a Stripe-only flag.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/registration-lite.js` around lines 495 - 496, The Pay button
is blocked by a Stripe-specific flag stripeReady in ButtonBar; change this to a
provider-agnostic readiness signal: rename stripeReady to paymentReady and
update providers to call the ready callback (e.g., have LawpayForm invoke the
same onReady/ready handler) or modify ButtonBar to enable the button based on
provider type (check current provider id/type) instead of !stripeReady; update
all references (stripeReady → paymentReady) including the Stripe provider's
ready callback and any prop names passed to ButtonBar so non-Stripe providers
can set readiness and the Pay button enables correctly.

)}
</div>
Expand All @@ -514,6 +519,7 @@ const mapStateToProps = ({ registrationLiteState }) => ({
passwordlessCodeError: registrationLiteState.passwordless.error,
nowUtc: registrationLiteState.nowUtc,
promoCode: registrationLiteState.promoCode,
stripeReady: registrationLiteState.stripeReady
})

RegistrationLite.defaultProps = {
Expand Down Expand Up @@ -577,5 +583,6 @@ export default connect(mapStateToProps, {
loadProfileData,
applyPromoCode,
removePromoCode,
validatePromoCode
validatePromoCode,
setStripeReady
})(RegistrationLite)
3 changes: 2 additions & 1 deletion src/components/stripe-component/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { isFreeOrder, isPrePaidOrder } from '../../utils/utils';
import { DefaultBGColor, DefaultTextColor, DefaultHintColor } from '../../utils/constants';


const StripeProvider = ({ userProfile, reservation, payTicket, providerKey, provider, stripeOptions, stripeReturnUrl, hidePostalCode, onError }) => {
const StripeProvider = ({ userProfile, reservation, payTicket, providerKey, provider, stripeOptions, stripeReturnUrl, hidePostalCode, onError, onStripeReady }) => {

const stripePromise = useMemo(() => loadStripe(providerKey), [providerKey]);

Expand Down Expand Up @@ -114,6 +114,7 @@ const StripeProvider = ({ userProfile, reservation, payTicket, providerKey, prov
hidePostalCode={hidePostalCode}
stripeReturnUrl={stripeReturnUrl}
onError={onError}
onStripeReady={onStripeReady}
/>
</Elements>
:
Expand Down
10 changes: 8 additions & 2 deletions src/components/stripe-form/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
**/

import React, { useEffect, useState } from 'react';
import T from 'i18n-react';
import { useForm } from 'react-hook-form';

import {
Expand Down Expand Up @@ -63,14 +64,19 @@ const stripeErrorCodeMap = {
};


const StripeForm = ({ reservation, payTicket, userProfile, provider, hidePostalCode, stripeReturnUrl, onError }) => {
const StripeForm = ({ reservation, payTicket, userProfile, provider, hidePostalCode, stripeReturnUrl, onError, onStripeReady }) => {
const stripe = useStripe();
const elements = useElements();
const [paymentElement, setPaymentElement] = useState(null);

useEffect(() => {
if (elements) {
setPaymentElement(elements.getElement('payment'));
const pe = elements.getElement("payment");
setPaymentElement(pe);

if (pe) {
pe.on("ready", () => onStripeReady());
}
}
}, [elements]);

Expand Down
7 changes: 7 additions & 0 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,12 @@
},
"promo_code": {
"promo_code_tooltip": "Only one promo code can be used per order; the code will be applied to all tickets in this order. If you'd like to use multiple promo codes, please place a separate registration order for each promo code."
},
"bar_button": {
"back": "Back",
"next": "Next",
"get_ticket": "Get Ticket",
"pay_now": "Pay Now",
"loading": "Loading"
}
}
9 changes: 7 additions & 2 deletions src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
LOAD_PROFILE_DATA,
SET_CURRENT_PROMO_CODE,
CLEAR_CURRENT_PROMO_CODE,
STRIPE_READY,
} from './actions';

import { LOGOUT_USER } from 'openstack-uicore-foundation/lib/security/actions';
Expand Down Expand Up @@ -68,7 +69,8 @@ const DEFAULT_STATE = {
userProfile: null,
},
nowUtc: localNowUtc,
promoCode: ''
promoCode: '',
stripeReady: false
};

const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
Expand Down Expand Up @@ -117,7 +119,7 @@ const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
};
}
case CHANGE_STEP: {
return { ...state, step: payload }
return { ...state, step: payload, stripeReady: false }
}
case GET_TICKET_TYPES: {
return { ...state, ticketTypes: payload.response.data, requestedTicketTypes: true };
Expand Down Expand Up @@ -168,6 +170,9 @@ const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
const { currentPromoCode } = payload;
return { ...state, promoCode: currentPromoCode}
}
case STRIPE_READY: {
return { ...state, stripeReady: true }
}
default: {
return state;
}
Expand Down