import { useEffect, useState } from 'react'; import { useHistory } 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 { TextField, CalendarField, TimeRangeField, SelectField, Button, Error, Recents, Footer, } from 'components'; import { StyledMain, CreateForm, TitleSmall, TitleLarge, P, OfflineMessage, ShareInfo, } from './createStyle'; import api from 'services'; import { useRecentsStore } from 'stores'; import timezones from 'res/timezones.json'; dayjs.extend(utc); dayjs.extend(timezone); dayjs.extend(customParseFormat); const Create = ({ offline }) => { const { register, handleSubmit } = 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 { push } = useHistory(); const { t } = useTranslation(['common', 'home', 'event']); const addRecent = useRecentsStore(state => state.addRecent); useEffect(() => { if (window.self === window.top) { push('/'); } document.title = 'Create a Crab Fit'; if (window.parent) { window.parent.postMessage('crabfit-create', '*'); window.addEventListener('message', e => { if (e.data === 'safari-extension') { setShowFooter(false); } }, { once: true }); } }, [push]); const onSubmit = async data => { setIsLoading(true); setError(null); try { 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')); } const isSpecificDates = typeof dates[0] === 'string' && dates[0].length === 8; if (start === end) { return setError(t('home:form.errors.same_times')); } 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') ); } 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') ); } else { day.push( dayjs().tz(data.timezone) .day(date).hour(i).minute(0).utc().format('HHmm-d') ); } } } return [...times, ...day]; }, []); if (times.length === 0) { return setError(t('home:form.errors.no_time')); } const response = await api.post('/event', { event: { name: data.name, times: times, timezone: data.timezone, }, }); 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); } finally { setIsLoading(false); } }; return ( <> {t('home:create')} CRAB FIT {createdEvent ? (

{t('common:created', { date: 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', }); }) .catch((e) => console.error('Failed to copy', e)) } title={!!navigator.clipboard ? t('event:nav.title') : ''} >{copied ?? `https://crab.fit/${createdEvent?.id}`} {/* eslint-disable-next-line */} Click the link above to copy it to your clipboard, or share via gtag('event', 'send_email', { 'event_category': 'event' })} href={`mailto:?subject=${encodeURIComponent(t('event:nav.email_subject', { event_name: createdEvent?.name }))}&body=${encodeURIComponent(`${t('event:nav.email_body')} https://crab.fit/${createdEvent?.id}`)}`} target="_blank">email. {showFooter &&