import { useEffect, useState } from 'react'; import { useHistory, Link } from 'react-router-dom'; import { useForm } from 'react-hook-form'; 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, Center, Donate, Error, } from 'components'; import { StyledMain, CreateForm, TitleSmall, TitleLarge, Logo, Links, AboutSection, Footer, P, Stats, Stat, StatNumber, StatLabel, OfflineMessage, Recent, } from './homeStyle'; import api from 'services'; import { useRecentsStore } from 'stores'; import logo from 'res/logo.svg'; import timezones from 'res/timezones.json'; dayjs.extend(utc); dayjs.extend(timezone); dayjs.extend(customParseFormat); const Home = ({ offline }) => { const { register, handleSubmit } = useForm({ defaultValues: { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, }, }); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [stats, setStats] = useState({ eventCount: null, personCount: null, version: 'loading...', }); const { push } = useHistory(); const recentsStore = useRecentsStore(); useEffect(() => { const fetch = async () => { try { const response = await api.get('/stats'); setStats(response.data); } catch (e) { console.error(e); } }; fetch(); document.title = 'Crab Fit'; }, []); 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(`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`); } 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(`You don't have any time selected`); } const response = await api.post('/event', { event: { name: data.name, times: times, }, }); push(`/${response.data.id}`); gtag('event', 'create_event', { 'event_category': 'home', }); } catch (e) { setError('An error ocurred while creating the event. Please try again later.'); console.error(e); } finally { setIsLoading(false); } }; return ( <>
CREATE A CRAB FIT About / Donate
{!!recentsStore.recents.length && (

Recently visited

{recentsStore.recents.map(event => ( {event.name} Created {dayjs.unix(event.created).format('D MMMM, YYYY')} ))}
)} {offline ? (

🦀📵

You can't create a Crab Fit when you don't have an internet connection. Please make sure you're connected.

) : ( {error && ( setError(null)}>{error} )}
)}

About Crab Fit

{stats.eventCount ?? '100+'} Events created {stats.personCount ?? '100+'} Availabilities entered

Crab Fit helps you fit your event around everyone's schedules. Simply create an event above and send the link to everyone that is participating. Results update live and you will be able to see a heat-map of when everyone is free.
Learn more about how to Crab Fit.

{/* eslint-disable-next-line */}

Create a lot of Crab Fits? Get the Chrome extension or Firefox extension for your browser!

{/* eslint-disable-next-line */}

Created by Ben Grant, Crab Fit is the modern-day solution to your group event planning debates.

The code for Crab Fit is open source, if you find any issues or want to contribute, you can visit the repository.

Crab Fit costs more than $100 per month to run. Consider donating below if it helped you out so it can stay free for everyone. 🦀

); }; export default Home;