Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions src/ReactBoilerplate/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ root = true
indent_style = space
indent_size = 2

[*.cs]
indent_style = space
indent_size = 4

[*.md]
trim_trailing_whitespace = false
81 changes: 61 additions & 20 deletions src/ReactBoilerplate/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,76 @@
"browser": true,
"node": true
},
"parser": "babel-eslint",
"parser": "typescript-eslint-parser",
"plugins": [
"react",
"import"
"import",
"typescript"
],
"rules": {
"comma-dangle": 0, // not sure why airbnb turned this on. gross!
"indent": [2, 2, {"SwitchCase": 1}],
"react/prefer-stateless-function": 0,
"react/prop-types": 0,
"react/jsx-closing-bracket-location": 0,
"no-console": 0,
"prefer-template": 0,
"max-len": 0,
"no-underscore-dangle": [2, {"allow": ["__data"]}],
"global-require": 0,
"no-restricted-syntax": 0,
"linebreak-style": 0,
"react/jsx-filename-extension": 0,
"import/imports-first": 0,
"no-class-assign": 0
"comma-dangle": "off", // Not sure why airbnb turned this on. Gross!
"indent": ["error", 2, {"SwitchCase": 1}],
"react/prefer-stateless-function": "off",
"react/prop-types": "off",
"react/jsx-closing-bracket-location": "off",
"no-console": "off",
"prefer-template": "off",
"max-len": "off",
"no-underscore-dangle": ["error", {"allow": ["__data"]}],
"global-require": "off",
"no-restricted-syntax": "off",
"linebreak-style": "off",
"react/jsx-filename-extension": "off",
"arrow-parens": ["error", "always"],
"no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
"jsx-a11y/anchor-is-valid": ["error", {
"specialLink": ["to"] // Allow "to" property in react-router-dom Link element
}],
"no-undef": "off", // TypeScript lint parser produces false positves; the compiler will error anyway
"no-unused-vars": "off", // TypeScript lint parser produces false positves; the compiler is set to error instead
"import/extensions": ["error", "ignorePackages", {
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}],
"react/sort-comp": ["error", { // Add type-annotations to the top
"order": [
"static-methods",
"type-annotations",
"instance-variables",
"lifecycle",
"/^on.+$/",
"getters",
"setters",
"/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/",
"instance-methods",
"everything-else",
"rendering"
]
}],
"typescript/adjacent-overload-signatures": ["error"],
"typescript/class-name-casing": ["error"],
"typescript/explicit-member-accessibility": ["error"],
"typescript/interface-name-prefix": ["error", "never"],
"typescript/member-delimiter-style": ["error"],
"typescript/no-angle-bracket-type-assertion": ["error"],
"typescript/no-array-constructor": ["error"],
"typescript/no-empty-interface": ["error"],
"typescript/no-inferrable-types": ["error"],
"typescript/no-unused-vars": ["error"],
"typescript/no-use-before-define": ["error"],
"typescript/type-annotation-spacing": ["error"]
},
"settings": {
"import/parser": "babel-eslint",
"import/resolver": {
"import/parser": "typescript-eslint-parser",
"import/resolver": {
"node": {
"moduleDirectory": ["node_modules", "Scripts"]
"moduleDirectory": ["node_modules", "Scripts"],
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
},
"import/extensions": [".js", ".jsx", ".ts", ".tsx"],
"no-underscore-dangle": {
"allow": ["__data"]
}
Expand Down
29 changes: 29 additions & 0 deletions src/ReactBoilerplate/.stylelintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"extends": [
"stylelint-config-standard"
],
"rules": {
'selector-pseudo-class-no-unknown': [ true, {
ignorePseudoClasses: [
'export',
'import',
'global',
'local'
],
}],
'property-no-unknown': [ true, {
ignoreProperties: [
'composes',
'compose-with'
],
}],
'at-rule-no-unknown': [ true, {
ignoreAtRules: [
'each',
'extend',
'include',
'mixin',
],
}]
}
}
44 changes: 31 additions & 13 deletions src/ReactBoilerplate/Scripts/client.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, browserHistory } from 'react-router';
import getRoutes from './routes';
import createHistory from 'history/createBrowserHistory';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import { AppContainer } from 'react-hot-loader';
import configureStore from './redux/configureStore';
import { syncHistoryWithStore } from 'react-router-redux';
import ApiClient from './helpers/ApiClient';
import getRoutes from './routes';

// Need to import App directly from its file so that this module is dependent on it directly for HMR
import App from './containers/App/App';

const client = new ApiClient();
const store = configureStore(window.__data, browserHistory, client);
const history = syncHistoryWithStore(browserHistory, store);
const history = createHistory();
const store = configureStore(window.__data, history, client);

const render = () => {
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<AppContainer>
<App>
{getRoutes(store)}
</App>
</AppContainer>
</ConnectedRouter>
</Provider>,
document.getElementById('content')
);
};

// Render the App inside the store and HMR AppContainer
render();

