chore(env): update application version to 2.2.8 in production environment

feat(marketing): enhance step components with validity reporting

- Added onValidityChange prop to multiple step components (BenefitsStep, ChallengesStep, ChartStep, ContactsStep, FeaturesStep, FooterStep, HeroStep) to handle form validity.
- Updated respective presenter hooks to utilize the new onValidityChange functionality for real-time validity reporting.
- Enhanced MarketingForm to manage step validity and disable the next button based on current step validity.
This commit is contained in:
AmirReza Jamali
2026-06-06 15:39:03 +03:30
parent 5d01d66ea3
commit 88f223bf08
19 changed files with 152 additions and 32 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
NEXT_PUBLIC_APP_VERSION=2.2.7 NEXT_PUBLIC_APP_VERSION=2.2.8
NEXT_PUBLIC_TOAST_AUTO_CLOSE_DURATION=2500 NEXT_PUBLIC_TOAST_AUTO_CLOSE_DURATION=2500
NEXT_PUBLIC_FIREBASE_API_KEY=AIzaSyCTjdsk2jE34IfnvSKP1JMTIf_Abd7tbt0 NEXT_PUBLIC_FIREBASE_API_KEY=AIzaSyCTjdsk2jE34IfnvSKP1JMTIf_Abd7tbt0
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=opplens-270d1.firebaseapp.com NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=opplens-270d1.firebaseapp.com
@@ -7,9 +7,10 @@ import useBenefitsStepPresenter, {
interface BenefitsStepProps { interface BenefitsStepProps {
initialData?: IBenefitsStepFields; initialData?: IBenefitsStepFields;
onValidityChange?: (valid: boolean) => void;
} }
const BenefitsStep = forwardRef<unknown, BenefitsStepProps>(({ initialData }, ref) => { const BenefitsStep = forwardRef<unknown, BenefitsStepProps>(({ initialData, onValidityChange }, ref) => {
const { const {
errors, errors,
handleSubmit, handleSubmit,
@@ -19,7 +20,7 @@ const BenefitsStep = forwardRef<unknown, BenefitsStepProps>(({ initialData }, re
append, append,
remove, remove,
control, control,
} = useBenefitsStepPresenter(initialData, ref); } = useBenefitsStepPresenter(initialData, ref, onValidityChange);
return ( return (
<SectionStep<IBenefitsStepFields> <SectionStep<IBenefitsStepFields>
@@ -7,10 +7,11 @@ import useChallengesStepPresenter, {
interface ChallengesStepProps { interface ChallengesStepProps {
initialData?: IChallengesStepFields; initialData?: IChallengesStepFields;
onValidityChange?: (valid: boolean) => void;
} }
const ChallengesStep = forwardRef<unknown, ChallengesStepProps>( const ChallengesStep = forwardRef<unknown, ChallengesStepProps>(
({ initialData }, ref) => { ({ initialData, onValidityChange }, ref) => {
const { const {
errors, errors,
handleSubmit, handleSubmit,
@@ -20,7 +21,7 @@ const ChallengesStep = forwardRef<unknown, ChallengesStepProps>(
append, append,
remove, remove,
control, control,
} = useChallengesStepPresenter(initialData, ref); } = useChallengesStepPresenter(initialData, ref, onValidityChange);
return ( return (
<SectionStep<IChallengesStepFields> <SectionStep<IChallengesStepFields>
+3 -2
View File
@@ -10,10 +10,11 @@ import useChartStepPresenter from "./useChartStepPresenter";
interface ChartStepProps { interface ChartStepProps {
initialData?: any; initialData?: any;
onValidityChange?: (valid: boolean) => void;
} }
const ChartStep = forwardRef<unknown, ChartStepProps>( const ChartStep = forwardRef<unknown, ChartStepProps>(
({ initialData }, ref) => { ({ initialData, onValidityChange }, ref) => {
const { const {
errors, errors,
handleSubmit, handleSubmit,
@@ -23,7 +24,7 @@ const ChartStep = forwardRef<unknown, ChartStepProps>(
append, append,
remove, remove,
watch, watch,
} = useChartStepPresenter(initialData, ref); } = useChartStepPresenter(initialData, ref, onValidityChange);
const chartTitle = watch("title"); const chartTitle = watch("title");
const chartData = watch("data"); const chartData = watch("data");
@@ -9,12 +9,13 @@ import useContactsStepPresenter from "./useContactsStepPresenter";
interface ContactsStepProps { interface ContactsStepProps {
initialData?: any; initialData?: any;
onValidityChange?: (valid: boolean) => void;
} }
const ContactsStep = forwardRef<unknown, ContactsStepProps>( const ContactsStep = forwardRef<unknown, ContactsStepProps>(
({ initialData }, ref) => { ({ initialData, onValidityChange }, ref) => {
const { errors, handleSubmit, onSubmit, register, fields } = const { errors, handleSubmit, onSubmit, register, fields } =
useContactsStepPresenter(initialData, ref); useContactsStepPresenter(initialData, ref, onValidityChange);
return ( return (
<form <form
@@ -7,10 +7,11 @@ import useFeaturesStepPresenter, {
interface FeaturesStepProps { interface FeaturesStepProps {
initialData?: IFeaturesStepFields; initialData?: IFeaturesStepFields;
onValidityChange?: (valid: boolean) => void;
} }
const FeaturesStep = forwardRef<unknown, FeaturesStepProps>( const FeaturesStep = forwardRef<unknown, FeaturesStepProps>(
({ initialData }, ref) => { ({ initialData, onValidityChange }, ref) => {
const { const {
errors, errors,
handleSubmit, handleSubmit,
@@ -20,7 +21,7 @@ const FeaturesStep = forwardRef<unknown, FeaturesStepProps>(
append, append,
remove, remove,
control, control,
} = useFeaturesStepPresenter(initialData, ref); } = useFeaturesStepPresenter(initialData, ref, onValidityChange);
return ( return (
<SectionStep<IFeaturesStepFields> <SectionStep<IFeaturesStepFields>
+3 -1
View File
@@ -8,13 +8,15 @@ import useFooterStepPresenter from "./useFooterStepPresenter";
interface FooterStepProps { interface FooterStepProps {
initialData?: any; initialData?: any;
onValidityChange?: (valid: boolean) => void;
} }
const FooterStep = forwardRef<unknown, FooterStepProps>( const FooterStep = forwardRef<unknown, FooterStepProps>(
({ initialData }, ref) => { ({ initialData, onValidityChange }, ref) => {
const { errors, handleSubmit, onSubmit, register } = useFooterStepPresenter( const { errors, handleSubmit, onSubmit, register } = useFooterStepPresenter(
initialData, initialData,
ref, ref,
onValidityChange,
); );
return ( return (
+3 -1
View File
@@ -9,12 +9,14 @@ import useHeroStepPresenter from "./useHeroStepPresenter";
interface HeroStepProps { interface HeroStepProps {
initialData?: any; initialData?: any;
onValidityChange?: (valid: boolean) => void;
} }
const HeroStep = forwardRef<unknown, HeroStepProps>(({ initialData }, ref) => { const HeroStep = forwardRef<unknown, HeroStepProps>(({ initialData, onValidityChange }, ref) => {
const { errors, handleSubmit, onSubmit, register } = useHeroStepPresenter( const { errors, handleSubmit, onSubmit, register } = useHeroStepPresenter(
initialData, initialData,
ref, ref,
onValidityChange,
); );
return ( return (
@@ -43,6 +43,8 @@ const MarketingForm = ({
watchPageType, watchPageType,
pageTypeErrors, pageTypeErrors,
isCompany, isCompany,
isCurrentStepValid,
stepValidityHandlers,
setValue, setValue,
heroRef, heroRef,
chartRef, chartRef,
@@ -177,28 +179,53 @@ const MarketingForm = ({
</div> </div>
<div style={{ display: step === 0 ? "block" : "none" }}> <div style={{ display: step === 0 ? "block" : "none" }}>
<HeroStep ref={heroRef} initialData={formData.hero} /> <HeroStep
ref={heroRef}
initialData={formData.hero}
onValidityChange={stepValidityHandlers[0]}
/>
</div> </div>
<div style={{ display: step === 1 ? "block" : "none" }}> <div style={{ display: step === 1 ? "block" : "none" }}>
<ChartStep ref={chartRef} initialData={formData.chart} /> <ChartStep
ref={chartRef}
initialData={formData.chart}
onValidityChange={stepValidityHandlers[1]}
/>
</div> </div>
<div style={{ display: step === 2 ? "block" : "none" }}> <div style={{ display: step === 2 ? "block" : "none" }}>
<FeaturesStep ref={featuresRef} initialData={formData.features} /> <FeaturesStep
ref={featuresRef}
initialData={formData.features}
onValidityChange={stepValidityHandlers[2]}
/>
</div> </div>
<div style={{ display: step === 3 ? "block" : "none" }}> <div style={{ display: step === 3 ? "block" : "none" }}>
<ChallengesStep <ChallengesStep
ref={challengesRef} ref={challengesRef}
initialData={formData.challenges} initialData={formData.challenges}
onValidityChange={stepValidityHandlers[3]}
/> />
</div> </div>
<div style={{ display: step === 4 ? "block" : "none" }}> <div style={{ display: step === 4 ? "block" : "none" }}>
<BenefitsStep ref={benefitsRef} initialData={formData.advantages} /> <BenefitsStep
ref={benefitsRef}
initialData={formData.advantages}
onValidityChange={stepValidityHandlers[4]}
/>
</div> </div>
<div style={{ display: step === 5 ? "block" : "none" }}> <div style={{ display: step === 5 ? "block" : "none" }}>
<ContactsStep ref={contactsRef} initialData={formData.contact} /> <ContactsStep
ref={contactsRef}
initialData={formData.contact}
onValidityChange={stepValidityHandlers[5]}
/>
</div> </div>
<div style={{ display: step === 6 ? "block" : "none" }}> <div style={{ display: step === 6 ? "block" : "none" }}>
<FooterStep ref={footerRef} initialData={formData.footer} /> <FooterStep
ref={footerRef}
initialData={formData.footer}
onValidityChange={stepValidityHandlers[6]}
/>
</div> </div>
<Stepper <Stepper
@@ -207,6 +234,7 @@ const MarketingForm = ({
onStepChange={handleStepChange} onStepChange={handleStepChange}
onSubmit={handleSubmitAll} onSubmit={handleSubmitAll}
isSubmitting={isPending} isSubmitting={isPending}
nextDisabled={!isCurrentStepValid}
/> />
</ShowcaseSection> </ShowcaseSection>
</> </>
@@ -1,6 +1,7 @@
"use client"; "use client";
import { ForwardedRef, useImperativeHandle } from "react"; import { ForwardedRef, useImperativeHandle } from "react";
import { useFieldArray, useForm } from "react-hook-form"; import { useFieldArray, useForm } from "react-hook-form";
import useReportStepValidity from "./useReportStepValidity";
export interface IBenefitsStepFields { export interface IBenefitsStepFields {
title: string; title: string;
@@ -15,21 +16,25 @@ export interface IBenefitsStepFields {
const useBenefitsStepPresenter = ( const useBenefitsStepPresenter = (
initialData?: IBenefitsStepFields, initialData?: IBenefitsStepFields,
ref?: ForwardedRef<unknown>, ref?: ForwardedRef<unknown>,
onValidityChange?: (valid: boolean) => void,
) => { ) => {
const { const {
register, register,
handleSubmit, handleSubmit,
control, control,
watch, watch,
formState: { errors }, formState: { errors, isValid },
getValues, getValues,
trigger, trigger,
} = useForm<IBenefitsStepFields>({ } = useForm<IBenefitsStepFields>({
defaultValues: initialData || { defaultValues: initialData || {
cards: [{ icon: "", title: "", description: "" }], cards: [{ icon: "", title: "", description: "" }],
}, },
mode: "onChange",
}); });
useReportStepValidity(isValid, onValidityChange);
const { fields, append, remove } = useFieldArray({ const { fields, append, remove } = useFieldArray({
control, control,
name: "cards", name: "cards",
@@ -1,6 +1,7 @@
"use client"; "use client";
import { ForwardedRef, useImperativeHandle } from "react"; import { ForwardedRef, useImperativeHandle } from "react";
import { useFieldArray, useForm } from "react-hook-form"; import { useFieldArray, useForm } from "react-hook-form";
import useReportStepValidity from "./useReportStepValidity";
export interface IChallengesStepFields { export interface IChallengesStepFields {
title: string; title: string;
@@ -15,21 +16,25 @@ export interface IChallengesStepFields {
const useChallengesStepPresenter = ( const useChallengesStepPresenter = (
initialData?: IChallengesStepFields, initialData?: IChallengesStepFields,
ref?: ForwardedRef<unknown>, ref?: ForwardedRef<unknown>,
onValidityChange?: (valid: boolean) => void,
) => { ) => {
const { const {
register, register,
handleSubmit, handleSubmit,
control, control,
watch, watch,
formState: { errors }, formState: { errors, isValid },
getValues, getValues,
trigger, trigger,
} = useForm<IChallengesStepFields>({ } = useForm<IChallengesStepFields>({
defaultValues: initialData || { defaultValues: initialData || {
cards: [{ icon: "", title: "", description: "" }], cards: [{ icon: "", title: "", description: "" }],
}, },
mode: "onChange",
}); });
useReportStepValidity(isValid, onValidityChange);
const { fields, append, remove } = useFieldArray({ const { fields, append, remove } = useFieldArray({
control, control,
name: "cards", name: "cards",
@@ -1,6 +1,7 @@
"use client"; "use client";
import { ForwardedRef, useImperativeHandle } from "react"; import { ForwardedRef, useImperativeHandle } from "react";
import { useFieldArray, useForm } from "react-hook-form"; import { useFieldArray, useForm } from "react-hook-form";
import useReportStepValidity from "./useReportStepValidity";
export interface IChartStepFields { export interface IChartStepFields {
title: string; title: string;
@@ -11,21 +12,25 @@ export interface IChartStepFields {
const useChartStepPresenter = ( const useChartStepPresenter = (
initialData?: IChartStepFields, initialData?: IChartStepFields,
ref?: ForwardedRef<unknown>, ref?: ForwardedRef<unknown>,
onValidityChange?: (valid: boolean) => void,
) => { ) => {
const { const {
register, register,
handleSubmit, handleSubmit,
control, control,
watch, watch,
formState: { errors }, formState: { errors, isValid },
getValues, getValues,
trigger, trigger,
} = useForm<IChartStepFields>({ } = useForm<IChartStepFields>({
defaultValues: initialData || { defaultValues: initialData || {
data: [{ key: "", value: 0 }], data: [{ key: "", value: 0 }],
}, },
mode: "onChange",
}); });
useReportStepValidity(isValid, onValidityChange);
const { fields, append, remove } = useFieldArray({ const { fields, append, remove } = useFieldArray({
control, control,
name: "data", name: "data",
@@ -1,6 +1,7 @@
"use client"; "use client";
import { ForwardedRef, useImperativeHandle } from "react"; import { ForwardedRef, useImperativeHandle } from "react";
import { useFieldArray, useForm } from "react-hook-form"; import { useFieldArray, useForm } from "react-hook-form";
import useReportStepValidity from "./useReportStepValidity";
export interface IContactsStepFields { export interface IContactsStepFields {
title: string; title: string;
@@ -17,15 +18,17 @@ export interface IContactsStepFields {
const useContactsStepPresenter = ( const useContactsStepPresenter = (
initialData?: IContactsStepFields, initialData?: IContactsStepFields,
ref?: ForwardedRef<unknown>, ref?: ForwardedRef<unknown>,
onValidityChange?: (valid: boolean) => void,
) => { ) => {
const { const {
register, register,
handleSubmit, handleSubmit,
control, control,
getValues, getValues,
formState: { errors }, formState: { errors, isValid },
trigger, trigger,
} = useForm<IContactsStepFields>({ } = useForm<IContactsStepFields>({
mode: "onChange",
defaultValues: initialData || { defaultValues: initialData || {
fields: [ fields: [
{ {
@@ -51,6 +54,8 @@ const useContactsStepPresenter = (
name: "fields", name: "fields",
}); });
useReportStepValidity(isValid, onValidityChange);
const onSubmit = (data: IContactsStepFields) => { const onSubmit = (data: IContactsStepFields) => {
console.log(data); console.log(data);
}; };
@@ -1,6 +1,7 @@
"use client"; "use client";
import { ForwardedRef, useImperativeHandle } from "react"; import { ForwardedRef, useImperativeHandle } from "react";
import { useFieldArray, useForm } from "react-hook-form"; import { useFieldArray, useForm } from "react-hook-form";
import useReportStepValidity from "./useReportStepValidity";
export interface IFeaturesStepFields { export interface IFeaturesStepFields {
title: string; title: string;
@@ -15,21 +16,25 @@ export interface IFeaturesStepFields {
const useFeaturesStepPresenter = ( const useFeaturesStepPresenter = (
initialData?: IFeaturesStepFields, initialData?: IFeaturesStepFields,
ref?: ForwardedRef<unknown>, ref?: ForwardedRef<unknown>,
onValidityChange?: (valid: boolean) => void,
) => { ) => {
const { const {
register, register,
handleSubmit, handleSubmit,
control, control,
watch, watch,
formState: { errors }, formState: { errors, isValid },
getValues, getValues,
trigger, trigger,
} = useForm<IFeaturesStepFields>({ } = useForm<IFeaturesStepFields>({
defaultValues: initialData || { defaultValues: initialData || {
cards: [{ icon: "", title: "", description: "" }], cards: [{ icon: "", title: "", description: "" }],
}, },
mode: "onChange",
}); });
useReportStepValidity(isValid, onValidityChange);
const { fields, append, remove } = useFieldArray({ const { fields, append, remove } = useFieldArray({
control, control,
name: "cards", name: "cards",
@@ -1,5 +1,6 @@
import { ForwardedRef, useImperativeHandle } from "react"; import { ForwardedRef, useImperativeHandle } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import useReportStepValidity from "./useReportStepValidity";
interface FooterFormValues { interface FooterFormValues {
email: string; email: string;
@@ -12,17 +13,21 @@ interface FooterFormValues {
const useFooterStepPresenter = ( const useFooterStepPresenter = (
initialData?: FooterFormValues, initialData?: FooterFormValues,
ref?: ForwardedRef<unknown>, ref?: ForwardedRef<unknown>,
onValidityChange?: (valid: boolean) => void,
) => { ) => {
const { const {
register, register,
handleSubmit, handleSubmit,
formState: { errors }, formState: { errors, isValid },
getValues, getValues,
trigger, trigger,
} = useForm<FooterFormValues>({ } = useForm<FooterFormValues>({
defaultValues: initialData, defaultValues: initialData,
mode: "onChange",
}); });
useReportStepValidity(isValid, onValidityChange);
const onSubmit = (data: FooterFormValues) => { const onSubmit = (data: FooterFormValues) => {
console.log(data); console.log(data);
}; };
@@ -1,6 +1,7 @@
"use client"; "use client";
import { ForwardedRef, useImperativeHandle } from "react"; import { ForwardedRef, useImperativeHandle } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import useReportStepValidity from "./useReportStepValidity";
export interface IHeroStepFields { export interface IHeroStepFields {
title: string; title: string;
@@ -13,17 +14,21 @@ export interface IHeroStepFields {
const useHeroStepPresenter = ( const useHeroStepPresenter = (
initialData?: IHeroStepFields, initialData?: IHeroStepFields,
ref?: ForwardedRef<unknown>, ref?: ForwardedRef<unknown>,
onValidityChange?: (valid: boolean) => void,
) => { ) => {
const { const {
register, register,
handleSubmit, handleSubmit,
formState: { errors }, formState: { errors, isValid },
getValues, getValues,
trigger, trigger,
} = useForm<IHeroStepFields>({ } = useForm<IHeroStepFields>({
defaultValues: initialData, defaultValues: initialData,
mode: "onChange",
}); });
useReportStepValidity(isValid, onValidityChange);
const onSubmit = (data: IHeroStepFields) => { const onSubmit = (data: IHeroStepFields) => {
console.log(data); console.log(data);
}; };
@@ -2,7 +2,7 @@
import { Step } from "@/components/ui/Stepper"; import { Step } from "@/components/ui/Stepper";
import { useEffect, useRef, useState } from "react"; import { useEffect, useMemo, useRef, useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@@ -13,6 +13,9 @@ interface IPageTypeFields {
country?: string; country?: string;
key: string; key: string;
} }
const TOTAL_STEPS = 7;
const useMarketingForm = ( const useMarketingForm = (
initialData: any, initialData: any,
onSubmit: (data: any) => void, onSubmit: (data: any) => void,
@@ -20,6 +23,9 @@ const useMarketingForm = (
const [step, setStep] = useState(0); const [step, setStep] = useState(0);
const [formData, setFormData] = useState<any>(initialData || {}); const [formData, setFormData] = useState<any>(initialData || {});
const [stepValidity, setStepValidity] = useState<boolean[]>(() =>
new Array(TOTAL_STEPS).fill(false),
);
const heroRef = useRef<any>(null); const heroRef = useRef<any>(null);
const chartRef = useRef<any>(null); const chartRef = useRef<any>(null);
const featuresRef = useRef<any>(null); const featuresRef = useRef<any>(null);
@@ -31,12 +37,13 @@ const useMarketingForm = (
const { const {
register: registerPageType, register: registerPageType,
watch: watchPageType, watch: watchPageType,
formState: { errors: pageTypeErrors }, formState: { errors: pageTypeErrors, isValid: isPageTypeValid },
getValues: getPageTypeValues, getValues: getPageTypeValues,
setValue, setValue,
reset, reset,
trigger: triggerPageType, trigger: triggerPageType,
} = useForm<IPageTypeFields>({ } = useForm<IPageTypeFields>({
mode: "onChange",
defaultValues: { defaultValues: {
type: "company", type: "company",
language: "en", language: "en",
@@ -46,6 +53,25 @@ const useMarketingForm = (
}, },
}); });
// Stable per-step callbacks so each step form can report its live validity
// without recreating handlers (which would re-fire the reporting effect).
const stepValidityHandlers = useMemo(
() =>
Array.from(
{ length: TOTAL_STEPS },
(_, index) => (valid: boolean) =>
setStepValidity((prev) => {
if (prev[index] === valid) return prev;
const next = [...prev];
next[index] = valid;
return next;
}),
),
[],
);
const isCurrentStepValid = isPageTypeValid && Boolean(stepValidity[step]);
useEffect(() => { useEffect(() => {
if (initialData) { if (initialData) {
const formValues = { const formValues = {
@@ -245,6 +271,8 @@ const useMarketingForm = (
watchPageType, watchPageType,
pageTypeErrors, pageTypeErrors,
isCompany, isCompany,
isCurrentStepValid,
stepValidityHandlers,
setValue, setValue,
heroRef, heroRef,
chartRef, chartRef,
@@ -0,0 +1,17 @@
"use client";
import { useEffect } from "react";
/**
* Bridges a step form's reactive `isValid` state up to the parent stepper.
* Shared across every step presenter so the reporting logic lives in one place.
*/
const useReportStepValidity = (
isValid: boolean,
onValidityChange?: (valid: boolean) => void,
) => {
useEffect(() => {
onValidityChange?.(isValid);
}, [isValid, onValidityChange]);
};
export default useReportStepValidity;
+7 -4
View File
@@ -22,6 +22,7 @@ interface StepperProps {
onStepChange?: (step: number) => void; onStepChange?: (step: number) => void;
onSubmit?: () => void; onSubmit?: () => void;
isSubmitting?: boolean; isSubmitting?: boolean;
nextDisabled?: boolean;
} }
const Stepper: React.FC<StepperProps> = ({ const Stepper: React.FC<StepperProps> = ({
@@ -30,6 +31,7 @@ const Stepper: React.FC<StepperProps> = ({
onStepChange, onStepChange,
onSubmit, onSubmit,
isSubmitting = false, isSubmitting = false,
nextDisabled = false,
}) => { }) => {
const [internalStep, setInternalStep] = useState(0); const [internalStep, setInternalStep] = useState(0);
const currentStep = const currentStep =
@@ -213,6 +215,7 @@ const Stepper: React.FC<StepperProps> = ({
}; };
const nextStep = () => { const nextStep = () => {
if (nextDisabled) return;
if (currentStep === steps.length - 1) { if (currentStep === steps.length - 1) {
if (onSubmit) onSubmit(); if (onSubmit) onSubmit();
} else if (currentStep < steps.length - 1) { } else if (currentStep < steps.length - 1) {
@@ -425,20 +428,20 @@ const Stepper: React.FC<StepperProps> = ({
onClick={nextStep} onClick={nextStep}
onMouseEnter={() => handleButtonHover(nextBtnRef.current, true)} onMouseEnter={() => handleButtonHover(nextBtnRef.current, true)}
onMouseLeave={() => handleButtonHover(nextBtnRef.current, false)} onMouseLeave={() => handleButtonHover(nextBtnRef.current, false)}
disabled={isSubmitting} disabled={isSubmitting || nextDisabled}
className={`group relative inline-flex items-center gap-2 overflow-hidden rounded-xl px-6 py-2.5 text-sm font-semibold text-white transition-all ${ className={`group relative inline-flex items-center gap-2 overflow-hidden rounded-xl px-6 py-2.5 text-sm font-semibold text-white transition-all ${
isSubmitting isSubmitting || nextDisabled
? "cursor-not-allowed bg-gray-4" ? "cursor-not-allowed bg-gray-4"
: "bg-gradient-to-r from-primary via-blue to-primary bg-[length:200%_100%] shadow-lg shadow-primary/30 hover:shadow-primary/50" : "bg-gradient-to-r from-primary via-blue to-primary bg-[length:200%_100%] shadow-lg shadow-primary/30 hover:shadow-primary/50"
}`} }`}
style={ style={
!isSubmitting !isSubmitting && !nextDisabled
? { animation: "stepperShimmer 3s linear infinite" } ? { animation: "stepperShimmer 3s linear infinite" }
: undefined : undefined
} }
> >
{/* Glow halo for submit */} {/* Glow halo for submit */}
{isLastStep && !isSubmitting && ( {isLastStep && !isSubmitting && !nextDisabled && (
<span <span
ref={submitGlowRef} ref={submitGlowRef}
aria-hidden aria-hidden