@chayns-components/date
Version:
A set of beautiful React components for developing your own applications with chayns.
238 lines • 8.5 kB
JavaScript
import { Checkbox, Popup, useElementSize } from '@chayns-components/core';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { HintTextPosition } from '../../types/openingTimes';
import HintText from './hint-text/HintText';
import OpeningInputs from './opening-inputs/OpeningInputs';
import { StyledOpeningTimes, StyledOpeningTimesTooltipContent, StyledOpeningTimesWeekDay, StyledOpeningTimesWrapper } from './OpeningTimes.styles';
const OpeningTimes = _ref => {
let {
closedText = 'closed',
currentDayId,
editMode = false,
hintText,
hintTextPosition = HintTextPosition.Bottom,
openingTimes,
weekdays,
onChange,
onTimeAdd,
onTimeRemove
} = _ref;
const [newOpeningTimes, setNewOpeningTimes] = useState();
const [invalidOpeningTimes, setInvalidOpeningTimes] = useState([]);
const [isPopupOpen, setIsPopupOpen] = useState(false);
const ref = useRef(null);
const popupRef = useRef(null);
useEffect(() => {
setNewOpeningTimes(openingTimes);
}, [openingTimes]);
const validateTime = useCallback((newTime, dayId) => {
if (newTime.start === newTime.end || newTime.start >= newTime.end) {
return false;
}
const dayTimes = newOpeningTimes?.find(day => day.id === dayId)?.times || [];
return dayTimes.every(time => time.id === newTime.id || newTime.end <= time.start || newTime.start >= time.end);
}, [newOpeningTimes]);
const handleCheckBoxChange = useCallback(id => {
setNewOpeningTimes(prevOpeningTimes => {
const updatedOpeningTimes = (prevOpeningTimes ?? []).map(openingTime => {
if (openingTime.id === id) {
return {
...openingTime,
isDisabled: !openingTime.isDisabled
};
}
return openingTime;
});
if (typeof onChange === 'function') {
onChange({
enabledDays: updatedOpeningTimes.filter(item => !item.isDisabled).map(item => item.id)
});
}
return updatedOpeningTimes;
});
}, [onChange]);
const handleChange = useCallback((newTime, id) => {
const isValid = validateTime(newTime, id);
setNewOpeningTimes(prevOpeningTimes => {
const updatedOpeningTimes = (prevOpeningTimes ?? []).map(openingTime => {
if (openingTime.id === id) {
const newTimes = openingTime.times.map(time => {
if (time.id === newTime.id) {
return newTime;
}
return time;
});
return {
...openingTime,
times: newTimes
};
}
return openingTime;
});
const changedOpeningTime = updatedOpeningTimes.find(updatedOpeningTime => updatedOpeningTime.id === id);
if (typeof onChange === 'function') {
onChange({
isValid,
dayId: changedOpeningTime?.id,
time: newTime
});
}
return updatedOpeningTimes;
});
}, [onChange, validateTime]);
const handleAdd = useCallback((time, id) => {
const isValid = validateTime(time, id);
if (typeof onTimeAdd === 'function') {
onTimeAdd({
time,
dayId: id,
isValid
});
}
setNewOpeningTimes(prevOpeningTimes => (prevOpeningTimes ?? []).map(openingTime => {
if (openingTime.id === id) {
return {
...openingTime,
times: [...openingTime.times, time]
};
}
return openingTime;
}));
}, [onTimeAdd, validateTime]);
const handleUpdateInvalidIds = useCallback((openingTimeId, invalidTimeIds) => {
setInvalidOpeningTimes(prevState => {
const updatedInvalidOpeningTimes = prevState.map(invalidOpeningTime => {
if (invalidOpeningTime.openingTimeId === openingTimeId) {
return {
openingTimeId,
invalidTimeIds
};
}
return invalidOpeningTime;
});
if (!updatedInvalidOpeningTimes.some(_ref2 => {
let {
openingTimeId: updatedInvalidOpeningId
} = _ref2;
return updatedInvalidOpeningId === openingTimeId;
}) && invalidTimeIds.length > 0) {
updatedInvalidOpeningTimes.push({
openingTimeId,
invalidTimeIds
});
}
return updatedInvalidOpeningTimes.filter(updatedInvalidOpeningTime => updatedInvalidOpeningTime.invalidTimeIds.length !== 0);
});
}, []);
const handleRemove = useCallback(id => {
setNewOpeningTimes(prevOpeningTimes => (prevOpeningTimes ?? []).map(openingTime => {
const newTimes = openingTime.times.filter(time => time.id !== id);
return {
...openingTime,
times: newTimes
};
}));
if (typeof onTimeRemove === 'function') {
onTimeRemove(id);
}
}, [onTimeRemove]);
const content = useMemo(() => {
const items = [];
if (!newOpeningTimes) {
return items;
}
newOpeningTimes.forEach(_ref3 => {
let {
times,
id,
weekdayId,
isDisabled
} = _ref3;
const weekday = weekdays.find(weekDay => weekDay.id === weekdayId)?.name;
if (!weekday) {
return;
}
items.push(/*#__PURE__*/React.createElement(StyledOpeningTimesWrapper, {
key: `openingTimes__${id}`
}, editMode ? /*#__PURE__*/React.createElement(Checkbox, {
isChecked: !isDisabled,
onChange: () => handleCheckBoxChange(id)
}, weekday) : /*#__PURE__*/React.createElement(StyledOpeningTimesWeekDay, null, weekday), /*#__PURE__*/React.createElement(OpeningInputs, {
closedText: closedText,
currentDayId: currentDayId,
id: id,
times: times,
isDisabled: isDisabled,
onInvalid: handleUpdateInvalidIds,
onChange: newTime => handleChange(newTime, id),
onRemove: handleRemove,
onAdd: handleAdd,
editMode: editMode
})));
});
return items;
}, [closedText, currentDayId, editMode, handleAdd, handleChange, handleCheckBoxChange, handleRemove, handleUpdateInvalidIds, newOpeningTimes, weekdays]);
const size = useElementSize(ref);
const hidePopup = useCallback(() => {
setIsPopupOpen(false);
popupRef.current?.hide();
}, []);
const showPopup = useCallback(() => {
setIsPopupOpen(true);
popupRef.current?.show();
}, []);
const displayedContent = useMemo(() => {
if (!currentDayId || editMode) {
return content;
}
const singleDay = newOpeningTimes?.find(_ref4 => {
let {
id
} = _ref4;
return id === currentDayId;
});
if (!singleDay) {
return content;
}
const {
id,
times,
weekdayId
} = singleDay;
const weekday = weekdays.find(weekDay => weekDay.id === weekdayId)?.name;
return /*#__PURE__*/React.createElement(StyledOpeningTimesWrapper, {
key: `currentDay__${currentDayId}`,
style: size && {
width: size.width
},
onMouseEnter: showPopup,
onMouseLeave: hidePopup,
onClick: () => isPopupOpen ? hidePopup() : showPopup()
}, /*#__PURE__*/React.createElement(Popup, {
onShow: () => setIsPopupOpen(true),
onHide: () => setIsPopupOpen(false),
ref: popupRef,
content: /*#__PURE__*/React.createElement(StyledOpeningTimesTooltipContent, {
key: "opening-time-tooltip"
}, content)
}, /*#__PURE__*/React.createElement(StyledOpeningTimesWeekDay, null, weekday)), /*#__PURE__*/React.createElement(OpeningInputs, {
closedText: closedText,
currentDayId: currentDayId,
onInvalid: handleUpdateInvalidIds,
id: id,
times: times,
editMode: editMode
}));
}, [currentDayId, editMode, newOpeningTimes, weekdays, size, showPopup, hidePopup, content, closedText, handleUpdateInvalidIds, isPopupOpen]);
const shouldShowHint = useMemo(() => invalidOpeningTimes.length > 0, [invalidOpeningTimes.length]);
return useMemo(() => /*#__PURE__*/React.createElement(StyledOpeningTimes, {
ref: ref
}, shouldShowHint && hintText && hintTextPosition === HintTextPosition.Top && /*#__PURE__*/React.createElement(HintText, {
text: hintText
}), displayedContent, shouldShowHint && hintText && hintTextPosition === HintTextPosition.Bottom && /*#__PURE__*/React.createElement(HintText, {
text: hintText
})), [displayedContent, hintText, hintTextPosition, shouldShowHint]);
};
OpeningTimes.displayName = 'OpeningTimes';
export default OpeningTimes;
//# sourceMappingURL=OpeningTimes.js.map