Create page translations

This commit is contained in:
Ben Grant 2021-05-18 22:10:48 +10:00
parent 5a3dd895f6
commit 9ed1522475
6 changed files with 48 additions and 42 deletions

View file

@ -5,6 +5,7 @@
"title": "Click to copy", "title": "Click to copy",
"copied": "Copied!", "copied": "Copied!",
"shareinfo": "Copy the link to this page, or share via <1>email</1>.", "shareinfo": "Copy the link to this page, or share via <1>email</1>.",
"shareinfo_alt": "Click the link above to copy it to your clipboard, or share via <1>email</1>.",
"email_subject": "Scheduling {{event_name}}", "email_subject": "Scheduling {{event_name}}",
"email_body": "Visit this link to enter your availabilities:" "email_body": "Visit this link to enter your availabilities:"
}, },

View file

@ -34,10 +34,10 @@
"button": "Create", "button": "Create",
"errors": { "errors": {
"no_dates": "You haven't selected any dates!", "no_dates": "There aren't any dates selected",
"same_times": "The start and end times can't be the same", "same_times": "The start and end times can't be the same",
"no_time": "You don't have any time selected", "no_time": "There isn't any time selected",
"unknown": "An error ocurred while creating the event. Please try again later." "unknown": "Something went wrong. Please try again later."
} }
}, },
"offline": "You can't create a Crab Fit when you don't have an internet connection. Please make sure you're connected.", "offline": "You can't create a Crab Fit when you don't have an internet connection. Please make sure you're connected.",

View file

