diff --git a/client/src/components/App.js b/client/src/components/App.js index 523385e..51e6998 100644 --- a/client/src/components/App.js +++ b/client/src/components/App.js @@ -20,31 +20,31 @@ export class App extends Component { render() { const { user } = this.props; return ( -
+
- - - - - + + + + + - + {this.props.children}
diff --git a/client/src/components/Auth/Login.js b/client/src/components/Auth/Login.js index 6ad0793..7ea95eb 100644 --- a/client/src/components/Auth/Login.js +++ b/client/src/components/Auth/Login.js @@ -3,6 +3,7 @@ import { connect } from 'react-redux'; import { replace } from 'react-router-redux'; import { SubmissionError } from 'redux-form'; +import { CardSingle } from '../UI'; import LoginForm from './LoginForm'; import { login } from '../../store/api'; @@ -15,7 +16,10 @@ export class Login extends Component { render() { return ( - + +

Login

+ +
); } } diff --git a/client/src/components/Auth/LoginForm.js b/client/src/components/Auth/LoginForm.js index 5d4a9f6..ff07563 100644 --- a/client/src/components/Auth/LoginForm.js +++ b/client/src/components/Auth/LoginForm.js @@ -3,32 +3,28 @@ import { isEmpty } from 'lodash'; import { Field, reduxForm } from 'redux-form'; import { Alert, Button, Form } from 'reactstrap'; -import { CardSingle } from '../UI'; import { InputField, required } from '../../forms'; class LoginForm extends Component { render() { - const { handleSubmit, pristine, reset, submitting, error } = this.props; + const { handleSubmit, submitting, error } = this.props; return ( - -

Login

-
- {error && {error}} - - - - -
+
+ {error && {error}} + + + + ); } } diff --git a/client/src/components/Categories/CategoryForm.js b/client/src/components/Categories/CategoryForm.js index 316ca30..1c5fb30 100644 --- a/client/src/components/Categories/CategoryForm.js +++ b/client/src/components/Categories/CategoryForm.js @@ -1,23 +1,36 @@ import React, { Component, PropTypes } from 'react'; import { isEmpty } from 'lodash'; import { Field, reduxForm } from 'redux-form'; +import { Button, Form, Col, Row } from 'reactstrap'; import { InputField, required } from '../../forms'; class CategoryForm extends Component { render() { - const { handleSubmit, pristine, reset, submitting } = this.props; + const { handleSubmit, onDelete, reset, isNew, submitSucceeded } = this.props; + + if (isNew && submitSucceeded) { + setTimeout(() => reset()); + } return ( -
-
- -
-
- - -
-
+
+ + + + + + { + isNew + ? + : + } + + +
); } } @@ -29,6 +42,5 @@ const validate = (values) => { export default reduxForm({ enableReinitialize: true, - form: 'category', validate, })(CategoryForm); diff --git a/client/src/components/Categories/CategoryList.js b/client/src/components/Categories/CategoryList.js index 4c24386..6f40db6 100644 --- a/client/src/components/Categories/CategoryList.js +++ b/client/src/components/Categories/CategoryList.js @@ -1,8 +1,8 @@ import React, { Component, PropTypes } from 'react'; -import { Link } from 'react-router'; import { find, keyBy } from 'lodash'; import { withResourceList } from '../../hocs'; +import CategoryForm from './CategoryForm'; export class CategoryList extends Component { componentWillMount() { @@ -10,15 +10,25 @@ export class CategoryList extends Component { } render() { - const { resourceList } = this.props; + const { resourceList, onSubmit, onDelete } = this.props; return (
{resourceList.data.map(category =>
- {category.name} +
, )} +
); } diff --git a/client/src/components/UI/SingleCard.js b/client/src/components/UI/CardSingle.js similarity index 71% rename from client/src/components/UI/SingleCard.js rename to client/src/components/UI/CardSingle.js index 02398c5..afb95d1 100644 --- a/client/src/components/UI/SingleCard.js +++ b/client/src/components/UI/CardSingle.js @@ -2,8 +2,8 @@ import React, { Component } from 'react'; import { Card, CardBlock } from 'reactstrap'; -export default () => ( +export default (props) => ( - {this.props.children} + {props.children} ); diff --git a/client/src/components/UI/index.js b/client/src/components/UI/index.js index 6d5175d..fce12be 100644 --- a/client/src/components/UI/index.js +++ b/client/src/components/UI/index.js @@ -1,3 +1,3 @@ +export CardSingle from './CardSingle'; export EditHeader from './EditHeader'; export Pagination from './Pagination'; -export SingleCard from './SingleCard'; diff --git a/client/src/hocs/withResource.js b/client/src/hocs/withResource.js index 956b323..01746ce 100644 --- a/client/src/hocs/withResource.js +++ b/client/src/hocs/withResource.js @@ -18,17 +18,11 @@ const withResource = resourceKey => (WrappedComponent) => { withHandlers({ onSubmit: props => (values) => { const { params, createResource, updateResource, redirectToIndex } = props; - - const payload = { - id: params.id, - ...values, - }; - + const payload = { id: params.id, ...values }; return (params.id ? updateResource : createResource)(payload) .then(redirectToIndex) .catch((errors) => { throw new SubmissionError(errors); }); }, - onDelete: props => (e) => { const { deleteResource, resource, redirectToIndex } = props; e.preventDefault(); diff --git a/client/src/hocs/withResourceList.js b/client/src/hocs/withResourceList.js index 97a50d6..14b2554 100644 --- a/client/src/hocs/withResourceList.js +++ b/client/src/hocs/withResourceList.js @@ -1,11 +1,15 @@ import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; +import { SubmissionError } from 'redux-form'; import { get, find, isEmpty, omitBy } from 'lodash'; import compose from 'recompose/compose'; import withHandlers from 'recompose/withHandlers'; import { fetchList, + createResource, + updateResource, + deleteResource, getList, } from '../store/api'; @@ -34,6 +38,16 @@ const withResourceList = resourceKey => (WrappedComponent) => { const { page = {} } = params; fetchResourceList({ ...params, page: { ...page, number } }); }, + onSubmit: props => (values) => { + const { createResource, updateResource } = props; + return (values.id ? updateResource : createResource)(values) + .catch((errors) => { throw new SubmissionError(errors); }); + }, + onDelete: props => (resource) => (e) => { + const { deleteResource } = props; + e.preventDefault(); + deleteResource(resource); + }, }), ); @@ -43,6 +57,9 @@ const withResourceList = resourceKey => (WrappedComponent) => { const mapDispatchToProps = dispatch => ({ fetchResourceList: (params = {}) => dispatch(fetchList(resourceKey, params)), + createResource: payload => dispatch(createResource(resourceKey, payload, {list: true})), + updateResource: payload => dispatch(updateResource(resourceKey, payload)), + deleteResource: payload => dispatch(deleteResource(resourceKey, payload)), }); return connect(mapStateToProps, mapDispatchToProps)(enhance(WrappedComponent)); diff --git a/client/src/index.css b/client/src/index.css new file mode 100644 index 0000000..981b522 --- /dev/null +++ b/client/src/index.css @@ -0,0 +1,3 @@ +.container-main { + padding-top: 15px; +} diff --git a/client/src/index.js b/client/src/index.js index 3d686d6..ce91001 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -9,7 +9,7 @@ import Routes from './components/Routes'; import configureStore from './store/configureStore'; import 'bootstrap/dist/css/bootstrap.css'; -import './index.scss'; +import './index.css'; const store = configureStore(hashHistory); const history = syncHistoryWithStore(hashHistory, store); diff --git a/client/src/index.scss b/client/src/index.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/store/api/reducer.js b/client/src/store/api/reducer.js index 530e503..a6835a6 100644 --- a/client/src/store/api/reducer.js +++ b/client/src/store/api/reducer.js @@ -60,7 +60,11 @@ export default (state = initialState, action) => { return addNormalized(newState, payload); } case actionType(CREATE, SUCCESS): { - return addNormalized(newState, payload); + newState = addNormalized(newState, payload); + if (meta.list) { + newState = imm.push(newState, [key, 'list', 'ids'], payload.data.id); + } + return newState; } case actionType(UPDATE, SUCCESS): { return addNormalized(newState, payload);