[Ivan Diaz] - Update React version and fix i18n issues

This commit is contained in:
Ivan Diaz 2016-01-26 18:05:09 -03:00
parent 9b297712e4
commit 7530512663
23 changed files with 94 additions and 96 deletions

View File

@ -1,6 +1,6 @@
OpenSupports v4.0 OpenSupports v4.0
[![Build Status](https://codeship.com/projects/3faec3f0-908d-0133-1dce-661fcf0def08/status?branch=master)](https://codeship.com/projects/124436/) [![Build Status](https://codeship.com/projects/3faec3f0-908d-0133-1dce-661fcf0def08/status?branch=master)](https://codeship.com/projects/124436/)
============ ============
### Getting up and running FRONT-END ### Getting up and running FRONT-END
@ -13,23 +13,20 @@ OpenSupports v4.0
3. Install npm `sudo apt-get install npm` 3. Install npm `sudo apt-get install npm`
4. Install gulp `sudo npm install -g gulp` 4. Install gulp `sudo npm install -g gulp`
5. Go to repo `cd os4-react` 5. Go to repo `cd os4-react`
6. Install dependences `sudo npm install` 6. Install dependences `npm install`
7. Rebuild node-sass `sudo npm rebuild node-sass` 7. Rebuild node-sass `npm rebuild node-sass`
8. Run `gulp dev` 8. Run `gulp dev`
9. Go to the main app: `http://localhost:3000/app` or the component demo `http://localhost:3000/demo` 9. Go to the main app: `http://localhost:3000/app` or the component demo `http://localhost:3000/demo`
10. Your browser will automatically be opened and directed to the browser-sync proxy address
### Getting up and running
1. [Create MySQL Database](#markdown-header-create-mysql-database)
2. Clone this repo
3. Run `npm install` from the root directory
4. Create a mysql database
5. Run `gulp dev` (may require installing Gulp globally `npm install gulp -g`)
6. Your browser will automatically be opened and directed to the browser-sync proxy address
7. To prepare assets for production, run the `gulp prod` task (Note: the production task does not fire up the express server, and won't provide you with browser-sync's live reloading. Simply use `gulp dev` during development. More information below)
Now that `gulp dev` is running, the server is up as well and serving files from the `/build` directory. Any changes in the `/src` directory will be automatically processed by Gulp and the changes will be injected to any open browsers pointed at the proxy address. Now that `gulp dev` is running, the server is up as well and serving files from the `/build` directory. Any changes in the `/src` directory will be automatically processed by Gulp and the changes will be injected to any open browsers pointed at the proxy address.
### Getting up and running BACK-END
1. Clone this repo
2. [Create MySQL Database](#markdown-header-create-mysql-database)
TODO
### Create MySQL Database ### Create MySQL Database
1. Install mysql-server 1. Install mysql-server
@ -37,13 +34,13 @@ Now that `gulp dev` is running, the server is up as well and serving files from
Ubuntu Ubuntu
`sudo apt-get install mysql-server` `sudo apt-get install mysql-server`
Cent OS Cent OS
`sudo yum install mysql-server` `sudo yum install mysql-server`
`/etc/init.d/mysqld start` `/etc/init.d/mysqld start`
2. Access the mysql shell 2. Access the mysql shell
`mysql -u root -p` `mysql -u root -p`
@ -63,4 +60,4 @@ Now that `gulp dev` is running, the server is up as well and serving files from
Just as there is the `gulp dev` task for development, there is also a `gulp prod` task for putting your project into a production-ready state. This will run each of the tasks, while also adding the image minification task discussed above. There is also an empty `gulp deploy` task that is included when running the production task. This deploy task can be fleshed out to automatically push your production-ready site to your hosting setup. Just as there is the `gulp dev` task for development, there is also a `gulp prod` task for putting your project into a production-ready state. This will run each of the tasks, while also adding the image minification task discussed above. There is also an empty `gulp deploy` task that is included when running the production task. This deploy task can be fleshed out to automatically push your production-ready site to your hosting setup.
**Reminder:** When running the production task, gulp will not fire up the express server and serve your index.html. This task is designed to be run before the `deploy` step that may copy the files from `/build` to a production web server. **Reminder:** When running the production task, gulp will not fire up the express server and serve your index.html. This task is designed to be run before the `deploy` step that may copy the files from `/build` to a production web server.

44
package.json Executable file → Normal file
View File

@ -1,19 +1,12 @@
{ {
"name": "react-rocket-boilerplate", "name": "os4-react",
"version": "0.2.0", "version": "4.0.0",
"author": "Jake Marsh <jakemmarsh@gmail.com>", "author": "Ivan Diaz <ivan@opensupports.com>",
"description": "Boilerplate using React, Browserify, SASS, and Gulp.", "description": "OpenSupports version 4 with reactjs",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/jakemmarsh/react-rocket-boilerplate.git" "url": "https://github.com/ivandiazwm/opensupports.git"
}, },
"keywords": [
"gulp",
"browserify",
"react",
"sass",
"boilerplate"
],
"private": true, "private": true,
"engines": { "engines": {
"node": "^0.12.x", "node": "^0.12.x",
@ -46,20 +39,25 @@
"gulp-util": "^3.0.6", "gulp-util": "^3.0.6",
"humps": "^0.6.0", "humps": "^0.6.0",
"jest-cli": "^0.5.10", "jest-cli": "^0.5.10",
"jquery": "^2.1.4",
"lodash": "^3.10.0",
"messageformat": "^0.2.2",
"morgan": "^1.6.1", "morgan": "^1.6.1",
"react": "^0.13.x",
"react-document-title": "^1.0.2",
"react-google-recaptcha": "^0.4.0",
"react-motion": "^0.3.0",
"react-router": "^0.13.x",
"reflux": "^0.2.9",
"run-sequence": "^1.1.1", "run-sequence": "^1.1.1",
"vinyl-source-stream": "^1.1.0", "vinyl-source-stream": "^1.1.0",
"watchify": "^3.2.x" "watchify": "^3.2.x"
}, },
"dependencies": {
"app-module-path": "^1.0.3",
"classnames": "^2.1.3",
"jquery": "^2.1.4",
"lodash": "^3.10.0",
"messageformat": "^0.2.2",
"react": "^0.14.6",
"react-document-title": "^1.0.2",
"react-dom": "^0.14.6",
"react-google-recaptcha": "^0.5.2",
"react-motion": "^0.3.0",
"react-router": "^2.0.0-rc5",
"reflux": "^0.2.9"
},
"jest": { "jest": {
"scriptPreprocessor": "./preprocessor.js", "scriptPreprocessor": "./preprocessor.js",
"testFileExtensions": [ "testFileExtensions": [
@ -74,9 +72,5 @@
"unmockedModulePathPatterns": [ "unmockedModulePathPatterns": [
"react" "react"
] ]
},
"dependencies": {
"app-module-path": "^1.0.3",
"classnames": "^2.1.3"
} }
} }

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import Reflux from 'reflux'; import Reflux from 'reflux';
import {ListenerMixin} from 'reflux'; import {ListenerMixin} from 'reflux';
import {RouteHandler} from 'react-router'; import {RouteHandler} from 'react-router';
@ -13,8 +13,7 @@ let App = React.createClass({
render() { render() {
return ( return (
<div> <div>
<RouteHandler params={this.props.params} {React.cloneElement(this.props.children, {})}
query={this.props.query} />
</div> </div>
); );
}, },
@ -24,7 +23,6 @@ let App = React.createClass({
this.forceUpdate(); this.forceUpdate();
} }
} }
}); });
export default App; export default App;

