import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; import { useCalendarStore } from "../state/store"; import "../styles/styles.css"; import type { CalendarComponentProps } from "../types/state"; import { calculateHourSizeInPx, getDaysBetweenDates, getHoursToDisplay } from "../utils"; import { DateValues } from "./DateValues"; import { EmptyCell } from "./event/Empty"; import { EventList } from "./event/EventList"; import { SchedulerColumns } from "./grid"; import { SchedulerHeading } from "./heading/SchedulerHeading"; import { HorizontalLines } from "./horizontalLines"; import { VeritcalLines } from "./verticalLines"; export function Calendar(props: CalendarComponentProps) { const container = useRef(null); const containerNav = useRef(null); const containerOffset = useRef(null); const schedulerGrid = useRef(null); const initalState = useCalendarStore((state) => state.initState); const startDate = useCalendarStore((state) => state.startDate); const endDate = useCalendarStore((state) => state.endDate); const startHour = useCalendarStore((state) => state.startHour || 0); const endHour = useCalendarStore((state) => state.endHour || 23); const usersCellsStopsPerHour = useCalendarStore((state) => state.gridCellsPerHour || 4); const availableTimeslots = useCalendarStore((state) => state.availableTimeslots); const hideHeader = useCalendarStore((state) => state.hideHeader); const days = useMemo(() => getDaysBetweenDates(startDate, endDate), [startDate, endDate]); const hours = useMemo(() => getHoursToDisplay(startHour || 0, endHour || 23), [startHour, endHour]); const numberOfGridStopsPerDay = hours.length * usersCellsStopsPerHour; const [hourSize, setHourSize] = useState(calculateHourSizeInPx(schedulerGrid?.current, startHour, endHour)); // Reset one hour size on window resize. useLayoutEffect(() => { const onResize = () => { setHourSize(calculateHourSizeInPx(schedulerGrid?.current, startHour, endHour)); }; window.addEventListener("resize", onResize); // By running this set function also one time in the uselayouteffect, instead of // only in the default value of useState, we make sure that the ref is rendered // to the screen and we read the correct value. setHourSize(calculateHourSizeInPx(schedulerGrid?.current, startHour, endHour)); return () => window.removeEventListener("resize", onResize); }, [startHour, endHour]); // Initalise State on inital mount useEffect(() => { initalState(props); }, [props, initalState]); return (
{hideHeader !== true && }
{/* TODO: Implement this at a later date. */} {/* */}
{/* Empty Cells */} <> {[...Array(days.length)].map((_, i) => (
  • {/* While startDate < endDate: */} {[...Array(numberOfGridStopsPerDay)].map((_, j) => { const key = `${i}-${j}`; return ( ); })}
  • ))}
    {/*Loop over events per day */} {days.map((day, i) => { return (
  • {/* */}
  • ); })}
    ); } /** @todo Will be removed once we have mobile support */ const MobileNotSupported = ({ children }: { children: React.ReactNode }) => { return ( <>

    Mobile not supported yet

    Please use a desktop browser to view this page

    {children}
    ); };