5bf3e53d95
- Updated the grid layout in the Home page for better responsiveness. - Adjusted tabIndex handling in MultiSelect component to enhance accessibility. - Added minimum width to the TopChannels table for consistent display. - Refined notification recipient placeholder logic for cleaner code.
177 lines
5.2 KiB
TypeScript
177 lines
5.2 KiB
TypeScript
"use client";
|
|
import DatePicker from "@/components/FormElements/DatePicker/DatePicker";
|
|
import InputGroup from "@/components/FormElements/InputGroup";
|
|
import { TextAreaGroup } from "@/components/FormElements/InputGroup/text-area";
|
|
import MultiSelect from "@/components/FormElements/MultiSelect";
|
|
import { Select } from "@/components/FormElements/select";
|
|
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
|
import FormFooter from "@/components/ui/FormFooter";
|
|
import { REGEX } from "@/constants/regex";
|
|
import { FormErrorMessages } from "@/constants/Texts";
|
|
import useCreateNotificationFormPresenter from "./useCreateNotificationFormPresenter";
|
|
|
|
const CreateNotificationForm = () => {
|
|
const {
|
|
register,
|
|
errors,
|
|
control,
|
|
handleSubmit,
|
|
recipient,
|
|
onSubmit,
|
|
onSelectTarget,
|
|
priorities,
|
|
targets,
|
|
types,
|
|
channels,
|
|
} = useCreateNotificationFormPresenter();
|
|
return (
|
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|
<ShowcaseSection
|
|
title="Create Notification"
|
|
className="grid grid-cols-1 gap-5 md:grid-cols-2"
|
|
>
|
|
<div className="flex flex-col gap-2">
|
|
<InputGroup
|
|
required
|
|
{...register("title", {
|
|
required: { value: true, message: FormErrorMessages.required },
|
|
})}
|
|
name="title"
|
|
label="Title"
|
|
type="text"
|
|
placeholder="Short headline shown to recipients"
|
|
/>
|
|
{errors.title && (
|
|
<p className="mt-1 text-sm text-red-500">{errors.title.message}</p>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-col gap-2">
|
|
<DatePicker
|
|
control={control}
|
|
name="schedule_at"
|
|
label="schedule at"
|
|
range={false}
|
|
timePicker
|
|
/>
|
|
</div>
|
|
<div className="flex flex-col gap-2">
|
|
<Select
|
|
required
|
|
{...register("target", {
|
|
required: {
|
|
value: true,
|
|
message: FormErrorMessages.required,
|
|
},
|
|
onChange: onSelectTarget,
|
|
})}
|
|
items={targets}
|
|
label="target"
|
|
placeholder="Choose who this applies to"
|
|
name="target"
|
|
/>
|
|
{errors.target && (
|
|
<p className="mt-1 text-sm text-red-500">{errors.target.message}</p>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-2">
|
|
<MultiSelect
|
|
disabled={!recipient}
|
|
required={!!recipient}
|
|
{...register("recipient")}
|
|
label="recipient"
|
|
items={recipient ?? []}
|
|
placeholder={
|
|
recipient && recipient.length > 0 ? "Choose recipients" : ""
|
|
}
|
|
name="recipient"
|
|
/>
|
|
</div>
|
|
<div className="flex flex-col gap-2">
|
|
<MultiSelect
|
|
required
|
|
{...register("channels")}
|
|
label="channels"
|
|
items={channels ?? []}
|
|
placeholder="Email, push, or both"
|
|
name="channels"
|
|
/>
|
|
</div>
|
|
<div className="flex flex-col gap-2">
|
|
<InputGroup
|
|
{...register("link", {
|
|
pattern: {
|
|
value: REGEX.URL,
|
|
message: FormErrorMessages.invalidPattern,
|
|
},
|
|
})}
|
|
name="link"
|
|
label="Link"
|
|
type="url"
|
|
/>
|
|
{errors.link && (
|
|
<p className="mt-1 text-sm text-red-500">{errors.link.message}</p>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-col gap-2">
|
|
<Select
|
|
required
|
|
{...register("priority", {
|
|
required: {
|
|
value: true,
|
|
message: FormErrorMessages.required,
|
|
},
|
|
})}
|
|
items={priorities}
|
|
label="Priority"
|
|
placeholder="Choose urgency"
|
|
name="priority"
|
|
/>
|
|
{errors.priority && (
|
|
<p className="mt-1 text-sm text-red-500">
|
|
{errors.priority.message}
|
|
</p>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-col gap-2">
|
|
<Select
|
|
required
|
|
{...register("type", {
|
|
required: {
|
|
value: true,
|
|
message: FormErrorMessages.required,
|
|
},
|
|
})}
|
|
items={types}
|
|
label="type"
|
|
placeholder="Info, warning, alert, or reject"
|
|
name="type"
|
|
/>
|
|
{errors.type && (
|
|
<p className="mt-1 text-sm text-red-500">{errors.type.message}</p>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-col gap-2 md:col-span-2">
|
|
<TextAreaGroup
|
|
required
|
|
{...register("description", {
|
|
required: {
|
|
value: true,
|
|
message: FormErrorMessages.required,
|
|
},
|
|
})}
|
|
label="Description"
|
|
name="description"
|
|
placeholder="Main message — include context and any action needed"
|
|
/>
|
|
</div>
|
|
<div className="md:col-span-2">
|
|
<FormFooter />
|
|
</div>
|
|
</ShowcaseSection>
|
|
</form>
|
|
);
|
|
};
|
|
|
|
export default CreateNotificationForm;
|