Days of the week in create form

This commit is contained in:
Ben Grant 2021-03-11 12:45:25 +11:00
parent 4c16a971a2
commit 4c36f2a550
4 changed files with 170 additions and 97 deletions

View file

@ -4,7 +4,7 @@ import isToday from 'dayjs/plugin/isToday';
import localeData from 'dayjs/plugin/localeData';
import updateLocale from 'dayjs/plugin/updateLocale';
import { Button } from 'components';
import { Button, ToggleField } from 'components';
import { useSettingsStore } from 'stores';
import {
@ -55,6 +55,8 @@ const CalendarField = ({
}) => {
const weekStart = useSettingsStore(state => state.weekStart);
const [type, setType] = useState(0);
const [dates, setDates] = useState(calculateMonth(dayjs().month(), dayjs().year(), weekStart));
const [month, setMonth] = useState(dayjs().month());
const [year, setYear] = useState(dayjs().year());
@ -67,6 +69,14 @@ const CalendarField = ({
_setSelectingDates(newDates);
};
const [selectedDays, setSelectedDays] = useState([]);
const [selectingDays, _setSelectingDays] = useState([]);
const staticSelectingDays = useRef([]);
const setSelectingDays = newDays => {
staticSelectingDays.current = newDays;
_setSelectingDays(newDays);
};
const startPos = useRef({});
const staticMode = useRef(null);
const [mode, _setMode] = useState(staticMode.current);
@ -93,10 +103,20 @@ const CalendarField = ({
id={id}
type="hidden"
ref={register}
value={JSON.stringify(selectedDates)}
value={type ? JSON.stringify(selectedDays) : JSON.stringify(selectedDates)}
{...props}
/>
<ToggleField
id="calendarMode"
name="calendarMode"
options={['Specific dates', 'Days of the week']}
value={type ? 'Days of the week' : 'Specific dates'}
onChange={value => setType(value === 'Specific dates' ? 0 : 1)}
/>
{type === 0 ? (
<>
<CalendarHeader>
<Button
buttonHeight="30px"
@ -130,8 +150,8 @@ const CalendarField = ({
</CalendarHeader>
<CalendarDays>
{dayjs.weekdaysShort().map((name, i) =>
<Day key={i}>{name}</Day>
{dayjs.weekdaysShort().map(name =>
<Day key={name}>{name}</Day>
)}
</CalendarDays>
<CalendarBody>
@ -176,6 +196,46 @@ const CalendarField = ({
)
)}
</CalendarBody>
</>
) : (
<CalendarBody>
{dayjs.weekdaysShort().map((name, i) =>
<Date
key={name}
isToday={dayjs.weekdaysShort()[dayjs().day()-weekStart] === name}
title={dayjs.weekdaysShort()[dayjs().day()-weekStart] === name ? 'Today' : ''}
selected={selectedDays.includes(((i + weekStart) % 7 + 7) % 7)}
selecting={selectingDays.includes(((i + weekStart) % 7 + 7) % 7)}
mode={mode}
onPointerDown={(e) => {
startPos.current = i;
setMode(selectedDays.includes(((i + weekStart) % 7 + 7) % 7) ? 'remove' : 'add');
setSelectingDays([((i + weekStart) % 7 + 7) % 7]);
e.currentTarget.releasePointerCapture(e.pointerId);
document.addEventListener('pointerup', () => {
if (staticMode.current === 'add') {
setSelectedDays([...selectedDays, ...staticSelectingDays.current]);
} else if (staticMode.current === 'remove') {
const toRemove = staticSelectingDays.current;
setSelectedDays(selectedDays.filter(d => !toRemove.includes(d)));
}
setMode(null);
}, { once: true });
}}
onPointerEnter={() => {
if (staticMode.current) {
let found = [];
for (let ci = Math.min(startPos.current, i); ci < Math.max(startPos.current, i)+1; ci++) {
found.push(((ci + weekStart) % 7 + 7) % 7);
}
setSelectingDays(found);
}
}}
>{name}</Date>
)}
</CalendarBody>
)}
</Wrapper>
);
};

View file

@ -12,7 +12,6 @@ export const StyledLabel = styled.label`
export const StyledSubLabel = styled.label`
display: block;
padding-bottom: 6px;
font-size: 13px;
opacity: .6;
`;

View file

@ -26,7 +26,6 @@ export const HiddenInput = styled.input`
width: 0;
position: absolute;
right: -1000px;
top: 0;
&:checked + label {
color: ${props => props.theme.background};
@ -36,8 +35,12 @@ export const HiddenInput = styled.input`
export const LabelButton = styled.label`
padding: 6px;
display: block;
display: flex;
text-align: center;
cursor: pointer;
user-select: none;
height: 100%;
box-sizing: border-box;
align-items: center;
justify-content: center;
`;

View file

@ -82,6 +82,7 @@ const Home = () => {
if (dates.length === 0) {
return setError(`You haven't selected any dates!`);
}
const isSpecificDates = typeof dates[0] === 'string' && dates[0].length === 8;
if (start === end) {
return setError(`The start and end times can't be the same`);
}
@ -89,28 +90,38 @@ const Home = () => {
let times = dates.reduce((times, date) => {
let day = [];
for (let i = start; i < (start > end ? 24 : end); i++) {
if (isSpecificDates) {
day.push(
dayjs.tz(date, 'DDMMYYYY', data.timezone)
.hour(i)
.minute(0)
.utc()
.format('HHmm-DDMMYYYY')
.hour(i).minute(0).utc().format('HHmm-DDMMYYYY')
);
} else {
day.push(
dayjs().tz(data.timezone)
.day(date).hour(i).minute(0).utc().format('HHmm-d')
);
}
}
if (start > end) {
for (let i = 0; i < end; i++) {
if (isSpecificDates) {
day.push(
dayjs.tz(date, 'DDMMYYYY', data.timezone)
.hour(i)
.minute(0)
.utc()
.format('HHmm-DDMMYYYY')
.hour(i).minute(0).utc().format('HHmm-DDMMYYYY')
);
} else {
day.push(
dayjs().tz(data.timezone)
.day(date).hour(i).minute(0).utc().format('HHmm-d')
);
}
}
}
return [...times, ...day];
}, []);
return console.log(times);
if (times.length === 0) {
return setError(`You don't have any time selected`);
}