Skip to content
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
2 changes: 2 additions & 0 deletions labellab-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"fs-extra": "^8.1.0",
"html-webpack-plugin": "4.0.0-beta.5",
"http-proxy-middleware": "^0.19.1",
"i18next": "^19.9.2",
"identity-obj-proxy": "3.0.0",
"immutability-helper": "^3.0.0",
"jest": "^24.9.0",
Expand Down Expand Up @@ -66,6 +67,7 @@
"react-google-login": "^5.1.20",
"react-google-maps": "^9.4.5",
"react-hot-keys": "^1.2.2",
"react-i18next": "^11.18.6",
"react-image-crop": "^8.6.4",
"react-image-lightbox": "^5.1.1",
"react-leaflet": "^2.2.0",
Expand Down
19 changes: 11 additions & 8 deletions labellab-client/src/__tests__/components/login.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ import React from 'react'
import Enzyme, { shallow } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16';
import { testStore, findByTestAttr } from '../../utils/TestUtils'
import LoginIndex from '../../components/login/index'
import { LoginIndex } from '../../components/login/index'

Enzyme.configure({
adapter: new Adapter(),
disableLifecycleMethods: true
});

const setUp = (initialState={}, props={}) => {
const store = testStore(initialState);
const wrapper = shallow(<LoginIndex store={store} {...props}/>)
.childAt(0)
.dive();
return wrapper;
};
const setUp = (initialState = {}, props = {}) => {
const store = testStore(initialState)
return shallow(
<LoginIndex
store={store}
t={(key) => key}
{...props}
/>
)
}

