refactor(marketing): Standardize step components and data structure
- Rename field names across step components for consistency - Update chart step to use more generic data structure - Modify input field names to follow consistent naming convention - Refactor chart step to use key-value pairs instead of x-y coordinates - Update form field names in multiple marketing wizard steps - Improve type consistency and naming across marketing wizard components
This commit is contained in:
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
||||
@@ -33,7 +33,7 @@ const BenefitsStep = forwardRef((props, ref) => {
|
||||
append={append}
|
||||
remove={remove}
|
||||
control={control}
|
||||
fieldName="benefits"
|
||||
fieldName="cards"
|
||||
defaultValues={{ icon: "", title: "", description: "" }}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -33,7 +33,7 @@ const ChallengesStep = forwardRef((props, ref) => {
|
||||
append={append}
|
||||
remove={remove}
|
||||
control={control}
|
||||
fieldName="challenges"
|
||||
fieldName="cards"
|
||||
defaultValues={{ icon: "", title: "", description: "" }}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -25,8 +25,8 @@ const ChartStep = forwardRef((props, ref) => {
|
||||
getData: () => getValues(),
|
||||
}));
|
||||
|
||||
const chartTitle = watch("chart_title");
|
||||
const chartPoints = watch("chart_points");
|
||||
const chartTitle = watch("title");
|
||||
const chartData = watch("data");
|
||||
|
||||
return (
|
||||
<form
|
||||
@@ -39,40 +39,43 @@ const ChartStep = forwardRef((props, ref) => {
|
||||
className="flex flex-col gap-5"
|
||||
>
|
||||
<InputGroup
|
||||
{...register("chart_title", {
|
||||
{...register("title", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
})}
|
||||
label="Chart Title"
|
||||
name="chart_title"
|
||||
name="title"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Chart Title"
|
||||
/>
|
||||
{errors.chart_title && (
|
||||
{errors.title && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.chart_title.message}
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("lost_amount", {
|
||||
{...register("missedAmount", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
label="Lost Amount"
|
||||
name="lost_amount"
|
||||
label="Missed Amount"
|
||||
name="missedAmount"
|
||||
required
|
||||
type="number"
|
||||
placeholder="Enter Lost Amount"
|
||||
type="text"
|
||||
placeholder="Enter Missed Amount"
|
||||
/>
|
||||
{errors.lost_amount && (
|
||||
{errors.missedAmount && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.lost_amount.message}
|
||||
{errors.missedAmount.message}
|
||||
</p>
|
||||
)}
|
||||
</ShowcaseSection>
|
||||
<ShowcaseSection title="Chart Preview">
|
||||
<ChartPreview
|
||||
series={chartPoints.filter((p) => p.x && p.y)}
|
||||
series={
|
||||
chartData
|
||||
?.filter((p) => p.key && p.value)
|
||||
.map((p) => ({ x: p.key, y: p.value })) || []
|
||||
}
|
||||
title={chartTitle}
|
||||
/>
|
||||
</ShowcaseSection>
|
||||
@@ -80,31 +83,31 @@ const ChartStep = forwardRef((props, ref) => {
|
||||
{fields.map((field, index) => (
|
||||
<div key={field.id} className="flex items-center gap-4">
|
||||
<InputGroup
|
||||
{...register(`chart_points.${index}.x`, {
|
||||
{...register(`data.${index}.key`, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
})}
|
||||
label="X-axis"
|
||||
name={`chart_points.${index}.x`}
|
||||
label="Key"
|
||||
name={`data.${index}.key`}
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter X-axis value"
|
||||
placeholder="Enter key"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register(`chart_points.${index}.y`, {
|
||||
{...register(`data.${index}.value`, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
label="Y-axis"
|
||||
name={`chart_points.${index}.y`}
|
||||
label="Value"
|
||||
name={`data.${index}.value`}
|
||||
required
|
||||
type="number"
|
||||
placeholder="Enter Y-axis value"
|
||||
placeholder="Enter value"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
@@ -118,7 +121,7 @@ const ChartStep = forwardRef((props, ref) => {
|
||||
<button
|
||||
type="button"
|
||||
className="mt-6 flex w-fit items-center justify-center rounded-lg bg-primary p-[13px] font-medium text-white hover:bg-opacity-90"
|
||||
onClick={() => append({ x: "", y: 0 })}
|
||||
onClick={() => append({ key: "", value: 0 })}
|
||||
>
|
||||
Add point
|
||||
</button>
|
||||
|
||||
@@ -44,11 +44,11 @@ const ContactsStep = forwardRef((props, ref) => {
|
||||
placeholder="Enter Description"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register("submit_button_title")}
|
||||
label="Submit Button Title"
|
||||
name="submit_button_title"
|
||||
{...register("submitButtonText")}
|
||||
label="Submit Button Text"
|
||||
name="submitButtonText"
|
||||
type="text"
|
||||
placeholder="Enter Submit Button Title"
|
||||
placeholder="Enter Submit Button Text"
|
||||
/>
|
||||
</div>
|
||||
</ShowcaseSection>
|
||||
@@ -59,9 +59,9 @@ const ContactsStep = forwardRef((props, ref) => {
|
||||
className="grid grid-cols-1 items-center gap-4 sm:grid-cols-2"
|
||||
>
|
||||
<InputGroup
|
||||
{...register(`fields.${index}.field_name`)}
|
||||
{...register(`fields.${index}.name`)}
|
||||
label="Field Name"
|
||||
name={`fields.${index}.field_name`}
|
||||
name={`fields.${index}.name`}
|
||||
type="text"
|
||||
placeholder="Field Name"
|
||||
disabled
|
||||
|
||||
@@ -33,7 +33,7 @@ const FeaturesStep = forwardRef((props, ref) => {
|
||||
append={append}
|
||||
remove={remove}
|
||||
control={control}
|
||||
fieldName="features"
|
||||
fieldName="cards"
|
||||
defaultValues={{ icon: "", title: "", description: "" }}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -41,18 +41,18 @@ const FooterStep = forwardRef((props, ref) => {
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("phoneNumber")}
|
||||
{...register("phone")}
|
||||
label="Phone Number"
|
||||
name="phoneNumber"
|
||||
name="phone"
|
||||
type="text"
|
||||
placeholder="Enter Phone Number"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register("address")}
|
||||
label="Address"
|
||||
name="address"
|
||||
{...register("location")}
|
||||
label="Location"
|
||||
name="location"
|
||||
type="text"
|
||||
placeholder="Enter Address"
|
||||
placeholder="Enter Location"
|
||||
/>
|
||||
<TextAreaGroup
|
||||
label="Tagline"
|
||||
|
||||
@@ -23,27 +23,6 @@ const HeroStep = forwardRef((props, ref) => {
|
||||
title="Hero Information"
|
||||
className="flex flex-col gap-5"
|
||||
>
|
||||
<InputGroup
|
||||
{...register("key", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
minLength: {
|
||||
value: 2,
|
||||
message: FormErrorMessages.minLength(2),
|
||||
},
|
||||
maxLength: {
|
||||
value: 200,
|
||||
message: FormErrorMessages.maxLength(200),
|
||||
},
|
||||
})}
|
||||
label="Key"
|
||||
name="key"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Key"
|
||||
/>
|
||||
{errors.key && (
|
||||
<p className="mt-1 text-sm text-red-500">{errors.key.message}</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("title", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
@@ -86,7 +65,7 @@ const HeroStep = forwardRef((props, ref) => {
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("button_text", {
|
||||
{...register("buttonText", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
minLength: {
|
||||
value: 2,
|
||||
@@ -98,18 +77,18 @@ const HeroStep = forwardRef((props, ref) => {
|
||||
},
|
||||
})}
|
||||
label="Button Text"
|
||||
name="button_text"
|
||||
name="buttonText"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Button Text"
|
||||
/>
|
||||
{errors.button_text && (
|
||||
{errors.buttonText && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.button_text.message}
|
||||
{errors.buttonText.message}
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("button_link", {
|
||||
{...register("buttonLink", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
minLength: {
|
||||
value: 2,
|
||||
@@ -121,14 +100,29 @@ const HeroStep = forwardRef((props, ref) => {
|
||||
},
|
||||
})}
|
||||
label="Button Link"
|
||||
name="button_link"
|
||||
name="buttonLink"
|
||||
required
|
||||
type="url"
|
||||
placeholder="Enter Button Link"
|
||||
/>
|
||||
{errors.button_link && (
|
||||
{errors.buttonLink && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.button_link.message}
|
||||
{errors.buttonLink.message}
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("gifFile", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
})}
|
||||
label="GIF File URL"
|
||||
name="gifFile"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter GIF File URL"
|
||||
/>
|
||||
{errors.gifFile && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.gifFile.message}
|
||||
</p>
|
||||
)}
|
||||
</ShowcaseSection>
|
||||
|
||||
@@ -5,14 +5,14 @@ import { TextAreaGroup } from "@/components/FormElements/InputGroup/text-area";
|
||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||
import { FormErrorMessages } from "@/constants/Texts";
|
||||
import {
|
||||
Control,
|
||||
FieldErrors,
|
||||
FieldValues,
|
||||
Path,
|
||||
UseFieldArrayAppend,
|
||||
UseFieldArrayRemove,
|
||||
UseFormHandleSubmit,
|
||||
UseFormRegister,
|
||||
Control,
|
||||
FieldErrors,
|
||||
FieldValues,
|
||||
Path,
|
||||
UseFieldArrayAppend,
|
||||
UseFieldArrayRemove,
|
||||
UseFormHandleSubmit,
|
||||
UseFormRegister,
|
||||
} from "react-hook-form";
|
||||
|
||||
interface IProps<T extends FieldValues> {
|
||||
@@ -52,24 +52,24 @@ const SectionStep = <T extends FieldValues>({
|
||||
className="flex flex-col gap-5"
|
||||
>
|
||||
<InputGroup
|
||||
{...register("section_title" as Path<T>, {
|
||||
{...register("title" as Path<T>, {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
})}
|
||||
label="Section Title"
|
||||
name="section_title"
|
||||
name="title"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Section Title"
|
||||
/>
|
||||
{errors.section_title && (
|
||||
{errors.title && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.section_title.message as string}
|
||||
{errors.title.message as string}
|
||||
</p>
|
||||
)}
|
||||
<TextAreaGroup
|
||||
label="Section Description"
|
||||
{...register("section_description" as Path<T>)}
|
||||
name="section_description"
|
||||
{...register("description" as Path<T>)}
|
||||
name="description"
|
||||
placeholder="Enter Section Description"
|
||||
/>
|
||||
</ShowcaseSection>
|
||||
@@ -80,35 +80,35 @@ const SectionStep = <T extends FieldValues>({
|
||||
className="grid grid-cols-1 gap-4 sm:grid-cols-2"
|
||||
>
|
||||
<InputGroup
|
||||
{...register(`${fieldName}.${index}.icon` as Path<T>, {
|
||||
{...register(`cards.${index}.icon` as Path<T>, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
})}
|
||||
label="Icon"
|
||||
name={`${fieldName}.${index}.icon`}
|
||||
name={`cards.${index}.icon`}
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Icon URL or name"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register(`${fieldName}.${index}.title` as Path<T>, {
|
||||
{...register(`cards.${index}.title` as Path<T>, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
})}
|
||||
label="Title"
|
||||
name={`${fieldName}.${index}.title`}
|
||||
name={`cards.${index}.title`}
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
<TextAreaGroup
|
||||
{...register(`${fieldName}.${index}.description` as Path<T>)}
|
||||
{...register(`cards.${index}.description` as Path<T>)}
|
||||
label="Description"
|
||||
name={`${fieldName}.${index}.description`}
|
||||
name={`cards.${index}.description`}
|
||||
placeholder="Enter Description"
|
||||
className="sm:col-span-2"
|
||||
/>
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IBenefitsStepFields {
|
||||
section_title: string;
|
||||
section_description: string;
|
||||
benefits: {
|
||||
title: string;
|
||||
description: string;
|
||||
cards: {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
@@ -21,13 +21,13 @@ const useBenefitsStepPresenter = () => {
|
||||
getValues,
|
||||
} = useForm<IBenefitsStepFields>({
|
||||
defaultValues: {
|
||||
benefits: [{ icon: "", title: "", description: "" }],
|
||||
cards: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "benefits",
|
||||
name: "cards",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IBenefitsStepFields) => {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IChallengesStepFields {
|
||||
section_title: string;
|
||||
section_description: string;
|
||||
challenges: {
|
||||
title: string;
|
||||
description: string;
|
||||
cards: {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
@@ -18,16 +18,16 @@ const useChallengesStepPresenter = () => {
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
getValues
|
||||
getValues,
|
||||
} = useForm<IChallengesStepFields>({
|
||||
defaultValues: {
|
||||
challenges: [{ icon: "", title: "", description: "" }],
|
||||
cards: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "challenges",
|
||||
name: "cards",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IChallengesStepFields) => {
|
||||
@@ -49,8 +49,8 @@ const useChallengesStepPresenter = () => {
|
||||
control,
|
||||
watch,
|
||||
getValues,
|
||||
collectData
|
||||
};
|
||||
collectData,
|
||||
};
|
||||
};
|
||||
|
||||
export default useChallengesStepPresenter;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IChartStepFields {
|
||||
chart_title: string;
|
||||
lost_amount: number;
|
||||
chart_points: { x: string; y: number }[];
|
||||
title: string;
|
||||
missedAmount: string;
|
||||
data: { key: string; value: number }[];
|
||||
}
|
||||
|
||||
const useChartStepPresenter = () => {
|
||||
@@ -14,16 +14,16 @@ const useChartStepPresenter = () => {
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
getValues
|
||||
getValues,
|
||||
} = useForm<IChartStepFields>({
|
||||
defaultValues: {
|
||||
chart_points: [{ x: "", y: 0 }],
|
||||
data: [{ key: "", value: 0 }],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "chart_points",
|
||||
name: "data",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IChartStepFields) => {
|
||||
@@ -45,7 +45,7 @@ const useChartStepPresenter = () => {
|
||||
control,
|
||||
watch,
|
||||
getValues,
|
||||
collectData
|
||||
collectData,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ import { useFieldArray, useForm } from "react-hook-form";
|
||||
export interface IContactsStepFields {
|
||||
title: string;
|
||||
description: string;
|
||||
submit_button_title: string;
|
||||
submitButtonText: string;
|
||||
fields: {
|
||||
field_name: string;
|
||||
name: string;
|
||||
label: string;
|
||||
placeholder: string;
|
||||
required: boolean;
|
||||
@@ -19,25 +19,24 @@ const useContactsStepPresenter = () => {
|
||||
handleSubmit,
|
||||
control,
|
||||
getValues,
|
||||
|
||||
formState: { errors },
|
||||
} = useForm<IContactsStepFields>({
|
||||
defaultValues: {
|
||||
fields: [
|
||||
{
|
||||
field_name: "first_name",
|
||||
name: "first_name",
|
||||
label: "",
|
||||
placeholder: "",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
field_name: "last_name",
|
||||
name: "last_name",
|
||||
label: "",
|
||||
placeholder: "",
|
||||
required: false,
|
||||
},
|
||||
{ field_name: "email", label: "", placeholder: "", required: false },
|
||||
{ field_name: "phone", label: "", placeholder: "", required: false },
|
||||
{ name: "email", label: "", placeholder: "", required: false },
|
||||
{ name: "phone", label: "", placeholder: "", required: false },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IFeaturesStepFields {
|
||||
section_title: string;
|
||||
section_description: string;
|
||||
features: {
|
||||
title: string;
|
||||
description: string;
|
||||
cards: {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
@@ -18,16 +18,16 @@ const useFeaturesStepPresenter = () => {
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
getValues
|
||||
getValues,
|
||||
} = useForm<IFeaturesStepFields>({
|
||||
defaultValues: {
|
||||
features: [{ icon: "", title: "", description: "" }],
|
||||
cards: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "features",
|
||||
name: "cards",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IFeaturesStepFields) => {
|
||||
@@ -49,8 +49,8 @@ const useFeaturesStepPresenter = () => {
|
||||
control,
|
||||
watch,
|
||||
getValues,
|
||||
collectData
|
||||
};
|
||||
collectData,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFeaturesStepPresenter;
|
||||
|
||||
@@ -2,10 +2,10 @@ import { useForm } from "react-hook-form";
|
||||
|
||||
interface FooterFormValues {
|
||||
email: string;
|
||||
phoneNumber?: string;
|
||||
address?: string;
|
||||
tagline?: string;
|
||||
copyright?: string;
|
||||
phone: string;
|
||||
location: string;
|
||||
tagline: string;
|
||||
copyright: string;
|
||||
}
|
||||
|
||||
const useFooterStepPresenter = () => {
|
||||
@@ -13,7 +13,7 @@ const useFooterStepPresenter = () => {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
getValues
|
||||
getValues,
|
||||
} = useForm<FooterFormValues>();
|
||||
|
||||
const onSubmit = (data: FooterFormValues) => {
|
||||
@@ -29,9 +29,9 @@ const useFooterStepPresenter = () => {
|
||||
handleSubmit,
|
||||
onSubmit,
|
||||
errors,
|
||||
collectData,
|
||||
getValues,
|
||||
};
|
||||
collectData,
|
||||
getValues,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFooterStepPresenter;
|
||||
@@ -2,11 +2,11 @@
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
export interface IHeroStepFields {
|
||||
key: string;
|
||||
title: string;
|
||||
description: string;
|
||||
button_text: string;
|
||||
button_link: string;
|
||||
buttonText: string;
|
||||
buttonLink: string;
|
||||
gifFile: string;
|
||||
}
|
||||
|
||||
const useHeroStepPresenter = () => {
|
||||
@@ -30,9 +30,4 @@ const useHeroStepPresenter = () => {
|
||||
};
|
||||
};
|
||||
|
||||
(useHeroStepPresenter as any).collectData = async () => {
|
||||
const { getValues } = useForm<IHeroStepFields>();
|
||||
return getValues();
|
||||
};
|
||||
|
||||
export default useHeroStepPresenter;
|
||||
|
||||
@@ -15,6 +15,7 @@ import HeroStep from "./_components/HeroStep";
|
||||
|
||||
const Marketing = () => {
|
||||
const [step, setStep] = useState(0);
|
||||
const [formData, setFormData] = useState<any>({});
|
||||
const heroRef = useRef<any>(null);
|
||||
const chartRef = useRef<any>(null);
|
||||
const featuresRef = useRef<any>(null);
|
||||
@@ -40,7 +41,7 @@ const Marketing = () => {
|
||||
},
|
||||
];
|
||||
|
||||
const collectAllStepsData = async () => {
|
||||
const saveCurrentStepData = async () => {
|
||||
const refs = [
|
||||
heroRef,
|
||||
chartRef,
|
||||
@@ -51,26 +52,57 @@ const Marketing = () => {
|
||||
footerRef,
|
||||
];
|
||||
|
||||
const allData: any = {
|
||||
hero: {},
|
||||
chart: {},
|
||||
features: {},
|
||||
challenges: {},
|
||||
benefits: {},
|
||||
contacts: {},
|
||||
footer: {},
|
||||
};
|
||||
const keys = [
|
||||
"hero",
|
||||
"chart",
|
||||
"features",
|
||||
"challenges",
|
||||
"advantages",
|
||||
"contact",
|
||||
"footer",
|
||||
];
|
||||
|
||||
const currentRef = refs[step];
|
||||
if (currentRef?.current?.getData) {
|
||||
try {
|
||||
const data = await currentRef.current.getData();
|
||||
setFormData((prev: any) => ({
|
||||
...prev,
|
||||
[keys[step]]: data,
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error(`Error collecting data from step ${step}:`, error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const collectAllStepsData = async () => {
|
||||
// First save current step data
|
||||
await saveCurrentStepData();
|
||||
|
||||
const refs = [
|
||||
heroRef,
|
||||
chartRef,
|
||||
featuresRef,
|
||||
challengesRef,
|
||||
benefitsRef,
|
||||
contactsRef,
|
||||
footerRef,
|
||||
];
|
||||
|
||||
const allData: any = { ...formData };
|
||||
|
||||
const keys = [
|
||||
"hero",
|
||||
"chart",
|
||||
"features",
|
||||
"challenges",
|
||||
"benefits",
|
||||
"contacts",
|
||||
"advantages",
|
||||
"contact",
|
||||
"footer",
|
||||
];
|
||||
|
||||
// Collect any remaining data from refs
|
||||
for (let i = 0; i < refs.length; i++) {
|
||||
const ref = refs[i];
|
||||
if (ref?.current?.getData) {
|
||||
@@ -104,48 +136,76 @@ const Marketing = () => {
|
||||
{
|
||||
title: "Hero",
|
||||
description: "Create the hero section",
|
||||
content: <HeroStep ref={heroRef} />,
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Chart",
|
||||
description: "Create the chart",
|
||||
content: <ChartStep ref={chartRef} />,
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Features",
|
||||
description: "Add features",
|
||||
content: <FeaturesStep ref={featuresRef} />,
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Challenges",
|
||||
description: "Create challenges section",
|
||||
content: <ChallengesStep ref={challengesRef} />,
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Benefits",
|
||||
description: "create benefits section",
|
||||
content: <BenefitsStep ref={benefitsRef} />,
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Contacts",
|
||||
description: "Create contacts section",
|
||||
content: <ContactsStep ref={contactsRef} />,
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Footer",
|
||||
description: "Add footer information",
|
||||
content: <FooterStep ref={footerRef} />,
|
||||
content: <></>,
|
||||
},
|
||||
];
|
||||
|
||||
const handleStepChange = async (newStep: number) => {
|
||||
await saveCurrentStepData();
|
||||
setStep(newStep);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Breadcrumb items={breadcrumbItems} />
|
||||
<ShowcaseSection title="Create Marketing page">
|
||||
{/* Render all steps but only show the current one */}
|
||||
<div style={{ display: step === 0 ? "block" : "none" }}>
|
||||
<HeroStep ref={heroRef} />
|
||||
</div>
|
||||
<div style={{ display: step === 1 ? "block" : "none" }}>
|
||||
<ChartStep ref={chartRef} />
|
||||
</div>
|
||||
<div style={{ display: step === 2 ? "block" : "none" }}>
|
||||
<FeaturesStep ref={featuresRef} />
|
||||
</div>
|
||||
<div style={{ display: step === 3 ? "block" : "none" }}>
|
||||
<ChallengesStep ref={challengesRef} />
|
||||
</div>
|
||||
<div style={{ display: step === 4 ? "block" : "none" }}>
|
||||
<BenefitsStep ref={benefitsRef} />
|
||||
</div>
|
||||
<div style={{ display: step === 5 ? "block" : "none" }}>
|
||||
<ContactsStep ref={contactsRef} />
|
||||
</div>
|
||||
<div style={{ display: step === 6 ? "block" : "none" }}>
|
||||
<FooterStep ref={footerRef} />
|
||||
</div>
|
||||
|
||||
<Stepper
|
||||
steps={steps}
|
||||
currentStep={step}
|
||||
onStepChange={setStep}
|
||||
onStepChange={handleStepChange}
|
||||
/>
|
||||
<div className="mt-6 flex justify-end gap-4">
|
||||
<button
|
||||
|
||||
@@ -1,5 +1,75 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const CmsCredentials = z.object({ advantages: z.object({
|
||||
cards: z.array(
|
||||
z.object({
|
||||
description: z.string(),
|
||||
icon: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
),
|
||||
description: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
challenges: z.object({
|
||||
cards: z.array(
|
||||
z.object({
|
||||
description: z.string(),
|
||||
icon: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
),
|
||||
description: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
chart: z.object({
|
||||
data: z.array(
|
||||
z.object({
|
||||
key: z.string(),
|
||||
value: z.number(),
|
||||
}),
|
||||
),
|
||||
missedAmount: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
contact: z.object({
|
||||
description: z.string(),
|
||||
fields: z.array(
|
||||
z.object({
|
||||
label: z.string(),
|
||||
name: z.string(),
|
||||
placeholder: z.string(),
|
||||
required: z.boolean(),
|
||||
}),
|
||||
),
|
||||
submitButtonText: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
features: z.object({
|
||||
cards: z.array(
|
||||
z.object({
|
||||
description: z.string(),
|
||||
icon: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
),
|
||||
description: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
footer: z.object({
|
||||
copyright: z.string(),
|
||||
email: z.string(),
|
||||
location: z.string(),
|
||||
phone: z.string(),
|
||||
tagline: z.string(),
|
||||
}),
|
||||
hero: z.object({
|
||||
buttonLink: z.string(),
|
||||
buttonText: z.string(),
|
||||
description: z.string(),
|
||||
gifFile: z.string(),
|
||||
title: z.string(),
|
||||
})})
|
||||
const CmsSchema = z.object({
|
||||
cms: z.array(
|
||||
z.object({
|
||||
@@ -82,3 +152,4 @@ const CmsSchema = z.object({
|
||||
),
|
||||
});
|
||||
export type TCmsResponse = z.infer<typeof CmsSchema>;
|
||||
export type TCmsCredentials = z.infer<typeof CmsCredentials>
|
||||
Reference in New Issue
Block a user