add all base translation folders

This commit is contained in:
Michael Schramm 2020-06-04 18:53:15 +02:00
parent 11c7148df3
commit f346ed3900
39 changed files with 285 additions and 146 deletions

View File

@ -22,7 +22,7 @@ const AuthFooterInner: React.FC<Props> = props => {
} }
return ( return (
<div <footer
style={{ style={{
position: 'absolute', position: 'absolute',
bottom: 0, bottom: 0,
@ -44,7 +44,7 @@ const AuthFooterInner: React.FC<Props> = props => {
Hi, {props.me.username} Hi, {props.me.username}
</span>, </span>,
<Button <Button
key={'Logout'} key={'logout'}
type={'link'} type={'link'}
ghost ghost
onClick={logout} onClick={logout}
@ -85,7 +85,7 @@ const AuthFooterInner: React.FC<Props> = props => {
> >
&copy; OhMyForm &copy; OhMyForm
</Button> </Button>
</div> </footer>
) )
} }

View File

@ -67,6 +67,7 @@ export const SelfNotificationsTab: React.FC<Props> = props => {
message: 'Please provide a Template', message: 'Please provide a Template',
}, },
]} ]}
extra={'You can also use <a href="https://mjml.io/try-it-live">MJML</a> to create your email templates'}
> >
<Input.TextArea autoSize /> <Input.TextArea autoSize />
</Form.Item> </Form.Item>

View File