View File

@ -1,5 +1,5 @@
import React from 'react/addons'; import React from 'react';
import {Route, NotFoundRoute, DefaultRoute} from 'react-router'; import {Router, Route, IndexRoute, browserHistory} from 'react-router';
import App from 'app/App'; import App from 'app/App';
import DemoPage from 'app/demo/components-demo-page'; import DemoPage from 'app/demo/components-demo-page';
@ -10,14 +10,14 @@ import MainSignUpPage from 'app/main/main-signup/main-sign
export default ( export default (
<Route handler={App} path='/'> <Router history={browserHistory}>
<Route component={App} path='/'>
<Route path='/app' component={MainLayout}>
<IndexRoute component={MainHomePage} />
<Route path='signup' component={MainSignUpPage}/>
</Route>
<Route name='main' path='/app' handler={MainLayout}> <Route name='Demo' path='demo' component={DemoPage} />
<DefaultRoute name='home' handler={MainHomePage} /> </Route>
<Route name='signup' path='/app/signup' handler={MainSignUpPage}/> </Router>
</Route> );
<Route name='Demo' path='/demo' handler={DemoPage} />
</Route>
);

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
import React from 'react/addons'; import React from 'react';
import {Link} from 'react-router'; import {Link} from 'react-router';
import DocumentTitle from 'react-document-title'; import DocumentTitle from 'react-document-title';

