@parkassist/pa-ui-library
Version:
INX Platform elements
370 lines (369 loc) • 12.7 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React, { useEffect, useState } from "react";
import DayRangePicker from "./DateRangeCalendar2";
import { Column, Row } from "../Layout/Flex";
import Modal from "../Modal";
import styled from "styled-components";
import "react-day-picker/lib/style.css";
import { Separator } from "../../index";
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import { ExpandMore } from "@mui/icons-material";
import Typography from "@mui/material/Typography";
import FontStyles from "../../constants/FontStyles";
import { ClockSquareIcon } from "../Icons";
import AccordionDetails from "@mui/material/AccordionDetails";
import FormControl from "@mui/material/FormControl";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Radio from "@mui/material/Radio";
import DaysPicker from "./DaysPicker";
import TimeRangePicker from "./TimeRangePicker";
import dayjs from "dayjs";
import Helmet from "react-helmet";
import Palette from "../../constants/Palette";
import { StyledEngineProvider } from "@mui/material/styles";
import * as Icons from "../Icons";
import { formatToDesiredTimezone, formatToLocalTimezone } from '../DateRangePicker';
import MaterialInput from '../MaterialInput';
const SelectorWrapper = styled.div(() => ({
marginTop: 0
}));
const LabelWrapper = styled(Row)(() => ({
marginBottom: 1,
font: FontStyles.LABEL_FONT
}));
const FakeSelector = styled.div(({
width,
backgroundColor,
borderColor
}) => ({
width,
minWidth: 180,
display: "flex",
paddingLeft: 8,
alignItems: "center",
backgroundColor,
border: `1px solid ${borderColor}`,
borderRadius: 3,
color: Palette.BLACK,
height: 32
}));
const timeTabs = (selectDayOfTheWeekText, selectTimePeriodText, selectTimeScheduleText) => [{
name: "DAY_OF_WEEK",
value: "0",
label: selectDayOfTheWeekText || "Select Day of the Week"
}, {
name: "TIME_PERIOD",
value: "1",
label: selectTimePeriodText || "Select Time Period"
}, {
name: "TIME_SCHEDULE",
value: "2",
label: selectTimeScheduleText || "Select Time Schedule"
}];
const NewDateRangePickerComponent = ({
from,
to,
hourFrom = "00:00:00",
hourTo = "23:59:59",
onUpdate = () => null,
width,
label = null,
backgroundColor = Palette.WHITE,
borderColor = Palette.DIM_GREY,
hideHourFilter = false,
allowedTabs = ["DAY_OF_WEEK", "TIME_PERIOD", "TIME_SCHEDULE"],
timezoneId,
rangeLimit,
minDate,
maxDate,
isAmPm = true,
minimalDateFormat = "M/DD",
compactDateFormat = "YYYY-MM-DD hh:mm a",
weekStartsOn = 0,
useMaterialInput = true,
showSelectedDays = false,
title = "Date and time range",
saveText = "Save",
locale,
selectDayOfTheWeekText = "Select Day of the Week",
selectTimePeriodText = "Select Time Period",
selectTimeScheduleText = "Select Time Schedule",
startText = "Start",
endText = "End",
detailedRangeText = "Detailed range",
everydayFromText = "Everyday From",
everydayToText = "Everyday To",
days = null,
timeStaticRanges = {}
}) => {
var _a;
const tabs = timeTabs(selectDayOfTheWeekText, selectTimePeriodText, selectTimeScheduleText).filter(tab => allowedTabs.includes(tab.name));
const [open, setOpen] = useState(false);
const [hourRange, setHourRange] = useState([hourFrom, hourTo, isAmPm]);
const [partialDate, setPartialDate] = useState(JSON.parse(JSON.stringify({
from,
to
})));
const compactTimeFormat = hourRange[2] ? "hh:mm a" : "HH:mm";
const [timeRange, setTimeRange] = useState({
hourFrom: dayjs(hourFrom, 'HH:mm:ss'),
hourTo: dayjs(hourTo, 'HH:mm:ss')
});
const [radioValue, setRadioValue] = React.useState(((_a = tabs[0]) === null || _a === void 0 ? void 0 : _a.value) || "0");
const [daysOfWeek, setDaysOfWeek] = React.useState({
monday: true,
tuesday: true,
wednesday: true,
thursday: true,
friday: true,
saturday: true,
sunday: true
});
const [selectedDays, setSelectedDays] = React.useState(["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]);
useEffect(() => {
let isMounted = true;
if (isMounted) {
setPartialDate(JSON.parse(JSON.stringify({
from,
to
})));
setHourRange([dayjs(hourFrom, 'HH:mm:ss').format(compactTimeFormat), dayjs(hourTo, 'HH:mm:ss').format(compactTimeFormat), isAmPm]);
}
return () => {
isMounted = false;
};
}, [to, from, hourFrom, hourTo]);
const selectorWidth = width || (hideHourFilter ? 120 : "auto");
const rangeToZeroHour = range => {
const fromResult = dayjs(partialDate.from).tz(timezoneId).startOf("day");
const toResult = dayjs(partialDate.to).tz(timezoneId).endOf("day");
const hourFrom = range.hourFrom.date(fromResult.date()).month(fromResult.month()).year(fromResult.year()).format();
const hourTo = range.hourTo.date(toResult.date()).month(toResult.month()).year(toResult.year()).format();
setHourRange([dayjs(hourFrom).format(compactTimeFormat), dayjs(hourTo).format(compactTimeFormat), isAmPm]);
return {
from: fromResult.format(),
to: toResult.format(),
hourFrom,
hourTo
};
};
const togglePopover = () => setOpen(!open);
const forceClosePopover = () => setOpen(false);
const toToShow = formatToLocalTimezone(partialDate.to);
const fromToShow = formatToLocalTimezone(partialDate.from);
const format = date => dayjs(date).format(minimalDateFormat);
let textToShow = `${format(fromToShow)} - ${format(toToShow)}`;
if (!hideHourFilter) textToShow += ` — ${hourRange[0]} - ${hourRange[1]}`;
const mobile = window.innerWidth < 900;
const confirmChanges = () => {
const range = timeRange;
let dayNames = [];
Object.entries(daysOfWeek).map(([key, value]) => {
if (value) {
dayNames.push(key);
}
return dayNames;
});
setSelectedDays(dayNames);
onUpdate(rangeToZeroHour(range));
forceClosePopover();
};
const handleChange = e => {
setRadioValue(e.target.value);
};
const handleSelectedDays = days => {
setDaysOfWeek(days);
};
const handleSelectedHours = hours => {
setTimeRange(Object.assign(Object.assign({}, timeRange), {
hourFrom: hours.hourFrom,
hourTo: hours.hourTo
}));
};
const btnDisabled = () => {
const from = dayjs(timeRange.hourFrom, 'HH:mm:ss');
const to = dayjs(timeRange.hourTo, 'HH:mm:ss');
return from.isAfter(to);
};
return _jsxs(StyledEngineProvider, {
injectFirst: true,
children: [_jsx(Modal, {
hideButtons: false,
visible: open,
modalTitle: title,
onClose: () => {
setPartialDate(JSON.parse(JSON.stringify({
from,
to
})));
forceClosePopover();
},
onConfirm: () => {
confirmChanges();
},
okDisabled: btnDisabled(),
width: mobile ? 350 : 920,
height: 900,
okButton: saveText,
padding: "24px",
children: _jsxs(Column, {
style: {
width: "100%",
height: "100%",
font: FontStyles.BODY2_FONT
},
children: [_jsx(DayRangePicker, {
weekStartsOn: weekStartsOn,
rangeLimit: rangeLimit,
minDate: minDate,
maxDate: maxDate,
locale: locale,
timeStaticRanges: timeStaticRanges,
update: range => {
const preferedZoneStr = timezoneId;
if (!range.selection.startDate || !range.selection.endDate) {
return;
}
const from = formatToDesiredTimezone(range.selection.startDate, preferedZoneStr).startOf("day");
const to = formatToDesiredTimezone(range.selection.endDate, preferedZoneStr).endOf("day");
setPartialDate({
from,
to
});
},
to: toToShow,
from: fromToShow,
timezoneId: timezoneId
}), !hideHourFilter && _jsxs(_Fragment, {
children: [_jsx(Separator, {}), _jsx(Row, {
style: {
width: "auto"
},
children: _jsxs(Accordion, {
children: [_jsx(AccordionSummary, {
expandIcon: _jsx(ExpandMore, {}),
"aria-controls": "panel1a-content",
id: "panel1a-header",
children: _jsxs(Typography, {
style: {
display: "flex",
flexDirection: "row"
},
children: [_jsx(ClockSquareIcon, {
style: {
marginRight: 16
}
}), " ", detailedRangeText]
})
}), _jsxs(AccordionDetails, {
children: [_jsx(FormControl, {
children: _jsx(RadioGroup, {
row: true,
name: "row-radio-buttons-group",
value: radioValue,
onChange: handleChange,
children: tabs.map(tab => _jsx(FormControlLabel, {
value: tab.value,
control: _jsx(Radio, {}),
label: tab.label
}))
})
}), radioValue === "0" && _jsx(DaysPicker, {
days: days,
selectedWeekDays: handleSelectedDays
}), radioValue === "1" && _jsx(TimeRangePicker, {
timeRange: timeRange,
labelFrom: startText,
labelTo: endText,
selectedHours: hour => handleSelectedHours(hour),
periodRange: true
}), radioValue === "2" && _jsx(TimeRangePicker, {
timeRange: timeRange,
labelFrom: everydayFromText,
labelTo: everydayToText,
selectedHours: hour => handleSelectedHours(hour),
scheduleRange: true
})]
})]
})
})]
})]
})
}), useMaterialInput ? _jsx(SelectorWrapper, {
style: {
width: selectorWidth
},
children: _jsx(MaterialInput, {
label: label,
iconEnd: _jsx(Icons.CalendarIcon, {
onClick: () => togglePopover()
}),
fullWidth: true,
onFocus: () => togglePopover(),
value: textToShow,
readOnly: true
})
}) : _jsxs(SelectorWrapper, {
children: [label && _jsx(LabelWrapper, {
children: label
}), _jsx(FakeSelector, {
width: selectorWidth,
backgroundColor: backgroundColor,
borderColor: borderColor,
onClick: () => togglePopover(),
children: _jsxs(Row, {
style: {
font: FontStyles.BODY1_FONT
},
children: [_jsx(Column, {
style: {
marginRight: 8,
marginTop: 1
},
children: _jsx(Icons.CalendarIcon, {
size: 15
})
}), _jsx(Column, {
children: textToShow
})]
})
})]
}), showSelectedDays && _jsx(Row, {
children: _jsxs(Column, {
children: [_jsx(LabelWrapper, {
children: "Selected days of week:"
}), selectedDays.map((day, i) => _jsx("div", {
children: day
}, i))]
})
}), _jsx(Helmet, {
children: _jsx("style", {
children: `
.MuiAccordionDetails-root .MuiFormControl-root,
.MuiAccordion-root.MuiPaper-root {
width: 100%;
margin-bottom: 24px;
}
.Mui-checked.MuiRadio-root.MuiRadio-colorPrimary {
color: ${Palette.BLACK};
}
.MuiPickersClock-pin,
.MuiPickersClockPointer-pointer,
.MuiPickersClockPointer-noPoint,
.MuiPickersToolbar-toolbar {
background-color: ${Palette.BLACK};
}
.MuiPickersClockPointer-thumb {
border-color: ${Palette.BLACK};
}
.MuiButton-textPrimary {
color: ${Palette.BLACK};
}
`
})
})]
});
};
export default NewDateRangePickerComponent;