Create page translations
This commit is contained in:
parent
5a3dd895f6
commit
9ed1522475
|
|
@ -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:"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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.",
|
||||||
|
|
|
||||||
|
|
@ -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¤cy_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¤cy_code=AUD&amount=2" target="_blank">{t('donate.options.$2')}</Link>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue