Files
calendar/packages/features/calendars/weeklyview/components/blocking/BlockedList.tsx
T
Jeroen ReumkensandGitHub ca47a589ba feat: weekly view for new booker. (#9389)
* WIP on weekly view for new booker.

* Set responsive grid height for booker weekly view.

* Fixed types

* Ensure you can't click on disabled dates in weekly calendar

* CAL-1916: Improvements for blocked out parts background blocks, made the lines connect by using a shared background.

* Margin, padding and color tweaks for new booker CAL-1911

* Made week view have more days visible by default

* Fix to prevent layout switch from breaking when clicking same layout twice.
2023-06-09 09:38:18 +00:00

130 lines
3.9 KiB
TypeScript

import { useMemo } from "react";
import { shallow } from "zustand/shallow";
import dayjs from "@calcom/dayjs";
import { useCalendarStore } from "../../state/store";
import { BlockedTimeCell } from "./BlockedTimeCell";
type Props = {
day: dayjs.Dayjs;
containerRef: React.RefObject<HTMLDivElement>;
};
function roundX(x: number, roundBy: number) {
return Math.round(x / roundBy) * roundBy;
}
type BlockedDayProps = {
startHour: number;
endHour: number;
day: dayjs.Dayjs;
};
function BlockedBeforeToday({ day, startHour, endHour }: BlockedDayProps) {
return (
<>
{day.isBefore(dayjs(), "day") && (
<div
key={day.format("YYYY-MM-DD")}
className="absolute z-40 w-full"
style={{
top: `var(--one-minute-height)`,
zIndex: 60,
height: `calc(${(endHour + 1 - startHour) * 60} * var(--one-minute-height))`, // Add 1 to endHour to include the last hour that we add to display the last vertical line
}}>
<BlockedTimeCell />
</div>
)}
</>
);
}
function BlockedToday({
day,
startHour,
gridCellsPerHour,
endHour,
}: BlockedDayProps & { gridCellsPerHour: number }) {
const dayStart = useMemo(() => day.startOf("day").hour(startHour), [day, startHour]);
const dayEnd = useMemo(() => day.startOf("day").hour(endHour), [day, endHour]);
const dayEndInMinutes = useMemo(() => dayEnd.diff(dayStart, "minutes"), [dayEnd, dayStart]);
let nowComparedToDayStart = useMemo(() => dayjs().diff(dayStart, "minutes"), [dayStart]);
if (nowComparedToDayStart > dayEndInMinutes) nowComparedToDayStart = dayEndInMinutes;
return (
<>
{day.isToday() && (
<div
key={day.format("YYYY-MM-DD")}
className="absolute z-40 w-full"
style={{
top: `var(--one-minute-height)`, // Still need this as this var takes into consideration the offset of the "AllDayEvents" bar
zIndex: 60,
height: `calc(${roundX(
nowComparedToDayStart,
60 / gridCellsPerHour
)} * var(--one-minute-height) - 2px)`, // We minus the border width to make it 🧹
}}>
<BlockedTimeCell />
</div>
)}
</>
);
}
export function BlockedList({ day }: Props) {
const { startHour, blockingDates, endHour, gridCellsPerHour } = useCalendarStore(
(state) => ({
startHour: state.startHour || 0,
endHour: state.endHour || 23,
blockingDates: state.blockingDates,
gridCellsPerHour: state.gridCellsPerHour || 4,
}),
shallow
);
return (
<>
<BlockedBeforeToday day={day} startHour={startHour} endHour={endHour} />
<BlockedToday gridCellsPerHour={gridCellsPerHour} day={day} startHour={startHour} endHour={endHour} />
{blockingDates &&
blockingDates.map((event, i) => {
const dayStart = day.startOf("day").hour(startHour);
const blockingStart = dayjs(event.start);
const eventEnd = dayjs(event.end);
const eventStart = dayStart.isAfter(blockingStart) ? dayStart : blockingStart;
if (!eventStart.isSame(day, "day")) {
return null;
}
if (eventStart.isBefore(dayjs())) {
if (eventEnd.isBefore(dayjs())) {
return null;
}
}
const eventDuration = eventEnd.diff(eventStart, "minutes");
const eventStartHour = eventStart.hour();
const eventStartDiff = (eventStartHour - (startHour || 0)) * 60;
return (
<div
key={`${eventStart.toISOString()}-${i}`}
className="absolute w-full"
style={{
zIndex: 60,
top: `calc(${eventStartDiff}*var(--one-minute-height))`,
height: `calc(${eventDuration}*var(--one-minute-height))`,
}}>
<BlockedTimeCell />
</div>
);
})}
</>
);
}