FactuGES_ERP/packages/rdx-ui/src/components/form/DatePickerField.tsx

107 lines
3.1 KiB
TypeScript
Raw Normal View History

2025-07-08 18:50:08 +00:00
// DatePickerField.tsx
import {
Button,
Calendar,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
Popover,
PopoverContent,
PopoverTrigger,
} from "@repo/shadcn-ui/components";
2025-07-09 17:56:15 +00:00
import { CalendarIcon, LockIcon } from "lucide-react";
2025-07-08 18:50:08 +00:00
import { cn } from "@repo/shadcn-ui/lib/utils";
import { format } from "date-fns";
import { Control, FieldPath, FieldValues } from "react-hook-form";
2025-07-09 17:56:15 +00:00
import { useTranslation } from "../../locales/i18n.ts";
2025-07-08 18:50:08 +00:00
type DatePickerFieldProps<TFormValues extends FieldValues> = {
control: Control<TFormValues>;
name: FieldPath<TFormValues>;
2025-07-09 17:56:15 +00:00
label?: string;
2025-07-08 18:50:08 +00:00
placeholder?: string;
description?: string;
disabled?: boolean;
required?: boolean;
2025-07-09 17:56:15 +00:00
readOnly?: boolean;
2025-07-08 18:50:08 +00:00
className?: string;
formatDateFn?: (iso: string) => string;
};
export function DatePickerField<TFormValues extends FieldValues>({
control,
name,
label,
placeholder,
description,
disabled = false,
required = false,
2025-07-09 17:56:15 +00:00
readOnly = false,
2025-07-08 18:50:08 +00:00
className,
formatDateFn = (iso) => format(new Date(iso), "dd/MM/yyyy"),
}: DatePickerFieldProps<TFormValues>) {
const { t } = useTranslation();
2025-07-09 17:56:15 +00:00
const isDisabled = disabled || readOnly;
2025-07-08 18:50:08 +00:00
return (
<FormField
control={control}
name={name}
render={({ field }) => (
2025-07-17 08:50:28 +00:00
<FormItem className={cn("space-y-0", className)}>
2025-07-09 17:56:15 +00:00
{label && (
<div className='flex justify-between items-center'>
<FormLabel className='m-0'>{label}</FormLabel>
{required && <span className='text-xs text-destructive'>{t("common.required")}</span>}
</div>
)}
2025-07-08 18:50:08 +00:00
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant='outline'
2025-07-09 17:56:15 +00:00
disabled={isDisabled}
2025-07-08 18:50:08 +00:00
className={cn(
"w-full justify-start text-left font-normal",
2025-07-09 17:56:15 +00:00
!field.value && "text-muted-foreground",
disabled && "bg-muted text-muted-foreground cursor-not-allowed",
readOnly && !disabled && "bg-muted text-foreground cursor-default"
2025-07-08 18:50:08 +00:00
)}
>
2025-07-09 17:56:15 +00:00
{readOnly ? (
<LockIcon className='mr-2 h-4 w-4 opacity-70' />
) : (
<CalendarIcon className='mr-2 h-4 w-4' />
)}
2025-07-08 18:50:08 +00:00
{field.value ? formatDateFn(field.value) : placeholder}
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className='w-auto p-0'>
<Calendar
mode='single'
selected={field.value ? new Date(field.value) : undefined}
2025-07-09 17:56:15 +00:00
onSelect={(date) => {
if (!readOnly) {
field.onChange(date?.toISOString());
}
}}
2025-07-08 18:50:08 +00:00
initialFocus
/>
</PopoverContent>
</Popover>
2025-07-09 17:56:15 +00:00
2025-07-08 18:50:08 +00:00
<p className={cn("text-xs text-muted-foreground", !description && "invisible")}>
{description || "\u00A0"}
</p>
<FormMessage />
</FormItem>
)}
/>
);
}