Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { useState, useRef, useCallback, useEffect } from "react";
- import { UseFormReturn } from "react-hook-form";
- import { Time } from "@fd-toolbox/dates/time";
- import { VoidFunc } from "@fd-toolbox/functions/getter-setter-functions";
- import { parseUtcStringToDate } from "@fd-toolbox/dates/date-times";
- import { useAsyncEffect } from "@fd-toolbox/hooks/use-async-effect";
- import {
- setDatePickerState,
- handleDatePickerOpenChange,
- } from "@fd-component-toolbox/datepicker/FdDatePicker.funcs";
- export interface UseDatePickerStateProps {
- date?: string;
- form?: UseFormReturn;
- name?: string;
- onDateValueChange?: (date?: Date) => void;
- onTimeValueChange?: VoidFunc<Time>;
- onOpenChange?: (isOpen: boolean) => void;
- }
- export interface UseDatePickerStateReturn {
- dateValue: Date | undefined;
- timeValue: Time;
- isOpen: boolean;
- setDateValue: (date?: Date) => void;
- setTimeValue: React.Dispatch<React.SetStateAction<Time>>;
- onOpenChangeCallback: (open: boolean) => void;
- onTimeValueChange: (operation: string, value: number) => void;
- }
- /**
- * Custom hook for managing the state of the DatePicker component
- *
- * @param props - hook parameters
- * @returns object with state and control methods
- */
- export function useDatePickerState({
- date = "",
- form,
- name,
- onDateValueChange: onDateValueChangeProp,
- onTimeValueChange: onTimeValueChangeProp,
- onOpenChange,
- }: UseDatePickerStateProps): UseDatePickerStateReturn {
- const [dateValue, setDateValue] = useState<Date>();
- const [timeValue, setTimeValue] = useState<Time>({ hours: 0, minutes: 0 });
- const [isOpen, setIsOpen] = useState(false);
- const prevIsoString = useRef<string | null>(null);
- // Initialize date and time from the date prop
- useEffect(() => {
- if (date !== "") {
- const parseData = parseUtcStringToDate(date);
- setDateValue(parseData);
- setTimeValue({ hours: parseData.getHours(), minutes: parseData.getMinutes() });
- } else {
- setDateValue(undefined);
- setTimeValue({ hours: 0, minutes: 0 });
- }
- }, [date]);
- // Check if the form is ready for update
- const isFormReadyToUpdate = useCallback(() => {
- return !!(form && name);
- }, [form, name]);
- // Set the previous ISO string
- const setPrevIsoString = useCallback((isoString: string | null) => {
- prevIsoString.current = isoString;
- }, []);
- // Set the value in the form
- const setFormValue = useCallback(
- (datePickerName: string, isoString: string | null) => {
- form?.setValue(datePickerName, isoString);
- },
- [form],
- );
- // Synchronize state with the form
- useAsyncEffect(async () => {
- setDatePickerState(
- timeValue,
- setPrevIsoString,
- setFormValue,
- isFormReadyToUpdate(),
- prevIsoString?.current ?? undefined,
- dateValue ?? undefined,
- name,
- onDateValueChangeProp,
- );
- }, [timeValue, dateValue, form, name]);
- // Notify about time change
- useAsyncEffect(async () => {
- onTimeValueChangeProp?.(timeValue);
- }, [timeValue]);
- // Time change handler
- const onTimeValueChange = useCallback(
- (operation: string, value: number) => {
- if (operation === "hours") {
- setTimeValue((prevTimeValue) => ({ ...prevTimeValue, hours: value }));
- } else if (operation === "minutes") {
- setTimeValue((prevTimeValue) => ({ ...prevTimeValue, minutes: value }));
- }
- },
- [setTimeValue],
- );
- // Handler for changing the open state of the popup
- const onOpenChangeCallback = useCallback(
- (open: boolean) => {
- handleDatePickerOpenChange(open, setIsOpen, onOpenChange);
- },
- [onOpenChange],
- );
- return {
- dateValue,
- timeValue,
- isOpen,
- setDateValue,
- setTimeValue,
- onOpenChangeCallback,
- onTimeValueChange,
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment