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:
+1
-1
@@ -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_FIREBASE_API_KEY=AIzaSyCTjdsk2jE34IfnvSKP1JMTIf_Abd7tbt0
|
||||
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=opplens-270d1.firebaseapp.com
|
||||
|
||||
@@ -7,9 +7,10 @@ import useBenefitsStepPresenter, {
|
||||
|
||||
interface BenefitsStepProps {
|
||||
initialData?: IBenefitsStepFields;
|
||||
onValidityChange?: (valid: boolean) => void;
|
||||
}
|
||||
|
||||
const BenefitsStep = forwardRef<unknown, BenefitsStepProps>(({ initialData }, ref) => {
|
||||
const BenefitsStep = forwardRef<unknown, BenefitsStepProps>(({ initialData, onValidityChange }, ref) => {
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
@@ -19,7 +20,7 @@ const BenefitsStep = forwardRef<unknown, BenefitsStepProps>(({ initialData }, re
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
} = useBenefitsStepPresenter(initialData, ref);
|
||||
} = useBenefitsStepPresenter(initialData, ref, onValidityChange);
|
||||
|
||||
return (
|
||||
<SectionStep<IBenefitsStepFields>
|
||||
|
||||
@@ -7,10 +7,11 @@ import useChallengesStepPresenter, {
|
||||
|
||||
interface ChallengesStepProps {
|
||||
initialData?: IChallengesStepFields;
|
||||
onValidityChange?: (valid: boolean) => void;
|
||||
}
|
||||
|
||||
const ChallengesStep = forwardRef<unknown, ChallengesStepProps>(
|
||||
({ initialData }, ref) => {
|
||||
({ initialData, onValidityChange }, ref) => {
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
@@ -20,7 +21,7 @@ const ChallengesStep = forwardRef<unknown, ChallengesStepProps>(
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
} = useChallengesStepPresenter(initialData, ref);
|
||||
} = useChallengesStepPresenter(initialData, ref, onValidityChange);
|
||||
|
||||
return (
|
||||
<SectionStep<IChallengesStepFields>
|
||||
|
||||
@@ -10,10 +10,11 @@ import useChartStepPresenter from "./useChartStepPresenter";
|
||||
|
||||
interface ChartStepProps {
|
||||
initialData?: any;
|
||||
onValidityChange?: (valid: boolean) => void;
|
||||
}
|
||||
|
||||
const ChartStep = forwardRef<unknown, ChartStepProps>(
|
||||
({ initialData }, ref) => {
|
||||
({ initialData, onValidityChange }, ref) => {
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
@@ -23,7 +24,7 @@ const ChartStep = forwardRef<unknown, ChartStepProps>(
|
||||
append,
|
||||
remove,
|
||||
watch,
|
||||
} = useChartStepPresenter(initialData, ref);
|
||||
} = useChartStepPresenter(initialData, ref, onValidityChange);
|
||||
|
||||
const chartTitle = watch("title");
|
||||
const chartData = watch("data");
|
||||
|
||||
@@ -9,12 +9,13 @@ import useContactsStepPresenter from "./useContactsStepPresenter";
|
||||
|
||||
interface ContactsStepProps {
|
||||
initialData?: any;
|
||||
onValidityChange?: (valid: boolean) => void;
|
||||
}
|
||||
|
||||
const ContactsStep = forwardRef<unknown, ContactsStepProps>(
|
||||
({ initialData }, ref) => {
|
||||
({ initialData, onValidityChange }, ref) => {
|
||||
const { errors, handleSubmit, onSubmit, register, fields } =
|
||||
useContactsStepPresenter(initialData, ref);
|
||||
useContactsStepPresenter(initialData, ref, onValidityChange);
|
||||
|
||||
return (
|
||||
<form
|
||||
|
||||
@@ -7,10 +7,11 @@ import useFeaturesStepPresenter, {
|
||||
|
||||
interface FeaturesStepProps {
|
||||
initialData?: IFeaturesStepFields;
|
||||
onValidityChange?: (valid: boolean) => void;
|
||||
}
|
||||
|
||||
const FeaturesStep = forwardRef<unknown, FeaturesStepProps>(
|
||||
({ initialData }, ref) => {
|
||||
({ initialData, onValidityChange }, ref) => {
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
@@ -20,7 +21,7 @@ const FeaturesStep = forwardRef<unknown, FeaturesStepProps>(
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
} = useFeaturesStepPresenter(initialData, ref);
|
||||
} = useFeaturesStepPresenter(initialData, ref, onValidityChange);
|
||||
|
||||
return (
|
||||
<SectionStep<IFeaturesStepFields>
|
||||
|
||||
@@ -8,13 +8,15 @@ import useFooterStepPresenter from "./useFooterStepPresenter";
|
||||
|
||||
interface FooterStepProps {
|
||||
initialData?: any;
|
||||
onValidityChange?: (valid: boolean) => void;
|
||||
}
|
||||
|
||||
const FooterStep = forwardRef<unknown, FooterStepProps>(
|
||||
({ initialData }, ref) => {
|
||||
({ initialData, onValidityChange }, ref) => {
|
||||
const { errors, handleSubmit, onSubmit, register } = useFooterStepPresenter(
|
||||
initialData,
|
||||
ref,
|
||||
onValidityChange,
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -9,12 +9,14 @@ import useHeroStepPresenter from "./useHeroStepPresenter";
|
||||
|
||||
interface HeroStepProps {
|
||||
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(
|
||||
initialData,
|
||||
ref,
|
||||
onValidityChange,
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -43,6 +43,8 @@ const MarketingForm = ({
|
||||
watchPageType,
|
||||
pageTypeErrors,
|
||||
isCompany,
|
||||
isCurrentStepValid,
|
||||
stepValidityHandlers,
|
||||
setValue,
|
||||
heroRef,
|
||||
chartRef,
|
||||
@@ -177,28 +179,53 @@ const MarketingForm = ({
|
||||
</div>
|
||||
|
||||
<div style={{ display: step === 0 ? "block" : "none" }}>
|
||||
<HeroStep ref={heroRef} initialData={formData.hero} />
|
||||
<HeroStep
|
||||
ref={heroRef}
|
||||
initialData={formData.hero}
|
||||
onValidityChange={stepValidityHandlers[0]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: step === 1 ? "block" : "none" }}>
|
||||
<ChartStep ref={chartRef} initialData={formData.chart} />
|
||||
<ChartStep
|
||||
ref={chartRef}
|
||||
initialData={formData.chart}
|
||||
onValidityChange={stepValidityHandlers[1]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: step === 2 ? "block" : "none" }}>
|
||||
<FeaturesStep ref={featuresRef} initialData={formData.features} />
|
||||
<FeaturesStep
|
||||
ref={featuresRef}
|
||||
initialData={formData.features}
|
||||
onValidityChange={stepValidityHandlers[2]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: step === 3 ? "block" : "none" }}>
|
||||
<ChallengesStep
|
||||
ref={challengesRef}
|
||||
initialData={formData.challenges}
|
||||
onValidityChange={stepValidityHandlers[3]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: step === 4 ? "block" : "none" }}>
|
||||
<BenefitsStep ref={benefitsRef} initialData={formData.advantages} />
|
||||
<BenefitsStep
|
||||
ref={benefitsRef}
|
||||
initialData={formData.advantages}
|
||||
onValidityChange={stepValidityHandlers[4]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: step === 5 ? "block" : "none" }}>
|
||||
<ContactsStep ref={contactsRef} initialData={formData.contact} />
|
||||
<ContactsStep
|
||||
ref={contactsRef}
|
||||
initialData={formData.contact}
|
||||
onValidityChange={stepValidityHandlers[5]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: step === 6 ? "block" : "none" }}>
|
||||
<FooterStep ref={footerRef} initialData={formData.footer} />
|
||||
<FooterStep
|
||||
ref={footerRef}
|
||||
initialData={formData.footer}
|
||||
onValidityChange={stepValidityHandlers[6]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Stepper
|
||||
@@ -207,6 +234,7 @@ const MarketingForm = ({
|
||||
onStepChange={handleStepChange}
|
||||
onSubmit={handleSubmitAll}
|
||||
isSubmitting={isPending}
|
||||
nextDisabled={!isCurrentStepValid}
|
||||
/>
|
||||
</ShowcaseSection>
|
||||
</>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { ForwardedRef, useImperativeHandle } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import useReportStepValidity from "./useReportStepValidity";
|
||||
|
||||
export interface IBenefitsStepFields {
|
||||
title: string;
|
||||
@@ -15,21 +16,25 @@ export interface IBenefitsStepFields {
|
||||
const useBenefitsStepPresenter = (
|
||||
initialData?: IBenefitsStepFields,
|
||||
ref?: ForwardedRef<unknown>,
|
||||
onValidityChange?: (valid: boolean) => void,
|
||||
) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
formState: { errors, isValid },
|
||||
getValues,
|
||||
trigger,
|
||||
} = useForm<IBenefitsStepFields>({
|
||||
defaultValues: initialData || {
|
||||
cards: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
useReportStepValidity(isValid, onValidityChange);
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "cards",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { ForwardedRef, useImperativeHandle } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import useReportStepValidity from "./useReportStepValidity";
|
||||
|
||||
export interface IChallengesStepFields {
|
||||
title: string;
|
||||
@@ -15,21 +16,25 @@ export interface IChallengesStepFields {
|
||||
const useChallengesStepPresenter = (
|
||||
initialData?: IChallengesStepFields,
|
||||
ref?: ForwardedRef<unknown>,
|
||||
onValidityChange?: (valid: boolean) => void,
|
||||
) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
formState: { errors, isValid },
|
||||
getValues,
|
||||
trigger,
|
||||
} = useForm<IChallengesStepFields>({
|
||||
defaultValues: initialData || {
|
||||
cards: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
useReportStepValidity(isValid, onValidityChange);
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "cards",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { ForwardedRef, useImperativeHandle } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import useReportStepValidity from "./useReportStepValidity";
|
||||
|
||||
export interface IChartStepFields {
|
||||
title: string;
|
||||
@@ -11,21 +12,25 @@ export interface IChartStepFields {
|
||||
const useChartStepPresenter = (
|
||||
initialData?: IChartStepFields,
|
||||
ref?: ForwardedRef<unknown>,
|
||||
onValidityChange?: (valid: boolean) => void,
|
||||
) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
formState: { errors, isValid },
|
||||
getValues,
|
||||
trigger,
|
||||
} = useForm<IChartStepFields>({
|
||||
defaultValues: initialData || {
|
||||
data: [{ key: "", value: 0 }],
|
||||
},
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
useReportStepValidity(isValid, onValidityChange);
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "data",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { ForwardedRef, useImperativeHandle } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import useReportStepValidity from "./useReportStepValidity";
|
||||
|
||||
export interface IContactsStepFields {
|
||||
title: string;
|
||||
@@ -17,15 +18,17 @@ export interface IContactsStepFields {
|
||||
const useContactsStepPresenter = (
|
||||
initialData?: IContactsStepFields,
|
||||
ref?: ForwardedRef<unknown>,
|
||||
onValidityChange?: (valid: boolean) => void,
|
||||
) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
getValues,
|
||||
formState: { errors },
|
||||
formState: { errors, isValid },
|
||||
trigger,
|
||||
} = useForm<IContactsStepFields>({
|
||||
mode: "onChange",
|
||||
defaultValues: initialData || {
|
||||
fields: [
|
||||
{
|
||||
@@ -51,6 +54,8 @@ const useContactsStepPresenter = (
|
||||
name: "fields",
|
||||
});
|
||||
|
||||
useReportStepValidity(isValid, onValidityChange);
|
||||
|
||||
const onSubmit = (data: IContactsStepFields) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { ForwardedRef, useImperativeHandle } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import useReportStepValidity from "./useReportStepValidity";
|
||||
|
||||
export interface IFeaturesStepFields {
|
||||
title: string;
|
||||
@@ -15,21 +16,25 @@ export interface IFeaturesStepFields {
|
||||
const useFeaturesStepPresenter = (
|
||||
initialData?: IFeaturesStepFields,
|
||||
ref?: ForwardedRef<unknown>,
|
||||
onValidityChange?: (valid: boolean) => void,
|
||||
) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
formState: { errors, isValid },
|
||||
getValues,
|
||||
trigger,
|
||||
} = useForm<IFeaturesStepFields>({
|
||||
defaultValues: initialData || {
|
||||
cards: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
useReportStepValidity(isValid, onValidityChange);
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "cards",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ForwardedRef, useImperativeHandle } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import useReportStepValidity from "./useReportStepValidity";
|
||||
|
||||
interface FooterFormValues {
|
||||
email: string;
|
||||
@@ -12,17 +13,21 @@ interface FooterFormValues {
|
||||
const useFooterStepPresenter = (
|
||||
initialData?: FooterFormValues,
|
||||
ref?: ForwardedRef<unknown>,
|
||||
onValidityChange?: (valid: boolean) => void,
|
||||
) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
formState: { errors, isValid },
|
||||
getValues,
|
||||
trigger,
|
||||
} = useForm<FooterFormValues>({
|
||||
defaultValues: initialData,
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
useReportStepValidity(isValid, onValidityChange);
|
||||
|
||||
const onSubmit = (data: FooterFormValues) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { ForwardedRef, useImperativeHandle } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import useReportStepValidity from "./useReportStepValidity";
|
||||
|
||||
export interface IHeroStepFields {
|
||||
title: string;
|
||||
@@ -13,17 +14,21 @@ export interface IHeroStepFields {
|
||||
const useHeroStepPresenter = (
|
||||
initialData?: IHeroStepFields,
|
||||
ref?: ForwardedRef<unknown>,
|
||||
onValidityChange?: (valid: boolean) => void,
|
||||
) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
formState: { errors, isValid },
|
||||
getValues,
|
||||
trigger,
|
||||
} = useForm<IHeroStepFields>({
|
||||
defaultValues: initialData,
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
useReportStepValidity(isValid, onValidityChange);
|
||||
|
||||
const onSubmit = (data: IHeroStepFields) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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";
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ interface IPageTypeFields {
|
||||
country?: string;
|
||||
key: string;
|
||||
}
|
||||
|
||||
const TOTAL_STEPS = 7;
|
||||
|
||||
const useMarketingForm = (
|
||||
initialData: any,
|
||||
onSubmit: (data: any) => void,
|
||||
@@ -20,6 +23,9 @@ const useMarketingForm = (
|
||||
|
||||
const [step, setStep] = useState(0);
|
||||
const [formData, setFormData] = useState<any>(initialData || {});
|
||||
const [stepValidity, setStepValidity] = useState<boolean[]>(() =>
|
||||
new Array(TOTAL_STEPS).fill(false),
|
||||
);
|
||||
const heroRef = useRef<any>(null);
|
||||
const chartRef = useRef<any>(null);
|
||||
const featuresRef = useRef<any>(null);
|
||||
@@ -31,12 +37,13 @@ const useMarketingForm = (
|
||||
const {
|
||||
register: registerPageType,
|
||||
watch: watchPageType,
|
||||
formState: { errors: pageTypeErrors },
|
||||
formState: { errors: pageTypeErrors, isValid: isPageTypeValid },
|
||||
getValues: getPageTypeValues,
|
||||
setValue,
|
||||
reset,
|
||||
trigger: triggerPageType,
|
||||
} = useForm<IPageTypeFields>({
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
type: "company",
|
||||
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(() => {
|
||||
if (initialData) {
|
||||
const formValues = {
|
||||
@@ -245,6 +271,8 @@ const useMarketingForm = (
|
||||
watchPageType,
|
||||
pageTypeErrors,
|
||||
isCompany,
|
||||
isCurrentStepValid,
|
||||
stepValidityHandlers,
|
||||
setValue,
|
||||
heroRef,
|
||||
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;
|
||||
@@ -22,6 +22,7 @@ interface StepperProps {
|
||||
onStepChange?: (step: number) => void;
|
||||
onSubmit?: () => void;
|
||||
isSubmitting?: boolean;
|
||||
nextDisabled?: boolean;
|
||||
}
|
||||
|
||||
const Stepper: React.FC<StepperProps> = ({
|
||||
@@ -30,6 +31,7 @@ const Stepper: React.FC<StepperProps> = ({
|
||||
onStepChange,
|
||||
onSubmit,
|
||||
isSubmitting = false,
|
||||
nextDisabled = false,
|
||||
}) => {
|
||||
const [internalStep, setInternalStep] = useState(0);
|
||||
const currentStep =
|
||||
@@ -213,6 +215,7 @@ const Stepper: React.FC<StepperProps> = ({
|
||||
};
|
||||
|
||||
const nextStep = () => {
|
||||
if (nextDisabled) return;
|
||||
if (currentStep === steps.length - 1) {
|
||||
if (onSubmit) onSubmit();
|
||||
} else if (currentStep < steps.length - 1) {
|
||||
@@ -425,20 +428,20 @@ const Stepper: React.FC<StepperProps> = ({
|
||||
onClick={nextStep}
|
||||
onMouseEnter={() => handleButtonHover(nextBtnRef.current, true)}
|
||||
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 ${
|
||||
isSubmitting
|
||||
isSubmitting || nextDisabled
|
||||
? "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"
|
||||
}`}
|
||||
style={
|
||||
!isSubmitting
|
||||
!isSubmitting && !nextDisabled
|
||||
? { animation: "stepperShimmer 3s linear infinite" }
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{/* Glow halo for submit */}
|
||||
{isLastStep && !isSubmitting && (
|
||||
{isLastStep && !isSubmitting && !nextDisabled && (
|
||||
<span
|
||||
ref={submitGlowRef}
|
||||
aria-hidden
|
||||
|
||||
Reference in New Issue
Block a user