Skip to content

Commit

Permalink
Merge 9b1c372 into 8d9355f
Browse files Browse the repository at this point in the history
  • Loading branch information
allebd committed Sep 13, 2019
2 parents 8d9355f + 9b1c372 commit 8ee2a4a
Show file tree
Hide file tree
Showing 24 changed files with 814 additions and 3 deletions.
1 change: 1 addition & 0 deletions server/server.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const path = require('path');
const express = require('express');
require('dotenv').config();

const app = express();

Expand Down
38 changes: 38 additions & 0 deletions src/components/Novel/Novel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { useContext } from 'react';
import ReactRouterPropTypes from 'react-router-prop-types';
import { CommentModalContext } from '../../context/CommentModalContext';
import CommentContextProvider from '../../context/CommentContext';
import Comment from '../Comment/Comment';

const Novel = ({ match: { params: { slug } } }) => {
const { modalComponent, setModalComponent } = useContext(CommentModalContext);

const handleOpenModal = (comment) => {
setModalComponent(comment);
document.body.style.height = '100vh';
document.body.style.overflowY = 'hidden';
};

const handleCloseModal = () => {
setModalComponent(null);
document.body.style.height = '100vh';
document.body.style.overflowY = 'auto';
};

return (
<>
{ modalComponent ? (
<CommentContextProvider slug={slug}>
<Comment closeModal={handleCloseModal} openModal={handleOpenModal} />
</CommentContextProvider>
) : ''}
<button type="button" style={{ margin: '200px' }} onClick={() => { handleOpenModal('comment'); }}>View Comments</button>
</>
);
};

Novel.propTypes = {
match: ReactRouterPropTypes.match.isRequired,
};

export default Novel;
52 changes: 52 additions & 0 deletions src/components/OtherProfile/OtherProfile.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useContext } from 'react';
import OtherProfileContent from './OtherProfileContent/OtherProfileContent';
import './otherProfile.scss';
import OtherProfileNovelListItem from './OtherProfileNovelListItem/OtherProfileNovelListItem';
import { OtherProfileContext } from '../../context/OtherProfileContext';

const OtherProfile = () => {
const { userProfile, authorNovels } = useContext(OtherProfileContext);
const {
name, image, bio, followers, following,
} = userProfile;
return (
<main className="profile-page">
<section className="profile-container">
{userProfile.name && (
<OtherProfileContent
name={name}
image={image}
bio={bio}
following={following}
followers={followers}
written={authorNovels.length}
/>
)}
<h4>{authorNovels.length > 0 ? 'Most Liked Novels' : ''}</h4>
{authorNovels.slice(0, 3).map((novel) => {
let summary;
if (novel.description && novel.description.length > 250) {
summary = `${novel.description.substring(0, 250)}...`;
} else {
summary = novel.description;
}
return (
<OtherProfileNovelListItem
key={novel.id}
summary={summary}
title={novel.title}
thumbImgUrl={novel.thumbImgUrl}
readTime={novel.readTime}
genre={novel.Genre.name}
likes={novel.Likes.length}
comments={novel.Comments.length}
/>
);
})}

</section>
</main>
);
};

export default OtherProfile;
16 changes: 16 additions & 0 deletions src/components/OtherProfile/OtherProfileContainer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import ReactRouterPropTypes from 'react-router-prop-types';
import OtherProfileContextProvider from '../../context/OtherProfileContext';
import OtherProfile from './OtherProfile';

const OtherProfileContainer = ({ match: { params: { userId } } }) => (
<OtherProfileContextProvider userId={userId}>
<OtherProfile />
</OtherProfileContextProvider>
);

OtherProfileContainer.propTypes = {
match: ReactRouterPropTypes.match.isRequired,
};

export default OtherProfileContainer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import PropTypes from 'prop-types';
import OtherProfileStats from '../OtherProfileStats/OtherProfileStats';
import './otherProfileContent.scss';

const OtherProfileContent = ({
name, image, bio, followers, following, written,
}) => (
<div className="profile-content">
<div className="avatar-container">
<img src={image} alt="avatar" />
</div>
<div className="bio-container">
<h3 className="name">{name}</h3>
<p className="bio">{bio}</p>
<OtherProfileStats following={following} followers={followers} written={written} />
<button className="generic-btn" type="button">
Follow
</button>
</div>
</div>
);

OtherProfileContent.propTypes = {
name: PropTypes.string.isRequired,
bio: PropTypes.string.isRequired,
image: PropTypes.string.isRequired,
following: PropTypes.number.isRequired,
followers: PropTypes.number.isRequired,
written: PropTypes.number.isRequired,
};

export default OtherProfileContent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Author Profile/Bio Component should render properly 1`] = `ShallowWrapper {}`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.profile-content {
display: flex;
flex-direction: row;

.name {
font-size: 1.9em;
text-transform: uppercase;
padding: 0;
margin: 0;
}

.bio {
max-width: 70ch;
min-width: 40ch;
margin-top: 1rem;
}

.avatar-container {
width: 200px;
margin-right: 3rem;
}

.bio-container {
display: flex;
flex-flow: column nowrap;
}

.generic-btn,
.generic-btn:focus,
.generic-btn:active {
padding: 0.5rem 1rem;
margin: 10px 10px;
border: 1px solid rgba(0, 0, 0, 0.6);
align-self: center;
font-size: 0.7rem;
text-transform: uppercase;
outline: none;
background-color: white;
cursor: pointer;
}

@media only screen and (max-width: 850px) {
flex-direction: column;
align-items: center;
text-align: center;
font-size: 90%;

.avatar-container {
width: 170px;
margin-right: 0;
margin-top: 2rem;
}
}

@media only screen and (max-width: 540px) {
font-size: 80%;
.avatar-container {
width: 150px;
}
}

@media only screen and (max-width: 435px) {
font-size: 70%;
.avatar-container {
width: 140px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import OtherProfileContent from './OtherProfileContent';

configure({ adapter: new Adapter() });

describe('Author Profile/Bio Component', () => {
const props = {
name: 'Some Name',
bio: 'Bio text',
image: 'https://some-image.com',
following: 0,
followers: 1,
written: 2,
};
it('should render properly', () => {
const wrapper = shallow(
<OtherProfileContent
name={props.name}
bio={props.bio}
image={props.image}
followers={props.followers}
following={props.following}
written={props.written}
/>,
);
expect(wrapper).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import PropTypes from 'prop-types';
import './otherProfileNovelListItem.scss';

const NovelListItem = (props) => {
const {
title,
summary,
readTime,
thumbImgUrl,
likes,
comments,
genre,
} = props;

const estimatedTime = readTime === 1 ? '1 day read' : ` ${readTime} days read`;


return (
<div className="novel-list-item">
<div className="img-container">
<img src={thumbImgUrl} alt={title} />
</div>
<div className="novel-details">
<h5>{title}</h5>
<div className="description">
<p>{summary}</p>
</div>
</div>

<div className="novel-activity">
<div className="activity-icon">
<i className="fas fa-comment" />
{' '}
{comments}
</div>
<div className="activity-icon">
<i className="fas fa-heart" />
{' '}
{likes}
</div>
</div>

<div className="novel-meta">
<div>
<i className="fas fa-clock" />
{' '}
{estimatedTime}
</div>
<div>
<i className="fas fa-tags" />
{' '}
{genre}
</div>
</div>
</div>
);
};

NovelListItem.propTypes = {
title: PropTypes.string.isRequired,
summary: PropTypes.string.isRequired,
readTime: PropTypes.number.isRequired,
thumbImgUrl: PropTypes.string.isRequired,
likes: PropTypes.number.isRequired,
comments: PropTypes.number.isRequired,
genre: PropTypes.string.isRequired,
};

export default NovelListItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Novel-list Component should render properly 1`] = `ShallowWrapper {}`;
Loading

0 comments on commit 8ee2a4a

Please sign in to comment.