mirror of
https://github.com/mvvasilev/findtheti.me.git
synced 2025-04-19 13:39:52 +03:00
Add disabled day display for large timezone differences. Disabled days will appear if a user is in a timezone so distant, that their availability pops into the next or previous day.
This commit is contained in:
parent
4abf196738
commit
7032156177
8 changed files with 124 additions and 62 deletions
|
@ -52,8 +52,8 @@ services:
|
||||||
In the end, your folder structure should be as follows:
|
In the end, your folder structure should be as follows:
|
||||||
```
|
```
|
||||||
installationDir/
|
installationDir/
|
||||||
| |-frontend/
|
|-frontend/
|
||||||
| |-dist/
|
| |-dist/
|
||||||
|-findtheti-me
|
|-findtheti-me
|
||||||
```
|
```
|
||||||
5. Next, create a `.env` file in the root of the installation directory, and look at `.env.example` for what should be in there
|
5. Next, create a `.env` file in the root of the installation directory, and look at `.env.example` for what should be in there
|
||||||
|
|
|
@ -60,8 +60,6 @@ const AvailabilityPicker = (props: {
|
||||||
let existingTime = day.availableTimes.findIndex(t => utils.dayjsIsBetweenUnixExclusive(t.fromTime, time, t.toTime));
|
let existingTime = day.availableTimes.findIndex(t => utils.dayjsIsBetweenUnixExclusive(t.fromTime, time, t.toTime));
|
||||||
|
|
||||||
if (existingTime >= 0) {
|
if (existingTime >= 0) {
|
||||||
console.log(`delete ${existingTime} from`, day)
|
|
||||||
|
|
||||||
day.availableTimes.splice(existingTime, 1);
|
day.availableTimes.splice(existingTime, 1);
|
||||||
|
|
||||||
let dayIndex = props.days.findIndex(d => d.forDate.unix() === day.forDate.unix());
|
let dayIndex = props.days.findIndex(d => d.forDate.unix() === day.forDate.unix());
|
||||||
|
@ -178,7 +176,6 @@ const AvailabilityPicker = (props: {
|
||||||
key={day.forDate.unix()}
|
key={day.forDate.unix()}
|
||||||
day={day}
|
day={day}
|
||||||
eventType={props.eventType}
|
eventType={props.eventType}
|
||||||
currentTotalRespondents={props.availabilityHeatmap.maxNumberOfRespondents}
|
|
||||||
halfHourDisplayHeight={HALFHOUR_DISPLAY_HEIGHT}
|
halfHourDisplayHeight={HALFHOUR_DISPLAY_HEIGHT}
|
||||||
availabilityHeatmap={props.availabilityHeatmap}
|
availabilityHeatmap={props.availabilityHeatmap}
|
||||||
onMouseEnterHalfhour={(e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>, time: dayjs.Dayjs) => {
|
onMouseEnterHalfhour={(e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>, time: dayjs.Dayjs) => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { AvailabilityDay, UserAvailabilityHeatmap } from "../types/Availabilities";
|
import { AvailabilityDay, UserAvailabilityHeatmap } from "../types/Availabilities";
|
||||||
import utils from "../utils";
|
import utils from "../utils";
|
||||||
import { Box, Card, Divider, Typography } from "@mui/material";
|
import { Box, Card, Divider, Tooltip, Typography } from "@mui/material";
|
||||||
import { EventTypes } from "../types/Event";
|
import { EventTypes } from "../types/Event";
|
||||||
import AvailabilityPickerHour from "./AvailabilityPickerHour";
|
import AvailabilityPickerHour from "./AvailabilityPickerHour";
|
||||||
import "./css/AvailabilityPicker.css";
|
import "./css/AvailabilityPicker.css";
|
||||||
|
@ -9,6 +9,7 @@ import utc from 'dayjs/plugin/utc';
|
||||||
import timezone from 'dayjs/plugin/timezone';
|
import timezone from 'dayjs/plugin/timezone';
|
||||||
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
||||||
import React, { useMemo } from "react";
|
import React, { useMemo } from "react";
|
||||||
|
import { InfoOutlined } from "@mui/icons-material";
|
||||||
|
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc)
|
||||||
dayjs.extend(timezone)
|
dayjs.extend(timezone)
|
||||||
|
@ -18,7 +19,6 @@ const AvailabilityPickerDay = (props: {
|
||||||
day: AvailabilityDay,
|
day: AvailabilityDay,
|
||||||
eventType: String,
|
eventType: String,
|
||||||
halfHourDisplayHeight: number,
|
halfHourDisplayHeight: number,
|
||||||
currentTotalRespondents: number,
|
|
||||||
availabilityHeatmap: UserAvailabilityHeatmap,
|
availabilityHeatmap: UserAvailabilityHeatmap,
|
||||||
onMouseEnterHalfhour: (e: React.MouseEvent<HTMLDivElement, globalThis.MouseEvent>, time: dayjs.Dayjs) => void,
|
onMouseEnterHalfhour: (e: React.MouseEvent<HTMLDivElement, globalThis.MouseEvent>, time: dayjs.Dayjs) => void,
|
||||||
onMouseClickHalfhour: (day: AvailabilityDay, time: dayjs.Dayjs, isDelete: boolean) => void
|
onMouseClickHalfhour: (day: AvailabilityDay, time: dayjs.Dayjs, isDelete: boolean) => void
|
||||||
|
@ -28,23 +28,32 @@ const AvailabilityPickerDay = (props: {
|
||||||
let hours: JSX.Element[] = [];
|
let hours: JSX.Element[] = [];
|
||||||
|
|
||||||
for (var i = 0; i < 24; i++) {
|
for (var i = 0; i < 24; i++) {
|
||||||
let fullHourTime = props.day.forDate.set("hour", i);
|
let fullHourTime = props.day.forDate.hour(i);
|
||||||
let halfHourTime = fullHourTime.add(30, "minutes");
|
let halfHourTime = utils.createHalfHourFromFullHour(fullHourTime);
|
||||||
|
|
||||||
hours.push(
|
hours.push(
|
||||||
<AvailabilityPickerHour
|
<AvailabilityPickerHour
|
||||||
key={fullHourTime.unix()}
|
key={fullHourTime.unix()}
|
||||||
|
disabled={props.day.disabled}
|
||||||
dateTime={fullHourTime}
|
dateTime={fullHourTime}
|
||||||
halfHourDisplayHeight={props.halfHourDisplayHeight}
|
halfHourDisplayHeight={props.halfHourDisplayHeight}
|
||||||
currentTotalRespondents={props.currentTotalRespondents}
|
currentTotalRespondents={props.availabilityHeatmap.maxNumberOfRespondents}
|
||||||
namesMarkedFullHourAsAvailable={props.availabilityHeatmap.getNamesAt(fullHourTime.unix())}
|
namesMarkedFullHourAsAvailable={props.availabilityHeatmap.getNamesAt(fullHourTime.unix())}
|
||||||
namesMarkedHalfHourAsAvailable={props.availabilityHeatmap.getNamesAt(fullHourTime.add(30, "minutes").unix())}
|
namesMarkedHalfHourAsAvailable={props.availabilityHeatmap.getNamesAt(halfHourTime.unix())}
|
||||||
isFullHourSelected={props.day.availableTimes.some(a => utils.dayjsIsBetweenUnixExclusive(a.fromTime, fullHourTime, a.toTime))}
|
isFullHourSelected={props.day.availableTimes.some(a => utils.dayjsIsBetweenUnixExclusive(a.fromTime, fullHourTime, a.toTime))}
|
||||||
isHalfHourSelected={props.day.availableTimes.some(a => utils.dayjsIsBetweenUnixExclusive(a.fromTime, halfHourTime, a.toTime))}
|
isHalfHourSelected={props.day.availableTimes.some(a => utils.dayjsIsBetweenUnixExclusive(a.fromTime, halfHourTime, a.toTime))}
|
||||||
onMouseEnterHalfhour={(e: React.MouseEvent<HTMLDivElement, globalThis.MouseEvent>, time: dayjs.Dayjs): void => {
|
onMouseEnterHalfhour={(e: React.MouseEvent<HTMLDivElement, globalThis.MouseEvent>, time: dayjs.Dayjs): void => {
|
||||||
|
if (props.day.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
props.onMouseEnterHalfhour(e, time);
|
props.onMouseEnterHalfhour(e, time);
|
||||||
}}
|
}}
|
||||||
onMouseClickOnHalfhour={(time: dayjs.Dayjs, isDelete: boolean): void => {
|
onMouseClickOnHalfhour={(time: dayjs.Dayjs, isDelete: boolean): void => {
|
||||||
|
if (props.day.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
props.onMouseClickHalfhour(props.day, time, isDelete);
|
props.onMouseClickHalfhour(props.day, time, isDelete);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -61,29 +70,33 @@ const AvailabilityPickerDay = (props: {
|
||||||
className={"day-card"}
|
className={"day-card"}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{ width: "100%" }}
|
sx={{ width: "100%" }}
|
||||||
padding={1}
|
padding={1}
|
||||||
>
|
height={"50px"}
|
||||||
{
|
>
|
||||||
(props.eventType === EventTypes.WEEK) &&
|
|
||||||
<Typography>
|
<Typography>
|
||||||
{ props.day.forDate.format("dddd") }
|
{
|
||||||
|
(props.eventType === EventTypes.WEEK) && props.day.forDate.format("dddd")
|
||||||
|
}
|
||||||
|
{
|
||||||
|
(props.eventType === EventTypes.DAY) && "Any Day"
|
||||||
|
}
|
||||||
|
{
|
||||||
|
(props.eventType === EventTypes.DATE_RANGE || props.eventType === EventTypes.SPECIFIC_DATE) && props.day.forDate.format("LL")
|
||||||
|
}
|
||||||
|
{
|
||||||
|
props.day.disabled &&
|
||||||
|
<Tooltip
|
||||||
|
title={props.day.disabled ? "This day is disabled and only shown as a result of timezone differences between yourself and another respondent" : ""}
|
||||||
|
placement="top"
|
||||||
|
arrow
|
||||||
|
>
|
||||||
|
<InfoOutlined sx={{ ml: 1 }} fontSize="inherit" />
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
</Box>
|
||||||
{
|
|
||||||
(props.eventType === EventTypes.DAY) &&
|
|
||||||
<Typography>
|
|
||||||
Any Day
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
(props.eventType === EventTypes.DATE_RANGE || props.eventType === EventTypes.SPECIFIC_DATE) &&
|
|
||||||
<Typography>
|
|
||||||
{ props.day.forDate.format("LL") }
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Divider></Divider>
|
<Divider></Divider>
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ dayjs.extend(localizedFormat)
|
||||||
|
|
||||||
const AvailabilityPickerHour = (props: {
|
const AvailabilityPickerHour = (props: {
|
||||||
dateTime: Dayjs,
|
dateTime: Dayjs,
|
||||||
|
disabled: boolean,
|
||||||
isFullHourSelected: boolean,
|
isFullHourSelected: boolean,
|
||||||
isHalfHourSelected: boolean,
|
isHalfHourSelected: boolean,
|
||||||
halfHourDisplayHeight: number,
|
halfHourDisplayHeight: number,
|
||||||
|
@ -28,12 +29,16 @@ const AvailabilityPickerHour = (props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
const heatMapColorforValue = (value: number) => {
|
const heatMapColorforValue = (value: number) => {
|
||||||
if (value === 0 || props.currentTotalRespondents === 0) {
|
// if (value === 0 || props.currentTotalRespondents === 0) {
|
||||||
return 'inherit';
|
// return 'inherit';
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
// if (value === 1 && props.currentTotalRespondents === 1) {
|
||||||
|
// return "hsl(" + 0 + ", 75%, 35%) !important";
|
||||||
|
// }
|
||||||
|
|
||||||
var h = (1.0 - (value / props.currentTotalRespondents)) * 240
|
var h = (1.0 - (value / props.currentTotalRespondents)) * 240
|
||||||
return "hsl(" + h + ", 75%, 35%)";
|
return "hsl(" + h + ", 75%, 35%) !important";
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -51,8 +56,10 @@ const AvailabilityPickerHour = (props: {
|
||||||
enterDelay={500}
|
enterDelay={500}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
className={classNames("full-hour", { "selected-availability": props.isFullHourSelected })}
|
sx={{
|
||||||
bgcolor={heatMapColorforValue(props.namesMarkedFullHourAsAvailable.length)}
|
bgcolor: props.namesMarkedFullHourAsAvailable.length > 0 ? heatMapColorforValue(props.namesMarkedFullHourAsAvailable.length) : 'inherit'
|
||||||
|
}}
|
||||||
|
className={classNames("full-hour", { "selected-availability": props.isFullHourSelected, "hour-disabled": props.disabled })}
|
||||||
height={props.halfHourDisplayHeight}
|
height={props.halfHourDisplayHeight}
|
||||||
onMouseEnter={(e) => props.onMouseEnterHalfhour(e, props.dateTime)}
|
onMouseEnter={(e) => props.onMouseEnterHalfhour(e, props.dateTime)}
|
||||||
onMouseDown={(e) => {
|
onMouseDown={(e) => {
|
||||||
|
@ -78,16 +85,18 @@ const AvailabilityPickerHour = (props: {
|
||||||
enterDelay={500}
|
enterDelay={500}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
className={classNames("half-hour", { "selected-availability": props.isHalfHourSelected })}
|
sx={{
|
||||||
bgcolor={heatMapColorforValue(props.namesMarkedHalfHourAsAvailable.length)}
|
bgcolor: props.namesMarkedHalfHourAsAvailable.length > 0 ? heatMapColorforValue(props.namesMarkedHalfHourAsAvailable.length) : 'inherit'
|
||||||
|
}}
|
||||||
|
className={classNames("half-hour", { "selected-availability": props.isHalfHourSelected, "hour-disabled": props.disabled })}
|
||||||
height={props.halfHourDisplayHeight}
|
height={props.halfHourDisplayHeight}
|
||||||
onMouseEnter={(e) => props.onMouseEnterHalfhour(e, props.dateTime.add(30, "minutes"))}
|
onMouseEnter={(e) => props.onMouseEnterHalfhour(e, utils.createHalfHourFromFullHour(props.dateTime))}
|
||||||
onMouseDown={(e) => {
|
onMouseDown={(e) => {
|
||||||
if (e.button !== 0 && e.button !== 2) {
|
if (e.button !== 0 && e.button !== 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
props.onMouseClickOnHalfhour(props.dateTime.add(30, "minutes"), e.button === 2);
|
props.onMouseClickOnHalfhour(utils.createHalfHourFromFullHour(props.dateTime), e.button === 2);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</DisableableTooltip>
|
</DisableableTooltip>
|
||||||
|
|
|
@ -22,7 +22,7 @@ div.hour-light {
|
||||||
background-color: var(--hour-light-color);
|
background-color: var(--hour-light-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.hour-dark {
|
div.hour-disabled {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-top: solid 1px;
|
border-top: solid 1px;
|
||||||
border-color: var(--hour-border-bolor);
|
border-color: var(--hour-border-bolor);
|
||||||
|
@ -47,7 +47,7 @@ div.selected-availability {
|
||||||
background-color: var(--hover-color);
|
background-color: var(--hover-color);
|
||||||
} */
|
} */
|
||||||
|
|
||||||
div.full-hour:active, div.half-hour:active {
|
div.full-hour:not(.hour-disabled):active, div.half-hour:not(.hour-disabled):active {
|
||||||
background-color: var(--active-color);
|
background-color: var(--active-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,6 @@ export default function ExistingEventPage() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
utils.showSpinner();
|
utils.showSpinner();
|
||||||
|
|
||||||
let localTimezone = dayjs.tz.guess();
|
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
utils.performRequest(`/api/events/${eventId}`)
|
utils.performRequest(`/api/events/${eventId}`)
|
||||||
.then(result => setEvent({
|
.then(result => setEvent({
|
||||||
|
@ -52,6 +50,8 @@ export default function ExistingEventPage() {
|
||||||
.then((result: [{ id: number, from_date: string, to_date: string, user_name: string }]) => {
|
.then((result: [{ id: number, from_date: string, to_date: string, user_name: string }]) => {
|
||||||
let heatmap = new UserAvailabilityHeatmap();
|
let heatmap = new UserAvailabilityHeatmap();
|
||||||
|
|
||||||
|
let localTimezone = dayjs.tz.guess();
|
||||||
|
|
||||||
const LENGTH_OF_30_MINUTES_IN_SECONDS = 1800;
|
const LENGTH_OF_30_MINUTES_IN_SECONDS = 1800;
|
||||||
|
|
||||||
for (const availability of result) {
|
for (const availability of result) {
|
||||||
|
@ -61,7 +61,30 @@ export default function ExistingEventPage() {
|
||||||
let startUnix = start.unix();
|
let startUnix = start.unix();
|
||||||
let endUnix = end.unix();
|
let endUnix = end.unix();
|
||||||
|
|
||||||
for (var timeInUnix = startUnix; timeInUnix <= endUnix; timeInUnix += LENGTH_OF_30_MINUTES_IN_SECONDS) {
|
let startDay = start.startOf("day");
|
||||||
|
let endDay = end.startOf("day");
|
||||||
|
|
||||||
|
// Add day on which this availability period is starts on ( timezone difference could be so large that it's in the previous day )
|
||||||
|
// This day will be disabled and unavailable for adding own availability, unless it falls within the events own from-to range.
|
||||||
|
if (!heatmap.daysWhenAvailabilitiesPresent.some(d => d.forDate.unix() === startDay.unix())) {
|
||||||
|
heatmap.daysWhenAvailabilitiesPresent.push({
|
||||||
|
forDate: startDay,
|
||||||
|
disabled: true,
|
||||||
|
availableTimes: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add day on which this availability period is set to end ( timezone difference could be so large that it flips to the next day )
|
||||||
|
// This day will be disabled and unavailable for adding own availability, unless it falls within the events own from-to range.
|
||||||
|
if (end.unix() !== endDay.unix() && !heatmap.daysWhenAvailabilitiesPresent.some(d => d.forDate.unix() === endDay.unix())) {
|
||||||
|
heatmap.daysWhenAvailabilitiesPresent.push({
|
||||||
|
forDate: endDay,
|
||||||
|
disabled: true,
|
||||||
|
availableTimes: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var timeInUnix = startUnix; timeInUnix < endUnix; timeInUnix += LENGTH_OF_30_MINUTES_IN_SECONDS) {
|
||||||
heatmap.addName(timeInUnix, availability.user_name);
|
heatmap.addName(timeInUnix, availability.user_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +93,7 @@ export default function ExistingEventPage() {
|
||||||
})
|
})
|
||||||
.catch(e => toast.error(e))
|
.catch(e => toast.error(e))
|
||||||
])
|
])
|
||||||
.finally(() => utils.hideSpinner());;
|
.finally(() => utils.hideSpinner())
|
||||||
|
|
||||||
}, [eventId]);
|
}, [eventId]);
|
||||||
|
|
||||||
|
@ -106,25 +129,41 @@ export default function ExistingEventPage() {
|
||||||
let localFromDate = event.fromDate.tz(localTimezone);
|
let localFromDate = event.fromDate.tz(localTimezone);
|
||||||
let localToDate = event.toDate.tz(localTimezone);
|
let localToDate = event.toDate.tz(localTimezone);
|
||||||
|
|
||||||
|
var days: AvailabilityDay[] = [];
|
||||||
|
|
||||||
switch (event.eventType) {
|
switch (event.eventType) {
|
||||||
case EventTypes.SPECIFIC_DATE: {
|
case EventTypes.SPECIFIC_DATE: {
|
||||||
createAvailabilitiesBasedOnInitialDate(localFromDate, 1);
|
days = createAvailabilitiesBasedOnInitialDate(localFromDate, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EventTypes.DATE_RANGE: {
|
case EventTypes.DATE_RANGE: {
|
||||||
createAvailabilitiesBasedOnInitialDate(localFromDate, Math.abs(localFromDate.diff(localToDate, "day", false)));
|
days = createAvailabilitiesBasedOnInitialDate(localFromDate, Math.abs(localFromDate.diff(localToDate, "day", false)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EventTypes.DAY: {
|
case EventTypes.DAY: {
|
||||||
createAvailabilitiesBasedOnUnspecifiedInitialDate(1, localTimezone);
|
days = createAvailabilitiesBasedOnUnspecifiedInitialDate(1, localTimezone);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EventTypes.WEEK: {
|
case EventTypes.WEEK: {
|
||||||
createAvailabilitiesBasedOnUnspecifiedInitialDate(7, localTimezone);
|
days = createAvailabilitiesBasedOnUnspecifiedInitialDate(7, localTimezone);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [event]);
|
|
||||||
|
availabilityHeatmap?.daysWhenAvailabilitiesPresent.forEach(hd => {
|
||||||
|
let createdDay = days.find(cd => cd.forDate.unix() === hd.forDate.unix());
|
||||||
|
|
||||||
|
if (createdDay) {
|
||||||
|
createdDay.disabled = false;
|
||||||
|
} else {
|
||||||
|
days.push(hd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
days.sort((a, b) => a.forDate.unix() - b.forDate.unix());
|
||||||
|
|
||||||
|
setDays([...days])
|
||||||
|
}, [event, availabilityHeatmap]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
var valid = !utils.isNullOrUndefined(userName) && userName !== "";
|
var valid = !utils.isNullOrUndefined(userName) && userName !== "";
|
||||||
|
@ -134,23 +173,24 @@ export default function ExistingEventPage() {
|
||||||
setCanSubmit(valid);
|
setCanSubmit(valid);
|
||||||
}, [userName, days]);
|
}, [userName, days]);
|
||||||
|
|
||||||
const createAvailabilitiesBasedOnUnspecifiedInitialDate = (numberOfDays: number, tz: string) => {
|
const createAvailabilitiesBasedOnUnspecifiedInitialDate = (numberOfDays: number, tz: string): AvailabilityDay[] => {
|
||||||
createAvailabilitiesBasedOnInitialDate(dayjs.tz("1970-01-05 00:00:00", tz), numberOfDays);
|
return createAvailabilitiesBasedOnInitialDate(dayjs.tz("1970-01-05 00:00:00", tz), numberOfDays);
|
||||||
}
|
}
|
||||||
|
|
||||||
const createAvailabilitiesBasedOnInitialDate = (date: Dayjs, numberOfDays: number) => {
|
const createAvailabilitiesBasedOnInitialDate = (date: Dayjs, numberOfDays: number): AvailabilityDay[] => {
|
||||||
let availabilities: AvailabilityDay[] = [];
|
let availabilities: AvailabilityDay[] = [];
|
||||||
|
|
||||||
for (var i: number = 0; i < numberOfDays; i++) {
|
for (var i: number = 0; i < numberOfDays; i++) {
|
||||||
let availability: AvailabilityDay = {
|
let availability: AvailabilityDay = {
|
||||||
forDate: date.add(i, "day").startOf("day"),
|
forDate: date.add(i, "day").startOf("day"),
|
||||||
|
disabled: false,
|
||||||
availableTimes: []
|
availableTimes: []
|
||||||
}
|
}
|
||||||
|
|
||||||
availabilities.push(availability);
|
availabilities.push(availability);
|
||||||
}
|
}
|
||||||
|
|
||||||
setDays(availabilities);
|
return availabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitAvailabilities = () => {
|
const submitAvailabilities = () => {
|
||||||
|
|
|
@ -7,6 +7,7 @@ export type AvailabilityTime = {
|
||||||
|
|
||||||
export type AvailabilityDay = {
|
export type AvailabilityDay = {
|
||||||
forDate: Dayjs,
|
forDate: Dayjs,
|
||||||
|
disabled: boolean,
|
||||||
availableTimes: AvailabilityTime[]
|
availableTimes: AvailabilityTime[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,12 +16,11 @@ export type UserAvailabilityHeatmapValue = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserAvailabilityHeatmap {
|
export class UserAvailabilityHeatmap {
|
||||||
private map: UserAvailabilityHeatmapValue[];
|
private map: any = {};
|
||||||
public maxNumberOfRespondents: number;
|
public maxNumberOfRespondents: number = 0;
|
||||||
|
public daysWhenAvailabilitiesPresent: AvailabilityDay[] = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.map = [];
|
|
||||||
this.maxNumberOfRespondents = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addName(unixTime: number, name: String): void {
|
addName(unixTime: number, name: String): void {
|
||||||
|
|
|
@ -78,6 +78,9 @@ const utils = {
|
||||||
},
|
},
|
||||||
isNullOrUndefined: (thing: any): boolean => {
|
isNullOrUndefined: (thing: any): boolean => {
|
||||||
return thing === null || thing === undefined;
|
return thing === null || thing === undefined;
|
||||||
|
},
|
||||||
|
createHalfHourFromFullHour: (fullHour: Dayjs): Dayjs => {
|
||||||
|
return fullHour.add(30, "minutes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue