From 9ac969ec7871476f8311dca898327751559a6430 Mon Sep 17 00:00:00 2001 From: Ben Grant Date: Tue, 16 Aug 2022 15:23:05 +1000 Subject: [PATCH] Update event page --- crabfit-frontend/src/App.jsx | 4 +- .../pages/Create/{Create.tsx => Create.jsx} | 140 +++---- .../{createStyle.ts => Create.styles.js} | 38 +- .../src/pages/Event/{Event.tsx => Event.jsx} | 351 +++++++++--------- .../Event/{eventStyle.ts => Event.styles.js} | 64 ++-- crabfit-frontend/src/pages/index.js | 4 +- crabfit-frontend/src/sw.js | 32 +- 7 files changed, 311 insertions(+), 322 deletions(-) rename crabfit-frontend/src/pages/Create/{Create.tsx => Create.jsx} (66%) rename crabfit-frontend/src/pages/Create/{createStyle.ts => Create.styles.js} (57%) rename crabfit-frontend/src/pages/Event/{Event.tsx => Event.jsx} (60%) rename crabfit-frontend/src/pages/Event/{eventStyle.ts => Event.styles.js} (63%) diff --git a/crabfit-frontend/src/App.jsx b/crabfit-frontend/src/App.jsx index 7f0c73a..8a1a401 100644 --- a/crabfit-frontend/src/App.jsx +++ b/crabfit-frontend/src/App.jsx @@ -66,8 +66,8 @@ const App = () => { } /> } /> } /> - {/* } /> - } /> */} + } /> + } /> diff --git a/crabfit-frontend/src/pages/Create/Create.tsx b/crabfit-frontend/src/pages/Create/Create.jsx similarity index 66% rename from crabfit-frontend/src/pages/Create/Create.tsx rename to crabfit-frontend/src/pages/Create/Create.jsx index f63213f..87350c4 100644 --- a/crabfit-frontend/src/pages/Create/Create.tsx +++ b/crabfit-frontend/src/pages/Create/Create.jsx @@ -1,12 +1,12 @@ -import { useEffect, useState } from 'react'; -import { useHistory } from 'react-router-dom'; -import { useForm } from 'react-hook-form'; -import { useTranslation, Trans } from 'react-i18next'; +import { useEffect, useState } from 'react' +import { useNavigate } from 'react-router-dom' +import { useForm } from 'react-hook-form' +import { useTranslation, Trans } from 'react-i18next' -import dayjs from 'dayjs'; -import utc from 'dayjs/plugin/utc'; -import timezone from 'dayjs/plugin/timezone'; -import customParseFormat from 'dayjs/plugin/customParseFormat'; +import dayjs from 'dayjs' +import utc from 'dayjs/plugin/utc' +import timezone from 'dayjs/plugin/timezone' +import customParseFormat from 'dayjs/plugin/customParseFormat' import { TextField, @@ -17,7 +17,7 @@ import { Error, Recents, Footer, -} from 'components'; +} from '/src/components' import { StyledMain, @@ -27,80 +27,80 @@ import { P, OfflineMessage, ShareInfo, -} from './createStyle'; +} from './Create.styles' -import api from 'services'; -import { useRecentsStore } from 'stores'; +import api from '/src/services' +import { useRecentsStore } from '/src/stores' -import timezones from 'res/timezones.json'; +import timezones from '/src/res/timezones.json' -dayjs.extend(utc); -dayjs.extend(timezone); -dayjs.extend(customParseFormat); +dayjs.extend(utc) +dayjs.extend(timezone) +dayjs.extend(customParseFormat) const Create = ({ offline }) => { const { register, handleSubmit, setValue } = useForm({ defaultValues: { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, }, - }); - const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(null); - const [createdEvent, setCreatedEvent] = useState(null); - const [copied, setCopied] = useState(null); - const [showFooter, setShowFooter] = useState(true); + }) + const [isLoading, setIsLoading] = useState(false) + const [error, setError] = useState(null) + const [createdEvent, setCreatedEvent] = useState(null) + const [copied, setCopied] = useState(null) + const [showFooter, setShowFooter] = useState(true) - const { push } = useHistory(); - const { t } = useTranslation(['common', 'home', 'event']); + const navigate = useNavigate() + const { t } = useTranslation(['common', 'home', 'event']) - const addRecent = useRecentsStore(state => state.addRecent); + const addRecent = useRecentsStore(state => state.addRecent) useEffect(() => { if (window.self === window.top) { - push('/'); + navigate('/') } - document.title = 'Create a Crab Fit'; + document.title = 'Create a Crab Fit' if (window.parent) { - window.parent.postMessage('crabfit-create', '*'); + window.parent.postMessage('crabfit-create', '*') window.addEventListener('message', e => { if (e.data === 'safari-extension') { - setShowFooter(false); + setShowFooter(false) } }, { once: true - }); + }) } - }, [push]); + }, [navigate]) const onSubmit = async data => { - setIsLoading(true); - setError(null); + setIsLoading(true) + setError(null) try { - const { start, end } = JSON.parse(data.times); - const dates = JSON.parse(data.dates); + const { start, end } = JSON.parse(data.times) + const dates = JSON.parse(data.dates) if (dates.length === 0) { - return setError(t('home:form.errors.no_dates')); + return setError(t('home:form.errors.no_dates')) } - const isSpecificDates = typeof dates[0] === 'string' && dates[0].length === 8; + const isSpecificDates = typeof dates[0] === 'string' && dates[0].length === 8 if (start === end) { - return setError(t('home:form.errors.same_times')); + return setError(t('home:form.errors.same_times')) } - let times = dates.reduce((times, date) => { - let day = []; + const times = dates.reduce((times, date) => { + const 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') - ); + .day(date).hour(i).minute(0).utc().format('HHmm-d') + ) } } if (start > end) { @@ -108,21 +108,21 @@ const Create = ({ offline }) => { 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') - ); + .day(date).hour(i).minute(0).utc().format('HHmm-d') + ) } } } - return [...times, ...day]; - }, []); + return [...times, ...day] + }, []) if (times.length === 0) { - return setError(t('home:form.errors.no_time')); + return setError(t('home:form.errors.no_time')) } const response = await api.post('/event', { @@ -131,23 +131,23 @@ const Create = ({ offline }) => { times: times, timezone: data.timezone, }, - }); - setCreatedEvent(response.data); + }) + setCreatedEvent(response.data) addRecent({ id: response.data.id, created: response.data.created, name: response.data.name, - }); + }) gtag('event', 'create_event', { 'event_category': 'create', - }); + }) } catch (e) { - setError(t('home:form.errors.unknown')); - console.error(e); + setError(t('home:form.errors.unknown')) + console.error(e) } finally { - setIsLoading(false); + setIsLoading(false) } - }; + } return ( <> @@ -162,16 +162,16 @@ const Create = ({ offline }) => {

{createdEvent?.name}

navigator.clipboard?.writeText(`https://crab.fit/${createdEvent.id}`) - .then(() => { - setCopied(t('event:nav.copied')); - setTimeout(() => setCopied(null), 1000); - gtag('event', 'copy_link', { - 'event_category': 'event', - }); + .then(() => { + setCopied(t('event:nav.copied')) + setTimeout(() => setCopied(null), 1000) + gtag('event', 'copy_link', { + 'event_category': 'event', }) - .catch((e) => console.error('Failed to copy', e)) + }) + .catch(e => console.error('Failed to copy', e)) } - title={!!navigator.clipboard ? t('event:nav.title') : ''} + title={navigator.clipboard ? t('event:nav.title') : ''} >{copied ?? `https://crab.fit/${createdEvent?.id}`} {/* eslint-disable-next-line */} @@ -236,7 +236,7 @@ const Create = ({ offline }) => { )} - ); -}; + ) +} -export default Create; +export default Create diff --git a/crabfit-frontend/src/pages/Create/createStyle.ts b/crabfit-frontend/src/pages/Create/Create.styles.js similarity index 57% rename from crabfit-frontend/src/pages/Create/createStyle.ts rename to crabfit-frontend/src/pages/Create/Create.styles.js index 6b3d021..1da9a0a 100644 --- a/crabfit-frontend/src/pages/Create/createStyle.ts +++ b/crabfit-frontend/src/pages/Create/Create.styles.js @@ -1,50 +1,50 @@ -import styled from '@emotion/styled'; +import { styled } from 'goober' -export const StyledMain = styled.div` +export const StyledMain = styled('div')` width: 600px; margin: 10px auto; max-width: calc(100% - 30px); -`; +` -export const CreateForm = styled.form` +export const CreateForm = styled('form')` margin: 0 0 30px; -`; +` -export const TitleSmall = styled.span` +export const TitleSmall = styled('span')` display: block; margin: 0; font-size: 2rem; text-align: center; font-family: 'Samurai Bob', sans-serif; font-weight: 400; - color: ${props => props.theme.primaryDark}; + color: var(--secondary); line-height: 1em; text-transform: uppercase; -`; +` -export const TitleLarge = styled.h1` +export const TitleLarge = styled('h1')` margin: 0; font-size: 2rem; text-align: center; - color: ${props => props.theme.primary}; + color: var(--primary); font-family: 'Molot', sans-serif; font-weight: 400; - text-shadow: 0 3px 0 ${props => props.theme.primaryDark}; + text-shadow: 0 3px 0 var(--secondary); line-height: 1em; text-transform: uppercase; -`; +` -export const P = styled.p` +export const P = styled('p')` font-weight: 500; line-height: 1.6em; -`; +` -export const OfflineMessage = styled.div` +export const OfflineMessage = styled('div')` text-align: center; margin: 50px 0 20px; -`; +` -export const ShareInfo = styled.p` +export const ShareInfo = styled('p')` margin: 6px 0; text-align: center; font-size: 15px; @@ -54,7 +54,7 @@ export const ShareInfo = styled.p` cursor: pointer; &:hover { - color: ${props.theme.primaryDark}; + color: var(--secondary); } `} -`; +` diff --git a/crabfit-frontend/src/pages/Event/Event.tsx b/crabfit-frontend/src/pages/Event/Event.jsx similarity index 60% rename from crabfit-frontend/src/pages/Event/Event.tsx rename to crabfit-frontend/src/pages/Event/Event.jsx index 1a63e58..4d74464 100644 --- a/crabfit-frontend/src/pages/Event/Event.tsx +++ b/crabfit-frontend/src/pages/Event/Event.jsx @@ -1,12 +1,13 @@ -import { useForm } from 'react-hook-form'; -import { useState, useEffect } from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { useForm } from 'react-hook-form' +import { useState, useEffect } from 'react' +import { useTranslation, Trans } from 'react-i18next' +import { useParams } from 'react-router-dom' -import dayjs from 'dayjs'; -import utc from 'dayjs/plugin/utc'; -import timezone from 'dayjs/plugin/timezone'; -import customParseFormat from 'dayjs/plugin/customParseFormat'; -import relativeTime from 'dayjs/plugin/relativeTime'; +import dayjs from 'dayjs' +import utc from 'dayjs/plugin/utc' +import timezone from 'dayjs/plugin/timezone' +import customParseFormat from 'dayjs/plugin/customParseFormat' +import relativeTime from 'dayjs/plugin/relativeTime' import { Footer, @@ -17,9 +18,9 @@ import { AvailabilityEditor, Error, Logo, -} from 'components'; +} from '/src/components' -import { StyledMain } from '../Home/homeStyle'; +import { StyledMain } from '../Home/Home.styles' import { EventName, @@ -30,232 +31,227 @@ import { ShareInfo, Tabs, Tab, -} from './eventStyle'; +} from './Event.styles' -import api from 'services'; -import { useSettingsStore, useRecentsStore, useLocaleUpdateStore } from 'stores'; +import api from '/src/services' +import { useSettingsStore, useRecentsStore, useLocaleUpdateStore } from '/src/stores' -import timezones from 'res/timezones.json'; +import timezones from '/src/res/timezones.json' -dayjs.extend(utc); -dayjs.extend(timezone); -dayjs.extend(customParseFormat); -dayjs.extend(relativeTime); +dayjs.extend(utc) +dayjs.extend(timezone) +dayjs.extend(customParseFormat) +dayjs.extend(relativeTime) -const Event = (props) => { - const timeFormat = useSettingsStore(state => state.timeFormat); - const weekStart = useSettingsStore(state => state.weekStart); +const Event = () => { + const timeFormat = useSettingsStore(state => state.timeFormat) + const weekStart = useSettingsStore(state => state.weekStart) - const addRecent = useRecentsStore(state => state.addRecent); - const removeRecent = useRecentsStore(state => state.removeRecent); - const locale = useLocaleUpdateStore(state => state.locale); + const addRecent = useRecentsStore(state => state.addRecent) + const removeRecent = useRecentsStore(state => state.removeRecent) + const locale = useLocaleUpdateStore(state => state.locale) - const { t } = useTranslation(['common', 'event']); + const { t } = useTranslation(['common', 'event']) - const { register, handleSubmit, setFocus, reset } = useForm(); - const { id } = props.match.params; - const { offline } = props; - const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone); - const [user, setUser] = useState(null); - const [password, setPassword] = useState(null); - const [tab, setTab] = useState(user ? 'you' : 'group'); - const [isLoading, setIsLoading] = useState(true); - const [isLoginLoading, setIsLoginLoading] = useState(false); - const [error, setError] = useState(null); - const [event, setEvent] = useState(null); - const [people, setPeople] = useState([]); + const { register, handleSubmit, setFocus, reset } = useForm() + const { id } = useParams() + const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone) + const [user, setUser] = useState(null) + const [password, setPassword] = useState(null) + const [tab, setTab] = useState(user ? 'you' : 'group') + const [isLoading, setIsLoading] = useState(true) + const [isLoginLoading, setIsLoginLoading] = useState(false) + const [error, setError] = useState(null) + const [event, setEvent] = useState(null) + const [people, setPeople] = useState([]) - const [times, setTimes] = useState([]); - const [timeLabels, setTimeLabels] = useState([]); - const [dates, setDates] = useState([]); - const [min, setMin] = useState(0); - const [max, setMax] = useState(0); + const [times, setTimes] = useState([]) + const [timeLabels, setTimeLabels] = useState([]) + const [dates, setDates] = useState([]) + const [min, setMin] = useState(0) + const [max, setMax] = useState(0) - const [copied, setCopied] = useState(null); + const [copied, setCopied] = useState(null) useEffect(() => { const fetchEvent = async () => { try { - const response = await api.get(`/event/${id}`); + const response = await api.get(`/event/${id}`) - setEvent(response.data); + setEvent(response.data) addRecent({ id: response.data.id, created: response.data.created, name: response.data.name, - }); - document.title = `${response.data.name} | Crab Fit`; + }) + document.title = `${response.data.name} | Crab Fit` } catch (e) { - console.error(e); + console.error(e) if (e.status === 404) { - removeRecent(id); + removeRecent(id) } } finally { - setIsLoading(false); + setIsLoading(false) } - }; + } - fetchEvent(); - }, [id, addRecent, removeRecent]); + fetchEvent() + }, [id, addRecent, removeRecent]) useEffect(() => { const fetchPeople = async () => { try { - const response = await api.get(`/event/${id}/people`); + const response = await api.get(`/event/${id}/people`) const adjustedPeople = response.data.people.map(person => ({ ...person, 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) { - console.error(e); + console.error(e) } } if (tab === 'group') { - fetchPeople(); + fetchPeople() } - }, [tab, id, timezone]); + }, [tab, id, timezone]) // Convert to timezone and expand minute segments useEffect(() => { if (event) { - const isSpecificDates = event.times[0].length === 13; + const isSpecificDates = event.times[0].length === 13 setTimes(event.times.reduce( (allTimes, time) => { 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'; + : dayjs(time, 'HHmm').day(time.substring(5)).utc(true).tz(timezone) + const format = isSpecificDates ? 'HHmm-DDMMYYYY' : 'HHmm-d' return [ ...allTimes, date.minute(0).format(format), date.minute(15).format(format), date.minute(30).format(format), date.minute(45).format(format), - ]; + ] }, [] ).sort((a, b) => { if (isSpecificDates) { - return dayjs(a, 'HHmm-DDMMYYYY').diff(dayjs(b, 'HHmm-DDMMYYYY')); + 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)); + .diff(dayjs(b, 'HHmm').day((parseInt(b.substring(5))-weekStart % 7 + 7) % 7)) } - })); + })) } - }, [event, timezone, weekStart]); + }, [event, timezone, weekStart]) useEffect(() => { if (!!times.length && !!people.length) { setMin(times.reduce((min, time) => { - let total = people.reduce( - (total, person) => person.availability.includes(time) ? total+1 : total, - 0 - ); - return total < min ? total : min; - }, - Infinity - )); + const total = people.reduce( + (total, person) => person.availability.includes(time) ? total+1 : total, + 0 + ) + return total < min ? total : min + }, Infinity)) setMax(times.reduce((max, time) => { - let total = people.reduce( - (total, person) => person.availability.includes(time) ? total+1 : total, - 0 - ); - return total > max ? total : max; - }, - -Infinity - )); + const total = people.reduce( + (total, person) => person.availability.includes(time) ? total+1 : total, + 0 + ) + return total > max ? total : max + }, -Infinity)) } - }, [times, people]); + }, [times, people]) useEffect(() => { - if (!!times.length) { + if (times.length) { setTimeLabels(times.reduce((labels, datetime) => { - const time = datetime.substring(0, 4); - if (labels.includes(time)) return labels; - return [...labels, time]; + const time = datetime.substring(0, 4) + if (labels.includes(time)) return labels + return [...labels, time] }, []) - .sort((a, b) => parseInt(a) - parseInt(b)) - .reduce((labels, time, i, allTimes) => { - if (time.substring(2) === '30') return [...labels, { label: '', time }]; - if (allTimes.length - 1 === i) return [ - ...labels, - { label: '', time }, - { label: dayjs(time, 'HHmm').add(1, 'hour').format(timeFormat === '12h' ? 'h A' : 'HH'), time: null } - ]; - if (allTimes.length - 1 > i && parseInt(allTimes[i+1].substring(0, 2))-1 > parseInt(time.substring(0, 2))) return [ - ...labels, - { label: '', time }, - { label: dayjs(time, 'HHmm').add(1, 'hour').format(timeFormat === '12h' ? 'h A' : 'HH'), time: 'space' }, - { label: '', time: 'space' }, - { label: '', time: 'space' }, - ]; - if (time.substring(2) !== '00') return [...labels, { label: '', time }]; - return [...labels, { label: dayjs(time, 'HHmm').format(timeFormat === '12h' ? 'h A' : 'HH'), time }]; - }, [])); + .sort((a, b) => parseInt(a) - parseInt(b)) + .reduce((labels, time, i, allTimes) => { + if (time.substring(2) === '30') return [...labels, { label: '', time }] + if (allTimes.length - 1 === i) return [ + ...labels, + { label: '', time }, + { label: dayjs(time, 'HHmm').add(1, 'hour').format(timeFormat === '12h' ? 'h A' : 'HH'), time: null } + ] + if (allTimes.length - 1 > i && parseInt(allTimes[i+1].substring(0, 2))-1 > parseInt(time.substring(0, 2))) return [ + ...labels, + { label: '', time }, + { label: dayjs(time, 'HHmm').add(1, 'hour').format(timeFormat === '12h' ? 'h A' : 'HH'), time: 'space' }, + { label: '', time: 'space' }, + { label: '', time: 'space' }, + ] + if (time.substring(2) !== '00') return [...labels, { label: '', time }] + return [...labels, { label: dayjs(time, 'HHmm').format(timeFormat === '12h' ? 'h A' : 'HH'), time }] + }, [])) setDates(times.reduce((allDates, time) => { - if (time.substring(2, 4) !== '00') return allDates; - const date = time.substring(5); - if (allDates.includes(date)) return allDates; - return [...allDates, date]; - }, [])); + if (time.substring(2, 4) !== '00') return allDates + const date = time.substring(5) + if (allDates.includes(date)) return allDates + return [...allDates, date] + }, [])) } - }, [times, timeFormat, locale]); + }, [times, timeFormat, locale]) useEffect(() => { const fetchUser = async () => { try { - 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 = { ...response.data, 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) { - console.log(e); + console.log(e) } - }; + } if (user) { - fetchUser(); + fetchUser() } // eslint-disable-next-line }, [timezone]); const onSubmit = async data => { if (!data.name || data.name.length === 0) { - setFocus('name'); - return setError(t('event:form.errors.name_required')); + setFocus('name') + return setError(t('event:form.errors.name_required')) } - setIsLoginLoading(true); - setError(null); + setIsLoginLoading(true) + setError(null) try { const response = await api.post(`/event/${id}/people/${data.name}`, { person: { password: data.password, }, - }); - setPassword(data.password); + }) + setPassword(data.password) const adjustedUser = { ...response.data, 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); - setTab('you'); + } + setUser(adjustedUser) + setTab('you') } catch (e) { if (e.status === 401) { - setError(t('event:form.errors.password_incorrect')); + setError(t('event:form.errors.password_incorrect')) } else if (e.status === 404) { // Create user try { @@ -264,25 +260,25 @@ const Event = (props) => { name: data.name, password: data.password, }, - }); - setPassword(data.password); + }) + setPassword(data.password) setUser({ name: data.name, availability: [], - }); - setTab('you'); + }) + setTab('you') } catch (e) { - setError(t('event:form.errors.unknown')); + setError(t('event:form.errors.unknown')) } } } finally { - setIsLoginLoading(false); + setIsLoginLoading(false) gtag('event', 'login', { 'event_category': 'event', - }); - reset(); + }) + reset() } - }; + } return ( <> @@ -291,39 +287,32 @@ const Event = (props) => { {(!!event || isLoading) ? ( <> - {event?.name} - {event?.created && t('common:created', { date: dayjs.unix(event?.created).fromNow() })} + {event?.name} + {event?.created && t('common:created', { date: dayjs.unix(event?.created).fromNow() })} navigator.clipboard?.writeText(`https://crab.fit/${id}`) - .then(() => { - setCopied(t('event:nav.copied')); - setTimeout(() => setCopied(null), 1000); - gtag('event', 'copy_link', { - 'event_category': 'event', - }); + .then(() => { + setCopied(t('event:nav.copied')) + setTimeout(() => setCopied(null), 1000) + gtag('event', 'copy_link', { + 'event_category': 'event', }) - .catch((e) => console.error('Failed to copy', e)) + }) + .catch(e => console.error('Failed to copy', e)) } - title={!!navigator.clipboard ? t('event:nav.title') : ''} + title={navigator.clipboard ? t('event:nav.title') : ''} >{copied ?? `https://crab.fit/${id}`} - + {!!event?.name && Copy the link to this page, or share via gtag('event', 'send_email', { 'event_category': 'event' })} href={`mailto:?subject=${encodeURIComponent(t('event:nav.email_subject', { event_name: event?.name }))}&body=${encodeURIComponent(`${t('event:nav.email_body')} https://crab.fit/${id}`)}`}>email. } ) : ( - offline ? ( -
- {t('event:offline.title')} - -
- ) : ( -
- {t('event:error.title')} - {t('event:error.body')} -
- ) +
+ {t('event:error.title')} + {t('event:error.body')} +
)} @@ -335,9 +324,9 @@ const Event = (props) => {

{t('event:form.signed_in', { name: user.name })}

) : ( @@ -363,7 +352,7 @@ const Event = (props) => { @@ -383,8 +372,8 @@ const Event = (props) => { /> {/* eslint-disable-next-line */} {event?.timezone && event.timezone !== timezone &&

This event was created in the timezone {{timezone: event.timezone}}. { - e.preventDefault(); - setTimezone(event.timezone); + e.preventDefault() + setTimezone(event.timezone) }}>Click here to use it.

} {(( Intl.DateTimeFormat().resolvedOptions().timeZone !== timezone @@ -395,8 +384,8 @@ const Event = (props) => { )) && ( /* eslint-disable-next-line */

Your local timezone is detected to be {{timezone: Intl.DateTimeFormat().resolvedOptions().timeZone}}. { - e.preventDefault(); - setTimezone(Intl.DateTimeFormat().resolvedOptions().timeZone); + e.preventDefault() + setTimezone(Intl.DateTimeFormat().resolvedOptions().timeZone) }}>Click here to use it.

)} @@ -407,11 +396,11 @@ const Event = (props) => { { - e.preventDefault(); + e.preventDefault() if (user) { - setTab('you'); + setTab('you') } else { - setFocus('name'); + setFocus('name') } }} selected={tab === 'you'} @@ -421,8 +410,8 @@ const Event = (props) => { { - e.preventDefault(); - setTab('group'); + e.preventDefault() + setTab('group') }} selected={tab === 'group'} >{t('event:tabs.group')} @@ -451,21 +440,21 @@ const Event = (props) => { isSpecificDates={!!dates.length && dates[0].length === 8} value={user.availability} onChange={async availability => { - const oldAvailability = [...user.availability]; + const oldAvailability = [...user.availability] 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 }); + : availability.map(date => dayjs.tz(date, 'HHmm', timezone).day(date.substring(5)).utc().format('HHmm-d')) + setUser({ ...user, availability }) try { await api.patch(`/event/${id}/people/${user.name}`, { person: { password, availability: utcAvailability, }, - }); + }) } catch (e) { - console.log(e); - setUser({ ...user, oldAvailability }); + console.log(e) + setUser({ ...user, oldAvailability }) } }} /> @@ -476,7 +465,7 @@ const Event = (props) => {