ReactDOM.render(
<Provider store={store}>
<Router history={history}>
{getRoutes(store)}
</Router>
</Provider>,
document.getElementById('content')
);
// Register to accept changes to the App
if (module.hot) {
module.hot.accept('./containers/App/App', () => { render(App); });
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,11 @@ class ChangeEmailForm extends Form {
}
}

ChangeEmailForm = reduxForm({
form: 'changeEmail',
fields: ['currentPassword', 'email', 'emailConfirm']
},
(state) => state,
{ }
export default reduxForm(
{
form: 'changeEmail',
fields: ['currentPassword', 'email', 'emailConfirm']
},
(state) => state,
{ }
)(ChangeEmailForm);

export default ChangeEmailForm;
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,11 @@ class ChangePasswordForm extends Form {
}
}

ChangePasswordForm = reduxForm({
form: 'changePassword',
fields: ['oldPassword', 'newPassword', 'newPasswordConfirm']
},
(state) => state,
{ }
export default reduxForm(
{
form: 'changePassword',
fields: ['oldPassword', 'newPassword', 'newPasswordConfirm']
},
(state) => state,
{ }
)(ChangePasswordForm);

export default ChangePasswordForm;
17 changes: 9 additions & 8 deletions src/ReactBoilerplate/Scripts/components/ErrorList.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ class ErrorList extends Component {
if (errors.length === 0) return null;
return (
<div className="alert alert-danger">
{errors.map((err, i) =>
(
<p key={i}>
<Glyphicon glyph="exclamation-sign" />
{' '}
{err}
</p>
))}
{errors.map((err) =>
(
<p key={err}>
<Glyphicon glyph="exclamation-sign" />
{' '}
{err}
</p>
))
}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,23 @@ class ExternalLogin extends Component {
} = this.props;
return (
<p>
{loginProviders.map((loginProvider, i) =>
(
<span key={i}>
<ExternalLoginButton
onClick={this.loginClick(loginProvider.scheme)}
scheme={loginProvider.scheme}
text={(this.props.leadingText ? (this.props.leadingText + ' ') : '') + loginProvider.displayName} />
{' '}
</span>
))}
{loginProviders.map((loginProvider) =>
(
<span key={loginProvider}>
<ExternalLoginButton
onClick={this.loginClick(loginProvider.scheme)}
scheme={loginProvider.scheme}
text={(this.props.leadingText ? (this.props.leadingText + ' ') : '') + loginProvider.displayName} />
{' '}
</span>
))
}
</p>
);
}
}

export default connect(
(state) => ({ loginProviders: state.externalLogin.loginProviders, location: state.routing.locationBeforeTransitions }),
{ authenticate }
(state) => ({ loginProviders: state.externalLogin.loginProviders, location: state.routing.locationBeforeTransitions }),
{ authenticate }
)(ExternalLogin);
16 changes: 8 additions & 8 deletions src/ReactBoilerplate/Scripts/components/ExternalLoginButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ const bootstrapSocial = require('bootstrap-social');
const fontAwesome = require('font-awesome/scss/font-awesome.scss');

export default (props) =>
(
<Button
{...props}
className={bootstrapSocial['btn-social'] + ' ' + bootstrapSocial['btn-' + props.scheme.toLowerCase()]}>
<span className={fontAwesome.fa + ' ' + fontAwesome['fa-' + props.scheme.toLowerCase()]} />
{props.text}
</Button>
);
(
<Button
{...props}
className={bootstrapSocial['btn-social'] + ' ' + bootstrapSocial['btn-' + props.scheme.toLowerCase()]}>
<span className={fontAwesome.fa + ' ' + fontAwesome['fa-' + props.scheme.toLowerCase()]} />
{props.text}
</Button>
);
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,11 @@ class ForgotPasswordForm extends Form {
}
}

ForgotPasswordForm = reduxForm({
form: 'forgotPassword',
fields: ['email']
},
(state) => state,
{ }
export default reduxForm(
{
form: 'forgotPassword',
fields: ['email']
},
(state) => state,
{ }
)(ForgotPasswordForm);

export default ForgotPasswordForm;
33 changes: 17 additions & 16 deletions src/ReactBoilerplate/Scripts/components/Form.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { Component } from 'react';
import { modelStateErrorToFormFields } from '../utils/modelState';
import { ErrorList } from 'components';
import ErrorList from './ErrorList';

class Form extends Component {
// eslint-disable-next-line class-methods-use-this
modifyValues(values) {
return values;
}
Expand All @@ -14,27 +15,27 @@ class Form extends Component {
new Promise((resolve, reject) => {
dispatch(action(this.modifyValues(values)))
.then(
(result) => {
if (result.success) {
resolve();
if (success) {
success(result);
(result) => {
if (result.success) {
resolve();
if (success) {
success(result);
}
} else {
reject(modelStateErrorToFormFields(result.errors));
if (error) {
error(result);
}
}
} else {
},
(result) => {
reject(modelStateErrorToFormFields(result.errors));
if (error) {
error(result);
}
}
},
(result) => {
reject(modelStateErrorToFormFields(result.errors));
if (error) {
error(result);
}
});
})
);
);
}));
}
renderGlobalErrorList() {
const {
Expand Down
Loading