refactor(marketing): Standardize marketing wizard steps with initial data support
- Add support for initial data in all marketing wizard step components - Update step presenters to accept and handle initial data - Modify forwardRef implementations to include initialData prop - Add TypeScript interfaces for step component props - Improve type safety and data handling across marketing wizard steps - Prepare components for edit and create workflows with consistent data management
This commit is contained in:
@@ -1,58 +1,9 @@
|
||||
"use client";
|
||||
import { GlobeIcon } from "@/assets/icons";
|
||||
import Breadcrumb from "@/components/Breadcrumbs/Breadcrumb";
|
||||
import InputGroup from "@/components/FormElements/InputGroup";
|
||||
import { Select } from "@/components/FormElements/select";
|
||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||
import Stepper, { Step } from "@/components/ui/Stepper";
|
||||
import { Countries } from "@/constants/countries";
|
||||
import { FormErrorMessages } from "@/constants/Texts";
|
||||
import { useCreateCms } from "@/hooks/queries/useCmsQueries";
|
||||
import { BreadcrumbItem } from "@/types/shared";
|
||||
import { useRef, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import BenefitsStep from "../_components/BenefitsStep";
|
||||
import ChallengesStep from "../_components/ChallengesStep";
|
||||
import ChartStep from "../_components/ChartStep";
|
||||
import ContactsStep from "../_components/ContactsStep";
|
||||
import FeaturesStep from "../_components/FeaturesStep";
|
||||
import FooterStep from "../_components/FooterStep";
|
||||
import HeroStep from "../_components/HeroStep";
|
||||
|
||||
interface IPageTypeFields {
|
||||
type: "company" | "organization";
|
||||
language?: string;
|
||||
company_name?: string;
|
||||
country?: string;
|
||||
key: string;
|
||||
}
|
||||
import MarketingForm from "../_components/MarketingForm";
|
||||
|
||||
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);
|
||||
const challengesRef = useRef<any>(null);
|
||||
const benefitsRef = useRef<any>(null);
|
||||
const contactsRef = useRef<any>(null);
|
||||
const footerRef = useRef<any>(null);
|
||||
|
||||
const {
|
||||
register: registerPageType,
|
||||
watch: watchPageType,
|
||||
formState: { errors: pageTypeErrors },
|
||||
getValues: getPageTypeValues,
|
||||
setValue,
|
||||
} = useForm<IPageTypeFields>({
|
||||
defaultValues: {
|
||||
type: "company",
|
||||
},
|
||||
});
|
||||
|
||||
const pageType = watchPageType("type");
|
||||
const isCompany = pageType === "company";
|
||||
|
||||
const { mutate: createCms, isPending } = useCreateCms();
|
||||
|
||||
const breadcrumbItems: BreadcrumbItem[] = [
|
||||
@@ -70,101 +21,8 @@ const Marketing = () => {
|
||||
},
|
||||
];
|
||||
|
||||
const saveCurrentStepData = async () => {
|
||||
const refs = [
|
||||
heroRef,
|
||||
chartRef,
|
||||
featuresRef,
|
||||
challengesRef,
|
||||
benefitsRef,
|
||||
contactsRef,
|
||||
footerRef,
|
||||
];
|
||||
|
||||
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",
|
||||
"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) {
|
||||
try {
|
||||
const data = await ref.current.getData();
|
||||
allData[keys[i]] = data;
|
||||
} catch (error) {
|
||||
console.error(`Error collecting data from step ${i}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allData;
|
||||
};
|
||||
|
||||
const handleSubmitAll = async () => {
|
||||
const allData = await collectAllStepsData();
|
||||
const pageTypeData = getPageTypeValues();
|
||||
|
||||
const finalData = {
|
||||
...allData,
|
||||
type: pageTypeData.type,
|
||||
key: pageTypeData.key,
|
||||
...(pageTypeData.type === "company" && {
|
||||
language: pageTypeData.language,
|
||||
company_name: pageTypeData.company_name,
|
||||
country: pageTypeData.country,
|
||||
}),
|
||||
};
|
||||
|
||||
console.log("All collected data:", finalData);
|
||||
|
||||
createCms(finalData, {
|
||||
const handleSubmit = (data: any) => {
|
||||
createCms(data, {
|
||||
onSuccess: () => {
|
||||
console.log("CMS created successfully");
|
||||
},
|
||||
@@ -174,196 +32,13 @@ const Marketing = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const steps: Step[] = [
|
||||
{
|
||||
title: "Hero",
|
||||
description: "Create the hero section",
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Chart",
|
||||
description: "Create the chart",
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Features",
|
||||
description: "Add features",
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Challenges",
|
||||
description: "Create challenges section",
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Benefits",
|
||||
description: "create benefits section",
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Contacts",
|
||||
description: "Create contacts section",
|
||||
content: <></>,
|
||||
},
|
||||
{
|
||||
title: "Footer",
|
||||
description: "Add footer information",
|
||||
content: <></>,
|
||||
},
|
||||
];
|
||||
|
||||
const handleStepChange = async (newStep: number) => {
|
||||
await saveCurrentStepData();
|
||||
setStep(newStep);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Breadcrumb items={breadcrumbItems} />
|
||||
<ShowcaseSection title="Create Marketing page">
|
||||
{/* Page Type Selection */}
|
||||
<div className="mb-6 rounded-xl bg-gray-1 p-6 dark:bg-gray-7">
|
||||
<h3 className="mb-4 text-lg font-semibold text-dark dark:text-white">
|
||||
Page Configuration
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 gap-5 sm:grid-cols-2">
|
||||
<Select
|
||||
{...registerPageType("type", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
})}
|
||||
name="type"
|
||||
label="Page Type"
|
||||
required
|
||||
items={[
|
||||
{ value: "company", label: "Company" },
|
||||
{ value: "organization", label: "Organization" },
|
||||
]}
|
||||
/>
|
||||
{pageTypeErrors.type && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{pageTypeErrors.type.message}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<InputGroup
|
||||
{...registerPageType("language", {
|
||||
required: isCompany
|
||||
? { message: FormErrorMessages.required, value: true }
|
||||
: false,
|
||||
minLength: isCompany
|
||||
? { value: 2, message: FormErrorMessages.minLength(2) }
|
||||
: undefined,
|
||||
maxLength: isCompany
|
||||
? { value: 10, message: FormErrorMessages.maxLength(10) }
|
||||
: undefined,
|
||||
})}
|
||||
label="Language"
|
||||
name="language"
|
||||
type="text"
|
||||
placeholder="Enter Language (e.g., en, ar)"
|
||||
disabled={!isCompany}
|
||||
required={isCompany}
|
||||
/>
|
||||
{pageTypeErrors.language && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{pageTypeErrors.language.message}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<InputGroup
|
||||
{...registerPageType("company_name", {
|
||||
required: isCompany
|
||||
? { message: FormErrorMessages.required, value: true }
|
||||
: false,
|
||||
minLength: isCompany
|
||||
? { value: 2, message: FormErrorMessages.minLength(2) }
|
||||
: undefined,
|
||||
maxLength: isCompany
|
||||
? { value: 200, message: FormErrorMessages.maxLength(200) }
|
||||
: undefined,
|
||||
})}
|
||||
label="Company Name"
|
||||
name="company_name"
|
||||
type="text"
|
||||
placeholder="Enter Company Name"
|
||||
disabled={!isCompany}
|
||||
required={isCompany}
|
||||
/>
|
||||
{pageTypeErrors.company_name && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{pageTypeErrors.company_name.message}
|
||||
</p>
|
||||
)}
|
||||
<Select
|
||||
{...registerPageType("country")}
|
||||
name="country"
|
||||
label="Country"
|
||||
items={Countries}
|
||||
defaultValue="USA"
|
||||
clearable
|
||||
prefixIcon={<GlobeIcon />}
|
||||
disabled={!isCompany}
|
||||
required={isCompany}
|
||||
placeholder="Please select country"
|
||||
onClear={() => setValue("country", undefined)}
|
||||
/>
|
||||
{pageTypeErrors.country && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{pageTypeErrors.country.message}
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...registerPageType("key", {
|
||||
required: {
|
||||
value: true,
|
||||
message: FormErrorMessages.required,
|
||||
},
|
||||
})}
|
||||
label="Page key"
|
||||
name="key"
|
||||
placeholder="Please enter page key"
|
||||
type="text"
|
||||
/>
|
||||
{pageTypeErrors.key && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{pageTypeErrors.key.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 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={handleStepChange}
|
||||
onSubmit={handleSubmitAll}
|
||||
isSubmitting={isPending}
|
||||
/>
|
||||
</ShowcaseSection>
|
||||
</>
|
||||
<MarketingForm
|
||||
breadcrumbItems={breadcrumbItems}
|
||||
title="Create Marketing page"
|
||||
onSubmit={handleSubmit}
|
||||
isPending={isPending}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user