Skip to content

Commit

Permalink
ft-user-can-view-and-edit-profile
Browse files Browse the repository at this point in the history
create user profile page
fetch get user profile api
fetch get user followers api
fetch get user followee api
fetch get users authored articles api
fetch update user profile api
[Start #166840973]
  • Loading branch information
Alpha1202 committed Aug 22, 2019
1 parent ae17efe commit d7db133
Show file tree
Hide file tree
Showing 15 changed files with 1,239 additions and 76 deletions.
722 changes: 656 additions & 66 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"react": "^16.8.6",
"react-addons-test-utils": "^15.6.2",
"react-dom": "^16.8.6",
"react-images-upload": "^1.2.7",
"react-infinite-scroller": "^1.2.4",
"react-lazyload": "^2.6.2",
"react-notify-toast": "^0.5.0",
Expand Down Expand Up @@ -76,6 +77,7 @@
"babel-jest": "^24.8.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-class-properties": "^6.24.1",
"bootstrap-4-react": "0.0.59",
"enzyme-to-json": "^3.4.0",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.1",
Expand All @@ -91,12 +93,14 @@
"jest": "^24.8.0",
"jest-localstorage-mock": "^2.4.0",
"jest-transform-css": "^2.0.0",
"mdbreact": "^4.19.1",
"node-fetch": "^2.6.0",
"postcss-loader": "^3.0.0",
"react-redux-toastr": "^7.5.1",
"react-test-renderer": "^16.8.6",
"redux-mock-store": "^1.5.3",
"redux-promise-middleware": "^6.1.1",
"svg-inline-loader": "^0.8.0",
"url-loader": "^2.1.0",
"webpack": "^3.1.0",
"webpack-cli": "^3.3.6",
Expand Down
15 changes: 15 additions & 0 deletions src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,18 @@ export const SET_NEW_PASSWORD_SUCCESS = 'SET_NEW_PASSWORD_SUCCESS';
export const RESET_PASSWORD_EMAIL_FAILURE = 'RESET_PASSWORD_EMAIL_FAILURE';
export const SET_NEW_PASSWORD_FAILURE = 'SET_NEW_PASSWORD_FAILURE';
export const SET_CURRENT_ARTICLES = 'SET_CURRENT_ARTICLES';
export const GET_AUTH_USER_PROFILE_START = 'GET_AUTH_USER_PROFILE_START';
export const GET_AUTH_USER_PROFILE_SUCCESS = 'GET_AUTH_USER_PROFILE_SUCCESS';
export const GET_AUTH_USER_PROFILE_FAILURE = 'GET_AUTH_USER_PROFILE_FAILURE';
export const GET_AUTH_USER_FOLLOWERS_START = 'GET_AUTH_USER_FOLLOWERS_START';
export const GET_AUTH_USER_FOLLOWERS_SUCCESS = 'GET_AUTH_USER_FOLLOWERS_SUCCESS';
export const GET_AUTH_USER_FOLLOWERS_FAILURE = 'GET_AUTH_USER_FOLLOWERS_FAILURE';
export const GET_AUTH_USER_FOLLOWEE_START = 'GET_AUTH_USER_FOLLOWEE_START';
export const GET_AUTH_USER_FOLLOWEE_SUCCESS = 'GET_AUTH_USER_FOLLOWEE_SUCCESS';
export const GET_AUTH_USER_FOLLOWEE_FAILURE = 'GET_AUTH_USER_FOLLOWEE_FAILURE';
export const GET_AUTH_USER_ARTICLES_START = 'GET_AUTH_USER_ARTICLES_START';
export const GET_AUTH_USER_ARTICLES_SUCCESS = 'GET_AUTH_USER_ARTICLES_SUCCESS';
export const GET_AUTH_USER_ARTICLES_FAILURE = 'GET_AUTH_USER_ARTICLES_FAILURE';
export const EDIT_AUTH_USER_IMAGE_START = 'EDIT_AUTH_USER_IMAGE_START';
export const EDIT_AUTH_USER_IMAGE_SUCCESS = 'EDIT_AUTH_USER_IMAGE_SUCCESS';
export const EDIT_AUTH_USER_IMAGE_FAILURE = 'EDIT_AUTH_USER_IMAGE_FAILURE';
152 changes: 152 additions & 0 deletions src/actions/userActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import axios from '../config/axiosInstance';
import {
GET_AUTH_USER_PROFILE_START,
GET_AUTH_USER_PROFILE_SUCCESS,
GET_AUTH_USER_PROFILE_FAILURE,
GET_AUTH_USER_FOLLOWERS_START,
GET_AUTH_USER_FOLLOWERS_SUCCESS,
GET_AUTH_USER_FOLLOWERS_FAILURE,
GET_AUTH_USER_FOLLOWEE_START,
GET_AUTH_USER_FOLLOWEE_SUCCESS,
GET_AUTH_USER_FOLLOWEE_FAILURE,
GET_AUTH_USER_ARTICLES_START,
GET_AUTH_USER_ARTICLES_SUCCESS,
GET_AUTH_USER_ARTICLES_FAILURE,
EDIT_AUTH_USER_IMAGE_START,
EDIT_AUTH_USER_IMAGE_SUCCESS,
EDIT_AUTH_USER_IMAGE_FAILURE,
} from './types';

export const getAuthUserProfileStart = () => ({
type: GET_AUTH_USER_PROFILE_START,
});

export const getAuthUserProfileSuccess = payload => ({
type: GET_AUTH_USER_PROFILE_SUCCESS,
payload,
});

export const getAuthUserProfileFailure = () => ({
type: GET_AUTH_USER_PROFILE_FAILURE,
});

export const authUserProfile = userName => (dispatch) => {
dispatch(getAuthUserProfileStart());
return axios
.get(`/user/profiles/${userName}`)
.then((res) => {
const { data } = res.data;
dispatch(getAuthUserProfileSuccess(data[0]));
})
.catch((error) => {
dispatch(getAuthUserProfileFailure());
});
};

export const getAuthUserFollowersStart = () => ({
type: GET_AUTH_USER_FOLLOWERS_START,
});

export const getAuthUserFollowersSuccess = payload => ({
type: GET_AUTH_USER_FOLLOWERS_SUCCESS,
payload,
});
export const getAuthUserFollowersFailure = () => ({
type: GET_AUTH_USER_FOLLOWERS_FAILURE,
});


export const getAuthUserFollowers = userId => (dispatch) => {
dispatch(getAuthUserFollowersStart());
return axios
.get(`/user/followers/${userId}`)
.then((res) => {
const { data } = res.data;
dispatch(getAuthUserFollowersSuccess(data[0].followers));
})
.catch((error) => {
dispatch(getAuthUserFollowersFailure());
});
};

export const getAuthUserFolloweeStart = () => ({
type: GET_AUTH_USER_FOLLOWEE_START,
});

export const getAuthUserFolloweeSuccess = payload => ({
type: GET_AUTH_USER_FOLLOWEE_SUCCESS,
payload,
});

export const getAuthUserFolloweeFailure = () => ({
type: GET_AUTH_USER_FOLLOWEE_FAILURE,
});

export const getAuthUserFollowee = userId => (dispatch) => {
dispatch(getAuthUserFolloweeStart());
return axios
.get(`/user/followees/${userId}`)
.then((res) => {
const { data } = res.data;
dispatch(getAuthUserFolloweeSuccess(data[0].followees));
})
.catch((error) => {
dispatch(getAuthUserFolloweeFailure());
});
};

export const getAuthUserArticlesStart = () => ({
type: GET_AUTH_USER_ARTICLES_START,
});

export const getAuthUserArticlesSuccess = payload => ({
type: GET_AUTH_USER_ARTICLES_SUCCESS,
payload,
});

export const getAuthUserArticlesFailure = () => ({
type: GET_AUTH_USER_ARTICLES_FAILURE,
});

export const getAuthUserArticles = userName => (dispatch) => {
dispatch(getAuthUserArticlesStart());
return axios
.get(`/searcharticles?author=${userName}`)
.then((res) => {
const { data } = res.data;
dispatch(getAuthUserArticlesSuccess(data[0]));
})
.catch((error) => {
if (error.response.data.status === 404) {
dispatch(getAuthUserArticlesSuccess('You Have not written any article'));
}
dispatch(getAuthUserArticlesFailure());
});
};

export const editAuthUserImageStart = () => ({
type: EDIT_AUTH_USER_IMAGE_START,
});

export const editAuthUserImageSuccess = payload => ({
type: EDIT_AUTH_USER_IMAGE_SUCCESS,
payload,
});

export const editAuthUserImageFailure = () => ({
type: EDIT_AUTH_USER_IMAGE_FAILURE,
});

export const editAuthUserImage = (avatar, userId) => (dispatch) => {
dispatch(editAuthUserImageStart());
return axios
.put(`/user/profiles/${userId}`, { avatar })
.then((res) => {
const { data } = res.data;
dispatch(editAuthUserImageSuccess(data[0]));
})
.catch((error) => {
console.log(error);
dispatch(editAuthUserImageFailure());
});
};
84 changes: 84 additions & 0 deletions src/components/Dashboard/UserArticles.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ArticleCard from '../ArticleCard/Index';

const UserArticles = (props) => {
const {
userProfile: {
articles: {
articles,
},
},
} = props;

let userPublishedArticles;
let userDraftArticles;
if (articles !== undefined) {
userPublishedArticles = articles.filter(article => article.isDraft === false);
userDraftArticles = articles.filter(article => article.isDraft === true);
}
const articlePublished = userPublishedArticles !== undefined ? userPublishedArticles : [];
const articlesDrafts = userDraftArticles !== undefined ? userDraftArticles : [];

return (
<div>
<div className="top">
<div className="col-md-8 centering fonts">Articles</div>

<div className="container col-sm-12 col-md-8 bg-white text-dark centering">
<div className="row">

{
articlePublished.length === 0
? <div>You have not authored any Article yet</div>
: (
articlePublished.map(article => (
<ArticleCard
title={article.title}

date={article.createdAt}
viewCount={articles.views}
count="150"
key={article.id}
/>
))
)
}
</div>
</div>
</div>
<div className="top">
<div className="col-md-8 centering fonts">Drafts</div>
<div className="container col-sm-12 col-md-8 bg-white text-dark centering">
<div className="row">
{
articlesDrafts.length === 0
? <div>You have not authored any Article yet</div>
: (
articlesDrafts.map(article => (
<ArticleCard
title={article.title}
date={article.createdAt}
/>
))
)

}
</div>
</div>
</div>
</div>
);
};

UserArticles.propTypes = {
userProfile: PropTypes.shape({ articles: {} }).isRequired,
};


const mapStatetoProps = ({ userProfile }) => ({
userProfile,
});

export default connect(mapStatetoProps)(UserArticles);
70 changes: 70 additions & 0 deletions src/components/Dashboard/UserDashboard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
body {
background-color: #D9D7D7;
}
.profilePics {
width: 150px;
height: 150px;
border-radius: 50%;
display: block;
}

.imgConatiner {
position: relative;
}

.editText {
position: absolute;
top: 50%;
left: 5%;
transform: translate(-5%, -50%);
visibility: hidden;
opacity: 0;
transition: all .4s ease-in-out;
background: white;
padding: 10px;
cursor: pointer;
}

.imgConatiner:hover .editText {
left: 50%;
visibility: visible;
opacity: 1;
transform: translate(-50%, -50%);

}

.margin-left-15 {
margin-left: 15px !important;
}
.margin-right-15 {
margin-right: 15px !important;
}
.top-left {
align-self: flex-end;
}
.top {
justify-content: space-between;
margin-top: 26px;
}
.centering {
margin: 0 auto;

}
.padding-top-10 {
padding-top: 10px;
}
.articleImages {
height: 200px !important;
}
.margin {
margin-top: 20px;
margin-bottom: 20px;
text-align: center;
}
.fonts{
font-family: rokkitt;
font-style: normal;
font-weight: 300;
font-size: 2rem;
line-height: 3rem;
}
Loading

0 comments on commit d7db133

Please sign in to comment.