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:
@@ -5,7 +5,11 @@ import useBenefitsStepPresenter, {
|
|||||||
IBenefitsStepFields,
|
IBenefitsStepFields,
|
||||||
} from "./useBenefitsStepPresenter";
|
} from "./useBenefitsStepPresenter";
|
||||||
|
|
||||||
const BenefitsStep = forwardRef((props, ref) => {
|
interface BenefitsStepProps {
|
||||||
|
initialData?: IBenefitsStepFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BenefitsStep = forwardRef<unknown, BenefitsStepProps>(({ initialData }, ref) => {
|
||||||
const {
|
const {
|
||||||
errors,
|
errors,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -16,7 +20,7 @@ const BenefitsStep = forwardRef((props, ref) => {
|
|||||||
remove,
|
remove,
|
||||||
control,
|
control,
|
||||||
getValues,
|
getValues,
|
||||||
} = useBenefitsStepPresenter();
|
} = useBenefitsStepPresenter(initialData);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
getData: () => getValues(),
|
getData: () => getValues(),
|
||||||
|
|||||||
@@ -5,39 +5,45 @@ import useChallengesStepPresenter, {
|
|||||||
IChallengesStepFields,
|
IChallengesStepFields,
|
||||||
} from "./useChallengesStepPresenter";
|
} from "./useChallengesStepPresenter";
|
||||||
|
|
||||||
const ChallengesStep = forwardRef((props, ref) => {
|
interface ChallengesStepProps {
|
||||||
const {
|
initialData?: IChallengesStepFields;
|
||||||
errors,
|
}
|
||||||
handleSubmit,
|
|
||||||
onSubmit,
|
|
||||||
register,
|
|
||||||
fields,
|
|
||||||
append,
|
|
||||||
remove,
|
|
||||||
control,
|
|
||||||
getValues,
|
|
||||||
} = useChallengesStepPresenter();
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
const ChallengesStep = forwardRef<unknown, ChallengesStepProps>(
|
||||||
getData: () => getValues(),
|
({ initialData }, ref) => {
|
||||||
}));
|
const {
|
||||||
|
errors,
|
||||||
|
handleSubmit,
|
||||||
|
onSubmit,
|
||||||
|
register,
|
||||||
|
fields,
|
||||||
|
append,
|
||||||
|
remove,
|
||||||
|
control,
|
||||||
|
getValues,
|
||||||
|
} = useChallengesStepPresenter(initialData);
|
||||||
|
|
||||||
return (
|
useImperativeHandle(ref, () => ({
|
||||||
<SectionStep<IChallengesStepFields>
|
getData: () => getValues(),
|
||||||
title="Challenges"
|
}));
|
||||||
fields={fields}
|
|
||||||
handleSubmit={handleSubmit}
|
return (
|
||||||
onSubmit={onSubmit}
|
<SectionStep<IChallengesStepFields>
|
||||||
register={register}
|
title="Challenges"
|
||||||
errors={errors}
|
fields={fields}
|
||||||
append={append}
|
handleSubmit={handleSubmit}
|
||||||
remove={remove}
|
onSubmit={onSubmit}
|
||||||
control={control}
|
register={register}
|
||||||
fieldName="cards"
|
errors={errors}
|
||||||
defaultValues={{ icon: "", title: "", description: "" }}
|
append={append}
|
||||||
/>
|
remove={remove}
|
||||||
);
|
control={control}
|
||||||
});
|
fieldName="cards"
|
||||||
|
defaultValues={{ icon: "", title: "", description: "" }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
ChallengesStep.displayName = "ChallengesStep";
|
ChallengesStep.displayName = "ChallengesStep";
|
||||||
|
|
||||||
|
|||||||
@@ -8,129 +8,135 @@ import { forwardRef, useImperativeHandle } from "react";
|
|||||||
import { ChartPreview } from "./ChartPreview";
|
import { ChartPreview } from "./ChartPreview";
|
||||||
import useChartStepPresenter from "./useChartStepPresenter";
|
import useChartStepPresenter from "./useChartStepPresenter";
|
||||||
|
|
||||||
const ChartStep = forwardRef((props, ref) => {
|
interface ChartStepProps {
|
||||||
const {
|
initialData?: any;
|
||||||
errors,
|
}
|
||||||
handleSubmit,
|
|
||||||
onSubmit,
|
|
||||||
register,
|
|
||||||
fields,
|
|
||||||
append,
|
|
||||||
remove,
|
|
||||||
watch,
|
|
||||||
getValues,
|
|
||||||
} = useChartStepPresenter();
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
const ChartStep = forwardRef<unknown, ChartStepProps>(
|
||||||
getData: () => getValues(),
|
({ initialData }, ref) => {
|
||||||
}));
|
const {
|
||||||
|
errors,
|
||||||
|
handleSubmit,
|
||||||
|
onSubmit,
|
||||||
|
register,
|
||||||
|
fields,
|
||||||
|
append,
|
||||||
|
remove,
|
||||||
|
watch,
|
||||||
|
getValues,
|
||||||
|
} = useChartStepPresenter(initialData);
|
||||||
|
|
||||||
const chartTitle = watch("title");
|
useImperativeHandle(ref, () => ({
|
||||||
const chartData = watch("data");
|
getData: () => getValues(),
|
||||||
|
}));
|
||||||
|
|
||||||
return (
|
const chartTitle = watch("title");
|
||||||
<form
|
const chartData = watch("data");
|
||||||
className="items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7 sm:grid-cols-2"
|
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
return (
|
||||||
>
|
<form
|
||||||
<div className="flex flex-col gap-9">
|
className="items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7 sm:grid-cols-2"
|
||||||
<ShowcaseSection
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
title="Chart Information"
|
>
|
||||||
className="flex flex-col gap-5"
|
<div className="flex flex-col gap-9">
|
||||||
>
|
<ShowcaseSection
|
||||||
<InputGroup
|
title="Chart Information"
|
||||||
{...register("title", {
|
className="flex flex-col gap-5"
|
||||||
required: { message: FormErrorMessages.required, value: true },
|
|
||||||
})}
|
|
||||||
label="Chart Title"
|
|
||||||
name="title"
|
|
||||||
required
|
|
||||||
type="text"
|
|
||||||
placeholder="Enter Chart Title"
|
|
||||||
/>
|
|
||||||
{errors.title && (
|
|
||||||
<p className="mt-1 text-sm text-red-500">
|
|
||||||
{errors.title.message}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<InputGroup
|
|
||||||
{...register("missedAmount", {
|
|
||||||
required: { message: FormErrorMessages.required, value: true },
|
|
||||||
})}
|
|
||||||
label="Missed Amount"
|
|
||||||
name="missedAmount"
|
|
||||||
required
|
|
||||||
type="text"
|
|
||||||
placeholder="Enter Missed Amount"
|
|
||||||
/>
|
|
||||||
{errors.missedAmount && (
|
|
||||||
<p className="mt-1 text-sm text-red-500">
|
|
||||||
{errors.missedAmount.message}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</ShowcaseSection>
|
|
||||||
<ShowcaseSection title="Chart Preview">
|
|
||||||
<ChartPreview
|
|
||||||
series={
|
|
||||||
chartData
|
|
||||||
?.filter((p) => p.key && p.value)
|
|
||||||
.map((p) => ({ x: p.key, y: p.value })) || []
|
|
||||||
}
|
|
||||||
title={chartTitle}
|
|
||||||
/>
|
|
||||||
</ShowcaseSection>
|
|
||||||
<ShowcaseSection title="Chart Points" className="flex flex-col gap-5">
|
|
||||||
{fields.map((field, index) => (
|
|
||||||
<div key={field.id} className="flex items-center gap-4">
|
|
||||||
<InputGroup
|
|
||||||
{...register(`data.${index}.key`, {
|
|
||||||
required: {
|
|
||||||
message: FormErrorMessages.required,
|
|
||||||
value: true,
|
|
||||||
},
|
|
||||||
})}
|
|
||||||
label="Key"
|
|
||||||
name={`data.${index}.key`}
|
|
||||||
required
|
|
||||||
type="text"
|
|
||||||
placeholder="Enter key"
|
|
||||||
/>
|
|
||||||
<InputGroup
|
|
||||||
{...register(`data.${index}.value`, {
|
|
||||||
required: {
|
|
||||||
message: FormErrorMessages.required,
|
|
||||||
value: true,
|
|
||||||
},
|
|
||||||
valueAsNumber: true,
|
|
||||||
})}
|
|
||||||
label="Value"
|
|
||||||
name={`data.${index}.value`}
|
|
||||||
required
|
|
||||||
type="number"
|
|
||||||
placeholder="Enter value"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => remove(index)}
|
|
||||||
className="mt-6 flex w-fit justify-center rounded-lg bg-error p-[13px] font-medium text-white hover:bg-opacity-90"
|
|
||||||
>
|
|
||||||
<TrashIcon />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<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({ key: "", value: 0 })}
|
|
||||||
>
|
>
|
||||||
Add point
|
<InputGroup
|
||||||
</button>
|
{...register("title", {
|
||||||
</ShowcaseSection>
|
required: { message: FormErrorMessages.required, value: true },
|
||||||
</div>
|
})}
|
||||||
<div className="flex flex-col gap-9"></div>
|
label="Chart Title"
|
||||||
</form>
|
name="title"
|
||||||
);
|
required
|
||||||
});
|
type="text"
|
||||||
|
placeholder="Enter Chart Title"
|
||||||
|
/>
|
||||||
|
{errors.title && (
|
||||||
|
<p className="mt-1 text-sm text-red-500">
|
||||||
|
{errors.title.message}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
<InputGroup
|
||||||
|
{...register("missedAmount", {
|
||||||
|
required: { message: FormErrorMessages.required, value: true },
|
||||||
|
})}
|
||||||
|
label="Missed Amount"
|
||||||
|
name="missedAmount"
|
||||||
|
required
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter Missed Amount"
|
||||||
|
/>
|
||||||
|
{errors.missedAmount && (
|
||||||
|
<p className="mt-1 text-sm text-red-500">
|
||||||
|
{errors.missedAmount.message}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</ShowcaseSection>
|
||||||
|
<ShowcaseSection title="Chart Preview">
|
||||||
|
<ChartPreview
|
||||||
|
series={
|
||||||
|
chartData
|
||||||
|
?.filter((p) => p.key && p.value)
|
||||||
|
.map((p) => ({ x: p.key, y: p.value })) || []
|
||||||
|
}
|
||||||
|
title={chartTitle}
|
||||||
|
/>
|
||||||
|
</ShowcaseSection>
|
||||||
|
<ShowcaseSection title="Chart Points" className="flex flex-col gap-5">
|
||||||
|
{fields.map((field, index) => (
|
||||||
|
<div key={field.id} className="flex items-center gap-4">
|
||||||
|
<InputGroup
|
||||||
|
{...register(`data.${index}.key`, {
|
||||||
|
required: {
|
||||||
|
message: FormErrorMessages.required,
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
label="Key"
|
||||||
|
name={`data.${index}.key`}
|
||||||
|
required
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter key"
|
||||||
|
/>
|
||||||
|
<InputGroup
|
||||||
|
{...register(`data.${index}.value`, {
|
||||||
|
required: {
|
||||||
|
message: FormErrorMessages.required,
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
valueAsNumber: true,
|
||||||
|
})}
|
||||||
|
label="Value"
|
||||||
|
name={`data.${index}.value`}
|
||||||
|
required
|
||||||
|
type="number"
|
||||||
|
placeholder="Enter value"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => remove(index)}
|
||||||
|
className="mt-6 flex w-fit justify-center rounded-lg bg-error p-[13px] font-medium text-white hover:bg-opacity-90"
|
||||||
|
>
|
||||||
|
<TrashIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<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({ key: "", value: 0 })}
|
||||||
|
>
|
||||||
|
Add point
|
||||||
|
</button>
|
||||||
|
</ShowcaseSection>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-9"></div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
ChartStep.displayName = "ChartStep";
|
ChartStep.displayName = "ChartStep";
|
||||||
|
|
||||||
|
|||||||
@@ -7,93 +7,102 @@ import { FormErrorMessages } from "@/constants/Texts";
|
|||||||
import { forwardRef, useImperativeHandle } from "react";
|
import { forwardRef, useImperativeHandle } from "react";
|
||||||
import useContactsStepPresenter from "./useContactsStepPresenter";
|
import useContactsStepPresenter from "./useContactsStepPresenter";
|
||||||
|
|
||||||
const ContactsStep = forwardRef((props, ref) => {
|
interface ContactsStepProps {
|
||||||
const { errors, handleSubmit, onSubmit, register, fields, getValues } =
|
initialData?: any;
|
||||||
useContactsStepPresenter();
|
}
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
const ContactsStep = forwardRef<unknown, ContactsStepProps>(
|
||||||
getData: () => getValues(),
|
({ initialData }, ref) => {
|
||||||
}));
|
const { errors, handleSubmit, onSubmit, register, fields, getValues } =
|
||||||
|
useContactsStepPresenter(initialData);
|
||||||
|
|
||||||
return (
|
useImperativeHandle(ref, () => ({
|
||||||
<form
|
getData: () => getValues(),
|
||||||
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7"
|
}));
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
|
||||||
>
|
return (
|
||||||
<ShowcaseSection title="Contacts Section" className="flex flex-col gap-5">
|
<form
|
||||||
<div className="flex flex-col gap-9">
|
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7"
|
||||||
<InputGroup
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
{...register("title", {
|
>
|
||||||
required: { message: FormErrorMessages.required, value: true },
|
<ShowcaseSection
|
||||||
})}
|
title="Contacts Section"
|
||||||
label="Title"
|
className="flex flex-col gap-5"
|
||||||
name="title"
|
>
|
||||||
required
|
<div className="flex flex-col gap-9">
|
||||||
type="text"
|
|
||||||
placeholder="Enter Title"
|
|
||||||
/>
|
|
||||||
{errors.title && (
|
|
||||||
<p className="mt-1 text-sm text-red-500">
|
|
||||||
{errors.title.message as string}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<TextAreaGroup
|
|
||||||
label="Description"
|
|
||||||
{...register("description")}
|
|
||||||
name="description"
|
|
||||||
placeholder="Enter Description"
|
|
||||||
/>
|
|
||||||
<InputGroup
|
|
||||||
{...register("submitButtonText")}
|
|
||||||
label="Submit Button Text"
|
|
||||||
name="submitButtonText"
|
|
||||||
type="text"
|
|
||||||
placeholder="Enter Submit Button Text"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ShowcaseSection>
|
|
||||||
<ShowcaseSection title="Form Fields" className="flex flex-col gap-5">
|
|
||||||
{fields.map((field, index) => (
|
|
||||||
<div
|
|
||||||
key={field.id}
|
|
||||||
className="grid grid-cols-1 items-center gap-4 sm:grid-cols-2"
|
|
||||||
>
|
|
||||||
<InputGroup
|
<InputGroup
|
||||||
{...register(`fields.${index}.name`)}
|
{...register("title", {
|
||||||
label="Field Name"
|
required: { message: FormErrorMessages.required, value: true },
|
||||||
name={`fields.${index}.name`}
|
})}
|
||||||
|
label="Title"
|
||||||
|
name="title"
|
||||||
|
required
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Field Name"
|
placeholder="Enter Title"
|
||||||
disabled
|
/>
|
||||||
|
{errors.title && (
|
||||||
|
<p className="mt-1 text-sm text-red-500">
|
||||||
|
{errors.title.message as string}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
<TextAreaGroup
|
||||||
|
label="Description"
|
||||||
|
{...register("description")}
|
||||||
|
name="description"
|
||||||
|
placeholder="Enter Description"
|
||||||
/>
|
/>
|
||||||
<InputGroup
|
<InputGroup
|
||||||
{...register(`fields.${index}.label`)}
|
{...register("submitButtonText")}
|
||||||
label="Label"
|
label="Submit Button Text"
|
||||||
name={`fields.${index}.label`}
|
name="submitButtonText"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Enter Label"
|
placeholder="Enter Submit Button Text"
|
||||||
/>
|
|
||||||
<InputGroup
|
|
||||||
{...register(`fields.${index}.placeholder`)}
|
|
||||||
label="Placeholder"
|
|
||||||
name={`fields.${index}.placeholder`}
|
|
||||||
type="text"
|
|
||||||
placeholder="Enter Placeholder"
|
|
||||||
/>
|
|
||||||
<Checkbox
|
|
||||||
{...register(`fields.${index}.required`)}
|
|
||||||
label="Required"
|
|
||||||
minimal
|
|
||||||
withIcon="check"
|
|
||||||
withBg
|
|
||||||
name={`fields.${index}.required`}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
</ShowcaseSection>
|
||||||
</ShowcaseSection>
|
<ShowcaseSection title="Form Fields" className="flex flex-col gap-5">
|
||||||
</form>
|
{fields.map((field, index) => (
|
||||||
);
|
<div
|
||||||
});
|
key={field.id}
|
||||||
|
className="grid grid-cols-1 items-center gap-4 sm:grid-cols-2"
|
||||||
|
>
|
||||||
|
<InputGroup
|
||||||
|
{...register(`fields.${index}.name`)}
|
||||||
|
label="Field Name"
|
||||||
|
name={`fields.${index}.name`}
|
||||||
|
type="text"
|
||||||
|
placeholder="Field Name"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<InputGroup
|
||||||
|
{...register(`fields.${index}.label`)}
|
||||||
|
label="Label"
|
||||||
|
name={`fields.${index}.label`}
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter Label"
|
||||||
|
/>
|
||||||
|
<InputGroup
|
||||||
|
{...register(`fields.${index}.placeholder`)}
|
||||||
|
label="Placeholder"
|
||||||
|
name={`fields.${index}.placeholder`}
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter Placeholder"
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
{...register(`fields.${index}.required`)}
|
||||||
|
label="Required"
|
||||||
|
minimal
|
||||||
|
withIcon="check"
|
||||||
|
withBg
|
||||||
|
name={`fields.${index}.required`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</ShowcaseSection>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
ContactsStep.displayName = "ContactsStep";
|
ContactsStep.displayName = "ContactsStep";
|
||||||
|
|
||||||
|
|||||||
@@ -5,39 +5,45 @@ import useFeaturesStepPresenter, {
|
|||||||
IFeaturesStepFields,
|
IFeaturesStepFields,
|
||||||
} from "./useFeaturesStepPresenter";
|
} from "./useFeaturesStepPresenter";
|
||||||
|
|
||||||
const FeaturesStep = forwardRef((props, ref) => {
|
interface FeaturesStepProps {
|
||||||
const {
|
initialData?: IFeaturesStepFields;
|
||||||
errors,
|
}
|
||||||
handleSubmit,
|
|
||||||
onSubmit,
|
|
||||||
register,
|
|
||||||
fields,
|
|
||||||
append,
|
|
||||||
remove,
|
|
||||||
control,
|
|
||||||
getValues,
|
|
||||||
} = useFeaturesStepPresenter();
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
const FeaturesStep = forwardRef<unknown, FeaturesStepProps>(
|
||||||
getData: () => getValues(),
|
({ initialData }, ref) => {
|
||||||
}));
|
const {
|
||||||
|
errors,
|
||||||
|
handleSubmit,
|
||||||
|
onSubmit,
|
||||||
|
register,
|
||||||
|
fields,
|
||||||
|
append,
|
||||||
|
remove,
|
||||||
|
control,
|
||||||
|
getValues,
|
||||||
|
} = useFeaturesStepPresenter(initialData);
|
||||||
|
|
||||||
return (
|
useImperativeHandle(ref, () => ({
|
||||||
<SectionStep<IFeaturesStepFields>
|
getData: () => getValues(),
|
||||||
title="Features"
|
}));
|
||||||
fields={fields}
|
|
||||||
handleSubmit={handleSubmit}
|
return (
|
||||||
onSubmit={onSubmit}
|
<SectionStep<IFeaturesStepFields>
|
||||||
register={register}
|
title="Features"
|
||||||
errors={errors}
|
fields={fields}
|
||||||
append={append}
|
handleSubmit={handleSubmit}
|
||||||
remove={remove}
|
onSubmit={onSubmit}
|
||||||
control={control}
|
register={register}
|
||||||
fieldName="cards"
|
errors={errors}
|
||||||
defaultValues={{ icon: "", title: "", description: "" }}
|
append={append}
|
||||||
/>
|
remove={remove}
|
||||||
);
|
control={control}
|
||||||
});
|
fieldName="cards"
|
||||||
|
defaultValues={{ icon: "", title: "", description: "" }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
FeaturesStep.displayName = "FeaturesStep";
|
FeaturesStep.displayName = "FeaturesStep";
|
||||||
|
|
||||||
|
|||||||
@@ -6,73 +6,79 @@ import { FormErrorMessages } from "@/constants/Texts";
|
|||||||
import { forwardRef, useImperativeHandle } from "react";
|
import { forwardRef, useImperativeHandle } from "react";
|
||||||
import useFooterStepPresenter from "./useFooterStepPresenter";
|
import useFooterStepPresenter from "./useFooterStepPresenter";
|
||||||
|
|
||||||
const FooterStep = forwardRef((props, ref) => {
|
interface FooterStepProps {
|
||||||
const { errors, handleSubmit, onSubmit, register, getValues } =
|
initialData?: any;
|
||||||
useFooterStepPresenter();
|
}
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
const FooterStep = forwardRef<unknown, FooterStepProps>(
|
||||||
getData: () => getValues(),
|
({ initialData }, ref) => {
|
||||||
}));
|
const { errors, handleSubmit, onSubmit, register, getValues } =
|
||||||
|
useFooterStepPresenter(initialData);
|
||||||
|
|
||||||
return (
|
useImperativeHandle(ref, () => ({
|
||||||
<form
|
getData: () => getValues(),
|
||||||
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7"
|
}));
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
|
||||||
>
|
return (
|
||||||
<ShowcaseSection title="Footer Section" className="flex flex-col gap-5">
|
<form
|
||||||
<div className="flex flex-col gap-9">
|
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7"
|
||||||
<InputGroup
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
{...register("email", {
|
>
|
||||||
required: { message: FormErrorMessages.required, value: true },
|
<ShowcaseSection title="Footer Section" className="flex flex-col gap-5">
|
||||||
pattern: {
|
<div className="flex flex-col gap-9">
|
||||||
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
<InputGroup
|
||||||
message: "Invalid email format",
|
{...register("email", {
|
||||||
},
|
required: { message: FormErrorMessages.required, value: true },
|
||||||
})}
|
pattern: {
|
||||||
label="Email"
|
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
||||||
name="email"
|
message: "Invalid email format",
|
||||||
required
|
},
|
||||||
type="email"
|
})}
|
||||||
placeholder="Enter Email"
|
label="Email"
|
||||||
/>
|
name="email"
|
||||||
{errors.email && (
|
required
|
||||||
<p className="mt-1 text-sm text-red-500">
|
type="email"
|
||||||
{errors.email.message as string}
|
placeholder="Enter Email"
|
||||||
</p>
|
/>
|
||||||
)}
|
{errors.email && (
|
||||||
<InputGroup
|
<p className="mt-1 text-sm text-red-500">
|
||||||
{...register("phone")}
|
{errors.email.message as string}
|
||||||
label="Phone Number"
|
</p>
|
||||||
name="phone"
|
)}
|
||||||
type="text"
|
<InputGroup
|
||||||
placeholder="Enter Phone Number"
|
{...register("phone")}
|
||||||
/>
|
label="Phone Number"
|
||||||
<InputGroup
|
name="phone"
|
||||||
{...register("location")}
|
type="text"
|
||||||
label="Location"
|
placeholder="Enter Phone Number"
|
||||||
name="location"
|
/>
|
||||||
type="text"
|
<InputGroup
|
||||||
placeholder="Enter Location"
|
{...register("location")}
|
||||||
/>
|
label="Location"
|
||||||
<TextAreaGroup
|
name="location"
|
||||||
label="Tagline"
|
type="text"
|
||||||
{...register("tagline")}
|
placeholder="Enter Location"
|
||||||
name="tagline"
|
/>
|
||||||
placeholder="Enter Tagline"
|
<TextAreaGroup
|
||||||
/>
|
label="Tagline"
|
||||||
<InputGroup
|
{...register("tagline")}
|
||||||
{...register("copyright")}
|
name="tagline"
|
||||||
label="Copyright"
|
placeholder="Enter Tagline"
|
||||||
name="copyright"
|
/>
|
||||||
type="text"
|
<InputGroup
|
||||||
placeholder="Enter Copyright Text"
|
{...register("copyright")}
|
||||||
/>
|
label="Copyright"
|
||||||
</div>
|
name="copyright"
|
||||||
</ShowcaseSection>
|
type="text"
|
||||||
</form>
|
placeholder="Enter Copyright Text"
|
||||||
);
|
/>
|
||||||
});
|
</div>
|
||||||
|
</ShowcaseSection>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
FooterStep.displayName = "FooterStep";
|
FooterStep.displayName = "FooterStep";
|
||||||
|
|
||||||
export default FooterStep;
|
export default FooterStep;
|
||||||
|
|||||||
@@ -7,8 +7,13 @@ import { FormErrorMessages } from "@/constants/Texts";
|
|||||||
import { forwardRef, useImperativeHandle } from "react";
|
import { forwardRef, useImperativeHandle } from "react";
|
||||||
import useHeroStepPresenter from "./useHeroStepPresenter";
|
import useHeroStepPresenter from "./useHeroStepPresenter";
|
||||||
|
|
||||||
const HeroStep = forwardRef((props, ref) => {
|
interface HeroStepProps {
|
||||||
const { errors, handleSubmit, onSubmit, register, getValues } = useHeroStepPresenter();
|
initialData?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HeroStep = forwardRef<unknown, HeroStepProps>(({ initialData }, ref) => {
|
||||||
|
const { errors, handleSubmit, onSubmit, register, getValues } =
|
||||||
|
useHeroStepPresenter(initialData);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
getData: () => getValues(),
|
getData: () => getValues(),
|
||||||
@@ -16,7 +21,7 @@ const HeroStep = forwardRef((props, ref) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className=" items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7 sm:grid-cols-2"
|
className="items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7 sm:grid-cols-2"
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col gap-9">
|
<div className="flex flex-col gap-9">
|
||||||
@@ -114,7 +119,10 @@ const HeroStep = forwardRef((props, ref) => {
|
|||||||
<InputGroup
|
<InputGroup
|
||||||
{...register("gifFile", {
|
{...register("gifFile", {
|
||||||
required: { message: FormErrorMessages.required, value: true },
|
required: { message: FormErrorMessages.required, value: true },
|
||||||
pattern: {message: FormErrorMessages.invalidPattern, value: REGEX.URL}
|
pattern: {
|
||||||
|
message: FormErrorMessages.invalidPattern,
|
||||||
|
value: REGEX.URL,
|
||||||
|
},
|
||||||
})}
|
})}
|
||||||
label="GIF File URL"
|
label="GIF File URL"
|
||||||
name="gifFile"
|
name="gifFile"
|
||||||
|
|||||||
@@ -0,0 +1,371 @@
|
|||||||
|
"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 { BreadcrumbItem } from "@/types/shared";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import BenefitsStep from "./BenefitsStep";
|
||||||
|
import ChallengesStep from "./ChallengesStep";
|
||||||
|
import ChartStep from "./ChartStep";
|
||||||
|
import ContactsStep from "./ContactsStep";
|
||||||
|
import FeaturesStep from "./FeaturesStep";
|
||||||
|
import FooterStep from "./FooterStep";
|
||||||
|
import HeroStep from "./HeroStep";
|
||||||
|
|
||||||
|
interface IPageTypeFields {
|
||||||
|
type: "company" | "organization";
|
||||||
|
language?: string;
|
||||||
|
company_name?: string;
|
||||||
|
country?: string;
|
||||||
|
key: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MarketingFormProps {
|
||||||
|
breadcrumbItems: BreadcrumbItem[];
|
||||||
|
title: string;
|
||||||
|
onSubmit: (data: any) => void;
|
||||||
|
isPending: boolean;
|
||||||
|
initialData?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MarketingForm = ({
|
||||||
|
breadcrumbItems,
|
||||||
|
title,
|
||||||
|
onSubmit,
|
||||||
|
isPending,
|
||||||
|
initialData,
|
||||||
|
}: MarketingFormProps) => {
|
||||||
|
const [step, setStep] = useState(0);
|
||||||
|
const [formData, setFormData] = useState<any>(initialData || {});
|
||||||
|
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,
|
||||||
|
reset,
|
||||||
|
} = useForm<IPageTypeFields>({
|
||||||
|
defaultValues: {
|
||||||
|
type: "company",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (initialData) {
|
||||||
|
const formValues = {
|
||||||
|
type: initialData.type || "company",
|
||||||
|
language: initialData.language || "",
|
||||||
|
company_name: initialData.company_name || "",
|
||||||
|
country: initialData.country || "",
|
||||||
|
key: initialData.key || "",
|
||||||
|
};
|
||||||
|
reset(formValues);
|
||||||
|
setFormData(initialData);
|
||||||
|
}
|
||||||
|
}, [initialData, reset]);
|
||||||
|
|
||||||
|
const pageType = watchPageType("type");
|
||||||
|
const isCompany = pageType === "company";
|
||||||
|
|
||||||
|
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 () => {
|
||||||
|
await saveCurrentStepData();
|
||||||
|
|
||||||
|
const refs = [
|
||||||
|
heroRef,
|
||||||
|
chartRef,
|
||||||
|
featuresRef,
|
||||||
|
challengesRef,
|
||||||
|
benefitsRef,
|
||||||
|
contactsRef,
|
||||||
|
footerRef,
|
||||||
|
];
|
||||||
|
|
||||||
|
const allData: any = { ...formData };
|
||||||
|
|
||||||
|
const keys = [
|
||||||
|
"hero",
|
||||||
|
"chart",
|
||||||
|
"features",
|
||||||
|
"challenges",
|
||||||
|
"advantages",
|
||||||
|
"contact",
|
||||||
|
"footer",
|
||||||
|
];
|
||||||
|
|
||||||
|
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,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
onSubmit(finalData);
|
||||||
|
};
|
||||||
|
|
||||||
|
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={title}>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<div style={{ display: step === 0 ? "block" : "none" }}>
|
||||||
|
<HeroStep ref={heroRef} initialData={formData.hero} />
|
||||||
|
</div>
|
||||||
|
<div style={{ display: step === 1 ? "block" : "none" }}>
|
||||||
|
<ChartStep ref={chartRef} initialData={formData.chart} />
|
||||||
|
</div>
|
||||||
|
<div style={{ display: step === 2 ? "block" : "none" }}>
|
||||||
|
<FeaturesStep ref={featuresRef} initialData={formData.features} />
|
||||||
|
</div>
|
||||||
|
<div style={{ display: step === 3 ? "block" : "none" }}>
|
||||||
|
<ChallengesStep
|
||||||
|
ref={challengesRef}
|
||||||
|
initialData={formData.challenges}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: step === 4 ? "block" : "none" }}>
|
||||||
|
<BenefitsStep ref={benefitsRef} initialData={formData.advantages} />
|
||||||
|
</div>
|
||||||
|
<div style={{ display: step === 5 ? "block" : "none" }}>
|
||||||
|
<ContactsStep ref={contactsRef} initialData={formData.contact} />
|
||||||
|
</div>
|
||||||
|
<div style={{ display: step === 6 ? "block" : "none" }}>
|
||||||
|
<FooterStep ref={footerRef} initialData={formData.footer} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Stepper
|
||||||
|
steps={steps}
|
||||||
|
currentStep={step}
|
||||||
|
onStepChange={handleStepChange}
|
||||||
|
onSubmit={handleSubmitAll}
|
||||||
|
isSubmitting={isPending}
|
||||||
|
/>
|
||||||
|
</ShowcaseSection>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MarketingForm;
|
||||||
@@ -11,7 +11,7 @@ export interface IBenefitsStepFields {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const useBenefitsStepPresenter = () => {
|
const useBenefitsStepPresenter = (initialData?: IBenefitsStepFields) => {
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -20,7 +20,7 @@ const useBenefitsStepPresenter = () => {
|
|||||||
formState: { errors },
|
formState: { errors },
|
||||||
getValues,
|
getValues,
|
||||||
} = useForm<IBenefitsStepFields>({
|
} = useForm<IBenefitsStepFields>({
|
||||||
defaultValues: {
|
defaultValues: initialData || {
|
||||||
cards: [{ icon: "", title: "", description: "" }],
|
cards: [{ icon: "", title: "", description: "" }],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export interface IChallengesStepFields {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const useChallengesStepPresenter = () => {
|
const useChallengesStepPresenter = (initialData?: IChallengesStepFields) => {
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -20,7 +20,7 @@ const useChallengesStepPresenter = () => {
|
|||||||
formState: { errors },
|
formState: { errors },
|
||||||
getValues,
|
getValues,
|
||||||
} = useForm<IChallengesStepFields>({
|
} = useForm<IChallengesStepFields>({
|
||||||
defaultValues: {
|
defaultValues: initialData || {
|
||||||
cards: [{ icon: "", title: "", description: "" }],
|
cards: [{ icon: "", title: "", description: "" }],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export interface IChartStepFields {
|
|||||||
data: { key: string; value: number }[];
|
data: { key: string; value: number }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const useChartStepPresenter = () => {
|
const useChartStepPresenter = (initialData?: IChartStepFields) => {
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -16,7 +16,7 @@ const useChartStepPresenter = () => {
|
|||||||
formState: { errors },
|
formState: { errors },
|
||||||
getValues,
|
getValues,
|
||||||
} = useForm<IChartStepFields>({
|
} = useForm<IChartStepFields>({
|
||||||
defaultValues: {
|
defaultValues: initialData || {
|
||||||
data: [{ key: "", value: 0 }],
|
data: [{ key: "", value: 0 }],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export interface IContactsStepFields {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const useContactsStepPresenter = () => {
|
const useContactsStepPresenter = (initialData?: IContactsStepFields) => {
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -21,7 +21,7 @@ const useContactsStepPresenter = () => {
|
|||||||
getValues,
|
getValues,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm<IContactsStepFields>({
|
} = useForm<IContactsStepFields>({
|
||||||
defaultValues: {
|
defaultValues: initialData || {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "first_name",
|
name: "first_name",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export interface IFeaturesStepFields {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const useFeaturesStepPresenter = () => {
|
const useFeaturesStepPresenter = (initialData?: IFeaturesStepFields) => {
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -20,7 +20,7 @@ const useFeaturesStepPresenter = () => {
|
|||||||
formState: { errors },
|
formState: { errors },
|
||||||
getValues,
|
getValues,
|
||||||
} = useForm<IFeaturesStepFields>({
|
} = useForm<IFeaturesStepFields>({
|
||||||
defaultValues: {
|
defaultValues: initialData || {
|
||||||
cards: [{ icon: "", title: "", description: "" }],
|
cards: [{ icon: "", title: "", description: "" }],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,13 +8,15 @@ interface FooterFormValues {
|
|||||||
copyright: string;
|
copyright: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useFooterStepPresenter = () => {
|
const useFooterStepPresenter = (initialData?: FooterFormValues) => {
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
getValues,
|
getValues,
|
||||||
} = useForm<FooterFormValues>();
|
} = useForm<FooterFormValues>({
|
||||||
|
defaultValues: initialData,
|
||||||
|
});
|
||||||
|
|
||||||
const onSubmit = (data: FooterFormValues) => {
|
const onSubmit = (data: FooterFormValues) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
@@ -34,4 +36,4 @@ const useFooterStepPresenter = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useFooterStepPresenter;
|
export default useFooterStepPresenter;
|
||||||
|
|||||||
@@ -9,13 +9,15 @@ export interface IHeroStepFields {
|
|||||||
gifFile: string;
|
gifFile: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useHeroStepPresenter = () => {
|
const useHeroStepPresenter = (initialData?: IHeroStepFields) => {
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
getValues,
|
getValues,
|
||||||
} = useForm<IHeroStepFields>();
|
} = useForm<IHeroStepFields>({
|
||||||
|
defaultValues: initialData,
|
||||||
|
});
|
||||||
|
|
||||||
const onSubmit = (data: IHeroStepFields) => {
|
const onSubmit = (data: IHeroStepFields) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|||||||
@@ -1,58 +1,9 @@
|
|||||||
"use client";
|
"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 { useCreateCms } from "@/hooks/queries/useCmsQueries";
|
||||||
import { BreadcrumbItem } from "@/types/shared";
|
import { BreadcrumbItem } from "@/types/shared";
|
||||||
import { useRef, useState } from "react";
|
import MarketingForm from "../_components/MarketingForm";
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Marketing = () => {
|
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 { mutate: createCms, isPending } = useCreateCms();
|
||||||
|
|
||||||
const breadcrumbItems: BreadcrumbItem[] = [
|
const breadcrumbItems: BreadcrumbItem[] = [
|
||||||
@@ -70,101 +21,8 @@ const Marketing = () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const saveCurrentStepData = async () => {
|
const handleSubmit = (data: any) => {
|
||||||
const refs = [
|
createCms(data, {
|
||||||
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, {
|
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
console.log("CMS created successfully");
|
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 (
|
return (
|
||||||
<>
|
<MarketingForm
|
||||||
<Breadcrumb items={breadcrumbItems} />
|
breadcrumbItems={breadcrumbItems}
|
||||||
<ShowcaseSection title="Create Marketing page">
|
title="Create Marketing page"
|
||||||
{/* Page Type Selection */}
|
onSubmit={handleSubmit}
|
||||||
<div className="mb-6 rounded-xl bg-gray-1 p-6 dark:bg-gray-7">
|
isPending={isPending}
|
||||||
<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>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
|
"use client";
|
||||||
import Loading from "@/app/loading";
|
import Loading from "@/app/loading";
|
||||||
import Breadcrumb from "@/components/Breadcrumbs/Breadcrumb";
|
import { useGetCmsDetails, useUpdateCms } from "@/hooks/queries/useCmsQueries";
|
||||||
import { useGetCmsDetails } from "@/hooks/queries/useCmsQueries";
|
|
||||||
import { BreadcrumbItem } from "@/types/shared";
|
import { BreadcrumbItem } from "@/types/shared";
|
||||||
import { use } from "react";
|
import { use } from "react";
|
||||||
|
import MarketingForm from "../../_components/MarketingForm";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
params: Promise<{ id: string }>;
|
params: Promise<{ id: string }>;
|
||||||
}
|
}
|
||||||
const EditMarketingPage = async ({ params }: IProps) => {
|
|
||||||
|
const EditMarketingPage = ({ params }: IProps) => {
|
||||||
const { id } = use(params);
|
const { id } = use(params);
|
||||||
const { data, isPending } = useGetCmsDetails(id);
|
const { data, isPending: isLoading } = useGetCmsDetails(id);
|
||||||
|
const { mutate: updateCms, isPending: isUpdating } = useUpdateCms(id);
|
||||||
|
|
||||||
const breadcrumbItems: BreadcrumbItem[] = [
|
const breadcrumbItems: BreadcrumbItem[] = [
|
||||||
{
|
{
|
||||||
href: "/",
|
href: "/",
|
||||||
@@ -24,10 +28,29 @@ const EditMarketingPage = async ({ params }: IProps) => {
|
|||||||
name: "Edit Marketing",
|
name: "Edit Marketing",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (isPending) return <Loading />;
|
|
||||||
|
const handleSubmit = (formData: any) => {
|
||||||
|
updateCms(formData, {
|
||||||
|
onSuccess: () => {
|
||||||
|
console.log("CMS updated successfully");
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.error("Error updating CMS:", error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isLoading || !data?.data) return <Loading />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<MarketingForm
|
||||||
<Breadcrumb items={breadcrumbItems} />
|
breadcrumbItems={breadcrumbItems}
|
||||||
</>
|
title="Edit Marketing page"
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
isPending={isUpdating}
|
||||||
|
initialData={data.data}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default EditMarketingPage;
|
||||||
|
|||||||
@@ -56,3 +56,25 @@ export const useDeleteCms = (successCallback?: () => void) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
export const useUpdateCms = (id: string) => {
|
||||||
|
const router = useRouter();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const mutationKey = useMemo(
|
||||||
|
() => [API_ENDPOINTS.CMS.BASE(id), "Update cms"],
|
||||||
|
[id],
|
||||||
|
);
|
||||||
|
return useMutation({
|
||||||
|
mutationKey,
|
||||||
|
mutationFn: (data: any) => cmsService.updateCms({ id, data }),
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success("CMS updated successfully");
|
||||||
|
router.push("/marketing");
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: [API_ENDPOINTS.CMS.BASE()],
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: [API_ENDPOINTS.CMS.BASE(id)],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import api from "../axios";
|
import api from "../axios";
|
||||||
import { API_ENDPOINTS } from "../endpoints";
|
import { API_ENDPOINTS } from "../endpoints";
|
||||||
import { ApiResponse } from "../types";
|
import { ApiResponse } from "../types";
|
||||||
import { TCmsListResponse } from "../types/TCms";
|
import { TCms, TCmsListResponse } from "../types/TCms";
|
||||||
|
|
||||||
export const cmsService = {
|
export const cmsService = {
|
||||||
getCms: async (): Promise<ApiResponse<TCmsListResponse>> => {
|
getCms: async (): Promise<ApiResponse<TCmsListResponse>> => {
|
||||||
@@ -36,4 +36,18 @@ export const cmsService = {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
updateCms: async ({
|
||||||
|
id,
|
||||||
|
data,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
data: any;
|
||||||
|
}): Promise<{ data: TCms; message: string }> => {
|
||||||
|
try {
|
||||||
|
return (await api.put(API_ENDPOINTS.CMS.BASE(id), data)).data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error Caught in CMS Service => Update cms", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user