Files
tm_panel/src/components/FormElements/DatePicker/DatePicker.tsx
T
AmirReza Jamali bb56e1013a feat(companies): Enhance company forms with additional fields
This commit expands the company profile by adding several new fields to the create and edit forms. This allows for the collection of more detailed and comprehensive company information.

Key changes include:
- Added new fields: Establishment Date, Company Type, Business Nature, Industry, Country, State, and City.
- Introduced a new reusable `DatePicker` component, utilizing `react-datepicker`, for date input.
- Created a new `CalendarIcon` for use in the date picker.
- Updated the company Zod schema, API services, and data types to support the new fields.

Additionally, this commit includes a refactor to standardize the `MultiSelect` component by renaming the `text` prop to `label` for better consistency across form elements. Form labels are now capitalized for a uniform UI.
2025-09-27 16:33:13 +03:30

121 lines
3.6 KiB
TypeScript

import { CalendarIcon } from "@/assets/icons";
import { cn } from "@/lib/utils";
import {
Control,
Controller,
FieldValues,
Path,
RegisterOptions,
} from "react-hook-form";
import MultiDatePicker, { DateObject } from "react-multi-date-picker";
import TimePicker from "react-multi-date-picker/plugins/time_picker";
interface IProps<T extends FieldValues> {
control: Control<T>;
name: Path<T>;
label: string;
placeholder?: string;
required?: boolean;
multiple?: boolean;
range?: boolean;
onlyMonthPicker?: boolean;
onlyYearPicker?: boolean;
minDate?: number;
maxDate?: number;
timePicker?: boolean;
rules?: Omit<
RegisterOptions<T, Path<T>>,
"valueAsNumber" | "valueAsDate" | "setValueAs" | "disabled"
>;
}
const DatePicker = <T extends FieldValues>({
control,
name,
label,
multiple = false,
placeholder,
required,
range = false,
timePicker = false,
onlyMonthPicker = false,
onlyYearPicker = false,
rules,
maxDate,
minDate,
}: IProps<T>) => {
return (
<div>
<label
htmlFor={name}
className="text-body-sm font-medium capitalize text-dark dark:text-white"
>
{label}
{required && <span className="ml-1 select-none text-error">*</span>}
</label>
<div className="mt-3">
<Controller
control={control}
name={name}
rules={rules}
render={({
field: { onChange, name, value },
formState: { errors },
}) => {
const error = errors[name];
return (
<>
<div className="relative">
<MultiDatePicker
range={range}
minDate={minDate}
maxDate={maxDate}
onlyMonthPicker={onlyMonthPicker}
plugins={
timePicker ? [<TimePicker position="bottom" />] : []
}
onlyYearPicker={onlyYearPicker}
multiple={multiple}
onChange={(date: DateObject | DateObject[] | null) => {
if (!date) {
return onChange("");
}
if (Array.isArray(date)) {
const unixTimestamps = date.map((d) => d.toUnix());
onChange(unixTimestamps);
} else if (date instanceof DateObject) {
onChange(date.isValid ? date.toUnix() : "");
}
}}
format={"YYYY/MM/DD"}
containerClassName="w-full"
inputClass={cn(
"w-full rounded-lg border-[1.5px] border-stroke bg-transparent px-5.5 py-3 pl-12.5 text-dark outline-none transition focus:border-primary disabled:cursor-default disabled:bg-gray-2 dark:border-dark-3 dark:bg-dark-2 dark:text-white dark:focus:border-primary dark:disabled:bg-dark",
error && "!border-red focus:!border-red dark:!border-red",
)}
placeholder={placeholder}
/>
<span className="absolute left-4.5 top-1/2 -translate-y-1/2">
<CalendarIcon />
</span>
</div>
{error && (
<p className="text-red mt-1.5 text-sm text-error">
{error.message as string}
</p>
)}
</>
);
}}
/>
</div>
</div>
);
};
export default DatePicker;