describe('Login Component', () => {

Expand Down
38 changes: 22 additions & 16 deletions labellab-client/src/components/login/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { withTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import {
Input,
Expand Down Expand Up @@ -56,11 +57,11 @@ class LoginIndex extends Component {
errors.email = value.length
? isEmail(value)
? ''
: 'E-mail address is invalid!'
: 'E-mail address is required!'
: t('login.emailInvalid')
: t('login.emailRequired')
break
case 'password':
errors.password = value.length ? '' : 'Password is required!'
errors.password = value.length ? '' : t('login.passwordRequired')
break
default:
break
Expand All @@ -81,7 +82,7 @@ class LoginIndex extends Component {
} else {
let errors = { ...this.state.errors }

errors.password = password.length ? '' : 'Password is required!'
errors.password = password.length ? '' : t('login.passwordRequired')
errors.email = email.length
? isEmail(email)
? ''
Expand Down Expand Up @@ -116,31 +117,32 @@ class LoginIndex extends Component {
statusText,
registerStatusText,
authError,
t,
} = this.props
const { email, password, errors } = this.state
return (
<div className="login-grand-parent">
{isAuthenticating ? (
<Dimmer active>
<Loader content="Authenticating..." />
<Loader content={t('login.authenticating')} />
</Dimmer>
) : null}
<div className="login-parent">
<Header as="h2" textAlign="center">
<Header.Content>
LabelLab
<Header.Subheader>Login to your account</Header.Subheader>
<Header.Subheader>{t('login.title')}</Header.Subheader>
</Header.Content>
</Header>

<div className="login-form">
<Form onSubmit={this.handleSubmit}>
<Form.Field error={!!errors.email}>
<label>E-mail address</label>
<label>{t('login.email')}</label>
<Input
type="text"
className="email"
placeholder="E-mail address"
placeholder={t('login.email')}
name="email"
value={email}
onChange={this.handleChange}
Expand All @@ -153,11 +155,11 @@ class LoginIndex extends Component {
</Form.Field>

<Form.Field error={!!errors.password}>
<label>Password</label>
<label>{t('login.password')}</label>

<Input
type={this.state.showPassword ? 'text' : 'password'}
placeholder="Password"
placeholder={t('login.password')}
className="password"
name="password"
value={password}
Expand Down Expand Up @@ -190,19 +192,19 @@ class LoginIndex extends Component {
</Message>
)}
<div className="action">
<Link to="/forgotpassword">Forgot password?</Link>
<Link to="/forgotpassword">{t('login.forgotPassword')}</Link>
</div>

<Button primary>Log in</Button>
<Button primary>{t('login.loginButton')}</Button>
</Form>
</div>

<div className="action">
Don&apos;t have an account?&nbsp;
<Link to="/register">Create an account</Link>
{t('login.noAccount')}&nbsp;
<Link to="/register">{t('login.createAccount')}</Link>
</div>

<Divider horizontal>Or</Divider>
<Divider horizontal>{t('login.or')}</Divider>

<div className="login-oauth-icon">
<GoogleContainer />
Expand Down Expand Up @@ -238,4 +240,8 @@ const mapActionToProps = (dispatch) => {
}
}

export default connect(mapStateToProps, mapActionToProps)(LoginIndex)
export { LoginIndex }

export default withTranslation()(
connect(mapStateToProps, mapActionToProps)(LoginIndex)
)
11 changes: 6 additions & 5 deletions labellab-client/src/components/navbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react'
import { Image, Header, Dropdown } from 'semantic-ui-react'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { withTranslation } from 'react-i18next'
import PropTypes from 'prop-types'
import './css/navbar.css'
import Searchbar from './searchbar'
Expand Down Expand Up @@ -35,7 +36,7 @@ class Navbar extends Component {
content={user.username}
/>
{isfetching ? (
<h4>LOADING</h4>
<h4>{this.props.t('navbar.loading')}</h4>
) : user ? (
<Image
className="profilepic"
Expand All @@ -53,17 +54,17 @@ class Navbar extends Component {
<Dropdown className="dropdown">
<Dropdown.Menu>
<Dropdown.Item>
<Link to="/profile">Profile</Link>
<Link to="/profile">{this.props.t('navbar.profile')}</Link>
</Dropdown.Item>
<Dropdown.Item as="label" onClick={this.handleClick}>
Logout
{this.props.t('navbar.logout')}
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</div>
</li>
<li>
<h4 className="logout">Logout</h4>
<h4 className="logout">{this.props.t('navbar.logout')}</h4>
</li>
</ul>
</header>
Expand All @@ -83,4 +84,4 @@ const mapStateToProps = state => {
}
}

export default connect(mapStateToProps, null)(Navbar)
export default withTranslation()(connect(mapStateToProps, null)(Navbar))
22 changes: 22 additions & 0 deletions labellab-client/src/i18n/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import en from './locales/en.json'
import hi from './locales/hi.json'

i18n.use(initReactI18next).init({
resources: {
en: {
translation: en
},
hi: {
translation: hi
}
},
lng: 'en',
fallbackLng: 'en',
interpolation: {
escapeValue: false
}
})

export default i18n
21 changes: 21 additions & 0 deletions labellab-client/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"login": {
"authenticating": "Authenticating...",
"title": "Login to your account",
"email": "E-mail address",
"password": "Password",
"forgotPassword": "Forgot password?",
"loginButton": "Log in",
"noAccount": "Don't have an account?",
"createAccount": "Create an account",
"or": "Or",
"emailRequired": "E-mail address is required!",
"emailInvalid": "E-mail address is invalid!",
"passwordRequired": "Password is required!"
},
"navbar": {
"profile": "Profile",
"logout": "Logout",
"loading": "LOADING"
}
}
21 changes: 21 additions & 0 deletions labellab-client/src/i18n/locales/hi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"login": {
"authenticating": "प्रमाणीकरण हो रहा है...",
"title": "अपने खाते में लॉग इन करें",
"email": "ई-मेल पता",
"password": "पासवर्ड",
"forgotPassword": "पासवर्ड भूल गए?",
"loginButton": "लॉग इन करें",
"noAccount": "खाता नहीं है?",
"createAccount": "खाता बनाएं",
"or": "या",
"emailRequired": "ई-मेल पता आवश्यक है!",
"emailInvalid": "ई-मेल पता अमान्य है!",
"passwordRequired": "पासवर्ड आवश्यक है!"
},
"navbar": {
"profile": "प्रोफ़ाइल",
"logout": "लॉग आउट",
"loading": "लोड हो रहा है"
}
}
1 change: 1 addition & 0 deletions labellab-client/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Provider } from 'react-redux'
import { store } from './utils/store'
import './index.css'
import 'semantic-ui-css/semantic.min.css'
import './i18n'
import App from './App'
import * as serviceWorker from './serviceWorker'
ReactDOM.render(
Expand Down