90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
import { DatePicker, TimeInput } from "@mantine/dates";
|
|
import { ActionIcon, Stack } from "@mantine/core";
|
|
import { useRef } from "react";
|
|
import { ClockIcon } from "@phosphor-icons/react";
|
|
|
|
interface DateTimePickerProps {
|
|
value: Date | null;
|
|
onChange: (date: string | null) => void;
|
|
label?: string;
|
|
[key: string]: any;
|
|
}
|
|
|
|
const DateTimePicker = ({ value, onChange, label, ...rest }: DateTimePickerProps) => {
|
|
const timeRef = useRef<HTMLInputElement>(null);
|
|
const currentDate = value ? new Date(value) : null;
|
|
|
|
const formatDate = (date: Date | null): string => {
|
|
if (!date) return "";
|
|
return date.toISOString().split('T')[0];
|
|
};
|
|
|
|
const formatTime = (date: Date | null): string => {
|
|
if (!date) return "";
|
|
return date.toTimeString().slice(0, 5);
|
|
};
|
|
|
|
const handleDateChange = (dateString: string | null) => {
|
|
if (!dateString) {
|
|
onChange('');
|
|
return;
|
|
}
|
|
|
|
const newDate = new Date(dateString + 'T00:00:00');
|
|
|
|
if (currentDate) {
|
|
newDate.setHours(currentDate.getHours());
|
|
newDate.setMinutes(currentDate.getMinutes());
|
|
}
|
|
|
|
onChange(newDate.toISOString());
|
|
};
|
|
|
|
const handleTimeChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
const timeValue = event.target.value;
|
|
if (!timeValue) return;
|
|
|
|
const [hours, minutes] = timeValue.split(':').map(Number);
|
|
if (isNaN(hours) || isNaN(minutes)) return;
|
|
|
|
const baseDate = currentDate || new Date();
|
|
const newDate = new Date(baseDate);
|
|
|
|
newDate.setHours(hours);
|
|
newDate.setMinutes(minutes);
|
|
newDate.setSeconds(0);
|
|
newDate.setMilliseconds(0);
|
|
|
|
onChange(newDate.toISOString());
|
|
};
|
|
|
|
return (
|
|
<Stack>
|
|
<DatePicker
|
|
size="md"
|
|
value={formatDate(currentDate)}
|
|
onChange={handleDateChange}
|
|
{...rest}
|
|
/>
|
|
<TimeInput
|
|
ref={timeRef}
|
|
label="Time"
|
|
size="md"
|
|
value={formatTime(currentDate)}
|
|
onChange={handleTimeChange}
|
|
rightSection={
|
|
<ActionIcon
|
|
variant="subtle"
|
|
color="gray"
|
|
onClick={() => timeRef.current?.showPicker()}
|
|
>
|
|
<ClockIcon size={16} />
|
|
</ActionIcon>
|
|
}
|
|
{...rest}
|
|
/>
|
|
</Stack>
|
|
);
|
|
};
|
|
|
|
export { DateTimePicker }; |