diff --git a/src/actions/posts.js b/src/actions/posts.js
index ca0a673..7ac8cf1 100644
--- a/src/actions/posts.js
+++ b/src/actions/posts.js
@@ -42,7 +42,7 @@ export const addPost = postData => async dispatch => {
export const editPost = (id, postData) => async dispatch => {
dispatch({ type: EDIT_POST_START });
try {
- const success = await serverHandshake(true).put('/posts', { id, postData });
+ const success = await serverHandshake(true).put(`/posts/${id}`, postData);
dispatch({ type: EDIT_POST_SUCCESS, payload: success.data });
return success;
} catch (error) {
@@ -54,7 +54,7 @@ export const editPost = (id, postData) => async dispatch => {
export const deletePost = id => async dispatch => {
dispatch({ type: DELETE_POST_START });
try {
- const success = await serverHandshake(true).delete('/posts', id);
+ const success = await serverHandshake(true).delete(`/posts/${id}`);
dispatch({ type: DELETE_POST_SUCCESS, payload: success.data });
return success;
} catch (error) {
diff --git a/src/components/Dashboard/Dashboard.js b/src/components/Dashboard/Dashboard.js
deleted file mode 100644
index f9cbf60..0000000
--- a/src/components/Dashboard/Dashboard.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-import { fetchUsers, fetchPosts, fetchCategories } from '../../actions';
-import PrivateRoute from '../PrivateRoute';
-import AppBar from '../AppBar';
-import NewPost from '../NewPost';
-import HowToCard from '../PreviewCard';
-import { getFilteredPosts } from '../../reducers';
-import Paper from '@material-ui/core/Paper';
-
-class Dashboard extends Component {
- componentDidMount() {
- this.props.fetchUsers();
- this.props.fetchPosts();
- this.props.fetchCategories();
- }
-
- render() {
- const { history, match, posts } = this.props;
-
- return (
-
-
-
-
- {posts.allPosts && posts.allPosts.map(post => (
-
- ))}
- {posts.allPosts && posts.allPosts.map(post => (
-
- ))}
-
-
- );
- }
-}
-
-// category & user IDs can be added to the second argument of getFilteredPosts as well
-// these should probably be handled via routes:
-// category/:id
-// user/:id
-const mapStateToProps = ({ posts, searchInput }) => ({
- posts: getFilteredPosts(posts, { searchInput })
-});
-
-export default connect(
- mapStateToProps,
- { fetchUsers, fetchPosts, fetchCategories }
-)(Dashboard);
diff --git a/src/components/Editor.js b/src/components/Editor.js
deleted file mode 100644
index 2afa2bc..0000000
--- a/src/components/Editor.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import React from 'react';
-import ReactQuill from 'react-quill';
-import { withStyles } from '@material-ui/core/styles';
-import 'react-quill/dist/quill.snow.css';
-import Fab from '@material-ui/core/Fab';
-import AddIcon from '@material-ui/icons/Add';
-import DeleteIcon from '@material-ui/icons/Delete';
-import Paper from '@material-ui/core/Paper'
-
-const styles = theme => ({
- fab: {
- margin: theme.spacing.unit,
- },
- extendedIcon: {
- marginLeft: theme.spacing.unit,
- },
- textarea: {
- height: '50vh'
- }
-});
-
-class Editor extends React.Component {
- state = {
- title: 'test',
- body: '' ,
- creator_id: '1'
- }
- handleChange = (value) => {
- this.setState({ body: value });
- }
-
- render() {
- return (
-
-
-
-
-
{ console.log('delete') }} >
-
-
-
{ console.log('post') }} >
-
-
-
- )
- }
-}
-
-export default withStyles(styles)(Editor);
diff --git a/src/components/EditorButtons.js b/src/components/EditorButtons.js
new file mode 100644
index 0000000..cee6b14
--- /dev/null
+++ b/src/components/EditorButtons.js
@@ -0,0 +1,40 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import Fab from '@material-ui/core/Fab';
+import AddIcon from '@material-ui/icons/Add';
+import DeleteIcon from '@material-ui/icons/Delete';
+
+const styles = theme => ({
+ fab: {
+ margin: theme.spacing.unit,
+ },
+ extendedIcon: {
+ marginLeft: theme.spacing.unit,
+ },
+});
+
+function FloatingActionButtons(props) {
+ const { classes, handleSubmit, history } = props;
+
+ const abortPost = () => {
+ history.replace('/dashboard');
+ }
+
+ return (
+
+ );
+}
+
+FloatingActionButtons.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(FloatingActionButtons);
diff --git a/src/components/HowToCard.js b/src/components/HowToCard.js
new file mode 100644
index 0000000..2e7d860
--- /dev/null
+++ b/src/components/HowToCard.js
@@ -0,0 +1,188 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import Card from '@material-ui/core/Card';
+import CardHeader from '@material-ui/core/CardHeader';
+// import CardMedia from '@material-ui/core/CardMedia';
+import CardContent from '@material-ui/core/CardContent';
+import CardActions from '@material-ui/core/CardActions';
+import Avatar from '@material-ui/core/Avatar';
+import IconButton from '@material-ui/core/IconButton';
+import Typography from '@material-ui/core/Typography';
+import red from '@material-ui/core/colors/red';
+import FavoriteIcon from '@material-ui/icons/Favorite';
+import ShareIcon from '@material-ui/icons/Share';
+import MoreVert from '@material-ui/icons/MoreVert';
+import Delete from '@material-ui/icons/Delete';
+import Edit from '@material-ui/icons/Edit';
+
+import ClickAwayListener from '@material-ui/core/ClickAwayListener';
+import Grow from '@material-ui/core/Grow';
+import Paper from '@material-ui/core/Paper';
+import Popper from '@material-ui/core/Popper';
+
+import MenuItem from '@material-ui/core/MenuItem';
+import MenuList from '@material-ui/core/MenuList';
+import ListItemIcon from '@material-ui/core/ListItemIcon';
+import ListItemText from '@material-ui/core/ListItemText';
+
+const styles = theme => ({
+ card: {
+ maxWidth: 500,
+ height: '100%',
+ display: 'flex',
+ flexDirection: 'column'
+ },
+ cardWrapper: {
+ position: 'relative',
+ margin: '1rem auto',
+ [theme.breakpoints.up('sm')]: {
+ margin: '1rem',
+ width: 'calc(50% - 2rem)'
+ },
+ [theme.breakpoints.up('md')]: {
+ width: 'calc(33.33% - 2rem)'
+ }
+ },
+ menuItem: {
+ '&:focus': {
+ backgroundColor: theme.palette.primary.main
+ }
+ },
+ media: {
+ height: 0,
+ paddingTop: '56.25%' // 16:9
+ },
+ actions: {
+ flexGrow: 1,
+ alignItems: 'flex-end'
+ },
+ likes: {
+ marginBottom: '1rem'
+ },
+ noHover: {
+ transition: '200ms',
+ '&:hover': {
+ backgroundColor: 'initial',
+ transform: 'scale(1.2)'
+ }
+ },
+ avatar: {
+ backgroundColor: red[500],
+ fontSize: '95%'
+ }
+});
+
+class HowToCard extends React.Component {
+ state = { open: false };
+
+ handleToggle = () => {
+ this.setState(state => ({ open: !state.open }));
+ };
+
+ handleClose = event => {
+ if (this.anchorEl.contains(event.target)) {
+ return;
+ }
+
+ this.setState({ open: false });
+ };
+
+ handleDelete = () => {
+ this.props.delete(this.props.post.id);
+ };
+
+ handleEdit = () => {
+ const { match, history, post } = this.props;
+ const navigate = match.url.endsWith('new') ? history.replace : history.push;
+ navigate(`${match.url}/new`, [post]);
+ };
+
+ handleLike = () => {
+ const { edit, post } = this.props;
+ edit(post.id, { ...post, likes: post.likes + 1 });
+ };
+
+ render() {
+ const { open } = this.state;
+ const { classes, user } = this.props;
+ const { title, body, updated_at, likes } = this.props.post;
+ const initials = user ? (user.firstName[0] + user.lastName[0]).toUpperCase() : 'X';
+
+ return (
+
+
+
+ {initials}
+
+ }
+ action={
+ {
+ this.anchorEl = node;
+ }}
+ aria-owns={open ? 'menu-list-grow' : undefined}
+ aria-haspopup="true"
+ onClick={this.handleToggle}
+ >
+
+
+ }
+ title={title}
+ subheader={updated_at}
+ />
+
+ {({ TransitionProps, placement }) => (
+
+ )}
+
+ {/* */}
+
+ {body}
+
+
+
+
+
+ {/* TODO: replace these with likes */}
+ {likes || 0}
+
+
+
+
+
+
+ );
+ }
+}
+
+HowToCard.propTypes = {
+ classes: PropTypes.object.isRequired
+};
+
+export default withStyles(styles)(HowToCard);
diff --git a/src/components/NewPost.js b/src/components/NewPost.js
deleted file mode 100644
index 797a47e..0000000
--- a/src/components/NewPost.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import React, { Component } from 'react';
-import AppBar from './AppBar';
-import Editor from './Editor';
-
-class NewPost extends Component {
- render() {
- return (
-
-
-
-
- );
- }
-}
-
-export default NewPost;
diff --git a/src/components/PreviewCard.js b/src/components/PreviewCard.js
deleted file mode 100644
index bf501a6..0000000
--- a/src/components/PreviewCard.js
+++ /dev/null
@@ -1,93 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { withStyles } from '@material-ui/core/styles';
-import Card from '@material-ui/core/Card';
-import CardHeader from '@material-ui/core/CardHeader';
-import CardContent from '@material-ui/core/CardContent';
-import CardActions from '@material-ui/core/CardActions';
-// import Avatar from '@material-ui/core/Avatar';
-import IconButton from '@material-ui/core/IconButton';
-import OpenInBrowser from '@material-ui/icons/OpenInBrowser';
-import Typography from '@material-ui/core/Typography';
-import Fab from '@material-ui/core/Fab';
-import ShareIcon from '@material-ui/icons/Share';
-import FavoriteIcon from '@material-ui/icons/Favorite';
-import AccountCircle from '@material-ui/icons/AccountCircle'; //tmp
-
-const styles = theme => ({
- card: {
- maxWidth: 400,
- },
- media: {
- height: 0,
- paddingTop: '56.25%', // 16:9
- },
- actions: {
- display: 'flex',
- },
- expand: {
- transform: 'rotate(0deg)',
- marginLeft: 'auto',
- transition: theme.transitions.create('transform', {
- duration: theme.transitions.duration.shortest,
- }),
- },
- fab: {
- margin: theme.spacing.unit,
- },
- extendedIcon: {
- marginRight: theme.spacing.unit,
- },
-});
-
-
-const HowToCard = props => {
- return (
-
- { console.log(`User ${props.creator_id}`) }} />
- //
- // Pass Avatar info here if applicable (when av can take user id)
- }
- action={
- { console.log(`Go to page ${props.id}`) }} >
-
-
- }
- title={props.title} /* Would be cool if this could be clickable */
- subheader={`Created: ${props.created_at}`}
- />
-
-
- {props.body}
-
-
-
- { console.log(`Heart ${props.id}`) }}>
-
-
- { console.log(`Share ${props.id}`) }}>
-
-
-
-
- );
- };
-
-
-HowToCard.defaultProps = {
- id: null,
- title: '',
- created_at: '',
- body: '',
- likes: '',
- updated_at: '',
- creator_id: '',
- };
-
-HowToCard.propTypes = {
- classes: PropTypes.object.isRequired,
-};
-
-export default withStyles(styles)(HowToCard);
\ No newline at end of file
diff --git a/src/components/Root.js b/src/components/Root.js
index cf22ba0..826a4f8 100644
--- a/src/components/Root.js
+++ b/src/components/Root.js
@@ -1,16 +1,14 @@
import React from 'react';
import { Provider } from 'react-redux';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
-import theme from '../theme';
import { MuiThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
-import Dashboard from './Dashboard/Dashboard';
-import Register from './Register';
-import SearchContainer from './SearchContainer';
-import ViewHowTo from './ViewHowTo';
-import NewPost from './NewPost';
-import CompList from './Testing/CompList';
-
+import PrivateRoute from './PrivateRoute';
+import Register from '../containers/Register';
+import Dashboard from '../containers/Dashboard';
+import NewPost from '../containers/NewPost';
+// import UserProfile from './UserProfile';
+import theme from '../theme';
const Root = ({ store }) => (
@@ -26,12 +24,10 @@ const Root = ({ store }) => (
}}
/>
-
-
-
-
-
- {/* */}
+
+
+ {/*
+ */}
diff --git a/src/components/SearchContainer.js b/src/components/SearchContainer.js
deleted file mode 100644
index b52c1d6..0000000
--- a/src/components/SearchContainer.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import React, { Component } from 'react';
-import AppBar from './AppBar';
-import HowToCard from './PreviewCard';
-import { Grid } from '@material-ui/core';
-import { Paper } from '@material-ui/core';
-
-class NewPost extends Component {
- render() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Imagine you typed search
- {/* Search returned corpuse */}
-
- )
- }
- }
-
-export default NewPost;
\ No newline at end of file
diff --git a/src/components/UserProfile/UserProfile.js b/src/components/UserProfile.js
similarity index 55%
rename from src/components/UserProfile/UserProfile.js
rename to src/components/UserProfile.js
index 9739a43..3a887f7 100644
--- a/src/components/UserProfile/UserProfile.js
+++ b/src/components/UserProfile.js
@@ -1,24 +1,21 @@
import React, { Component } from 'react';
-import AppBar from '../AppBar';
+import MenuBar from '../containers/MenuBar';
import { Paper, Avatar } from '@material-ui/core';
-import PreviewCard from '../PreviewCard';
class NewPost extends Component {
render() {
return (
-
-
Avi
-
-
Users How-Tos
+
-
-
+ Avi
+
+
User How-Tos
)
}
}
-
- export default NewPost;
\ No newline at end of file
+
+ export default NewPost;
diff --git a/src/components/UserProfile/Avatar.js b/src/components/UserProfile/Avatar.js
deleted file mode 100644
index 341ebf7..0000000
--- a/src/components/UserProfile/Avatar.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { withStyles } from '@material-ui/core/styles';
-import Avatar from '@material-ui/core/Avatar';
-
-const styles = {
- avatar: {
- margin: 10,
- },
- bigAvatar: {
- margin: 10,
- width: 60,
- height: 60,
- },
-};
-
-function ImageAvatars(props) {
- const { classes } = props;
- return (
-
- );
-}
-
-ImageAvatars.propTypes = {
- classes: PropTypes.object.isRequired,
-};
-
-export default withStyles(styles)(ImageAvatars);
\ No newline at end of file
diff --git a/src/components/ViewHowTo.js b/src/components/ViewHowTo.js
deleted file mode 100644
index 7f105e6..0000000
--- a/src/components/ViewHowTo.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react';
-import AppBar from './AppBar';
-import { Paper, Avatar } from '@material-ui/core';
-import Fab from '@material-ui/core/Fab';
-import ShareIcon from '@material-ui/icons/Share';
-import FavoriteIcon from '@material-ui/icons/Favorite';
-import CommentIcon from '@material-ui/icons/Comment';
-
-const ViewHowTo = props => {
- return (
-
-
-
{props.title}
-
{ console.log(`User ${props.creator_id}`) }}/> {/* Link to user profile */}
-
- {props.body}
-
- { console.log(`Heart ${props.id}`) }}> {/* idk */}
-
-
- { console.log(`Share ${props.id}`) }}> {/* return address*/}
-
-
- { console.log(`Add comment? ${props.id}`) }}> {/* send delete, change to delete?s */}
-
- Comment
-
-
- )
- }
-
- ViewHowTo.defaultProps = {
- id: null,
- title: 'Sample',
- created_at: 'createdAt',
- body: 'sampleBody',
- likes: 100,
- updated_at: 'updatedAt',
- creator_id: 'creatorID',
- };
-
- export default ViewHowTo;
\ No newline at end of file
diff --git a/src/containers/Dashboard.js b/src/containers/Dashboard.js
new file mode 100644
index 0000000..6685a90
--- /dev/null
+++ b/src/containers/Dashboard.js
@@ -0,0 +1,63 @@
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import { fetchUsers, fetchPosts, fetchCategories, editPost, deletePost } from '../actions';
+import { withStyles } from '@material-ui/core/styles';
+import MenuBar from './MenuBar';
+import HowToCard from '../components/HowToCard';
+import { getFilteredPosts } from '../reducers';
+
+const styles = {
+ postsContainer: {
+ display: 'flex',
+ flexFlow: 'row wrap'
+ }
+};
+
+class Dashboard extends Component {
+ componentDidMount() {
+ this.props.fetchUsers();
+ this.props.fetchPosts();
+ this.props.fetchCategories();
+ }
+
+ render() {
+ const { classes, history, match, posts, users, editPost, deletePost } = this.props;
+
+ return (
+
+
+
+
+ {posts.allPosts &&
+ posts.allPosts.map(post => (
+
+ ))}
+
+
+
+ );
+ }
+}
+
+// category & user IDs can be added to the second argument of getFilteredPosts as well
+// these should probably be handled via routes:
+// category/:id
+// user/:id
+const mapStateToProps = ({ posts, searchInput, users }) => ({
+ posts: getFilteredPosts(posts, { searchInput }),
+ users
+});
+
+export default connect(
+ mapStateToProps,
+ { fetchUsers, fetchPosts, fetchCategories, editPost, deletePost }
+)(withStyles(styles)(Dashboard));
diff --git a/src/components/AppBar.js b/src/containers/MenuBar.js
similarity index 96%
rename from src/components/AppBar.js
rename to src/containers/MenuBar.js
index 0cbac5c..54563d7 100644
--- a/src/components/AppBar.js
+++ b/src/containers/MenuBar.js
@@ -96,7 +96,7 @@ const styles = theme => ({
}
});
-class PrimarySearchAppBar extends React.Component {
+class PrimarySearchMenuBar extends React.Component {
state = {
anchorEl: null,
mobileMoreAnchorEl: null
@@ -152,7 +152,7 @@ class PrimarySearchAppBar extends React.Component {
onClose={this.handleMenuClose}
>
-
+
);
@@ -217,8 +217,8 @@ class PrimarySearchAppBar extends React.Component {
/>
@@ -251,7 +251,7 @@ class PrimarySearchAppBar extends React.Component {
}
}
-PrimarySearchAppBar.propTypes = {
+PrimarySearchMenuBar.propTypes = {
classes: PropTypes.object.isRequired
};
@@ -260,4 +260,4 @@ const mapStateToProps = ({ searchInput }) => ({ searchInput });
export default connect(
mapStateToProps,
{ updateInput }
-)(withStyles(styles)(PrimarySearchAppBar));
+)(withStyles(styles)(PrimarySearchMenuBar));
diff --git a/src/containers/NewPost.js b/src/containers/NewPost.js
new file mode 100644
index 0000000..6534821
--- /dev/null
+++ b/src/containers/NewPost.js
@@ -0,0 +1,65 @@
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import ReactQuill from 'react-quill';
+import EditorButtons from '../components/EditorButtons';
+import 'react-quill/dist/quill.snow.css';
+import { addPost, editPost } from '../actions';
+
+const initialPost = { title: '', body: '', id: null };
+
+class NewPost extends Component {
+ state = { post: this.props.post };
+
+ handleTitle = ({ target: { value } }) => {
+ this.setState(({ post }) => ({ post: { ...post, title: value } }));
+ };
+
+ handleBody = value => {
+ this.setState(({ post }) => ({ post: { ...post, body: value } }));
+ };
+
+ handleSubmit = () => {
+ const { id } = this.state.post;
+ const { addPost, editPost, currentUser, history } = this.props;
+
+ const div = document.createElement('div'); div.innerHTML = this.state.post.body;
+ const body = div.textContent || div.innerText || this.state.post;
+ const creator_id = currentUser.id;
+
+ this.setState(
+ ({ post }) => ({ post: { ...post, body } }),
+ () => {
+ const postData = id ? this.state.post : { ...this.state.post, creator_id };
+
+ (Boolean(id) ? editPost(id, postData) : addPost(postData)).then(() => {
+ history.push('/dashboard');
+ });
+
+ this.setState({ post: initialPost });
+ }
+ );
+ };
+
+ render() {
+ const { title, body } = this.state.post;
+ const { history } = this.props;
+
+ return (
+
+
+
+
+
+ );
+ }
+}
+
+const mapStateToProps = (ownState, { location: { state } }) => ({
+ post: state ? state[0] : initialPost,
+ currentUser: ownState.currentUser
+});
+
+export default connect(
+ mapStateToProps,
+ { addPost, editPost }
+)(NewPost);
diff --git a/src/components/Register.js b/src/containers/Register.js
similarity index 95%
rename from src/components/Register.js
rename to src/containers/Register.js
index 3d10cf6..3b73490 100644
--- a/src/components/Register.js
+++ b/src/containers/Register.js
@@ -12,7 +12,7 @@ import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import withStyles from '@material-ui/core/styles/withStyles';
-import RegisterRedirect from './RegisterRedirect';
+import RegisterRedirect from '../components/RegisterRedirect';
import { connect } from 'react-redux';
import { useInput } from '../hooks';
import { authLogin, authSignup } from '../actions';
@@ -56,7 +56,7 @@ const styles = theme => ({
}
});
-const AuthForm = ({ classes, authLogin, authSignup, history: { push, replace }, location: { pathname } }) => {
+const Register = ({ classes, authLogin, authSignup, history: { push, replace }, location: { pathname } }) => {
const [email, setEmail, updateEmail] = useInput();
const [username, setUsername, updateUsername] = useInput();
const [password, setPassword, updatePassword] = useInput();
@@ -160,12 +160,11 @@ const AuthForm = ({ classes, authLogin, authSignup, history: { push, replace },
);
};
-AuthForm.propTypes = {
- classes: PropTypes.object.isRequired,
- handleSubmit: PropTypes.func.isRequired
+Register.propTypes = {
+ classes: PropTypes.object.isRequired
};
export default connect(
null,
{ authLogin, authSignup }
-)(withStyles(styles)(AuthForm));
+)(withStyles(styles)(Register));
diff --git a/src/reducers/currentUser.js b/src/reducers/currentUser.js
index e66b34b..3a54f2d 100644
--- a/src/reducers/currentUser.js
+++ b/src/reducers/currentUser.js
@@ -1,9 +1,16 @@
import { LOGIN_SUCCESS, SIGNUP_SUCCESS } from "../actions/types";
-export default (state = null, action) => {
+const loadUser = () => {
+ const serializedState = localStorage.getItem('currentUser');
+ return Boolean(serializedState) ? JSON.parse(serializedState) : null;
+};
+
+export default (state = loadUser(), action) => {
switch (action.type) {
case SIGNUP_SUCCESS:
case LOGIN_SUCCESS:
+ const serializedState = JSON.stringify(action.payload.currentUser);
+ localStorage.setItem('currentUser', serializedState);
return action.payload.currentUser;
default:
return state;
diff --git a/src/reducers/error.js b/src/reducers/error.js
index 1db341f..45a4745 100644
--- a/src/reducers/error.js
+++ b/src/reducers/error.js
@@ -5,7 +5,11 @@ import {
FETCH_CATEGORIES_FAILURE,
ADD_CATEGORY_FAILURE,
EDIT_CATEGORY_FAILURE,
- DELETE_CATEGORY_FAILURE
+ DELETE_CATEGORY_FAILURE,
+ FETCH_POSTS_FAILURE,
+ ADD_POST_FAILURE,
+ EDIT_POST_FAILURE,
+ DELETE_POST_FAILURE
} from '../actions/types';
export default (state, action) => {
@@ -17,6 +21,10 @@ export default (state, action) => {
case ADD_CATEGORY_FAILURE:
case EDIT_CATEGORY_FAILURE:
case DELETE_CATEGORY_FAILURE:
+ case FETCH_POSTS_FAILURE:
+ case ADD_POST_FAILURE:
+ case EDIT_POST_FAILURE:
+ case DELETE_POST_FAILURE:
return action.payload.response
? action.payload.response.data.message
: '?';
diff --git a/src/reducers/posts.js b/src/reducers/posts.js
index 8f2fc4d..7772c34 100644
--- a/src/reducers/posts.js
+++ b/src/reducers/posts.js
@@ -2,9 +2,15 @@ import { FETCH_POSTS_SUCCESS, ADD_POST_SUCCESS, EDIT_POST_SUCCESS, DELETE_POST_S
export default (state = [], action) => {
switch (action.type) {
+ case EDIT_POST_SUCCESS:
+ const { id, changedPost } = action.payload;
+ return state.map(post =>
+ post.id === id
+ ? changedPost
+ : post
+ );
case FETCH_POSTS_SUCCESS:
case ADD_POST_SUCCESS:
- case EDIT_POST_SUCCESS:
case DELETE_POST_SUCCESS:
return action.payload;
default:
@@ -15,10 +21,13 @@ export default (state = [], action) => {
const getCategoryPosts = ({ posts_categories }, id) =>
posts_categories.reduce((acc, cur) => (cur.category_id === id ? [...acc, cur.post_id] : acc), []);
-const getPostsBySearch = (state, filter) => ({
- ...state,
- allPosts: state.allPosts.filter(({ title, body }) => title.includes(filter) || body.includes(filter))
-});
+const getPostsBySearch = (state, filter) => {
+ const pattern = new RegExp(filter, 'i');
+ return {
+ ...state,
+ allPosts: state.allPosts.filter(({ title, body }) => pattern.test(title) || pattern.test(body))
+ }
+};
const getPostsByCategory = (state, id) => {
console.log(state);
diff --git a/src/reducers/status.js b/src/reducers/status.js
index 11f3a0c..7ba1f36 100644
--- a/src/reducers/status.js
+++ b/src/reducers/status.js
@@ -19,7 +19,19 @@ import {
EDIT_CATEGORY_FAILURE,
DELETE_CATEGORY_START,
DELETE_CATEGORY_SUCCESS,
- DELETE_CATEGORY_FAILURE
+ DELETE_CATEGORY_FAILURE,
+ FETCH_POSTS_START,
+ FETCH_POSTS_SUCCESS,
+ FETCH_POSTS_FAILURE,
+ ADD_POST_START,
+ ADD_POST_SUCCESS,
+ ADD_POST_FAILURE,
+ EDIT_POST_START,
+ EDIT_POST_SUCCESS,
+ EDIT_POST_FAILURE,
+ DELETE_POST_START,
+ DELETE_POST_SUCCESS,
+ DELETE_POST_FAILURE
} from '../actions/types';
export default (state = {}, action) => {
@@ -59,6 +71,26 @@ export default (state = {}, action) => {
case DELETE_CATEGORY_SUCCESS:
case DELETE_CATEGORY_FAILURE:
return { ...state, deletingCategory: false };
+ case FETCH_POSTS_START:
+ return { ...state, fetchingPosts: true };
+ case FETCH_POSTS_SUCCESS:
+ case FETCH_POSTS_FAILURE:
+ return { ...state, fetchingPosts: false };
+ case ADD_POST_START:
+ return { ...state, addingPost: true };
+ case ADD_POST_SUCCESS:
+ case ADD_POST_FAILURE:
+ return { ...state, addingPost: false };
+ case EDIT_POST_START:
+ return { ...state, editingPost: true };
+ case EDIT_POST_SUCCESS:
+ case EDIT_POST_FAILURE:
+ return { ...state, editingPost: false };
+ case DELETE_POST_START:
+ return { ...state, deletingPost: true };
+ case DELETE_POST_SUCCESS:
+ case DELETE_POST_FAILURE:
+ return { ...state, deletingPost: false };
default:
return state;
}
diff --git a/src/reducers/users.js b/src/reducers/users.js
index abf3d06..9d9fefb 100644
--- a/src/reducers/users.js
+++ b/src/reducers/users.js
@@ -3,7 +3,9 @@ import { FETCH_USERS_SUCCESS } from "../actions/types";
export default (state = [], action) => {
switch (action.type) {
case FETCH_USERS_SUCCESS:
- return action.payload;
+ return action.payload.reduce(
+ (acc, cur) => ({ ...acc, [cur.id]: cur }),
+ {});
default:
return state;
}