Skip to content
This repository has been archived by the owner on Sep 25, 2020. It is now read-only.

hackathon app: localize #38

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion python/hackathon_app/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
"@types/styled-components": "^4.1.19",
"@types/yup": "^0.26.24",
"formik": "^1.5.8",
"i18next": "^19.3.1",
"i18next-browser-languagedetector": "^4.0.1",
"prettier": "^1.18.2",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react-google-login": "^5.0.7",
"react-scripts": "3.2.0",
"react-i18next": "^11.3.3",
"react-scripts": "^3.4.0",
"styled-components": "^4.4.0",
"typescript": "3.6.3",
"yup": "^0.27.0"
Expand Down
58 changes: 36 additions & 22 deletions python/hackathon_app/frontend/src/RegisterScene.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import i18n from './i18n'
import {
Button,
Box,
Expand Down Expand Up @@ -34,7 +35,9 @@ const ValidatedFieldCheckbox: React.FC<FieldProps> = ({
return (
<FieldCheckbox
validationMessage={
error && touch ? {type: 'error', message: error as string} : undefined
error && touch
? {type: 'error', message: i18n.t('checkboxError', {error})}
: undefined
}
{...field}
{...props}
Expand All @@ -49,10 +52,16 @@ const ValidatedFieldText: React.FC<FieldProps> = ({
}) => {
const error = errors[field.name]
const touch = touched[field.name]
const key =
error === 'email must be a valid email'
? 'textFieldValidationError'
: 'textFieldMissingError'
return (
<FieldText
validationMessage={
error && touch ? {type: 'error', message: error as string} : undefined
error && touch
? {type: 'error', message: i18n.t(key, {field: `$t(${field.name})`})}
: undefined
}
{...field}
{...props}
Expand Down Expand Up @@ -81,7 +90,10 @@ const TshirtSize: React.FC<FieldProps> = ({
<ButtonItem>XXL</ButtonItem>
</ButtonToggle>
{error && touch && (
<ValidationMessage type="error" message={error as string} />
<ValidationMessage
type="error"
message={i18n.t('checkboxError', {error})}
/>
)}
</Box>
)
Expand All @@ -97,7 +109,9 @@ const ValidatedFieldSelect: React.FC<FieldProps> = ({
return (
<FieldSelect
validationMessage={
error && touch ? {type: 'error', message: error as string} : undefined
error && touch
? {type: 'error', message: i18n.t(error as string)}
: undefined
}
{...field}
{...props}
Expand Down Expand Up @@ -214,10 +228,10 @@ export const RegisterScene: React.FC<{path: string}> = () => {

return (
<>
<Heading as="h1">Hackathon Registration</Heading>
<Paragraph>Register for a Hackathon below</Paragraph>
<Heading as="h1">{i18n.t('Hackathon Registration')}</Heading>
<Paragraph>{i18n.t('Register for a Hackathon below')}</Paragraph>
<Divider my="large" />
<Heading mb="medium">Registration</Heading>
<Heading mb="medium">{i18n.t('Registration')}</Heading>
<GoogleLogin
clientId="280777447286-iigstshu4o2tnkp5fjucrd3nvq03g5hs.apps.googleusercontent.com"
onSuccess={responseGoogle}
Expand Down Expand Up @@ -303,42 +317,42 @@ export const RegisterScene: React.FC<{path: string}> = () => {
<Form>
<Field type="hidden" name="csrf_token" value={csrfToken} />
<Field
label="First Name"
label={i18n.t('First Name')}
component={ValidatedFieldText}
name="first_name"
placeholder="First Name"
placeholder={i18n.t('First Name')}
/>
<Field
label="Last Name"
label={i18n.t('Last Name')}
component={ValidatedFieldText}
name="last_name"
placeholder="Last Name"
placeholder={i18n.t('Last Name')}
/>
<Field
label="Email"
label={i18n.t('Email')}
component={ValidatedFieldText}
name="email"
placeholder="Email Address"
placeholder={i18n.t('Email Address')}
/>
<Field
label="Organization"
label={i18n.t('Organization')}
component={ValidatedFieldText}
name="organization"
placeholder="Organization"
placeholder={i18n.t('Organization')}
/>
<Field
label="Role"
label={i18n.t('Role')}
component={ValidatedFieldText}
name="role"
placeholder="Role"
placeholder={i18n.t('Role')}
/>
<HackathonSelect hackathons={hackathons} />
<Label>T-Shirt Size</Label>
<Label>{i18n.t('T-Shirt Size')}</Label>
<Field name="tshirt_size" component={TshirtSize} />
<Field
name="ndaq"
type="checkbox"
label="I agree to the Terms and Conditions/NDAQ"
label={i18n.t('I agree to the Terms and Conditions/NDAQ')}
alignLabel="right"
labelWidth="auto"
component={ValidatedFieldCheckbox}
Expand All @@ -347,7 +361,7 @@ export const RegisterScene: React.FC<{path: string}> = () => {
<Field
name="code_of_conduct"
type="checkbox"
label="I agree to the Code of Conduct"
label={i18n.t('I agree to the Code of Conduct')}
alignLabel="right"
labelWidth="auto"
component={ValidatedFieldCheckbox}
Expand All @@ -356,7 +370,7 @@ export const RegisterScene: React.FC<{path: string}> = () => {
<Field
name="contributing"
type="checkbox"
label="I agree to the Contribution Guidelines"
label={i18n.t('I agree to the Contribution Guidelines')}
alignLabel="right"
labelWidth="auto"
component={ValidatedFieldCheckbox}
Expand All @@ -370,7 +384,7 @@ export const RegisterScene: React.FC<{path: string}> = () => {
{status && <div>{status}</div>}
<Flex alignItems="center" mt="medium">
{isSubmitting && <Spinner mr="small" />}
<Button disabled={isSubmitting}>Register</Button>
<Button disabled={isSubmitting}>{i18n.t('Register')}</Button>
</Flex>
</Form>
)
Expand Down
12 changes: 7 additions & 5 deletions python/hackathon_app/frontend/src/ResourcesScene.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import {Button, Heading, Paragraph, Divider} from '@looker/components'
import i18n from './i18n'

export const ResourcesScene: React.FC<{path: string}> = ({path}) => {
const [name, setName] = React.useState('')
Expand Down Expand Up @@ -36,15 +37,16 @@ export const ResourcesScene: React.FC<{path: string}> = ({path}) => {
return (
<>
<Heading as="h1">Looker Hackathons</Heading>
<Paragraph>Find information on Hackathons below</Paragraph>
<Paragraph>{i18n.t('Find information on Hackathons below')}</Paragraph>
<Divider my="large" />
<Heading>{message}</Heading>
<Heading>{i18n.t(message)}</Heading>
<Paragraph mb="large">
Explore the links below to find useful documentation and tools for
participating in a hackathon.
{i18n.t(
'Explore the links below to find useful documentation and tools for participating in a hackathon.'
)}
</Paragraph>
<Button forwardedAs="a" href="/registration" mr="large">
Register for a Hackathon
{i18n.t('Register for a Hackathon')}
</Button>
<Button forwardedAs="a" href="//lookerhack.slack.com/">
Slack
Expand Down
29 changes: 29 additions & 0 deletions python/hackathon_app/frontend/src/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'

import translationIt from './locales/it/translation.json'

i18n.use(LanguageDetector).init({
resources: {
it: {
translations: translationIt,
},
},

ns: ['translations'],
defaultNS: 'translations',
keySeparator: false,

interpolation: {
escapeValue: false,
formatSeparator: ',',
},

react: {
wait: true,
},

fallbackLng: ['en-US'],
})

export default i18n
21 changes: 14 additions & 7 deletions python/hackathon_app/frontend/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import {I18nextProvider} from 'react-i18next'
import i18n from './i18n'
import * as serviceWorker from './serviceWorker'

ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.render(
<I18nextProvider i18n={i18n}>
<App />
</I18nextProvider>,
document.getElementById('root')
)

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
serviceWorker.unregister()
10 changes: 10 additions & 0 deletions python/hackathon_app/frontend/src/locales/it/translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"Register for a Hackathon": "Registrati per un hackathon",
"textFieldMissingError": "{{field}} è obbligatorio",
"textFieldValidationError": "{{field}} deve essere valido",
"first_name": "nome",
"last_name": "congnome",
"email": "email",
"organization": "organizzazione",
"role": "ruolo"
}