feat(marketing): Refactor marketing wizard steps and add data collection methods
- Moved all marketing wizard step components to `create/_components` directory - Added `collectData` static method to each step component for data retrieval - Reorganized file structure to improve component modularity - Prepared steps for dynamic data collection in wizard workflow - Added VSCode settings file for project configuration - Introduced new CMS-related components and services - Updated API endpoints and added new query hooks
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
"use client";
|
||||
import SectionStep from "./SectionStep";
|
||||
import useBenefitsStepPresenter, {
|
||||
IBenefitsStepFields,
|
||||
} from "./useBenefitsStepPresenter";
|
||||
|
||||
const BenefitsStep = () => {
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
onSubmit,
|
||||
register,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
} = useBenefitsStepPresenter();
|
||||
return (
|
||||
<SectionStep<IBenefitsStepFields>
|
||||
title="Benefits"
|
||||
fields={fields}
|
||||
handleSubmit={handleSubmit}
|
||||
onSubmit={onSubmit}
|
||||
register={register}
|
||||
errors={errors}
|
||||
append={append}
|
||||
remove={remove}
|
||||
control={control}
|
||||
fieldName="benefits"
|
||||
defaultValues={{ icon: "", title: "", description: "" }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default BenefitsStep;
|
||||
@@ -1,35 +0,0 @@
|
||||
"use client";
|
||||
import SectionStep from "./SectionStep";
|
||||
import useChallengesStepPresenter, {
|
||||
IChallengesStepFields,
|
||||
} from "./useChallengesStepPresenter";
|
||||
|
||||
const ChallengesStep = () => {
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
onSubmit,
|
||||
register,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
} = useChallengesStepPresenter();
|
||||
return (
|
||||
<SectionStep<IChallengesStepFields>
|
||||
title="Challenges"
|
||||
fields={fields}
|
||||
handleSubmit={handleSubmit}
|
||||
onSubmit={onSubmit}
|
||||
register={register}
|
||||
errors={errors}
|
||||
append={append}
|
||||
remove={remove}
|
||||
control={control}
|
||||
fieldName="challenges"
|
||||
defaultValues={{ icon: "", title: "", description: "" }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChallengesStep;
|
||||
@@ -1,101 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useIsMobile } from "@/hooks/use-mobile";
|
||||
import type { ApexOptions } from "apexcharts";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
type PropsType = {
|
||||
series: { x: string; y: number }[];
|
||||
title: string;
|
||||
};
|
||||
|
||||
const Chart = dynamic(() => import("react-apexcharts"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export function ChartPreview({ series, title }: PropsType) {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const options: ApexOptions = {
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
colors: ["#5750F1"],
|
||||
chart: {
|
||||
height: 310,
|
||||
type: "area",
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
fontFamily: "inherit",
|
||||
},
|
||||
fill: {
|
||||
gradient: {
|
||||
opacityFrom: 0.55,
|
||||
opacityTo: 0,
|
||||
},
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1024,
|
||||
options: {
|
||||
chart: {
|
||||
height: 300,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1366,
|
||||
options: {
|
||||
chart: {
|
||||
height: 320,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
stroke: {
|
||||
curve: "smooth",
|
||||
width: isMobile ? 2 : 3,
|
||||
},
|
||||
grid: {
|
||||
strokeDashArray: 5,
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
tooltip: {
|
||||
marker: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="-ml-4 -mr-5 h-[310px]">
|
||||
<Chart
|
||||
options={options}
|
||||
series={[
|
||||
{
|
||||
name: title,
|
||||
data: series,
|
||||
},
|
||||
]}
|
||||
type="area"
|
||||
height={310}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
"use client";
|
||||
import InputGroup from "@/components/FormElements/InputGroup";
|
||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||
|
||||
import { TrashIcon } from "@/assets/icons";
|
||||
import FormFooter from "@/components/ui/FormFooter";
|
||||
import { FormErrorMessages } from "@/constants/Texts";
|
||||
import { ChartPreview } from "./ChartPreview";
|
||||
import useChartStepPresenter from "./useChartStepPresenter";
|
||||
|
||||
const ChartStep = () => {
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
onSubmit,
|
||||
register,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
watch,
|
||||
} = useChartStepPresenter();
|
||||
|
||||
const chartTitle = watch("chart_title");
|
||||
const chartPoints = watch("chart_points");
|
||||
|
||||
return (
|
||||
<form
|
||||
className="items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7 sm:grid-cols-2"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<div className="flex flex-col gap-9">
|
||||
<ShowcaseSection
|
||||
title="Chart Information"
|
||||
className="flex flex-col gap-5"
|
||||
>
|
||||
<InputGroup
|
||||
{...register("chart_title", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
})}
|
||||
label="Chart Title"
|
||||
name="chart_title"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Chart Title"
|
||||
/>
|
||||
{errors.chart_title && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.chart_title.message}
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("lost_amount", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
label="Lost Amount"
|
||||
name="lost_amount"
|
||||
required
|
||||
type="number"
|
||||
placeholder="Enter Lost Amount"
|
||||
/>
|
||||
{errors.lost_amount && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.lost_amount.message}
|
||||
</p>
|
||||
)}
|
||||
</ShowcaseSection>
|
||||
<ShowcaseSection title="Chart Preview">
|
||||
<ChartPreview
|
||||
series={chartPoints.filter((p) => p.x && p.y)}
|
||||
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(`chart_points.${index}.x`, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
})}
|
||||
label="X-axis"
|
||||
name={`chart_points.${index}.x`}
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter X-axis value"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register(`chart_points.${index}.y`, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
label="Y-axis"
|
||||
name={`chart_points.${index}.y`}
|
||||
required
|
||||
type="number"
|
||||
placeholder="Enter Y-axis 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({ x: "", y: 0 })}
|
||||
>
|
||||
Add point
|
||||
</button>
|
||||
</ShowcaseSection>
|
||||
</div>
|
||||
<div className="flex flex-col gap-9"></div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChartStep;
|
||||
@@ -1,92 +0,0 @@
|
||||
"use client";
|
||||
import { Checkbox } from "@/components/FormElements/checkbox";
|
||||
import InputGroup from "@/components/FormElements/InputGroup";
|
||||
import { TextAreaGroup } from "@/components/FormElements/InputGroup/text-area";
|
||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||
import { FormErrorMessages } from "@/constants/Texts";
|
||||
import useContactsStepPresenter from "./useContactsStepPresenter";
|
||||
|
||||
const ContactsStep = () => {
|
||||
const { errors, handleSubmit, onSubmit, register, fields } =
|
||||
useContactsStepPresenter();
|
||||
return (
|
||||
<form
|
||||
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<ShowcaseSection title="Contacts Section" className="flex flex-col gap-5">
|
||||
<div className="flex flex-col gap-9">
|
||||
<InputGroup
|
||||
{...register("title", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
})}
|
||||
label="Title"
|
||||
name="title"
|
||||
required
|
||||
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("submit_button_title")}
|
||||
label="Submit Button Title"
|
||||
name="submit_button_title"
|
||||
type="text"
|
||||
placeholder="Enter Submit Button Title"
|
||||
/>
|
||||
</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
|
||||
{...register(`fields.${index}.field_name`)}
|
||||
label="Field Name"
|
||||
name={`fields.${index}.field_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>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContactsStep;
|
||||
@@ -1,35 +0,0 @@
|
||||
"use client";
|
||||
import SectionStep from "./SectionStep";
|
||||
import useFeaturesStepPresenter, {
|
||||
IFeaturesStepFields,
|
||||
} from "./useFeaturesStepPresenter";
|
||||
|
||||
const FeaturesStep = () => {
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
onSubmit,
|
||||
register,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
} = useFeaturesStepPresenter();
|
||||
return (
|
||||
<SectionStep<IFeaturesStepFields>
|
||||
title="Features"
|
||||
fields={fields}
|
||||
handleSubmit={handleSubmit}
|
||||
onSubmit={onSubmit}
|
||||
register={register}
|
||||
errors={errors}
|
||||
append={append}
|
||||
remove={remove}
|
||||
control={control}
|
||||
fieldName="features"
|
||||
defaultValues={{ icon: "", title: "", description: "" }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default FeaturesStep;
|
||||
@@ -1,72 +0,0 @@
|
||||
"use client";
|
||||
import InputGroup from "@/components/FormElements/InputGroup";
|
||||
import { TextAreaGroup } from "@/components/FormElements/InputGroup/text-area";
|
||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||
import { FormErrorMessages } from "@/constants/Texts";
|
||||
import useFooterStepPresenter from "./useFooterStepPresenter";
|
||||
|
||||
|
||||
const FooterStep = () => {
|
||||
const { errors, handleSubmit, onSubmit, register } =
|
||||
useFooterStepPresenter();
|
||||
|
||||
return (
|
||||
<form
|
||||
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<ShowcaseSection title="Footer Section" className="flex flex-col gap-5">
|
||||
<div className="flex flex-col gap-9">
|
||||
<InputGroup
|
||||
{...register("email", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
pattern: {
|
||||
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
||||
message: "Invalid email format",
|
||||
},
|
||||
})}
|
||||
label="Email"
|
||||
name="email"
|
||||
required
|
||||
type="email"
|
||||
placeholder="Enter Email"
|
||||
/>
|
||||
{errors.email && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.email.message as string}
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("phoneNumber")}
|
||||
label="Phone Number"
|
||||
name="phoneNumber"
|
||||
type="text"
|
||||
placeholder="Enter Phone Number"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register("address")}
|
||||
label="Address"
|
||||
name="address"
|
||||
type="text"
|
||||
placeholder="Enter Address"
|
||||
/>
|
||||
<TextAreaGroup
|
||||
label="Tagline"
|
||||
{...register("tagline")}
|
||||
name="tagline"
|
||||
placeholder="Enter Tagline"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register("copyright")}
|
||||
label="Copyright"
|
||||
name="copyright"
|
||||
type="text"
|
||||
placeholder="Enter Copyright Text"
|
||||
/>
|
||||
</div>
|
||||
</ShowcaseSection>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default FooterStep;
|
||||
@@ -1,134 +0,0 @@
|
||||
"use client";
|
||||
import InputGroup from "@/components/FormElements/InputGroup";
|
||||
import { TextAreaGroup } from "@/components/FormElements/InputGroup/text-area";
|
||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||
import { FormErrorMessages } from "@/constants/Texts";
|
||||
import useHeroStepPresenter from "./useHeroStepPresenter";
|
||||
|
||||
const HeroStep = () => {
|
||||
const { errors, handleSubmit, onSubmit, register } = useHeroStepPresenter();
|
||||
return (
|
||||
<form
|
||||
className=" items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7 sm:grid-cols-2"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<div className="flex flex-col gap-9">
|
||||
<ShowcaseSection
|
||||
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 },
|
||||
minLength: {
|
||||
value: 2,
|
||||
message: FormErrorMessages.minLength(2),
|
||||
},
|
||||
maxLength: {
|
||||
value: 200,
|
||||
message: FormErrorMessages.maxLength(200),
|
||||
},
|
||||
})}
|
||||
label="Title"
|
||||
name="title"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
{errors.title && (
|
||||
<p className="mt-1 text-sm text-red-500">{errors.title.message}</p>
|
||||
)}
|
||||
<TextAreaGroup
|
||||
label="Description"
|
||||
{...register("description", {
|
||||
minLength: {
|
||||
value: 10,
|
||||
message: FormErrorMessages.minLength(10),
|
||||
},
|
||||
maxLength: {
|
||||
value: 1000,
|
||||
message: FormErrorMessages.maxLength(1000),
|
||||
},
|
||||
})}
|
||||
name="description"
|
||||
placeholder="Enter Description"
|
||||
/>
|
||||
{errors.description && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.description.message}
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("button_text", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
minLength: {
|
||||
value: 2,
|
||||
message: FormErrorMessages.minLength(2),
|
||||
},
|
||||
maxLength: {
|
||||
value: 50,
|
||||
message: FormErrorMessages.maxLength(50),
|
||||
},
|
||||
})}
|
||||
label="Button Text"
|
||||
name="button_text"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Button Text"
|
||||
/>
|
||||
{errors.button_text && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.button_text.message}
|
||||
</p>
|
||||
)}
|
||||
<InputGroup
|
||||
{...register("button_link", {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
minLength: {
|
||||
value: 2,
|
||||
message: FormErrorMessages.minLength(2),
|
||||
},
|
||||
maxLength: {
|
||||
value: 200,
|
||||
message: FormErrorMessages.maxLength(200),
|
||||
},
|
||||
})}
|
||||
label="Button Link"
|
||||
name="button_link"
|
||||
required
|
||||
type="url"
|
||||
placeholder="Enter Button Link"
|
||||
/>
|
||||
{errors.button_link && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.button_link.message}
|
||||
</p>
|
||||
)}
|
||||
</ShowcaseSection>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeroStep;
|
||||
@@ -1,137 +0,0 @@
|
||||
"use client";
|
||||
import { TrashIcon } from "@/assets/icons";
|
||||
import InputGroup from "@/components/FormElements/InputGroup";
|
||||
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,
|
||||
} from "react-hook-form";
|
||||
|
||||
interface IProps<T extends FieldValues> {
|
||||
title: string;
|
||||
fields: any[];
|
||||
handleSubmit: UseFormHandleSubmit<T>;
|
||||
onSubmit: (data: T) => void;
|
||||
register: UseFormRegister<T>;
|
||||
errors: FieldErrors<T>;
|
||||
append: UseFieldArrayAppend<T, any>;
|
||||
remove: UseFieldArrayRemove;
|
||||
control: Control<T, any>;
|
||||
fieldName: string;
|
||||
defaultValues: any;
|
||||
}
|
||||
|
||||
const SectionStep = <T extends FieldValues>({
|
||||
title,
|
||||
fields,
|
||||
handleSubmit,
|
||||
onSubmit,
|
||||
register,
|
||||
errors,
|
||||
append,
|
||||
remove,
|
||||
fieldName,
|
||||
defaultValues,
|
||||
}: IProps<T>) => {
|
||||
return (
|
||||
<form
|
||||
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<div className="flex flex-col gap-9">
|
||||
<ShowcaseSection
|
||||
title={`${title} Section`}
|
||||
className="flex flex-col gap-5"
|
||||
>
|
||||
<InputGroup
|
||||
{...register("section_title" as Path<T>, {
|
||||
required: { message: FormErrorMessages.required, value: true },
|
||||
})}
|
||||
label="Section Title"
|
||||
name="section_title"
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Section Title"
|
||||
/>
|
||||
{errors.section_title && (
|
||||
<p className="mt-1 text-sm text-red-500">
|
||||
{errors.section_title.message as string}
|
||||
</p>
|
||||
)}
|
||||
<TextAreaGroup
|
||||
label="Section Description"
|
||||
{...register("section_description" as Path<T>)}
|
||||
name="section_description"
|
||||
placeholder="Enter Section Description"
|
||||
/>
|
||||
</ShowcaseSection>
|
||||
<ShowcaseSection title={`${title} cards`} className="flex flex-col gap-5">
|
||||
{fields.map((field, index) => (
|
||||
<div
|
||||
key={field.id}
|
||||
className="grid grid-cols-1 gap-4 sm:grid-cols-2"
|
||||
>
|
||||
<InputGroup
|
||||
{...register(`${fieldName}.${index}.icon` as Path<T>, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
})}
|
||||
label="Icon"
|
||||
name={`${fieldName}.${index}.icon`}
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Icon URL or name"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register(`${fieldName}.${index}.title` as Path<T>, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
})}
|
||||
label="Title"
|
||||
name={`${fieldName}.${index}.title`}
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
<TextAreaGroup
|
||||
{...register(`${fieldName}.${index}.description` as Path<T>)}
|
||||
label="Description"
|
||||
name={`${fieldName}.${index}.description`}
|
||||
placeholder="Enter Description"
|
||||
className="sm:col-span-2"
|
||||
/>
|
||||
<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(defaultValues)}
|
||||
>
|
||||
Add point
|
||||
</button>
|
||||
</ShowcaseSection>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionStep;
|
||||
@@ -1,49 +0,0 @@
|
||||
"use client";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IBenefitsStepFields {
|
||||
section_title: string;
|
||||
section_description: string;
|
||||
benefits: {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
const useBenefitsStepPresenter = () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useForm<IBenefitsStepFields>({
|
||||
defaultValues: {
|
||||
benefits: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "benefits",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IBenefitsStepFields) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
return {
|
||||
register,
|
||||
handleSubmit,
|
||||
errors,
|
||||
onSubmit,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
watch,
|
||||
};
|
||||
};
|
||||
|
||||
export default useBenefitsStepPresenter;
|
||||
@@ -1,49 +0,0 @@
|
||||
"use client";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IChallengesStepFields {
|
||||
section_title: string;
|
||||
section_description: string;
|
||||
challenges: {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
const useChallengesStepPresenter = () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useForm<IChallengesStepFields>({
|
||||
defaultValues: {
|
||||
challenges: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "challenges",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IChallengesStepFields) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
return {
|
||||
register,
|
||||
handleSubmit,
|
||||
errors,
|
||||
onSubmit,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
watch,
|
||||
};
|
||||
};
|
||||
|
||||
export default useChallengesStepPresenter;
|
||||
@@ -1,45 +0,0 @@
|
||||
"use client";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IChartStepFields {
|
||||
chart_title: string;
|
||||
lost_amount: number;
|
||||
chart_points: { x: string; y: number }[];
|
||||
}
|
||||
|
||||
const useChartStepPresenter = () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useForm<IChartStepFields>({
|
||||
defaultValues: {
|
||||
chart_points: [{ x: "", y: 0 }],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "chart_points",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IChartStepFields) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
return {
|
||||
register,
|
||||
handleSubmit,
|
||||
errors,
|
||||
onSubmit,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
watch,
|
||||
};
|
||||
};
|
||||
|
||||
export default useChartStepPresenter;
|
||||
@@ -1,62 +0,0 @@
|
||||
"use client";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IContactsStepFields {
|
||||
title: string;
|
||||
description: string;
|
||||
submit_button_title: string;
|
||||
fields: {
|
||||
field_name: string;
|
||||
label: string;
|
||||
placeholder: string;
|
||||
required: boolean;
|
||||
}[];
|
||||
}
|
||||
|
||||
const useContactsStepPresenter = () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useForm<IContactsStepFields>({
|
||||
defaultValues: {
|
||||
fields: [
|
||||
{
|
||||
field_name: "first_name",
|
||||
label: "",
|
||||
placeholder: "",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
field_name: "last_name",
|
||||
label: "",
|
||||
placeholder: "",
|
||||
required: false,
|
||||
},
|
||||
{ field_name: "email", label: "", placeholder: "", required: false },
|
||||
{ field_name: "phone", label: "", placeholder: "", required: false },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields } = useFieldArray({
|
||||
control,
|
||||
name: "fields",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IContactsStepFields) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
return {
|
||||
register,
|
||||
handleSubmit,
|
||||
errors,
|
||||
onSubmit,
|
||||
fields,
|
||||
control,
|
||||
};
|
||||
};
|
||||
|
||||
export default useContactsStepPresenter;
|
||||
@@ -1,49 +0,0 @@
|
||||
"use client";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
export interface IFeaturesStepFields {
|
||||
section_title: string;
|
||||
section_description: string;
|
||||
features: {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
const useFeaturesStepPresenter = () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useForm<IFeaturesStepFields>({
|
||||
defaultValues: {
|
||||
features: [{ icon: "", title: "", description: "" }],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name: "features",
|
||||
});
|
||||
|
||||
const onSubmit = (data: IFeaturesStepFields) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
return {
|
||||
register,
|
||||
handleSubmit,
|
||||
errors,
|
||||
onSubmit,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
watch,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFeaturesStepPresenter;
|
||||
@@ -1,30 +0,0 @@
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
interface FooterFormValues {
|
||||
email: string;
|
||||
phoneNumber?: string;
|
||||
address?: string;
|
||||
tagline?: string;
|
||||
copyright?: string;
|
||||
}
|
||||
|
||||
const useFooterStepPresenter = () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<FooterFormValues>();
|
||||
|
||||
const onSubmit = (data: FooterFormValues) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
return {
|
||||
register,
|
||||
handleSubmit,
|
||||
onSubmit,
|
||||
errors,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFooterStepPresenter;
|
||||
@@ -1,31 +0,0 @@
|
||||
"use client";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
export interface IHeroStepFields {
|
||||
key: string;
|
||||
title: string;
|
||||
description: string;
|
||||
button_text: string;
|
||||
button_link: string;
|
||||
}
|
||||
|
||||
const useHeroStepPresenter = () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<IHeroStepFields>();
|
||||
|
||||
const onSubmit = (data: IHeroStepFields) => {
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
return {
|
||||
register,
|
||||
handleSubmit,
|
||||
errors,
|
||||
onSubmit,
|
||||
};
|
||||
};
|
||||
|
||||
export default useHeroStepPresenter;
|
||||
Reference in New Issue
Block a user