Skip to content
Snippets Groups Projects
datevisibilityinput.tsx 2.57 KiB
Newer Older
  • Learn to ignore specific revisions
  • import React, { useEffect, useState } from "react";
    import "./datevisibilityinput.css";
    
    type DateVisibilityInputProps = {
        date?: string; // YYYY-MM-DD
        onDateChange: (date?: string) => void;
    };
    
    function DateVisibilityInput({ date, onDateChange }: DateVisibilityInputProps) {
        const isDate = (date?: string): boolean => {
    
            if (!date || date.length !== 10) {
    
                return false;
            }
    
            // Format: YYYY-MM-DD
            // Try to convert to date and trigger onChange
            const splits: string[] = date.split("-", 3);
            if (splits.length != 3) {
                return false;
            }
    
            const year = parseInt(splits[0]);
            const month = parseInt(splits[1]);
            const day = parseInt(splits[2]);
    
            if (isNaN(day) || isNaN(month) || isNaN(year)) {
                return false;
            }
    
            return true;
        };
    
        const dateToString = (date: Date): string => {
            return (
                date.getFullYear() +
                "-" +
    
    Maximilian Giller's avatar
    Maximilian Giller committed
                (date.getMonth() + 1).toString().padStart(2, "0") +
    
                "-" +
                date.getDate().toString().padStart(2, "0")
            );
        };
    
        const initialEditedDate = () => {
            return isDate(date) ? date : dateToString(new Date());
        };
    
        const [editedDate, setEditedDate] = useState<string>(initialEditedDate());
        const [alwaysVisible, setAlwaysVisible] = useState<boolean>(!isDate(date));
    
        useEffect(() => {
            setEditedDate(initialEditedDate());
            setAlwaysVisible(!isDate(date));
        }, [date]);
    
        const updateVisibilityState = (visible: boolean) => {
            setAlwaysVisible(visible);
    
            if (alwaysVisible) {
                onDateChange(undefined);
            } else {
                onDateChange(editedDate);
            }
        };
    
        const handleDateChange = (date?: string) => {
            if (isDate(date)) {
                setEditedDate(date);
                updateVisibilityState(false);
            } else {
                updateVisibilityState(true);
            }
        };
    
        return (
            <div className="date-input">
                <input
                    id="date-checkbox"
                    type={"checkbox"}
                    checked={alwaysVisible}
                    onChange={(e) => updateVisibilityState(e.target.checked)}
                />
                <label htmlFor="date-checkbox">Always visible</label>
                {!alwaysVisible && (
                    <input
                        type={"date"}
                        value={editedDate}
                        onChange={(e) => handleDateChange(e.target.value)}
                    />
                )}
            </div>
        );
    }
    
    export default DateVisibilityInput;