admin/src/components/ui/JalaliDateTimePicker.tsx

92 lines
3.6 KiB
TypeScript

import React from 'react';
import DatePicker from 'react-multi-date-picker';
import TimePicker from 'react-multi-date-picker/plugins/time_picker';
import persian from 'react-date-object/calendars/persian';
import persian_fa from 'react-date-object/locales/persian_fa';
import DateObject from 'react-date-object';
import { Label } from './Typography';
import { X } from 'lucide-react';
interface JalaliDateTimePickerProps {
label?: string;
value?: string | null;
onChange: (value: string | undefined) => void;
error?: string;
placeholder?: string;
}
const toIsoLike = (date?: DateObject | null): string | undefined => {
if (!date) return undefined;
try {
const g = date.convert(undefined);
const yyyy = g.year.toString().padStart(4, '0');
const mm = g.month.toString().padStart(2, '0');
const dd = g.day.toString().padStart(2, '0');
const hh = g.hour.toString().padStart(2, '0');
const mi = g.minute.toString().padStart(2, '0');
return `${yyyy}-${mm}-${dd}T${hh}:${mi}:00Z`;
} catch {
return undefined;
}
};
const fromIsoToDateObject = (value?: string | null): DateObject | undefined => {
if (!value) return undefined;
try {
const d = new Date(value);
if (isNaN(d.getTime())) return undefined;
return new DateObject(d).convert(persian, persian_fa);
} catch {
return undefined;
}
};
export const JalaliDateTimePicker: React.FC<JalaliDateTimePickerProps> = ({ label, value, onChange, error, placeholder }) => {
const selected = fromIsoToDateObject(value);
return (
<div className="space-y-1">
{label && <Label>{label}</Label>}
<div className="relative">
<DatePicker
value={selected}
onChange={(val) => onChange(toIsoLike(val as DateObject | null))}
format="YYYY/MM/DD HH:mm"
calendar={persian}
locale={persian_fa}
calendarPosition="bottom-center"
disableDayPicker={false}
inputClass={`w-full border rounded-lg px-3 py-3 pr-10 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 ${error ? 'border-red-300 focus:border-red-500 focus:ring-red-500' : 'border-gray-300 dark:border-gray-600 focus:border-primary-500 focus:ring-primary-500'}`}
containerClassName="w-full"
placeholder={placeholder || 'تاریخ و ساعت'}
editable={false}
plugins={[<TimePicker key="time" position="bottom" />]}
disableMonthPicker={false}
disableYearPicker={false}
showOtherDays
/>
{value && (
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onChange(undefined);
}}
className="absolute left-2 top-1/2 -translate-y-1/2 p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors"
title="پاک کردن"
>
<X className="h-4 w-4" />
</button>
)}
</div>
{error && (
<p className="text-xs text-red-600 dark:text-red-400" role="alert">{error}</p>
)}
</div>
);
};
export default JalaliDateTimePicker;