Merge branch 'dev' into main
This commit is contained in:
commit
920f29e465
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState } from 'react';
|
import { useState, Suspense, lazy } from 'react';
|
||||||
import {
|
import {
|
||||||
BrowserRouter,
|
BrowserRouter,
|
||||||
Switch,
|
Switch,
|
||||||
|
|
@ -6,14 +6,13 @@ import {
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
import { ThemeProvider, Global } from '@emotion/react';
|
import { ThemeProvider, Global } from '@emotion/react';
|
||||||
|
|
||||||
import { Settings } from 'components';
|
import { Settings, Loading } from 'components';
|
||||||
import {
|
|
||||||
Home,
|
|
||||||
Event,
|
|
||||||
} from 'pages';
|
|
||||||
|
|
||||||
import theme from 'theme';
|
import theme from 'theme';
|
||||||
|
|
||||||
|
const Home = lazy(() => import('pages/Home/Home'));
|
||||||
|
const Event = lazy(() => import('pages/Event/Event'));
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
const darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
const [isDark, setIsDark] = useState(darkQuery.matches);
|
const [isDark, setIsDark] = useState(darkQuery.matches);
|
||||||
|
|
@ -61,8 +60,16 @@ const App = () => {
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/" component={Home} exact />
|
<Route path="/" exact render={props => (
|
||||||
<Route path="/:id" component={Event} exact />
|
<Suspense fallback={<Loading />}>
|
||||||
|
<Home {...props} />
|
||||||
|
</Suspense>
|
||||||
|
)} />
|
||||||
|
<Route path="/:id" exact render={props => (
|
||||||
|
<Suspense fallback={<Loading />}>
|
||||||
|
<Event {...props} />
|
||||||
|
</Suspense>
|
||||||
|
)} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
||||||
<Settings />
|
<Settings />
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ const AvailabilityEditor = ({
|
||||||
times,
|
times,
|
||||||
timeLabels,
|
timeLabels,
|
||||||
dates,
|
dates,
|
||||||
|
isSpecificDates,
|
||||||
value = [],
|
value = [],
|
||||||
onChange,
|
onChange,
|
||||||
...props
|
...props
|
||||||
|
|
@ -54,12 +55,12 @@ const AvailabilityEditor = ({
|
||||||
)}
|
)}
|
||||||
</TimeLabels>
|
</TimeLabels>
|
||||||
{dates.map((date, x) => {
|
{dates.map((date, x) => {
|
||||||
const parsedDate = dayjs(date, 'DDMMYYYY');
|
const parsedDate = isSpecificDates ? dayjs(date, 'DDMMYYYY') : dayjs().day(date);
|
||||||
const last = dates.length === x+1 || dayjs(dates[x+1], 'DDMMYYYY').diff(parsedDate, 'day') > 1;
|
const last = dates.length === x+1 || (isSpecificDates ? dayjs(dates[x+1], 'DDMMYYYY') : dayjs().day(dates[x+1])).diff(parsedDate, 'day') > 1;
|
||||||
return (
|
return (
|
||||||
<Fragment key={x}>
|
<Fragment key={x}>
|
||||||
<Date>
|
<Date>
|
||||||
<DateLabel>{parsedDate.format('MMM D')}</DateLabel>
|
{isSpecificDates && <DateLabel>{parsedDate.format('MMM D')}</DateLabel>}
|
||||||
<DayLabel>{parsedDate.format('ddd')}</DayLabel>
|
<DayLabel>{parsedDate.format('ddd')}</DayLabel>
|
||||||
|
|
||||||
<Times>
|
<Times>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import dayjs from 'dayjs';
|
||||||
import localeData from 'dayjs/plugin/localeData';
|
import localeData from 'dayjs/plugin/localeData';
|
||||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||||
|
|
||||||
|
import { useSettingsStore } from 'stores';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Wrapper,
|
Wrapper,
|
||||||
Container,
|
Container,
|
||||||
|
|
@ -28,12 +30,14 @@ const AvailabilityViewer = ({
|
||||||
times,
|
times,
|
||||||
timeLabels,
|
timeLabels,
|
||||||
dates,
|
dates,
|
||||||
|
isSpecificDates,
|
||||||
people = [],
|
people = [],
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 0,
|
max = 0,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const [tooltip, setTooltip] = useState(null);
|
const [tooltip, setTooltip] = useState(null);
|
||||||
|
const timeFormat = useSettingsStore(state => state.timeFormat);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
|
|
@ -46,12 +50,12 @@ const AvailabilityViewer = ({
|
||||||
)}
|
)}
|
||||||
</TimeLabels>
|
</TimeLabels>
|
||||||
{dates.map((date, i) => {
|
{dates.map((date, i) => {
|
||||||
const parsedDate = dayjs(date, 'DDMMYYYY');
|
const parsedDate = isSpecificDates ? dayjs(date, 'DDMMYYYY') : dayjs().day(date);
|
||||||
const last = dates.length === i+1 || dayjs(dates[i+1], 'DDMMYYYY').diff(parsedDate, 'day') > 1;
|
const last = dates.length === i+1 || (isSpecificDates ? dayjs(dates[i+1], 'DDMMYYYY') : dayjs().day(dates[i+1])).diff(parsedDate, 'day') > 1;
|
||||||
return (
|
return (
|
||||||
<Fragment key={i}>
|
<Fragment key={i}>
|
||||||
<Date>
|
<Date>
|
||||||
<DateLabel>{parsedDate.format('MMM D')}</DateLabel>
|
{isSpecificDates && <DateLabel>{parsedDate.format('MMM D')}</DateLabel>}
|
||||||
<DayLabel>{parsedDate.format('ddd')}</DayLabel>
|
<DayLabel>{parsedDate.format('ddd')}</DayLabel>
|
||||||
|
|
||||||
<Times>
|
<Times>
|
||||||
|
|
@ -76,11 +80,12 @@ const AvailabilityViewer = ({
|
||||||
minPeople={min}
|
minPeople={min}
|
||||||
onMouseEnter={(e) => {
|
onMouseEnter={(e) => {
|
||||||
const cellBox = e.currentTarget.getBoundingClientRect();
|
const cellBox = e.currentTarget.getBoundingClientRect();
|
||||||
|
const timeText = timeFormat === '12h' ? 'h:mma' : 'HH:mm';
|
||||||
setTooltip({
|
setTooltip({
|
||||||
x: Math.round(cellBox.x + cellBox.width/2),
|
x: Math.round(cellBox.x + cellBox.width/2),
|
||||||
y: Math.round(cellBox.y + cellBox.height)+6,
|
y: Math.round(cellBox.y + cellBox.height)+6,
|
||||||
available: `${peopleHere.length} / ${people.length} available`,
|
available: `${peopleHere.length} / ${people.length} available`,
|
||||||
date: parsedDate.hour(time.slice(0, 2)).minute(time.slice(2, 4)).format('h:mma ddd, D MMM YYYY'),
|
date: parsedDate.hour(time.slice(0, 2)).minute(time.slice(2, 4)).format(isSpecificDates ? `${timeText} ddd, D MMM YYYY` : `${timeText} ddd`),
|
||||||
people: peopleHere.join(', '),
|
people: peopleHere.join(', '),
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ export const Tooltip = styled.div`
|
||||||
border: 1px solid ${props => props.theme.text};
|
border: 1px solid ${props => props.theme.text};
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
background-color: ${props => props.theme.background}99;
|
background-color: ${props => props.theme.background}DD;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import isToday from 'dayjs/plugin/isToday';
|
||||||
import localeData from 'dayjs/plugin/localeData';
|
import localeData from 'dayjs/plugin/localeData';
|
||||||
import updateLocale from 'dayjs/plugin/updateLocale';
|
import updateLocale from 'dayjs/plugin/updateLocale';
|
||||||
|
|
||||||
import { Button } from 'components';
|
import { Button, ToggleField } from 'components';
|
||||||
import { useSettingsStore } from 'stores';
|
import { useSettingsStore } from 'stores';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
@ -55,6 +55,8 @@ const CalendarField = ({
|
||||||
}) => {
|
}) => {
|
||||||
const weekStart = useSettingsStore(state => state.weekStart);
|
const weekStart = useSettingsStore(state => state.weekStart);
|
||||||
|
|
||||||
|
const [type, setType] = useState(0);
|
||||||
|
|
||||||
const [dates, setDates] = useState(calculateMonth(dayjs().month(), dayjs().year(), weekStart));
|
const [dates, setDates] = useState(calculateMonth(dayjs().month(), dayjs().year(), weekStart));
|
||||||
const [month, setMonth] = useState(dayjs().month());
|
const [month, setMonth] = useState(dayjs().month());
|
||||||
const [year, setYear] = useState(dayjs().year());
|
const [year, setYear] = useState(dayjs().year());
|
||||||
|
|
@ -67,6 +69,14 @@ const CalendarField = ({
|
||||||
_setSelectingDates(newDates);
|
_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 startPos = useRef({});
|
||||||
const staticMode = useRef(null);
|
const staticMode = useRef(null);
|
||||||
const [mode, _setMode] = useState(staticMode.current);
|
const [mode, _setMode] = useState(staticMode.current);
|
||||||
|
|
@ -93,10 +103,20 @@ const CalendarField = ({
|
||||||
id={id}
|
id={id}
|
||||||
type="hidden"
|
type="hidden"
|
||||||
ref={register}
|
ref={register}
|
||||||
value={JSON.stringify(selectedDates)}
|
value={type ? JSON.stringify(selectedDays) : JSON.stringify(selectedDates)}
|
||||||
{...props}
|
{...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>
|
<CalendarHeader>
|
||||||
<Button
|
<Button
|
||||||
buttonHeight="30px"
|
buttonHeight="30px"
|
||||||
|
|
@ -130,8 +150,8 @@ const CalendarField = ({
|
||||||
</CalendarHeader>
|
</CalendarHeader>
|
||||||
|
|
||||||
<CalendarDays>
|
<CalendarDays>
|
||||||
{dayjs.weekdaysShort().map((name, i) =>
|
{dayjs.weekdaysShort().map(name =>
|
||||||
<Day key={i}>{name}</Day>
|
<Day key={name}>{name}</Day>
|
||||||
)}
|
)}
|
||||||
</CalendarDays>
|
</CalendarDays>
|
||||||
<CalendarBody>
|
<CalendarBody>
|
||||||
|
|
@ -176,6 +196,46 @@ const CalendarField = ({
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</CalendarBody>
|
</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>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ export const StyledLabel = styled.label`
|
||||||
|
|
||||||
export const StyledSubLabel = styled.label`
|
export const StyledSubLabel = styled.label`
|
||||||
display: block;
|
display: block;
|
||||||
padding-bottom: 6px;
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
opacity: .6;
|
opacity: .6;
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
12
crabfit-frontend/src/components/Loading/Loading.tsx
Normal file
12
crabfit-frontend/src/components/Loading/Loading.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import {
|
||||||
|
Wrapper,
|
||||||
|
Loader,
|
||||||
|
} from './loadingStyle';
|
||||||
|
|
||||||
|
const Loading = () => (
|
||||||
|
<Wrapper>
|
||||||
|
<Loader />
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Loading;
|
||||||
26
crabfit-frontend/src/components/Loading/loadingStyle.ts
Normal file
26
crabfit-frontend/src/components/Loading/loadingStyle.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
export const Wrapper = styled.main`
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Loader = styled.div`
|
||||||
|
@keyframes load {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
border: 3px solid ${props => props.theme.primary};
|
||||||
|
border-left-color: transparent;
|
||||||
|
border-radius: 100px;
|
||||||
|
animation: load .5s linear infinite;
|
||||||
|
`;
|
||||||
|
|
@ -26,7 +26,6 @@ export const HiddenInput = styled.input`
|
||||||
width: 0;
|
width: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: -1000px;
|
right: -1000px;
|
||||||
top: 0;
|
|
||||||
|
|
||||||
&:checked + label {
|
&:checked + label {
|
||||||
color: ${props => props.theme.background};
|
color: ${props => props.theme.background};
|
||||||
|
|
@ -36,8 +35,12 @@ export const HiddenInput = styled.input`
|
||||||
|
|
||||||
export const LabelButton = styled.label`
|
export const LabelButton = styled.label`
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
display: block;
|
display: flex;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ export { default as Legend } from './Legend/Legend';
|
||||||
export { default as AvailabilityViewer } from './AvailabilityViewer/AvailabilityViewer';
|
export { default as AvailabilityViewer } from './AvailabilityViewer/AvailabilityViewer';
|
||||||
export { default as AvailabilityEditor } from './AvailabilityEditor/AvailabilityEditor';
|
export { default as AvailabilityEditor } from './AvailabilityEditor/AvailabilityEditor';
|
||||||
export { default as Error } from './Error/Error';
|
export { default as Error } from './Error/Error';
|
||||||
|
export { default as Loading } from './Loading/Loading';
|
||||||
|
|
||||||
export { default as Center } from './Center/Center';
|
export { default as Center } from './Center/Center';
|
||||||
export { default as Donate } from './Donate/Donate';
|
export { default as Donate } from './Donate/Donate';
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ dayjs.extend(customParseFormat);
|
||||||
|
|
||||||
const Event = (props) => {
|
const Event = (props) => {
|
||||||
const timeFormat = useSettingsStore(state => state.timeFormat);
|
const timeFormat = useSettingsStore(state => state.timeFormat);
|
||||||
|
const weekStart = useSettingsStore(state => state.weekStart);
|
||||||
|
|
||||||
const { register, handleSubmit } = useForm();
|
const { register, handleSubmit } = useForm();
|
||||||
const { id } = props.match.params;
|
const { id } = props.match.params;
|
||||||
|
|
@ -87,7 +88,9 @@ const Event = (props) => {
|
||||||
const response = await api.get(`/event/${id}/people`);
|
const response = await api.get(`/event/${id}/people`);
|
||||||
const adjustedPeople = response.data.people.map(person => ({
|
const adjustedPeople = response.data.people.map(person => ({
|
||||||
...person,
|
...person,
|
||||||
availability: person.availability.map(date => dayjs(date, 'HHmm-DDMMYYYY').utc(true).tz(timezone).format('HHmm-DDMMYYYY')),
|
availability: (!!person.availability.length && person.availability[0].length === 13)
|
||||||
|
? person.availability.map(date => dayjs(date, 'HHmm-DDMMYYYY').utc(true).tz(timezone).format('HHmm-DDMMYYYY'))
|
||||||
|
: person.availability.map(date => dayjs(date, 'HHmm').day(date.substring(5)).utc(true).tz(timezone).format('HHmm-d')),
|
||||||
}));
|
}));
|
||||||
setPeople(adjustedPeople);
|
setPeople(adjustedPeople);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -103,21 +106,32 @@ const Event = (props) => {
|
||||||
// Convert to timezone and expand minute segments
|
// Convert to timezone and expand minute segments
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (event) {
|
if (event) {
|
||||||
|
const isSpecificDates = event.times[0].length === 13;
|
||||||
setTimes(event.times.reduce(
|
setTimes(event.times.reduce(
|
||||||
(allTimes, time) => {
|
(allTimes, time) => {
|
||||||
const date = dayjs(time, 'HHmm-DDMMYYYY').utc(true).tz(timezone);
|
const date = isSpecificDates ?
|
||||||
|
dayjs(time, 'HHmm-DDMMYYYY').utc(true).tz(timezone)
|
||||||
|
: dayjs(time, 'HHmm').day(time.substring(5)).utc(true).tz(timezone);
|
||||||
|
const format = isSpecificDates ? 'HHmm-DDMMYYYY' : 'HHmm-d';
|
||||||
return [
|
return [
|
||||||
...allTimes,
|
...allTimes,
|
||||||
date.minute(0).format('HHmm-DDMMYYYY'),
|
date.minute(0).format(format),
|
||||||
date.minute(15).format('HHmm-DDMMYYYY'),
|
date.minute(15).format(format),
|
||||||
date.minute(30).format('HHmm-DDMMYYYY'),
|
date.minute(30).format(format),
|
||||||
date.minute(45).format('HHmm-DDMMYYYY'),
|
date.minute(45).format(format),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
).sort((a, b) => dayjs(a, 'HHmm-DDMMYYYY').diff(dayjs(b, 'HHmm-DDMMYYYY'))));
|
).sort((a, b) => {
|
||||||
|
if (isSpecificDates) {
|
||||||
|
return dayjs(a, 'HHmm-DDMMYYYY').diff(dayjs(b, 'HHmm-DDMMYYYY'));
|
||||||
|
} else {
|
||||||
|
return dayjs(a, 'HHmm').day((parseInt(a.substring(5))-weekStart % 7 + 7) % 7)
|
||||||
|
.diff(dayjs(b, 'HHmm').day((parseInt(b.substring(5))-weekStart % 7 + 7) % 7));
|
||||||
}
|
}
|
||||||
}, [event, timezone]);
|
}));
|
||||||
|
}
|
||||||
|
}, [event, timezone, weekStart]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!!times.length && !!people.length) {
|
if (!!times.length && !!people.length) {
|
||||||
|
|
@ -183,7 +197,9 @@ const Event = (props) => {
|
||||||
const response = await api.post(`/event/${id}/people/${user.name}`, { person: { password } });
|
const response = await api.post(`/event/${id}/people/${user.name}`, { person: { password } });
|
||||||
const adjustedUser = {
|
const adjustedUser = {
|
||||||
...response.data,
|
...response.data,
|
||||||
availability: response.data.availability.map(date => dayjs(date, 'HHmm-DDMMYYYY').utc(true).tz(timezone).format('HHmm-DDMMYYYY')),
|
availability: (!!response.data.availability.length && response.data.availability[0].length === 13)
|
||||||
|
? response.data.availability.map(date => dayjs(date, 'HHmm-DDMMYYYY').utc(true).tz(timezone).format('HHmm-DDMMYYYY'))
|
||||||
|
: response.data.availability.map(date => dayjs(date, 'HHmm').day(date.substring(5)).utc(true).tz(timezone).format('HHmm-d')),
|
||||||
};
|
};
|
||||||
setUser(adjustedUser);
|
setUser(adjustedUser);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -192,7 +208,6 @@ const Event = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
console.log('FETCHING', timezone);
|
|
||||||
fetchUser();
|
fetchUser();
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
|
|
@ -210,7 +225,9 @@ const Event = (props) => {
|
||||||
setPassword(data.password);
|
setPassword(data.password);
|
||||||
const adjustedUser = {
|
const adjustedUser = {
|
||||||
...response.data,
|
...response.data,
|
||||||
availability: response.data.availability.map(date => dayjs(date, 'HHmm-DDMMYYYY').utc(true).tz(timezone).format('HHmm-DDMMYYYY')),
|
availability: (!!response.data.availability.length && response.data.availability[0].length === 13)
|
||||||
|
? response.data.availability.map(date => dayjs(date, 'HHmm-DDMMYYYY').utc(true).tz(timezone).format('HHmm-DDMMYYYY'))
|
||||||
|
: response.data.availability.map(date => dayjs(date, 'HHmm').day(date.substring(5)).utc(true).tz(timezone).format('HHmm-d')),
|
||||||
};
|
};
|
||||||
setUser(adjustedUser);
|
setUser(adjustedUser);
|
||||||
setTab('you');
|
setTab('you');
|
||||||
|
|
@ -361,6 +378,7 @@ const Event = (props) => {
|
||||||
times={times}
|
times={times}
|
||||||
timeLabels={timeLabels}
|
timeLabels={timeLabels}
|
||||||
dates={dates}
|
dates={dates}
|
||||||
|
isSpecificDates={!!dates.length && dates[0].length === 8}
|
||||||
people={people.filter(p => p.availability.length > 0)}
|
people={people.filter(p => p.availability.length > 0)}
|
||||||
min={min}
|
min={min}
|
||||||
max={max}
|
max={max}
|
||||||
|
|
@ -375,10 +393,13 @@ const Event = (props) => {
|
||||||
times={times}
|
times={times}
|
||||||
timeLabels={timeLabels}
|
timeLabels={timeLabels}
|
||||||
dates={dates}
|
dates={dates}
|
||||||
|
isSpecificDates={!!dates.length && dates[0].length === 8}
|
||||||
value={user.availability}
|
value={user.availability}
|
||||||
onChange={async availability => {
|
onChange={async availability => {
|
||||||
const oldAvailability = [...user.availability];
|
const oldAvailability = [...user.availability];
|
||||||
const utcAvailability = availability.map(date => dayjs.tz(date, 'HHmm-DDMMYYYY', timezone).utc().format('HHmm-DDMMYYYY'));
|
const utcAvailability = (!!availability.length && availability[0].length === 13)
|
||||||
|
? availability.map(date => dayjs.tz(date, 'HHmm-DDMMYYYY', timezone).utc().format('HHmm-DDMMYYYY'))
|
||||||
|
: availability.map(date => dayjs.tz(date, 'HHmm', timezone).day(date.substring(5)).utc().format('HHmm-d'));
|
||||||
setUser({ ...user, availability });
|
setUser({ ...user, availability });
|
||||||
try {
|
try {
|
||||||
await api.patch(`/event/${id}/people/${user.name}`, {
|
await api.patch(`/event/${id}/people/${user.name}`, {
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ const Home = () => {
|
||||||
if (dates.length === 0) {
|
if (dates.length === 0) {
|
||||||
return setError(`You haven't selected any dates!`);
|
return setError(`You haven't selected any dates!`);
|
||||||
}
|
}
|
||||||
|
const isSpecificDates = typeof dates[0] === 'string' && dates[0].length === 8;
|
||||||
if (start === end) {
|
if (start === end) {
|
||||||
return setError(`The start and end times can't be the same`);
|
return setError(`The start and end times can't be the same`);
|
||||||
}
|
}
|
||||||
|
|
@ -89,23 +90,31 @@ const Home = () => {
|
||||||
let times = dates.reduce((times, date) => {
|
let times = dates.reduce((times, date) => {
|
||||||
let day = [];
|
let day = [];
|
||||||
for (let i = start; i < (start > end ? 24 : end); i++) {
|
for (let i = start; i < (start > end ? 24 : end); i++) {
|
||||||
|
if (isSpecificDates) {
|
||||||
day.push(
|
day.push(
|
||||||
dayjs.tz(date, 'DDMMYYYY', data.timezone)
|
dayjs.tz(date, 'DDMMYYYY', data.timezone)
|
||||||
.hour(i)
|
.hour(i).minute(0).utc().format('HHmm-DDMMYYYY')
|
||||||
.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) {
|
if (start > end) {
|
||||||
for (let i = 0; i < end; i++) {
|
for (let i = 0; i < end; i++) {
|
||||||
|
if (isSpecificDates) {
|
||||||
day.push(
|
day.push(
|
||||||
dayjs.tz(date, 'DDMMYYYY', data.timezone)
|
dayjs.tz(date, 'DDMMYYYY', data.timezone)
|
||||||
.hour(i)
|
.hour(i).minute(0).utc().format('HHmm-DDMMYYYY')
|
||||||
.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 [...times, ...day];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue