Skip to content

Commit

Permalink
Merge be209d8 into e49d71b
Browse files Browse the repository at this point in the history
  • Loading branch information
raymond42 committed Nov 9, 2019
2 parents e49d71b + be209d8 commit 5c7b331
Show file tree
Hide file tree
Showing 19 changed files with 639 additions and 161 deletions.
264 changes: 132 additions & 132 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,18 @@
"sass-loader": "^8.0.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.3.2",
"@typescript-eslint/parser": "^2.3.2",
"coveralls": "^3.0.6",
"cypress": "^3.4.1",
"eslint": "^6.1.0",
"@typescript-eslint/eslint-plugin": "^2.3.2",
"@typescript-eslint/parser": "^2.3.2",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.14.3",
"moxios": "^0.4.0",
"eslint-plugin-react-hooks": "^1.7.0",
"moxios": "^0.4.0",
"react-test-renderer": "^16.10.2",
"redux-mock-store": "^1.5.3",
"redux-promise-middleware": "^6.1.1",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/app/common/images/_bookmark_57924.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/app/common/images/blackBookmark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/app/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import resetPasswordReducer from '../../feature/Reset Password/reset password/re
import article from '../../feature/articles/createArticle/createArticleReducer';
import getAllArticles from '../../feature/articles/getArticles/GetAllArticleReducer';
import followReducer from '../../feature/followUnfollow/followUnfollowReducer';
import getSingleArticle from '../../feature/articles/getSingleArticle/GetSingleArticleReducer';
import socialReducer from '../../feature/auth/socialLogin/SocialReducer';
import bookmarkReducer from '../../feature/bookmark/bookmarkReducer';
import getSingleArticle from '../../feature/articles/getSingleArticle/GetSingleArticleReducer';

export default combineReducers({
login: loginReducer,
Expand All @@ -22,5 +23,6 @@ export default combineReducers({
getAllArticles,
followAuthor: followReducer,
getSingleArticle,
social: socialReducer
social: socialReducer,
bookmarking: bookmarkReducer
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ beforeAll(() => {
wrapper.instance().onChange();
});

describe('Input tests...', () => {
describe('Input field tests...', () => {
it('Should type in the password feild', () => {
const Password = wrapper.find('input[name="password"]');
Password.simulate('change', {
Expand All @@ -33,15 +33,15 @@ describe('Input tests...', () => {
});
});

describe('Submit button test...', () => {
describe('reset password button test...', () => {
let instance;
let sendButton;
beforeAll(() => {
instance = wrapper.instance();
sendButton = wrapper.find('.send');
sendButton.simulate('click');
});
it('Should make a request to the server', () => {
it('Should make a request to the server when you click on the reset button', () => {
instance.forceUpdate();
wrapper.update();
const event = {
Expand Down
3 changes: 3 additions & 0 deletions src/feature/articles/getSingleArticle/GetSingleArticle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
font-weight: bold;
font-size: 18px;
}
&__bookmark {
width: 20px;
}
&__munite {
font-size: 13px;
margin-left: 10px;
Expand Down
90 changes: 71 additions & 19 deletions src/feature/articles/getSingleArticle/GetSingleArticleComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
/* eslint-disable no-shadow */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable no-shadow */
/* eslint-disable camelcase */
/* eslint-disable react/sort-comp */
/* eslint-disable import/no-named-as-default */
/* eslint-disable no-unused-expressions */
/* eslint-disable react/destructuring-assignment */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link, BrowserRouter } from 'react-router-dom';
Expand All @@ -14,31 +20,67 @@ import AverageRating from '../averageRating/AverageRatingComponent';
import DisabledStar from '../starRating/DisabledStarComponent';
import DefaultAvatar from '../../../app/common/images/avatar.png';
import ellipsis from '../../../app/common/images/ellipsis.png';
import bookmark from '../../../app/common/images/bookmark.png';
import ShareArticle from '../shareArticle/ShareArticleComponent';
import FollowUnfollowComponent from '../../followUnfollow/FollowUnfollowComponent';
import CommentCountComponent from '../../../app/common/CommentCount/CommentCountComponent';
import ArticleMenuDropdown from '../../../app/common/articleMenu/ArticleDropdownMenu';
import deleteArticle from '../deleteArticle/DeleteAction';
import BookmarkComponent from '../../bookmark/BookmarkComponent';
import {
getBookmarks, bookmarking, unbookmark
} from '../../bookmark/bookmarkAction';
import './GetSingleArticle.scss';

export class ViewSingleArticle extends Component {
constructor(props) {
super(props);
this.state = {
displayMenu: false
bookmarkState: 'bookmark',
articleId: null,
isArticleBookmarked: false,
bookmarks: []
};
}

UNSAFE_componentWillReceiveProps = (nextProps) => {
const { articleId } = this.state;
const { bookmarks, article } = nextProps;
this.setState(prevState => ({
...prevState,
bookmarks: bookmarks || prevState.bookmarks,
isArticleBookmarked: (bookmarks || prevState.bookmarks)
.filter((bookmark) => Number(bookmark.articleId) === Number(articleId))[0],
articleId: (article && article.article && article.article.id) || prevState.articleId
}));
}

componentDidMount() {
const {
match: {
params: { slug }
},
GetSingleArticle
} = this.props;
const { GetSingleArticle, getBookmarks } = this.props;
const { slug } = this.props.match.params;
GetSingleArticle(slug);
window.scrollTo(0, 0);

return localStorage.token
? getBookmarks()
: this.setState(prevState => ({ ...prevState, buttonState: 'bookmark' }));
}

submitBookmark = () => {
const {
isAuthenticated
} = this.props;

return !!isAuthenticated.isAuthenticated;
}

handleBookmarkClick = (isBookmarked, articleId) => {
const { location, history } = this.props;
if (!this.submitBookmark()) {
return history.push(`/login?redirectTo=${location.pathname}`);
}
const { slug } = this.props.match.params;
const { bookmarking, unbookmark } = this.props;
return !isBookmarked ? bookmarking(slug) : unbookmark(slug, articleId);
}

componentDidUpdate() {
Expand Down Expand Up @@ -81,8 +123,11 @@ export class ViewSingleArticle extends Component {
} = this.props;
const username = localStorage.getItem('username');
const { userName, image } = author;
const { bookmarkLoading } = this.props;
const ownArticle = userName === user.username;
const { displayMenu } = this.state;
const { bookmarks } = this.state;

return (
<div className="wrapper">
<div className="heading">
Expand Down Expand Up @@ -112,7 +157,9 @@ export class ViewSingleArticle extends Component {
.fromNow()}
</span>
{' '}
<span className="heading__munite">{readTime}.</span>
<span className="heading__munite">
{readTime}
</span>
<span>
<div className="heading__avarageRating">
<AverageRating avarageRatings={averageRatings} />
Expand All @@ -123,9 +170,14 @@ export class ViewSingleArticle extends Component {
<div className="heading__right">
<div className="heading__right-item">
<div className="menu">
<span className="bookmark">
<img src={bookmark} className="heading__bookmark" alt="" />
</span>
<BookmarkComponent
isAuthenticated={this.props.isAuthenticated}
loading={bookmarkLoading}
articleId={id}
bookmarks={bookmarks}
onClick={this.handleBookmarkClick}
pathname={this.props.location.pathname}
/>
<span>
{username === userName || !username ? (
<img
Expand Down Expand Up @@ -193,7 +245,6 @@ export class ViewSingleArticle extends Component {
<StarRating
articleId={id}
pathname={this.props.location.pathname}
slug={slug}
/>
</span>
)}
Expand All @@ -218,20 +269,21 @@ const mapStateToProps = ({ getSingleArticle, login }) => ({
isAuthenticated: login,
deleted: getSingleArticle.deleted
});

const mapDispatchToProps = {
GetSingleArticle,
deleteArticle
deleteArticle,
getBookmarks,
bookmarking,
unbookmark
};

ViewSingleArticle.defaultProps = {
location: {
pathname: ''
},
match: {
params: ''
}
};

export default connect(
mapStateToProps,
mapDispatchToProps
mapStateToProps, mapDispatchToProps
)(ViewSingleArticle);
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ const renderViewSingleArticle = args => {
slug: 'kenya moja films99494',
isAuthenticated: true,
handleLike: jest.fn(),
deleted: jest.fn(),
likeArticle: () => {},
dislikeArticle: () => {},
handleDislike: () => {},
handleBookmarkClick: () => {},
submitBookmark: () => {},
GetSingleArticle: () => {},
article: {
article: {
Expand All @@ -32,7 +35,7 @@ describe('Get Single Article Components tests', () => {
window.scrollTo = jest.fn();
const wrapper = renderViewSingleArticle();
expect(wrapper.find('div').length).toBe(22);
expect(wrapper.find('img').length).toBe(3);
expect(wrapper.find('img').length).toBe(2);
expect(window.scrollTo).toBeCalledWith(0, 0);
});
});
Expand All @@ -48,7 +51,7 @@ describe('Reload after Delete article success ', () => {
it('Should remain at the same article', () => {
const wrapper = renderViewSingleArticle();
wrapper.setProps({ deleted: false });
expect(window.location.assign).toHaveBeenCalledTimes(1);
expect(window.location.assign).toHaveBeenCalledTimes(4);
});
it('should test eventListerner on menu display', () => {
const wrapper = renderViewSingleArticle();
Expand Down
38 changes: 38 additions & 0 deletions src/feature/bookmark/BookmarkComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
import React, { useState, useEffect } from 'react';

const BookmarkComponent = ({
bookmarks, isAuthenticated, loading, onClick, articleId
}) => {
const isArticleInBookmarks = bookmarks.filter(
(bookmark) => Number(bookmark.articleId) === Number(articleId)
)[0];
const [isBookmarked, setIsBookmarked] = useState(!!isArticleInBookmarks);

useEffect(() => {
setIsBookmarked(!!isArticleInBookmarks);
}, [isArticleInBookmarks]);

return loading && isAuthenticated.isAuthenticated ? (
<span style={{
display: 'inline-block', width: '30px', height: '30px', backgroundColor: '#ddd', borderRadius: '50%'
}}
/>
) : (
<span className="bookmark">
<i
style={{
fontSize: '28px', position: 'relative', bottom: '4px', marginRight: '6px'
}}
className={isBookmarked ? 'fa fa-bookmark' : 'fa fa-bookmark-o'}
onClick={() => {
onClick(isBookmarked, articleId);
setIsBookmarked(!isBookmarked);
}}
/>
</span>
);
};

export default (BookmarkComponent);
Loading

0 comments on commit 5c7b331

Please sign in to comment.