From 4c36f2a550733ef9559b27931a335c8212b8eef0 Mon Sep 17 00:00:00 2001 From: Ben Grant Date: Thu, 11 Mar 2021 12:45:25 +1100 Subject: [PATCH] Days of the week in create form --- .../CalendarField/CalendarField.tsx | 220 +++++++++++------- .../CalendarField/calendarFieldStyle.ts | 1 - .../ToggleField/toggleFieldStyle.ts | 7 +- crabfit-frontend/src/pages/Home/Home.tsx | 39 ++-- 4 files changed, 170 insertions(+), 97 deletions(-) diff --git a/crabfit-frontend/src/components/CalendarField/CalendarField.tsx b/crabfit-frontend/src/components/CalendarField/CalendarField.tsx index dea287e..b46e631 100644 --- a/crabfit-frontend/src/components/CalendarField/CalendarField.tsx +++ b/crabfit-frontend/src/components/CalendarField/CalendarField.tsx @@ -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,7 +55,9 @@ const CalendarField = ({ }) => { const weekStart = useSettingsStore(state => state.weekStart); - const [dates, setDates] = useState(calculateMonth(dayjs().month(), dayjs().year(), 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,89 +103,139 @@ const CalendarField = ({ id={id} type="hidden" ref={register} - value={JSON.stringify(selectedDates)} + value={type ? JSON.stringify(selectedDays) : JSON.stringify(selectedDates)} {...props} /> - - - {dayjs.months()[month]} {year} - - + setType(value === 'Specific dates' ? 0 : 1)} + /> - - {dayjs.weekdaysShort().map((name, i) => - {name} - )} - - - {dates.length > 0 && dates.map((dateRow, y) => - dateRow.map((date, x) => - { - startPos.current = {x, y}; - setMode(selectedDates.includes(date.format('DDMMYYYY')) ? 'remove' : 'add'); - setSelectingDates([date]); - e.currentTarget.releasePointerCapture(e.pointerId); + {type === 0 ? ( + <> + + + {dayjs.months()[month]} {year} + + - document.addEventListener('pointerup', () => { - if (staticMode.current === 'add') { - setSelectedDates([...selectedDates, ...staticSelectingDates.current.map(d => d.format('DDMMYYYY'))]); - } else if (staticMode.current === 'remove') { - const toRemove = staticSelectingDates.current.map(d => d.format('DDMMYYYY')); - setSelectedDates(selectedDates.filter(d => !toRemove.includes(d))); - } - setMode(null); - }, { once: true }); - }} - onPointerEnter={() => { - if (staticMode.current) { - let found = []; - for (let cy = Math.min(startPos.current.y, y); cy < Math.max(startPos.current.y, y)+1; cy++) { - for (let cx = Math.min(startPos.current.x, x); cx < Math.max(startPos.current.x, x)+1; cx++) { - found.push({y: cy, x: cx}); - } - } - setSelectingDates(found.map(d => dates[d.y][d.x])); - } - }} - >{date.date()} - ) - )} - + + {dayjs.weekdaysShort().map(name => + {name} + )} + + + {dates.length > 0 && dates.map((dateRow, y) => + dateRow.map((date, x) => + { + startPos.current = {x, y}; + setMode(selectedDates.includes(date.format('DDMMYYYY')) ? 'remove' : 'add'); + setSelectingDates([date]); + e.currentTarget.releasePointerCapture(e.pointerId); + + document.addEventListener('pointerup', () => { + if (staticMode.current === 'add') { + setSelectedDates([...selectedDates, ...staticSelectingDates.current.map(d => d.format('DDMMYYYY'))]); + } else if (staticMode.current === 'remove') { + const toRemove = staticSelectingDates.current.map(d => d.format('DDMMYYYY')); + setSelectedDates(selectedDates.filter(d => !toRemove.includes(d))); + } + setMode(null); + }, { once: true }); + }} + onPointerEnter={() => { + if (staticMode.current) { + let found = []; + for (let cy = Math.min(startPos.current.y, y); cy < Math.max(startPos.current.y, y)+1; cy++) { + for (let cx = Math.min(startPos.current.x, x); cx < Math.max(startPos.current.x, x)+1; cx++) { + found.push({y: cy, x: cx}); + } + } + setSelectingDates(found.map(d => dates[d.y][d.x])); + } + }} + >{date.date()} + ) + )} + + + ) : ( + + {dayjs.weekdaysShort().map((name, i) => + { + 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} + )} + + )} ); }; diff --git a/crabfit-frontend/src/components/CalendarField/calendarFieldStyle.ts b/crabfit-frontend/src/components/CalendarField/calendarFieldStyle.ts index e415def..b664e32 100644 --- a/crabfit-frontend/src/components/CalendarField/calendarFieldStyle.ts +++ b/crabfit-frontend/src/components/CalendarField/calendarFieldStyle.ts @@ -12,7 +12,6 @@ export const StyledLabel = styled.label` export const StyledSubLabel = styled.label` display: block; - padding-bottom: 6px; font-size: 13px; opacity: .6; `; diff --git a/crabfit-frontend/src/components/ToggleField/toggleFieldStyle.ts b/crabfit-frontend/src/components/ToggleField/toggleFieldStyle.ts index a1e91aa..c33601c 100644 --- a/crabfit-frontend/src/components/ToggleField/toggleFieldStyle.ts +++ b/crabfit-frontend/src/components/ToggleField/toggleFieldStyle.ts @@ -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; `; diff --git a/crabfit-frontend/src/pages/Home/Home.tsx b/crabfit-frontend/src/pages/Home/Home.tsx index 4e718a3..623cbde 100644 --- a/crabfit-frontend/src/pages/Home/Home.tsx +++ b/crabfit-frontend/src/pages/Home/Home.tsx @@ -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++) { - day.push( - dayjs.tz(date, 'DDMMYYYY', data.timezone) - .hour(i) - .minute(0) - .utc() - .format('HHmm-DDMMYYYY') - ); + if (isSpecificDates) { + day.push( + dayjs.tz(date, 'DDMMYYYY', data.timezone) + .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++) { - day.push( - dayjs.tz(date, 'DDMMYYYY', data.timezone) - .hour(i) - .minute(0) - .utc() - .format('HHmm-DDMMYYYY') - ); + if (isSpecificDates) { + day.push( + dayjs.tz(date, 'DDMMYYYY', data.timezone) + .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`); }