@ -1,6 +1,7 @@
import {Descriptions, Table} from 'antd' import {Descriptions, Table} from 'antd'
import {ColumnsType} from 'antd/lib/table/interface' import {ColumnsType} from 'antd/lib/table/interface'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import { import {
AdminPagerSubmissionEntryFieldQueryData, AdminPagerSubmissionEntryFieldQueryData,
AdminPagerSubmissionEntryQueryData, AdminPagerSubmissionEntryQueryData,
@ -13,9 +14,11 @@ interface Props {
} }
export const SubmissionValues: React.FC<Props> = props => { export const SubmissionValues: React.FC<Props> = props => {
const { t } = useTranslation()
const columns: ColumnsType<AdminPagerSubmissionEntryFieldQueryData> = [ const columns: ColumnsType<AdminPagerSubmissionEntryFieldQueryData> = [
{ {
title: 'Field', title: t('submission:field'),
render: (row: AdminPagerSubmissionEntryFieldQueryData) => { render: (row: AdminPagerSubmissionEntryFieldQueryData) => {
if (row.field) { if (row.field) {
@ -26,7 +29,7 @@ export const SubmissionValues: React.FC<Props> = props => {
} }
}, },
{ {
title: 'Value', title: t('submission:value'),
render: row => { render: row => {
try { try {
const data = JSON.parse(row.value) const data = JSON.parse(row.value)
@ -41,11 +44,11 @@ export const SubmissionValues: React.FC<Props> = props => {
return ( return (
<div> <div>
<Descriptions title={'Submission'}> <Descriptions title={t('submission:submission')}>
<Descriptions.Item label="Country">{props.submission.geoLocation.country}</Descriptions.Item> <Descriptions.Item label={t('submission:country')}>{props.submission.geoLocation.country}</Descriptions.Item>
<Descriptions.Item label="City">{props.submission.geoLocation.city}</Descriptions.Item> <Descriptions.Item label={t('submission:city')}>{props.submission.geoLocation.city}</Descriptions.Item>
<Descriptions.Item label="Device Type">{props.submission.device.type}</Descriptions.Item> <Descriptions.Item label={t('submission:device.type')}>{props.submission.device.type}</Descriptions.Item>
<Descriptions.Item label="Device Name">{props.submission.device.name}</Descriptions.Item> <Descriptions.Item label={t('submission:device.name')}>{props.submission.device.name}</Descriptions.Item>
</Descriptions> </Descriptions>
<Table <Table

View File

@ -1,13 +1,16 @@
import {DatePicker, Form} from 'antd' import {DatePicker, Form} from 'antd'
import moment from 'moment' import moment from 'moment'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const DateType: React.FC<AdminFieldTypeProps> = ({field, form}) => { export const DateType: React.FC<AdminFieldTypeProps> = ({field, form}) => {
const { t } = useTranslation()
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Date'} label={t('type:date.default')}
name={[field.name, 'value']} name={[field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
getValueFromEvent={e => e ? e.format('YYYY-MM-DD') : undefined} getValueFromEvent={e => e ? e.format('YYYY-MM-DD') : undefined}
@ -18,7 +21,7 @@ export const DateType: React.FC<AdminFieldTypeProps> = ({field, form}) => {
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={'Min Date'} label={t('type:date.min')}
name={[field.name, 'optionKeys', 'min']} name={[field.name, 'optionKeys', 'min']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
getValueFromEvent={e => e.format('YYYY-MM-DD')} getValueFromEvent={e => e.format('YYYY-MM-DD')}
@ -28,7 +31,7 @@ export const DateType: React.FC<AdminFieldTypeProps> = ({field, form}) => {
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={'Max Date'} label={t('type:date.max')}
name={[field.name, 'optionKeys', 'max']} name={[field.name, 'optionKeys', 'max']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
getValueFromEvent={e => e.format('YYYY-MM-DD')} getValueFromEvent={e => e.format('YYYY-MM-DD')}

View File

@ -1,12 +1,15 @@
import {Button, Col, Form, Input, Row} from 'antd' import {Button, Col, Form, Input, Row} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const DropdownType: React.FC<AdminFieldTypeProps> = props => { export const DropdownType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Value'} label={t('type:dropdown.default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >
@ -26,7 +29,7 @@ export const DropdownType: React.FC<AdminFieldTypeProps> = props => {
sm: { offset: index === 0 ? 0 : 6 }, sm: { offset: index === 0 ? 0 : 6 },
}} }}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
label={index === 0 ? 'Options' : ''} label={index === 0 ? t('type:dropdown.options') : ''}
key={field.key} key={field.key}
> >
<Row gutter={16}> <Row gutter={16}>
@ -36,7 +39,7 @@ export const DropdownType: React.FC<AdminFieldTypeProps> = props => {
name={[field.name, 'title']} name={[field.name, 'title']}
style={{marginBottom: 0}} style={{marginBottom: 0}}
> >
<Input placeholder={'Title'} /> <Input placeholder={t('type:dropdown.titlePlaceholder')} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={8}> <Col span={8}>
@ -45,15 +48,15 @@ export const DropdownType: React.FC<AdminFieldTypeProps> = props => {
name={[field.name, 'value']} name={[field.name, 'value']}
style={{marginBottom: 0}} style={{marginBottom: 0}}
rules={[ rules={[
{ required: true, message: 'Please provide a value' } { required: true, message: t('validation:valueRequired') }
]} ]}
> >
<Input placeholder={'Value'} /> <Input placeholder={t('type:dropdown.valuePlaceholder')} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={4}> <Col span={4}>
<Button danger onClick={() => remove(index)}> <Button danger onClick={() => remove(index)}>
Remove {t('type:dropdown.removeOption')}
</Button> </Button>
</Col> </Col>
</Row> </Row>
@ -69,7 +72,8 @@ export const DropdownType: React.FC<AdminFieldTypeProps> = props => {
<Button <Button
type={'dashed'} type={'dashed'}
onClick={() => add()} onClick={() => add()}
>Add Option</Button> >
{t('type:dropdown.addOption')}</Button>
</Form.Item> </Form.Item>
</div> </div>
) )

View File

@ -1,15 +1,18 @@
import {Form, Input} from 'antd' import {Form, Input} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const EmailType: React.FC<AdminFieldTypeProps> = props => { export const EmailType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Email'} label={t('type:email.default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
rules={[ rules={[
{ type: 'email', message: 'Must be a valid email' } { type: 'email', message: t('validation:emailRequired') }
]} ]}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >

View File

@ -1,12 +1,15 @@
import {Form, Input} from 'antd' import {Form, Input} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const HiddenType: React.FC<AdminFieldTypeProps> = props => { export const HiddenType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Value'} label={t('type:hidden.default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >

View File

@ -1,15 +1,18 @@
import {Form, Input} from 'antd' import {Form, Input} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const LinkType: React.FC<AdminFieldTypeProps> = props => { export const LinkType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Link'} label={t('type:link.default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
rules={[ rules={[
{ type: 'url', message: 'Must be a valid URL' } { type: 'url', message: t('validation:invalidUrl') }
]} ]}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >

View File

@ -1,12 +1,15 @@
import {Form, InputNumber} from 'antd' import {Form, InputNumber} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const NumberType: React.FC<AdminFieldTypeProps> = props => { export const NumberType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Number'} label={t('type:number:default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >

View File

@ -1,12 +1,15 @@
import {Button, Col, Form, Input, Row} from 'antd' import {Button, Col, Form, Input, Row} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const RadioType: React.FC<AdminFieldTypeProps> = props => { export const RadioType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Value'} label={t('type:radio:default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >

View File

@ -1,13 +1,16 @@
import {Form, Rate} from 'antd' import {Form, Rate} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const RatingType: React.FC<AdminFieldTypeProps> = props => { export const RatingType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
// TODO add ratings // TODO add ratings
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Value'} label={t('type:rating:default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
extra={'Click again to remove default value'} extra={'Click again to remove default value'}

View File

@ -1,11 +1,14 @@
import {Form, Input} from 'antd' import {Form, Input} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const TextType: React.FC<AdminFieldTypeProps> = props => { export const TextType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
return ( return (
<Form.Item <Form.Item
label={'Default Value'} label={t('type:text:default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >

View File

@ -1,12 +1,15 @@
import {Form, Input} from 'antd' import {Form, Input} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const TextareaType: React.FC<AdminFieldTypeProps> = props => { export const TextareaType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Value'} label={t('type:textarea:default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >

View File

@ -1,13 +1,16 @@
import {Form, Input} from 'antd' import {Form, Input} from 'antd'
import React from 'react' import React from 'react'
import {useTranslation} from 'react-i18next'
import {AdminFieldTypeProps} from './type.props' import {AdminFieldTypeProps} from './type.props'
export const YesNoType: React.FC<AdminFieldTypeProps> = props => { export const YesNoType: React.FC<AdminFieldTypeProps> = props => {
const { t } = useTranslation()
// TODO add switch // TODO add switch
return ( return (
<div> <div>
<Form.Item <Form.Item
label={'Default Value'} label={t('type:yes_no:default')}
name={[props.field.name, 'value']} name={[props.field.name, 'value']}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
> >

View File

@ -3,10 +3,7 @@ import detector from "i18next-browser-languagedetector"
import {initReactI18next} from "react-i18next" import {initReactI18next} from "react-i18next"
import {resources} from './locales' import {resources} from './locales'
export const languages = [ export const languages = Object.keys(resources)
'de',
'en',
]
i18n i18n
.use(detector) .use(detector)

1
locales/cn/index.ts Normal file
View File

@ -0,0 +1 @@
export const cn = {}

1
locales/de/index.ts Normal file
View File

@ -0,0 +1 @@
export const de = {}

View File

@ -3,4 +3,6 @@ export const admin = {
users: 'Users', users: 'Users',
forms: 'Forms', forms: 'Forms',
submissions: 'Submissions', submissions: 'Submissions',
profile: 'Profile',
username: 'Username',
} }

View File

@ -4,5 +4,4 @@ export const common = {
register: "Create Account", register: "Create Account",
recover: 'Lost Password', recover: 'Lost Password',
admin: "Admin", admin: "Admin",
'mandatory-fields-missing': 'Mandatory fields missing',
} }

View File

@ -2,4 +2,31 @@ export const form = {
building: 'Building Form', building: 'Building Form',
submitted: 'Thank you for your submission!', submitted: 'Thank you for your submission!',
restart: 'Restart Form', restart: 'Restart Form',
loading: 'Loading Form',
mange: 'Edit Form "{{title}}"',
new: 'New Form',
created: 'Form Created',
creationError: 'Could not create form',
create: 'Create new form',
createNow: 'Save',
baseData: 'Base Data',
updated: 'Form updated',
updateError: 'Could not update form',
updateNow: 'Save',
design: 'Design',
startPage: 'Start Page',
endPage: 'End Page',
confirmDelete: 'Are you sure delete this form with all submissions?',
deleted: 'Form deleted',
deleteError: 'could not delete form',
deleteNow: 'Delete Now!',
row: {
isLive: 'Live',
title: 'Title',
admin: 'Owner',
language: 'Language',
created: 'Created',
lastModified: 'Last Modified',
menu: ''
}
} }

View File

@ -2,8 +2,11 @@ import {admin} from './admin'
import {common} from './common' import {common} from './common'
import {form} from './form' import {form} from './form'
import {login} from './login' import {login} from './login'
import {profile} from './profile'
import {register} from './register' import {register} from './register'
import {statistic} from './statistic' import {statistic} from './statistic'
import {submission} from './submission'
import {user} from './user'
import {validation} from './validation' import {validation} from './validation'
export const en = { export const en = {
@ -11,7 +14,10 @@ export const en = {
common, common,
form, form,
login, login,
profile,
register, register,
statistic, statistic,
submission,
user,
validation, validation,
} }

10
locales/en/profile.ts Normal file
View File

@ -0,0 +1,10 @@
export const profile = {
updated: 'Profile updated',
updateError: 'Could not update Profile',
updateNow: 'Save',
language: 'Language',
email: 'Email',
username: 'Username',
firstName: 'First Name',
lastName: 'Last Name',
}

16
locales/en/submission.ts Normal file
View File

@ -0,0 +1,16 @@
export const submission = {
progress: 'Progress',
created: 'Created',
lastModified: 'Last Change',
submission: 'Submission',
add: 'Add Submission',
edit: 'Edit',
field: 'Field',
value: 'Value',
country: 'Country',
city: 'City',
device: {
type: 'Device Type',
name: 'Device Name',
}
}

42
locales/en/type.ts Normal file
View File

@ -0,0 +1,42 @@
export const type = {
date: {
default: 'Default Date',
min: 'Min Date',
max: 'Max Date',
},
dropdown: {
default: 'Default Value',
options: 'Options',
titlePlaceholder: 'Title',
valuePlaceholder: 'Value',
removeOption: 'Remove',
addOption: 'Add Option',
},
email: {
default: 'Default Email',
},
hidden: {
default: 'Default Value',
},
link: {
default: 'Default Link',
},
number: {
default: 'Default Number',
},
radio: {
default: 'Default Value',
},
rating: {
default: 'Default Value',
},
text: {
default: 'Default Value',
},
textarea: {
default: 'Default Value',
},
yes_no: {
default: 'Default Value',
},
}

18
locales/en/user.ts Normal file
View File

@ -0,0 +1,18 @@
export const user = {
confirmDelete: 'Are you sure delete this user?',
deleted: 'User deleted',
deleteError: 'could not delete user',
deleteNow: 'Delete Now!',
loading: 'Loading User',
mange: 'Edit User "{{email}}"',
row: {
roles: 'Role',
email: 'Email',
created: 'Created',
menu: ''
},
updated: 'Form updated',
updateError: 'Could not update form',
updateNow: 'Save',
baseData: 'Base Data',
}

View File

@ -1,3 +1,9 @@
export const validation = { export const validation = {
'invalid-email': 'Must be a valid email!', invalidEmail: 'Must be a valid email!',
mandatoryFieldsMissing: 'Mandatory fields missing',
usernameRequired: 'Please provide a Username',
emailRequired: 'Please provide an Email',
languageRequired: 'Please select a Language',
valueRequired: 'Please provide a Value',
invalidUrl: 'Must be a valid URL',
} }

1
locales/es/index.ts Normal file
View File

@ -0,0 +1 @@
export const es = {}

1
locales/fr/index.ts Normal file
View File

@ -0,0 +1 @@
export const fr = {}

View File

@ -1,5 +1,15 @@
import {cn} from './cn'
import {de} from './de'
import {en} from './en' import {en} from './en'
import {es} from './es'
import {fr} from './fr'
import {it} from './it'
export const resources = { export const resources = {
cn,
de,
en, en,
es,
fr,
it,
} }

1
locales/it/index.ts Normal file
View File

@ -0,0 +1 @@
export const it = {}

View File

@ -98,21 +98,19 @@ const Index: NextPage = () => {
form.setFieldsValue(next) form.setFieldsValue(next)
setFields(next.form.fields) setFields(next.form.fields)
message.success('Form Updated') message.success(t('form:updated'))
} catch (e) { } catch (e) {
console.error('failed to save', e) console.error('failed to save', e)
message.error('Could not save Form') message.error(t('form:updateError'))
} }
setSaving(false) setSaving(false)
} }
return ( return (
<Structure <Structure
loading={loading || saving} loading={loading || saving}
title={loading ? 'Loading Form' : `Edit Form "${data.form.title}"`} title={loading ? t('form:loading') : t('form:mange', { title: data.form.title })}
selected={'forms'} selected={'forms'}
breadcrumbs={[ breadcrumbs={[
{ href: '/admin', name: t('admin:home') }, { href: '/admin', name: t('admin:home') },
@ -124,17 +122,13 @@ const Index: NextPage = () => {
href={'/admin/forms/[id]/submissions'} href={'/admin/forms/[id]/submissions'}
as={`/admin/forms/${router.query.id}/submissions`} as={`/admin/forms/${router.query.id}/submissions`}
> >
<Button> <Button>{t('admin:submissions')}</Button>
Submissions
</Button>
</Link>, </Link>,
<Button <Button
key={'save'} key={'save'}
onClick={form.submit} onClick={form.submit}
type={'primary'} type={'primary'}
> >{t('form:updateNow')}</Button>,
Save
</Button>,
]} ]}
style={{paddingTop: 0}} style={{paddingTop: 0}}
> >
@ -142,7 +136,8 @@ const Index: NextPage = () => {
form={form} form={form}
onFinish={save} onFinish={save}
onFinishFailed={errors => { onFinishFailed={errors => {
message.error('Required fields are missing') // TODO process errors
message.error(t('validation:mandatoryFieldsMissing'))
}} }}
labelCol={{ labelCol={{
xs: { span: 24 }, xs: { span: 24 },
@ -163,8 +158,8 @@ const Index: NextPage = () => {
onChangeFields={setFields} onChangeFields={setFields}
form={form} form={form}
/> />
<BaseDataTab key={'base_data'} tab={'Base Data'} /> <BaseDataTab key={'base_data'} tab={t('form:baseData')} />
<DesignTab key={'design'} tab={'Design'} /> <DesignTab key={'design'} tab={'form:design'} />
<SelfNotificationsTab <SelfNotificationsTab
key={'self_notifications'} key={'self_notifications'}
tab={'Self Notifications'} tab={'Self Notifications'}
@ -177,8 +172,8 @@ const Index: NextPage = () => {
fields={fields} fields={fields}
form={form} form={form}
/> />
<StartPageTab key={'start_page'} tab={'Start Page'} /> <StartPageTab key={'start_page'} tab={t('form:startPage')} />
<EndPageTab key={'end_page'} tab={'End Page'} /> <EndPageTab key={'end_page'} tab={t('form:endPage')} />
</Tabs> </Tabs>
</Form> </Form>
</Structure> </Structure>

View File

@ -47,7 +47,7 @@ const Submissions: NextPage = () => {
const columns:ColumnsType<AdminPagerSubmissionEntryQueryData> = [ const columns:ColumnsType<AdminPagerSubmissionEntryQueryData> = [
{ {
title: 'Progress', title: t('submission:progress'),
render: (row: AdminPagerSubmissionEntryQueryData) => { render: (row: AdminPagerSubmissionEntryQueryData) => {
let status: any = 'active' let status: any = 'active'
@ -63,12 +63,12 @@ const Submissions: NextPage = () => {
} }
}, },
{ {
title: 'Created', title: t('submission:created'),
dataIndex: 'created', dataIndex: 'created',
render: date => <DateTime date={date} /> render: date => <DateTime date={date} />
}, },
{ {
title: 'Last Change', title: t('submission:lastModified'),
dataIndex: 'lastModified', dataIndex: 'lastModified',
render: date => <TimeAgo date={date} /> render: date => <TimeAgo date={date} />
}, },
@ -82,7 +82,7 @@ const Submissions: NextPage = () => {
breadcrumbs={[ breadcrumbs={[
{ href: '/admin', name: t('admin:home') }, { href: '/admin', name: t('admin:home') },
{ href: '/admin/forms', name: t('admin:forms') }, { href: '/admin/forms', name: t('admin:forms') },
{ href: '/admin/forms/[id]', name: loading || !form ? 'Loading Form' : `Edit Form "${form.title}"`, as: `/admin/forms/${router.query.id}` }, { href: '/admin/forms/[id]', name: loading || !form ? t('form:loading') : t('form:mange', { title: form.title }), as: `/admin/forms/${router.query.id}` },
]} ]}
padded={false} padded={false}
extra={[ extra={[
@ -91,18 +91,14 @@ const Submissions: NextPage = () => {
href={'/admin/forms/[id]'} href={'/admin/forms/[id]'}
as={`/admin/forms/${router.query.id}`} as={`/admin/forms/${router.query.id}`}
> >
<Button> <Button>{t('submission:edit')}</Button>
Edit
</Button>
</Link>, </Link>,
<Button <Button
key={'web'} key={'web'}
href={`/form/${router.query.id}`} href={`/form/${router.query.id}`}
target={'_blank'} target={'_blank'}
type={'primary'} type={'primary'}
> >{t('submission:add')}</Button>,
Add Submission
</Button>,
]} ]}
> >
<Table <Table

View File

@ -25,19 +25,18 @@ const Create: NextPage = () => {
const save = async (formData: AdminFormQueryData) => { const save = async (formData: AdminFormQueryData) => {
setSaving(true) setSaving(true)
console.log('try to save form!', formData)
try { try {
const next = (await create({ const next = (await create({
variables: cleanInput(formData), variables: cleanInput(formData),
})).data })).data
message.success('Form Created') message.success(t('form:created'))
router.replace('/admin/forms/[id]', `/admin/forms/${next.form.id}`) router.replace('/admin/forms/[id]', `/admin/forms/${next.form.id}`)
} catch (e) { } catch (e) {
console.error('failed to save', e) console.error('failed to save', e)
message.error('Could not save Form') message.error(t('form:creationError'))
} }
setSaving(false) setSaving(false)
@ -46,7 +45,7 @@ const Create: NextPage = () => {
return ( return (
<Structure <Structure
loading={saving} loading={saving}
title={'Create New Form'} title={t('form:create')}
selected={'forms'} selected={'forms'}
breadcrumbs={[ breadcrumbs={[
{ href: '/admin', name: t('admin:home') }, { href: '/admin', name: t('admin:home') },
@ -57,9 +56,7 @@ const Create: NextPage = () => {
key={'create'} key={'create'}
onClick={form.submit} onClick={form.submit}
type={'primary'} type={'primary'}
> >{t('form:createNow')}</Button>,
Save
</Button>,
]} ]}
style={{paddingTop: 0}} style={{paddingTop: 0}}
> >
@ -67,7 +64,8 @@ const Create: NextPage = () => {
form={form} form={form}
onFinish={save} onFinish={save}
onFinishFailed={errors => { onFinishFailed={errors => {
message.error('Required fields are missing') // TODO process errors
message.error(t('validation:mandatoryFieldsMissing'))
}} }}
labelCol={{ labelCol={{
xs: { span: 24 }, xs: { span: 24 },
@ -81,33 +79,7 @@ const Create: NextPage = () => {
<Form.Item noStyle name={['form', 'id']}><Input type={'hidden'} /></Form.Item> <Form.Item noStyle name={['form', 'id']}><Input type={'hidden'} /></Form.Item>
<Tabs> <Tabs>
{/* <BaseDataTab key={'base_data'} tab={t('form:baseData')} />
<FieldsTab
key={'fields'}
tab={'Fields'}
fields={fields}
onChangeFields={setFields}
form={form}
/>
*/}
<BaseDataTab key={'base_data'} tab={'Base Data'} />
{/*
<DesignTab key={'design'} tab={'Design'} />
<SelfNotificationsTab
key={'self_notifications'}
tab={'Self Notifications'}
fields={fields}
form={form}
/>
<RespondentNotificationsTab
key={'respondent_notifications'}
tab={'Respondent Notifications'}
fields={fields}
form={form}
/>
<StartPageTab key={'start_page'} tab={'Start Page'} />
<EndPageTab key={'end_page'} tab={'End Page'} />
*/}
</Tabs> </Tabs>
</Form> </Form>
</Structure> </Structure>

View File

@ -59,24 +59,24 @@ const Index: NextPage = () => {
setEntries(next) setEntries(next)
} }
message.success('form deleted') message.success(t('form:deleted'))
} catch (e) { } catch (e) {
message.error('could not delete form') message.error(t('form:deleteError'))
} }
} }
const columns: ColumnsType<AdminPagerFormEntryQueryData> = [ const columns: ColumnsType<AdminPagerFormEntryQueryData> = [
{ {
title: 'Live', title: t('form:row.isLive'),
dataIndex: 'isLive', dataIndex: 'isLive',
render: live => <FormIsLive isLive={live} /> render: live => <FormIsLive isLive={live} />
}, },
{ {
title: 'Title', title: t('form:row.title'),
dataIndex: 'title', dataIndex: 'title',
}, },
{ {
title: 'Owner', title: t('form:row.admin'),
dataIndex: 'admin', dataIndex: 'admin',
render: user => ( render: user => (
<Link href={'/admin/users/[id]'} as={`/admin/users/${user.id}`}> <Link href={'/admin/users/[id]'} as={`/admin/users/${user.id}`}>
@ -87,20 +87,21 @@ const Index: NextPage = () => {
) )
}, },
{ {
title: 'Language', title: t('form:row.language'),
dataIndex: 'language', dataIndex: 'language',
}, },
{ {
title: 'Created', title: t('form:row.created'),
dataIndex: 'created', dataIndex: 'created',
render: date => <DateTime date={date} /> render: date => <DateTime date={date} />
}, },
{ {
title: 'Last Change', title: t('form:row.lastModified'),
dataIndex: 'lastModified', dataIndex: 'lastModified',
render: date => <TimeAgo date={date} /> render: date => <TimeAgo date={date} />
}, },
{ {
title: t('form:row.menu'),
align: 'right', align: 'right',
render: row => { render: row => {
return ( return (
@ -122,9 +123,9 @@ const Index: NextPage = () => {
</Link> </Link>
<Popconfirm <Popconfirm
title="Are you sure delete this form with all submissions?" title={t('form:confirmDelete')}
onConfirm={() => deleteForm(row)} onConfirm={() => deleteForm(row)}
okText={'Delete now!'} okText={t('form:deleteNow')}
okButtonProps={{ danger: true }} okButtonProps={{ danger: true }}
> >
<Button danger><DeleteOutlined /></Button> <Button danger><DeleteOutlined /></Button>
@ -160,9 +161,7 @@ const Index: NextPage = () => {
> >
<Button <Button
type={'primary'} type={'primary'}
> >{t('form:new')}</Button>
New Form
</Button>
</Link>, </Link>,
]} ]}
> >

View File

@ -4,6 +4,7 @@ import {useForm} from 'antd/lib/form/Form'
import {NextPage} from 'next' import {NextPage} from 'next'
import {useRouter} from 'next/router' import {useRouter} from 'next/router'
import React, {useState} from 'react' import React, {useState} from 'react'
import {useTranslation} from 'react-i18next'
import {cleanInput} from '../../components/clean.input' import {cleanInput} from '../../components/clean.input'
import Structure from '../../components/structure' import Structure from '../../components/structure'
import { import {
@ -20,6 +21,7 @@ import {AdminUserQueryData} from '../../graphql/query/admin.user.query'
import {languages} from '../../i18n' import {languages} from '../../i18n'
const Profile: NextPage = () => { const Profile: NextPage = () => {
const { t } = useTranslation()
const router = useRouter() const router = useRouter()
const [form] = useForm() const [form] = useForm()
const [saving, setSaving] = useState(false) const [saving, setSaving] = useState(false)
@ -42,10 +44,10 @@ const Profile: NextPage = () => {
form.setFieldsValue(next) form.setFieldsValue(next)
message.success('Profile Updated') message.success(t('profile:updated'))
} catch (e) { } catch (e) {
console.error('failed to save', e) console.error('failed to save', e)
message.error('Could not save Profile') message.error(t('profile:updateError'))
} }
setSaving(false) setSaving(false)
@ -55,26 +57,25 @@ const Profile: NextPage = () => {
return ( return (
<Structure <Structure
loading={loading || saving} loading={loading || saving}
title={'Profile'} title={t('admin:profile')}
selected={'profile'} selected={'profile'}
breadcrumbs={[ breadcrumbs={[
{ href: '/admin', name: 'Home' }, { href: '/admin', name: t('admin:home') },
]} ]}
extra={[ extra={[
<Button <Button
key={'save'} key={'save'}
onClick={form.submit} onClick={form.submit}
type={'primary'} type={'primary'}
> >{t('profile:updateNow')}</Button>,
Save
</Button>,
]} ]}
> >
<Form <Form
form={form} form={form}
onFinish={save} onFinish={save}
onFinishFailed={errors => { onFinishFailed={errors => {
message.error('Required fields are missing') // TODO process errors
message.error(t('validation:mandatoryFieldsMissing'))
}} }}
labelCol={{ labelCol={{
xs: { span: 24 }, xs: { span: 24 },
@ -88,12 +89,12 @@ const Profile: NextPage = () => {
<Form.Item noStyle name={['user', 'id']}><Input type={'hidden'} /></Form.Item> <Form.Item noStyle name={['user', 'id']}><Input type={'hidden'} /></Form.Item>
<Form.Item <Form.Item
label="Username" label={t('profile:username')}
name={['user', 'username']} name={['user', 'username']}
rules={[ rules={[
{ {
required: true, required: true,
message: 'Please provide a Username', message: t('validation:usernameRequired'),
}, },
]} ]}
> >
@ -101,16 +102,16 @@ const Profile: NextPage = () => {
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="Email" label={t('profile:email')}
name={['user', 'email']} name={['user', 'email']}
rules={[ rules={[
{ {
required: true, required: true,
message: 'Please provide an email', message: t('validation:emailRequired'),
}, },
{ {
type: 'email', type: 'email',
message: 'Must be a valid email', message: t('validation:invalidEmail'),
}, },
]} ]}
> >
@ -118,12 +119,12 @@ const Profile: NextPage = () => {
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="Language" label={t('profile:language')}
name={['user', 'language']} name={['user', 'language']}
rules={[ rules={[
{ {
required: true, required: true,
message: 'Please select a Language', message: t('validation:languageRequired'),
}, },
]} ]}
> >
@ -133,14 +134,14 @@ const Profile: NextPage = () => {
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="First Name" label={t('profile:firstName')}
name={['user', 'firstName']} name={['user', 'firstName']}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="Last Name" label={t('profile:lastName')}
name={['user', 'lastName']} name={['user', 'lastName']}
> >
<Input /> <Input />

View File

@ -42,10 +42,10 @@ const Index: NextPage = () => {
form.setFieldsValue(next) form.setFieldsValue(next)
message.success('User Updated') message.success(t('user:updated'))
} catch (e) { } catch (e) {
console.error('failed to save', e) console.error('failed to save', e)
message.error('Could not save User') message.error(t('user:updateError'))
} }
setSaving(false) setSaving(false)
@ -54,7 +54,7 @@ const Index: NextPage = () => {
return ( return (
<Structure <Structure
loading={loading || saving} loading={loading || saving}
title={loading ? 'Loading User' : `Edit User "${data.user.email}"`} title={loading ? t('user:loading') : t('user:mange', { title: data.user.email })}
selected={'users'} selected={'users'}
breadcrumbs={[ breadcrumbs={[
{ href: '/admin', name: t('admin:home') }, { href: '/admin', name: t('admin:home') },
@ -65,9 +65,7 @@ const Index: NextPage = () => {
key={'save'} key={'save'}
onClick={form.submit} onClick={form.submit}
type={'primary'} type={'primary'}
> >{t('user:updateNow')}</Button>,
Save
</Button>,
]} ]}
style={{paddingTop: 0}} style={{paddingTop: 0}}
> >
@ -75,7 +73,8 @@ const Index: NextPage = () => {
form={form} form={form}
onFinish={save} onFinish={save}
onFinishFailed={errors => { onFinishFailed={errors => {
message.error('Required fields are missing') // TODO process errors
message.error(t('validation:mandatoryFieldsMissing'))
}} }}
labelCol={{ labelCol={{
xs: { span: 24 }, xs: { span: 24 },
@ -91,7 +90,7 @@ const Index: NextPage = () => {
<Tabs> <Tabs>
<BaseDataTab <BaseDataTab
key={'base_data'} key={'base_data'}
tab={'Base Data'} tab={t('user:baseData')}
/> />
</Tabs> </Tabs>
</Form> </Form>

View File

@ -57,28 +57,29 @@ const Index: NextPage = () => {
} else { } else {
setEntries(next) setEntries(next)
} }
message.success('user deleted') message.success(t('user:deleted'))
} catch (e) { } catch (e) {
message.error('could not delete user') message.error(t('user:deleteError'))
} }
} }
const columns: ColumnsType<AdminPagerUserEntryQueryData> = [ const columns: ColumnsType<AdminPagerUserEntryQueryData> = [
{ {
title: 'Role', title: t('user:row.roles'),
dataIndex: 'roles', dataIndex: 'roles',
render: roles => <UserRole roles={roles} /> render: roles => <UserRole roles={roles} />
}, },
{ {
title: 'Email', title: t('user:row.email'),
render: row => <Tag color={row.verifiedEmail ? 'lime' : 'volcano' }>{row.email}</Tag> render: row => <Tag color={row.verifiedEmail ? 'lime' : 'volcano' }>{row.email}</Tag>
}, },
{ {
title: 'Created', title: t('user:row.created'),
dataIndex: 'created', dataIndex: 'created',
render: date => <DateTime date={date} /> render: date => <DateTime date={date} />
}, },
{ {
title: t('user:row.menu'),
align: 'right', align: 'right',
render: row => { render: row => {
return ( return (
@ -91,9 +92,9 @@ const Index: NextPage = () => {
</Link> </Link>
<Popconfirm <Popconfirm
title="Are you sure delete this user?" title={t('user:confirmDelete')}
onConfirm={() => deleteUser(row)} onConfirm={() => deleteUser(row)}
okText={'Delete now!'} okText={t('user:deleteNow')}
okButtonProps={{ danger: true }} okButtonProps={{ danger: true }}
> >
<Button danger><DeleteOutlined /></Button> <Button danger><DeleteOutlined /></Button>

View File

@ -41,7 +41,7 @@ const Index: NextPage = () => {
} }
const failed = () => { const failed = () => {
message.error(t('mandatory-fields-missing')) message.error(t('validation:mandatoryFieldsMissing'))
} }
return ( return (

View File

@ -44,7 +44,7 @@ const Register: NextPage = () => {
} }
const failed = () => { const failed = () => {
message.error(t('mandatory-fields-missing')) message.error(t('validation:mandatoryFieldsMissing'))
} }
return ( return (
@ -86,7 +86,7 @@ const Register: NextPage = () => {
name="email" name="email"
rules={[ rules={[
{ required: true, message: t('register:email-required') }, { required: true, message: t('register:email-required') },
{ type: 'email', message: t('validation:invalid-email') } { type: 'email', message: t('validation:invalidEmail') }
]} ]}
> >
<Input <Input