refactor(marketing): Abstract form logic into reusable SectionStep component
Reduces code duplication in the marketing page forms by creating a generic `SectionStep` component. This new component encapsulates the shared UI and logic for sections that include a title, description, and a dynamic list of fields (e.g., feature cards, pricing points). The `FeaturesStep` component has been refactored to use this new `SectionStep`, resulting in a much cleaner and more maintainable implementation.
This commit is contained in:
@@ -1,104 +1,34 @@
|
||||
"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 useFeaturesStepPresenter from "./useFeaturesStepPresenter";
|
||||
import SectionStep from "./SectionStep";
|
||||
import useFeaturesStepPresenter, {
|
||||
IFeaturesStepFields,
|
||||
} from "./useFeaturesStepPresenter";
|
||||
|
||||
const FeaturesStep = () => {
|
||||
const { errors, handleSubmit, onSubmit, register, fields, append, remove } =
|
||||
useFeaturesStepPresenter();
|
||||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
onSubmit,
|
||||
register,
|
||||
fields,
|
||||
append,
|
||||
remove,
|
||||
control,
|
||||
} = useFeaturesStepPresenter();
|
||||
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="Features Section"
|
||||
className="flex flex-col gap-5"
|
||||
>
|
||||
<InputGroup
|
||||
{...register("section_title", {
|
||||
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}
|
||||
</p>
|
||||
)}
|
||||
<TextAreaGroup
|
||||
label="Section Description"
|
||||
{...register("section_description")}
|
||||
name="section_description"
|
||||
placeholder="Enter Section Description"
|
||||
/>
|
||||
</ShowcaseSection>
|
||||
<ShowcaseSection title="Features 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(`features.${index}.icon`, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
})}
|
||||
label="Icon"
|
||||
name={`features.${index}.icon`}
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Icon URL or name"
|
||||
/>
|
||||
<InputGroup
|
||||
{...register(`features.${index}.title`, {
|
||||
required: {
|
||||
message: FormErrorMessages.required,
|
||||
value: true,
|
||||
},
|
||||
})}
|
||||
label="Title"
|
||||
name={`features.${index}.title`}
|
||||
required
|
||||
type="text"
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
<TextAreaGroup
|
||||
{...register(`features.${index}.description`)}
|
||||
label="Description"
|
||||
name={`features.${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({ icon: "", title: "", description: "" })}
|
||||
>
|
||||
Add point
|
||||
</button>
|
||||
</ShowcaseSection>
|
||||
</div>
|
||||
</form>
|
||||
<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: "" }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user