Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple languages #187

Merged
merged 43 commits into from
Feb 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
0d7fe7b
Added i18next packages
hql287 Jan 22, 2018
899bf5f
Added i18next to mainWindow
hql287 Jan 22, 2018
93d3181
Allows user to set default language
hql287 Jan 22, 2018
d2d55e3
Added translation
hql287 Jan 22, 2018
d6f525e
Translated components
hql287 Jan 22, 2018
471805f
Converted js to json
hql287 Jan 23, 2018
6adf402
Added & refactored translations
hql287 Jan 24, 2018
7ffa431
Uddated English Translation
hql287 Jan 24, 2018
6361600
Fixed Tests
hql287 Jan 25, 2018
5f6a6a5
Merge branch 'dev' into multiple-languages
hql287 Jan 26, 2018
4d1a665
Removed date-fns, use moment instead.
hql287 Jan 27, 2018
d0bae24
Fixed typos
hql287 Jan 27, 2018
6fd7abf
Added Invoices translation
hql287 Jan 27, 2018
ae7f30d
Translated Invoices & Invoice components
hql287 Jan 27, 2018
5c6422e
Added Fr & Vi translations
hql287 Jan 27, 2018
aa2e7d7
Replaced date-fns with moment
hql287 Jan 27, 2018
1907532
Fixed Tests
hql287 Jan 27, 2018
afb639c
Translated Contacts tab & added empty messages translation
hql287 Jan 29, 2018
05483fe
Keep i18n with moment in sync
hql287 Jan 29, 2018
a862b2e
Refactored Invoices/Invoice component and tests
hql287 Jan 29, 2018
15f5c30
Translated Notifications
hql287 Jan 29, 2018
d775279
Added missing translation for English & French
hql287 Jan 29, 2018
8569bb5
Converted Dialog windows to React component
hql287 Jan 29, 2018
2dafbbd
Updated Webpack Config
hql287 Jan 29, 2018
9e37b61
Removed unused component
hql287 Jan 29, 2018
501278e
Added dialog & common translations
hql287 Jan 29, 2018
265c8bb
Refactored components
hql287 Jan 29, 2018
06301d6
Refactored helpers
hql287 Jan 29, 2018
cf6fba3
Added missing translation
hql287 Jan 29, 2018
3c41aaa
Fixed Tests
hql287 Jan 30, 2018
f0bde11
Added translation for tourWindow & previewWindow
hql287 Jan 31, 2018
4bc4d52
Refactored previewWindow components
hql287 Jan 31, 2018
20593d7
Refactored templates
hql287 Jan 31, 2018
cd2fb73
Refactored tourWindow components
hql287 Jan 31, 2018
8eee3e8
Fixed snapshot
hql287 Jan 31, 2018
0ab2b40
Fixed typos
hql287 Jan 31, 2018
5a490fa
Fixed Typos
hql287 Jan 31, 2018
8fb98de
Merge branch 'dev' into multiple-languages
hql287 Feb 1, 2018
e9aaaff
Fixed typos
hql287 Feb 1, 2018
91d60cf
Fixed test
hql287 Feb 1, 2018
171e7c3
Updated Vietnamese Translation
hql287 Feb 2, 2018
32df196
Updated French translation
hql287 Feb 2, 2018
1658748
Updated English Translation
hql287 Feb 2, 2018
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
8 changes: 6 additions & 2 deletions app/components/form/Currency.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,16 @@ export class Currency extends Component {
}