@ -4,12 +4,12 @@ import { useTranslation } from 'react-i18next';
import { Donate } from 'components'; import { Donate } from 'components';
import { Wrapper, Link } from './footerStyle'; import { Wrapper, Link } from './footerStyle';
const Footer = () => { const Footer = (props) => {
const [donateMode, setDonateMode] = useState(false); const [donateMode, setDonateMode] = useState(false);
const { t } = useTranslation('common'); const { t } = useTranslation('common');
return ( return (
<Wrapper id="donate" donateMode={donateMode}> <Wrapper id="donate" donateMode={donateMode} {...props}>
{donateMode ? ( {donateMode ? (
<> <>
<Link href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation&currency_code=AUD&amount=2" target="_blank">{t('donate.options.$2')}</Link> <Link href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation&currency_code=AUD&amount=2" target="_blank">{t('donate.options.$2')}</Link>

View file

@ -8,7 +8,22 @@ export const Wrapper = styled.footer`
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
${props => props.small && `
margin: 60px auto 0;
width: 250px;
max-width: initial;
display: block;
& span {
display: block;
margin-bottom: 20px;
}
`}
${props => props.donateMode && ` ${props => props.donateMode && `
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
`} `}
`; `;

View file

@ -1,6 +1,7 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { useTranslation, Trans } from 'react-i18next';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc'; import utc from 'dayjs/plugin/utc';
@ -13,9 +14,9 @@ import {
TimeRangeField, TimeRangeField,
SelectField, SelectField,
Button, Button,
Donate,
Error, Error,
Recents, Recents,
Footer,
} from 'components'; } from 'components';
import { import {
@ -26,7 +27,6 @@ import {
P, P,
OfflineMessage, OfflineMessage,
ShareInfo, ShareInfo,
Footer,
} from './createStyle'; } from './createStyle';
import api from 'services'; import api from 'services';
@ -50,6 +50,7 @@ const Create = ({ offline }) => {
const [copied, setCopied] = useState(null); const [copied, setCopied] = useState(null);
const { push } = useHistory(); const { push } = useHistory();
const { t } = useTranslation(['common', 'home', 'event']);
const addRecent = useRecentsStore(state => state.addRecent); const addRecent = useRecentsStore(state => state.addRecent);
@ -68,11 +69,11 @@ const Create = ({ offline }) => {
const dates = JSON.parse(data.dates); const dates = JSON.parse(data.dates);
if (dates.length === 0) { if (dates.length === 0) {
return setError(`You haven't selected any 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) { if (start === end) {
return setError(`The start and end times can't be the same`); return setError(t('home:form.errors.same_times'));
} }
let times = dates.reduce((times, date) => { let times = dates.reduce((times, date) => {
@ -109,7 +110,7 @@ const Create = ({ offline }) => {
}, []); }, []);
if (times.length === 0) { if (times.length === 0) {
return setError(`You don't have any time selected`); return setError(t('home:form.errors.no_time'));
} }
const response = await api.post('/event', { const response = await api.post('/event', {
@ -126,10 +127,10 @@ const Create = ({ offline }) => {
name: response.data.name, name: response.data.name,
}); });
gtag('event', 'create_event', { gtag('event', 'create_event', {
'event_category': 'home', 'event_category': 'create',
}); });
} catch (e) { } catch (e) {
setError('An error ocurred while creating the event. Please try again later.'); setError(t('home:form.errors.unknown'));
console.error(e); console.error(e);
} finally { } finally {
setIsLoading(false); setIsLoading(false);
@ -139,18 +140,18 @@ const Create = ({ offline }) => {
return ( return (
<> <>
<StyledMain> <StyledMain>
<TitleSmall>CREATE A</TitleSmall> <TitleSmall>{t('home:create')}</TitleSmall>
<TitleLarge>CRAB FIT</TitleLarge> <TitleLarge>CRAB FIT</TitleLarge>
</StyledMain> </StyledMain>
{createdEvent ? ( {createdEvent ? (
<StyledMain> <StyledMain>
<OfflineMessage> <OfflineMessage>
<h2>Created {createdEvent.name}</h2> <h2>{t('common:created')} {createdEvent?.name}</h2>
<ShareInfo <ShareInfo
onClick={() => navigator.clipboard?.writeText(`https://crab.fit/${createdEvent.id}`) onClick={() => navigator.clipboard?.writeText(`https://crab.fit/${createdEvent.id}`)
.then(() => { .then(() => {
setCopied('Copied!'); setCopied(t('event:nav.copied'));
setTimeout(() => setCopied(null), 1000); setTimeout(() => setCopied(null), 1000);
gtag('event', 'copy_link', { gtag('event', 'copy_link', {
'event_category': 'event', 'event_category': 'event',
@ -158,16 +159,13 @@ const Create = ({ offline }) => {
}) })
.catch((e) => console.error('Failed to copy', e)) .catch((e) => console.error('Failed to copy', e))
} }
title={!!navigator.clipboard ? 'Click to copy' : ''} title={!!navigator.clipboard ? t('event:nav.title') : ''}
>{copied ?? `https://crab.fit/${createdEvent.id}`}</ShareInfo> >{copied ?? `https://crab.fit/${createdEvent?.id}`}</ShareInfo>
<ShareInfo> <ShareInfo>
{/* eslint-disable-next-line */} {/* eslint-disable-next-line */}
Click the link above to copy it to your clipboard, or share via <a onClick={() => gtag('event', 'send_email', { 'event_category': 'event' })} href={`mailto:?subject=${encodeURIComponent(`Scheduling ${createdEvent.name}`)}&body=${encodeURIComponent(`Visit this link to enter your availabilities: https://crab.fit/${createdEvent.id}`)}`} target="_blank">email</a>. <Trans i18nKey="event:nav.shareinfo_alt">Click the link above to copy it to your clipboard, or share via <a onClick={() => 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</a>.</Trans>
</ShareInfo> </ShareInfo>
<Footer> <Footer small />
<span>Thank you for using Crab Fit. If you like it, consider donating.</span>
<Donate />
</Footer>
</OfflineMessage> </OfflineMessage>
</StyledMain> </StyledMain>
) : ( ) : (
@ -178,13 +176,13 @@ const Create = ({ offline }) => {
{offline ? ( {offline ? (
<OfflineMessage> <OfflineMessage>
<h1>🦀📵</h1> <h1>🦀📵</h1>
<P>You can't create a Crab Fit when you don't have an internet connection. Please make sure you're connected.</P> <P>{t('home:offline')}</P>
</OfflineMessage> </OfflineMessage>
) : ( ) : (
<CreateForm onSubmit={handleSubmit(onSubmit)} id="create"> <CreateForm onSubmit={handleSubmit(onSubmit)} id="create">
<TextField <TextField
label="Give your event a name!" label={t('home:form.name.label')}
subLabel="Or leave blank to generate one" subLabel={t('home:form.name.sublabel')}
type="text" type="text"
name="name" name="name"
id="name" id="name"
@ -192,8 +190,8 @@ const Create = ({ offline }) => {
/> />
<CalendarField <CalendarField
label="What dates might work?" label={t('home:form.dates.label')}
subLabel="Click and drag to select" subLabel={t('home:form.dates.sublabel')}
name="dates" name="dates"
id="dates" id="dates"
required required
@ -201,8 +199,8 @@ const Create = ({ offline }) => {
/> />
<TimeRangeField <TimeRangeField
label="What times might work?" label={t('home:form.times.label')}
subLabel="Click and drag to select a time range" subLabel={t('home:form.times.sublabel')}
name="times" name="times"
id="times" id="times"
required required
@ -210,20 +208,20 @@ const Create = ({ offline }) => {
/> />
<SelectField <SelectField
label="And the timezone" label={t('home:form.timezone.label')}
name="timezone" name="timezone"
id="timezone" id="timezone"
register={register} register={register}
options={timezones} options={timezones}
required required
defaultOption="Select..." defaultOption={t('home:form.timezone.defaultOption')}
/> />
{error && ( {error && (
<Error onClose={() => setError(null)}>{error}</Error> <Error onClose={() => setError(null)}>{error}</Error>
)} )}
<Button type="submit" isLoading={isLoading} disabled={isLoading} buttonWidth="100%">Create</Button> <Button type="submit" isLoading={isLoading} disabled={isLoading} buttonWidth="100%">{t('home:form.button')}</Button>
</CreateForm> </CreateForm>
)} )}
</StyledMain> </StyledMain>

View file

@ -19,6 +19,7 @@ export const TitleSmall = styled.span`
font-weight: 400; font-weight: 400;
color: ${props => props.theme.primaryDark}; color: ${props => props.theme.primaryDark};
line-height: 1em; line-height: 1em;
text-transform: uppercase;
`; `;
export const TitleLarge = styled.h1` export const TitleLarge = styled.h1`
@ -30,6 +31,7 @@ export const TitleLarge = styled.h1`
font-weight: 400; font-weight: 400;
text-shadow: 0 3px 0 ${props => props.theme.primaryDark}; text-shadow: 0 3px 0 ${props => props.theme.primaryDark};
line-height: 1em; line-height: 1em;
text-transform: uppercase;
`; `;
export const P = styled.p` export const P = styled.p`
@ -37,16 +39,6 @@ export const P = styled.p`
line-height: 1.6em; line-height: 1.6em;
`; `;
export const Footer = styled.footer`
margin: 60px auto 0;
width: 250px;
& span {
display: block;
margin-bottom: 20px;
}
`;
export const OfflineMessage = styled.div` export const OfflineMessage = styled.div`
text-align: center; text-align: center;
margin: 50px 0 20px; margin: 50px 0 20px;