View File

@ -1,4 +1,5 @@
import React from 'react/addons'; import React from 'react';
import {render} from 'react-dom'
import Router from 'react-router'; import Router from 'react-router';
import routes from './Routes'; import routes from './Routes';
@ -8,6 +9,4 @@ if ( process.env.NODE_ENV !== 'production' ) {
window.React = React; window.React = React;
} }
Router.run(routes, Router.HistoryLocation, (Handler, state) => { render(routes, document.getElementById('app'));
React.render(<Handler params={state.params} query={state.query} />, document.getElementById('app'));
});

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import UserActions from 'actions/user-actions'; import UserActions from 'actions/user-actions';
import UserStore from 'stores/user-store'; import UserStore from 'stores/user-store';

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import {ListenerMixin} from 'reflux'; import {ListenerMixin} from 'reflux';
import {RouteHandler} from 'react-router'; import {RouteHandler} from 'react-router';

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
let MainLayoutFooter = React.createClass({ let MainLayoutFooter = React.createClass({

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import i18n from 'lib/i18n'; import i18n from 'lib/i18n';
import CommonActions from 'actions/common-actions'; import CommonActions from 'actions/common-actions';
@ -24,7 +24,7 @@ let MainLayoutHeader = React.createClass({
<div className="main-layout-header"> <div className="main-layout-header">
<div className="main-layout-header--login-links"> <div className="main-layout-header--login-links">
<Button type="clean" route={{to:'/app'}}>{i18n('LOG_IN')}</Button> <Button type="clean" route={{to:'/app'}}>{i18n('LOG_IN')}</Button>
<Button type="clean" route={{to:'/app/signup'}}>{i18n('SIGN_UP')}</Button> <Button type="clean" route={{to:'/app/signup'}}>Sign up</Button>
</div> </div>
<DropDown className="main-layout-header--languages" items={this.getLanguageList()} onChange={this.changeLanguage}/> <DropDown className="main-layout-header--languages" items={this.getLanguageList()} onChange={this.changeLanguage}/>
</div> </div>
@ -50,4 +50,4 @@ let MainLayoutHeader = React.createClass({
} }
}); });
export default MainLayoutHeader; export default MainLayoutHeader;

View File

@ -1,5 +1,4 @@
import React from 'react/addons'; import React from 'react';
import {RouteHandler} from 'react-router';
import MainHeader from 'app/main/main-layout-header'; import MainHeader from 'app/main/main-layout-header';
import MainFooter from 'app/main/main-layout-footer'; import MainFooter from 'app/main/main-layout-footer';
@ -13,8 +12,7 @@ let MainLayout = React.createClass({
<MainHeader /> <MainHeader />
<div className="main-layout--content"> <div className="main-layout--content">
<RouteHandler params={this.props.params} {this.props.children}
query={this.props.query} />
</div> </div>
<MainFooter /> <MainFooter />
@ -23,4 +21,4 @@ let MainLayout = React.createClass({
} }
}); });
export default MainLayout; export default MainLayout;

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import {ListenerMixin} from 'reflux'; import {ListenerMixin} from 'reflux';
import ReCAPTCHA from 'react-google-recaptcha'; import ReCAPTCHA from 'react-google-recaptcha';

View File

@ -1,6 +1,6 @@
jest.dontMock('../button.js'); jest.dontMock('../button.js');
import React from 'react/addons'; import React from 'react';
import Button from '../button.js'; import Button from '../button.js';
let TestUtils = React.addons.TestUtils; let TestUtils = React.addons.TestUtils;

View File

@ -1,7 +1,7 @@
jest.dontMock('core-components/form.js'); jest.dontMock('core-components/form.js');
jest.dontMock('core-components/form.js'); jest.dontMock('core-components/form.js');
import React from 'react/addons'; import React from 'react';
import Form from 'core-components/form.js'; import Form from 'core-components/form.js';
import Input from 'core-components/input.js'; import Input from 'core-components/input.js';

View File

