2024-01-11 12:52:41 +02:00
|
|
|
import { Box, Typography } from "@mui/material";
|
|
|
|
import classNames from "classnames";
|
|
|
|
import utils from "../utils";
|
|
|
|
import "./css/AvailabilityPicker.css";
|
|
|
|
import dayjs, { Dayjs } from "dayjs";
|
|
|
|
import utc from 'dayjs/plugin/utc';
|
|
|
|
import timezone from 'dayjs/plugin/timezone';
|
|
|
|
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
|
|
|
import DisableableTooltip from "./DisableableTooltip";
|
|
|
|
|
|
|
|
dayjs.extend(utc)
|
|
|
|
dayjs.extend(timezone)
|
|
|
|
dayjs.extend(localizedFormat)
|
|
|
|
|
|
|
|
const AvailabilityPickerHour = (props: {
|
|
|
|
dateTime: Dayjs,
|
2024-01-13 00:07:50 +02:00
|
|
|
disabled: boolean,
|
2024-01-11 12:52:41 +02:00
|
|
|
isFullHourSelected: boolean,
|
|
|
|
isHalfHourSelected: boolean,
|
|
|
|
halfHourDisplayHeight: number,
|
2024-01-12 11:53:39 +02:00
|
|
|
currentTotalRespondents: number,
|
2024-01-13 00:10:03 +02:00
|
|
|
fullHourAvailableNames: String[],
|
|
|
|
halfHourAvailableNames: String[],
|
2024-01-11 12:52:41 +02:00
|
|
|
onMouseEnterHalfhour: (e: React.MouseEvent<HTMLDivElement, globalThis.MouseEvent>, time: Dayjs) => void,
|
|
|
|
onMouseClickOnHalfhour: (time: Dayjs, isDelete: boolean) => void
|
|
|
|
}) => {
|
|
|
|
const generateTooltipText = (names: String[]): String => {
|
|
|
|
return `${names.length} ${names.length > 1 ? "people have" : "person has"} marked this time as available: ${names.join(", ")}`;
|
|
|
|
}
|
|
|
|
|
2024-01-13 00:26:39 +02:00
|
|
|
const determineCellColor = (isSelected: boolean, availableNames: String[], isDisabled: boolean) => {
|
|
|
|
if (isDisabled) {
|
2024-01-13 00:29:07 +02:00
|
|
|
if (availableNames.length > 0) {
|
|
|
|
return heatMapColorforValue(availableNames.length);
|
|
|
|
}
|
|
|
|
|
2024-01-13 00:26:39 +02:00
|
|
|
return '#222222';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isSelected) {
|
|
|
|
return '#338822';
|
|
|
|
}
|
2024-01-13 00:07:50 +02:00
|
|
|
|
2024-01-13 00:26:39 +02:00
|
|
|
if (availableNames.length > 0) {
|
|
|
|
return heatMapColorforValue(availableNames.length);
|
|
|
|
}
|
2024-01-12 11:53:39 +02:00
|
|
|
|
2024-01-13 00:26:39 +02:00
|
|
|
return 'inherit';
|
|
|
|
}
|
|
|
|
|
|
|
|
const heatMapColorforValue = (value: number) => {
|
2024-01-12 11:53:39 +02:00
|
|
|
var h = (1.0 - (value / props.currentTotalRespondents)) * 240
|
2024-01-13 00:07:50 +02:00
|
|
|
return "hsl(" + h + ", 75%, 35%) !important";
|
2024-01-12 11:53:39 +02:00
|
|
|
}
|
|
|
|
|
2024-01-11 12:52:41 +02:00
|
|
|
return (
|
|
|
|
<Box
|
|
|
|
//className={classNames({ "hour-light": isEvenHour, "hour-dark": !isEvenHour })}
|
|
|
|
className={"hour-light"}
|
|
|
|
>
|
|
|
|
<DisableableTooltip
|
2024-01-13 00:10:03 +02:00
|
|
|
disabled={props.fullHourAvailableNames.length < 1}
|
|
|
|
title={generateTooltipText(props.fullHourAvailableNames)}
|
2024-01-11 12:52:41 +02:00
|
|
|
placement="top"
|
|
|
|
disableInteractive
|
|
|
|
followCursor={true}
|
|
|
|
arrow
|
|
|
|
enterDelay={500}
|
|
|
|
>
|
|
|
|
<Box
|
2024-01-13 00:07:50 +02:00
|
|
|
sx={{
|
2024-01-13 00:26:39 +02:00
|
|
|
bgcolor: determineCellColor(props.isFullHourSelected, props.fullHourAvailableNames, props.disabled)
|
2024-01-13 00:07:50 +02:00
|
|
|
}}
|
|
|
|
className={classNames("full-hour", { "selected-availability": props.isFullHourSelected, "hour-disabled": props.disabled })}
|
2024-01-11 12:52:41 +02:00
|
|
|
height={props.halfHourDisplayHeight}
|
|
|
|
onMouseEnter={(e) => props.onMouseEnterHalfhour(e, props.dateTime)}
|
|
|
|
onMouseDown={(e) => {
|
|
|
|
if (e.button !== 0 && e.button !== 2) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
props.onMouseClickOnHalfhour(props.dateTime, e.button === 2);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<Typography className={"noselect time-text"}>
|
|
|
|
{ utils.formatTimeFromHourOfDay(props.dateTime.hour(), 0) }
|
|
|
|
</Typography>
|
|
|
|
</Box>
|
|
|
|
</DisableableTooltip>
|
|
|
|
<DisableableTooltip
|
2024-01-13 00:10:03 +02:00
|
|
|
disabled={props.halfHourAvailableNames.length < 1}
|
|
|
|
title={generateTooltipText(props.halfHourAvailableNames)}
|
2024-01-11 12:52:41 +02:00
|
|
|
placement="top"
|
|
|
|
disableInteractive
|
|
|
|
followCursor={true}
|
|
|
|
arrow
|
|
|
|
enterDelay={500}
|
|
|
|
>
|
|
|
|
<Box
|
2024-01-13 00:07:50 +02:00
|
|
|
sx={{
|
2024-01-13 00:26:39 +02:00
|
|
|
bgcolor: determineCellColor(props.isHalfHourSelected, props.halfHourAvailableNames, props.disabled)
|
2024-01-13 00:07:50 +02:00
|
|
|
}}
|
|
|
|
className={classNames("half-hour", { "selected-availability": props.isHalfHourSelected, "hour-disabled": props.disabled })}
|
2024-01-11 12:52:41 +02:00
|
|
|
height={props.halfHourDisplayHeight}
|
2024-01-13 00:07:50 +02:00
|
|
|
onMouseEnter={(e) => props.onMouseEnterHalfhour(e, utils.createHalfHourFromFullHour(props.dateTime))}
|
2024-01-11 12:52:41 +02:00
|
|
|
onMouseDown={(e) => {
|
|
|
|
if (e.button !== 0 && e.button !== 2) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-01-13 00:07:50 +02:00
|
|
|
props.onMouseClickOnHalfhour(utils.createHalfHourFromFullHour(props.dateTime), e.button === 2);
|
2024-01-11 12:52:41 +02:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</DisableableTooltip>
|
|
|
|
</Box>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default AvailabilityPickerHour;
|