render() {
const { t } = this.props;
return (
<Section>
<Header>
<label className="itemLabel">Currency</label>
<label className="itemLabel">
{t('form:fields:currency')}
</label>
{!this.isSettingsSaved() && (
<a href="#" onClick={this.saveAsDefault}>
<i className="ion-checkmark" /> Save as default?
<i className="ion-checkmark" /> {t('common:saveAsDefault')}
</a>
)}
</Header>
Expand All @@ -90,6 +93,7 @@ export class Currency extends Component {
Currency.propTypes = {
currency: PropTypes.object.isRequired,
savedSettings: PropTypes.string.isRequired,
t: PropTypes.func.isRequired,
updateFieldData: PropTypes.func.isRequired,
updateSavedSettings: PropTypes.func.isRequired,
};
Expand Down
14 changes: 10 additions & 4 deletions app/components/form/Discount.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,21 @@ export class Discount extends Component {
}

render() {
const { t } = this.props;
return (
<Section>
<DiscountWrapper>
<label className="itemLabel">Discount</label>
<label className="itemLabel">
{t('form:fields:discount.name')}
</label>
<DiscountContent>
<DiscountAmount>
<input
name="amount"
type="number"
value={this.state.amount}
onChange={this.handleInputChange}
placeholder="Amount"
placeholder={t('common:amount')}
/>
</DiscountAmount>
<DiscountType>
Expand All @@ -103,7 +106,8 @@ export class Discount extends Component {
onChange={this.handleInputChange}
checked={this.state.type === 'percentage'}
value="percentage"
/>Percentage
/>
{t('form:fields:discount:percentage')}
</label>
</div>
<div className="radio">
Expand All @@ -114,7 +118,8 @@ export class Discount extends Component {
onChange={this.handleInputChange}
checked={this.state.type === 'flat'}
value="flat"
/>Flat Rate
/>
{t('form:fields:discount:flat')}
</label>
</div>
</DiscountType>
Expand All @@ -127,6 +132,7 @@ export class Discount extends Component {

Discount.propTypes = {
discount: PropTypes.object.isRequired,
t: PropTypes.func.isRequired,
updateFieldData: PropTypes.func.isRequired,
};

Expand Down
7 changes: 4 additions & 3 deletions app/components/form/DueDate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ export class DueDate extends Component {
}

render() {
const { dueDate } = this.props;
const { t, dueDate } = this.props;
const selectedDate = dueDate.selectedDate
? moment(dueDate.selectedDate)
: null;
return (
<Section>
<label className="itemLabel">Due Date</label>
<label className="itemLabel">{t('form:fields:dueDate:name')}</label>
<DueDateContent>
<SingleDatePicker
id="invoice-duedate"
placeholder="Select A Date"
placeholder={t('form:fields:dueDate:placeHolder')}
firstDayOfWeek={1}
withFullScreenPortal
displayFormat="DD/MM/YYYY"
Expand All @@ -83,6 +83,7 @@ export class DueDate extends Component {

DueDate.propTypes = {
dueDate: PropTypes.object.isRequired,
t: PropTypes.func.isRequired,
updateFieldData: PropTypes.func.isRequired,
};

Expand Down
9 changes: 5 additions & 4 deletions app/components/form/ItemRow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export class ItemRow extends Component {
}

render() {
const { actions, hasHandler } = this.props;
const { t, actions, hasHandler } = this.props;
return (
<ItemDiv>
{hasHandler && (
Expand All @@ -140,7 +140,7 @@ export class ItemRow extends Component {
value={this.state.description}
onChange={this.handleTextInputChange}
onKeyDown={this.handleKeyDown}
placeholder="Description"
placeholder={t('form:fields:items:description')}
/>
</div>

Expand All @@ -151,8 +151,8 @@ export class ItemRow extends Component {
step="0.01"
value={this.state.price}
onChange={this.handleNumberInputChange}
placeholder="Price"
onKeyDown={this.handleKeyDown}
placeholder={t('form:fields:items:price')}
/>
</div>

Expand All @@ -163,8 +163,8 @@ export class ItemRow extends Component {
step="0.01"
value={this.state.quantity}
onChange={this.handleNumberInputChange}
placeholder="Quantity"
onKeyDown={this.handleKeyDown}
placeholder={t('form:fields:items:quantity')}
/>
</div>

Expand All @@ -185,6 +185,7 @@ export class ItemRow extends Component {
ItemRow.propTypes = {
actions: PropTypes.bool.isRequired,
addItem: PropTypes.func.isRequired,
t: PropTypes.func.isRequired,
hasHandler: PropTypes.bool.isRequired,
item: PropTypes.object.isRequired,
removeRow: PropTypes.func.isRequired,
Expand Down
9 changes: 6 additions & 3 deletions app/components/form/ItemsList.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Libs
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';

// Redux
import { compose } from 'recompose';
Expand Down Expand Up @@ -70,11 +71,12 @@ export class ItemsList extends PureComponent {
// Bound Actions
const { addItem, removeItem, updateItem } = this.props.boundActionCreators;
// Item Rows
const { rows } = this.props;
const { t, rows } = this.props;
const rowsComponent = rows.map((item, index) => (
<ItemRow
key={item.id}
item={item}
t={t}
hasHandler={rows.length > 1}
actions={index !== 0}
updateRow={updateItem}
Expand All @@ -88,7 +90,7 @@ export class ItemsList extends PureComponent {
<Section>
<ItemsListWrapper>
<ItemsListHeader>
<label className="itemLabel">Product/Service *</label>
<label className="itemLabel">{t('form:fields:items:name')} *</label>
</ItemsListHeader>
<ItemsListDiv>
<TransitionList componentHeight={50}>
Expand All @@ -97,7 +99,7 @@ export class ItemsList extends PureComponent {
</ItemsListDiv>
<div className="itemsListActions">
<ItemsListActionsBtn primary onClick={addItem}>
Add An Item
{t('form:fields:items:add')}
</ItemsListActionsBtn>
</div>
</ItemsListWrapper>
Expand All @@ -123,5 +125,6 @@ const mapDispatchToProps = dispatch => ({
// Export
export default compose(
connect(mapStateToProps, mapDispatchToProps),
translate('form'),
_withDragNDrop
)(ItemsList);
6 changes: 4 additions & 2 deletions app/components/form/Note.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,16 @@ export class Note extends Component {
}

render() {
const { t } = this.props;
return (
<Section>
<label className="itemLabel">Note</label>
<label className="itemLabel">{t('form:fields:note')}</label>
<NoteContent
cols="50"
rows="4"
onChange={this.handleInputChange}
placeholder="Note"
value={this.state.content}
placeholder={t('form:fields:note')}
/>
</Section>
);
Expand All @@ -67,6 +68,7 @@ export class Note extends Component {

Note.propTypes = {
note: PropTypes.object.isRequired,
t: PropTypes.func.isRequired,
updateFieldData: PropTypes.func.isRequired,
};

Expand Down
19 changes: 13 additions & 6 deletions app/components/form/Recipient.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Libraries
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { compose } from 'recompose';
import { translate } from 'react-i18next';

// Redux & Selectors
import { getContacts } from '../../reducers/ContactsReducer';
Expand Down Expand Up @@ -85,10 +87,11 @@ export class Recipient extends Component {

// Render Form or Select Input
renderComponent() {
const { contacts } = this.props;
const { t, contacts } = this.props;
if (contacts.length === 0) {
return (
<RecipientForm
t={t}
formData={this.state.new}
updateRecipientForm={this.updateRecipientForm}
/>
Expand All @@ -98,6 +101,7 @@ export class Recipient extends Component {
if (this.state.newRecipient) {
return (
<RecipientForm
t={t}
formData={this.state.new}
updateRecipientForm={this.updateRecipientForm}
/>
Expand All @@ -114,10 +118,10 @@ export class Recipient extends Component {

// Render
render() {
const { contacts } = this.props;
const { t, contacts } = this.props;
return (
<Section>
<label className="itemLabel">Client *</label>
<label className="itemLabel">{t('form:fields:recipient:name')} *</label>
{this.renderComponent()}
{contacts.length > 0 ? (
<div>
Expand All @@ -129,7 +133,7 @@ export class Recipient extends Component {
checked={this.state.newRecipient === true}
value="new"
/>
Add New
{t('form:fields:recipient:add')}
</label>
</div>
<div className="radio">
Expand All @@ -140,7 +144,7 @@ export class Recipient extends Component {
checked={this.state.newRecipient === false}
value="select"
/>
Select
{t('form:fields:recipient:select')}
</label>
</div>
</div>
Expand All @@ -167,4 +171,7 @@ const mapStateToProps = state => ({
recipient: getRecipient(state),
});

export default connect(mapStateToProps)(Recipient);
export default compose(
connect(mapStateToProps),
translate('form'),
)(Recipient);
11 changes: 6 additions & 5 deletions app/components/form/RecipientForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ const Field = styled.div`
margin: 0 15px 20px 15px;
`;

export function RecipientForm({ formData, updateRecipientForm }) {
export function RecipientForm({ t, formData, updateRecipientForm }) {
const { fullname, company, email, phone } = formData;
return (
<Form>
<Row>
<Field>
<label className="itemLabel">Full Name *</label>
<label className="itemLabel">{t('common:fields:fullname')} *</label>
<input
name="fullname"
type="text"
Expand All @@ -40,7 +40,7 @@ export function RecipientForm({ formData, updateRecipientForm }) {
/>
</Field>
<Field>
<label className="itemLabel">Company</label>
<label className="itemLabel">{t('common:fields:company')}</label>
<input
name="company"
type="text"
Expand All @@ -51,7 +51,7 @@ export function RecipientForm({ formData, updateRecipientForm }) {
</Row>
<Row>
<Field>
<label className="itemLabel">Email *</label>
<label className="itemLabel">{t('common:fields:email')} *</label>
<input
name="email"
type="text"
Expand All @@ -60,7 +60,7 @@ export function RecipientForm({ formData, updateRecipientForm }) {
/>
</Field>
<Field>
<label className="itemLabel">Phone Number</label>
<label className="itemLabel">{t('common:fields:phone')}</label>
<input
name="phone"
type="text"
Expand All @@ -76,6 +76,7 @@ export function RecipientForm({ formData, updateRecipientForm }) {
// PropTypes Validation
RecipientForm.propTypes = {
formData: PropTypes.object,
t: PropTypes.func.isRequired,
updateRecipientForm: PropTypes.func.isRequired,
};

Expand Down
Loading