@ -1,12 +1,13 @@
import React from 'react/addons'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import {Navigation} from 'react-router'; import Router from 'react-router';
import callback from 'lib/callback'; import callback from 'lib/callback';
let Button = React.createClass({ let Button = React.createClass({
mixins: [Navigation], contextTypes: {
router: React.PropTypes.object
},
propTypes: { propTypes: {
children: React.PropTypes.node, children: React.PropTypes.node,
@ -49,7 +50,7 @@ let Button = React.createClass({
handleClick() { handleClick() {
if (this.props.route) { if (this.props.route) {
this.transitionTo(this.props.route.to, this.props.route.param, this.props.route.query); this.context.router.push(this.props.route.to);
} }
} }
}); });

View File

@ -12,7 +12,7 @@ let DropDown = React.createClass({
selectedIndex: React.PropTypes.number, selectedIndex: React.PropTypes.number,
items: React.PropTypes.arrayOf(React.PropTypes.shape({ items: React.PropTypes.arrayOf(React.PropTypes.shape({
content: React.PropTypes.string.isRequired, content: React.PropTypes.node.isRequired,
icon: React.PropTypes.string icon: React.PropTypes.string
})).isRequired })).isRequired
}, },
@ -52,7 +52,7 @@ let DropDown = React.createClass({
return ( return (
<div className={this.getClass()}> <div className={this.getClass()}>
<div className="drop-down--current" onBlur={this.handleBlur} onClick={this.handleClick} tabIndex="0" ref="current"> <div className="drop-down--current" onBlur={this.handleBlur} onClick={this.handleClick} tabIndex="0" ref="current">
{this.props.items[this.getSelectedIndex()]} {this.props.items[this.getSelectedIndex()].content}
</div> </div>
<Motion defaultStyle={animation.defaultStyle} style={animation.style}> <Motion defaultStyle={animation.defaultStyle} style={animation.style}>
{this.renderList} {this.renderList}
@ -75,7 +75,7 @@ let DropDown = React.createClass({
renderItem(item, index) { renderItem(item, index) {
return ( return (
<li className="drop-down--list-item" onClick={this.handleItemClick.bind(this, index)} onMouseDown={this.handleItemMouseDown}> <li {...this.getItemProps(index)}>
{item.content} {item.content}
</li> </li>
); );
@ -91,6 +91,15 @@ let DropDown = React.createClass({
return classNames(classes); return classNames(classes);
}, },
getItemProps(index) {
return {
className: 'drop-down--list-item',
onClick: this.handleItemClick.bind(this, index),
onMouseDown: this.handleItemMouseDown,
key: index
};
},
handleBlur() { handleBlur() {
this.setState({ this.setState({
opened: false opened: false
@ -110,7 +119,9 @@ let DropDown = React.createClass({
}); });
if (this.props.onChange) { if (this.props.onChange) {
this.props.onChange(index); this.props.onChange({
index
});
} }
}, },
@ -123,4 +134,4 @@ let DropDown = React.createClass({
} }
}); });
export default DropDown; export default DropDown;

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import _ from 'lodash'; import _ from 'lodash';
import {reactDFS, renderChildrenWithProps} from 'lib/react-dfs'; import {reactDFS, renderChildrenWithProps} from 'lib/react-dfs';

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import _ from 'lodash'; import _ from 'lodash';
import {Motion, spring} from 'react-motion'; import {Motion, spring} from 'react-motion';

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
let Widget = React.createClass({ let Widget = React.createClass({

View File

@ -1,7 +1,7 @@
import keys from 'data/i18n-keys' import keys from 'data/i18n-keys'
let languages = [ let languages = [
'en', 'us',
'es' 'es'
]; ];
@ -12,4 +12,4 @@ let i18nData = function (key, lang) {
return keys[key][langIndex]; return keys[key][langIndex];
}; };
export default i18nData export default i18nData

View File

@ -1,4 +1,4 @@
import React from 'react/addons'; import React from 'react';
import _ from 'lodash'; import _ from 'lodash';
let reactDFS = function (children, visitFunction) { let reactDFS = function (children, visitFunction) {

View File

@ -1,4 +1,4 @@
const React = require('react/addons'); const React = require('react');
const { PropTypes } = React; const { PropTypes } = React;
const { TransitionMotion, spring } = require('react-motion'); const { TransitionMotion, spring } = require('react-motion');

View File

@ -5,7 +5,7 @@ import CommonActions from 'actions/common-actions';
let CommonStore = Reflux.createStore({ let CommonStore = Reflux.createStore({
init() { init() {
this.language = 'en'; this.language = 'us';
this.listenTo(CommonActions.changeLanguage, this.changeLanguage); this.listenTo(CommonActions.changeLanguage, this.changeLanguage);
}, },
@ -16,4 +16,4 @@ let CommonStore = Reflux.createStore({
} }
}); });
export default CommonStore; export default CommonStore;