Skip to content

Commit

Permalink
feature(author-profile): add view profile page
Browse files Browse the repository at this point in the history
- design and create components for viewing profile
- add unit testing

[Starts #167164944]
  • Loading branch information
OvieMudi committed Sep 12, 2019
1 parent b8ec24b commit d448c22
Show file tree
Hide file tree
Showing 25 changed files with 15,653 additions and 7 deletions.
14,842 changes: 14,842 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

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
13 changes: 9 additions & 4 deletions src/api/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import axios from 'axios';
import appConfig from '../config/appConfig';

const { BASE_PATH } = appConfig;
const { token } = JSON.parse(window.localStorage.getItem('AuthorsHavenUser'));
const { BACKEND_PATH } = appConfig;

axios.defaults.baseURL = BASE_PATH;
axios.defaults.headers.common.Authorization = token;
const user = JSON.parse(window.localStorage.getItem('AuthorsHavenUser'));

if (user) {
const { token } = user;
axios.defaults.headers.common.Authorization = token;
}

axios.defaults.baseURL = BACKEND_PATH;

export default axios;
14 changes: 14 additions & 0 deletions src/api/userProfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import axios from '.';
import appConfig from '../config/appConfig';


const { BACKEND_PATH } = appConfig;

const userProfleApi = (userId, setProfileState) => {
axios.get(`${BACKEND_PATH}/profiles/${userId}`)
.then(({ data }) => {
setProfileState(data.data);
});
};

export default userProfleApi;
70 changes: 70 additions & 0 deletions src/components/ProfilePage/NovelListItem/NovelListItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import PropTypes from 'prop-types';
import './novelListItem.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 {}`;
134 changes: 134 additions & 0 deletions src/components/ProfilePage/NovelListItem/novelListItem.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
.novel-list-item {
display: grid;
grid-template-columns: 100px 550px 100px;
grid-template-rows: 70% 1fr;
height: 140px;
grid-template-areas:
'image novel activity'
'image novel activity'
'image meta meta';
margin: 2rem;
border: 1px solid rgba(0, 0, 0, 0.068);

.img-container {
grid-area: image;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
img {
width: 90px;
height: 132px;
cursor: pointer;
}
}

.novel-details {
grid-area: novel;
padding: 0 .5rem;
text-align: justify;
}

h5 {
margin-bottom: 1rem;
font-size: 1.4em;
text-transform: capitalize;
cursor: pointer;
}

p {
max-width: 85ch;
}

.novel-meta {
grid-area: meta;
display: flex;
font-size: 0.9em;
color: rgba(0, 0, 0, 0.699);

div:first-of-type {
padding-right: 8rem;
padding-left: .5rem;
}
}

.novel-activity {
grid-area: activity;
display: flex;
align-items: center;
color: rgba(0, 0, 0, 0.699);
padding: 0 1rem;

div {
padding-right: 0.7rem;
}
}

@media only screen and (max-width: 850px) {
grid-template-columns: 100px 400px 100px;
grid-template-areas:
'image novel novel'
'image novel novel'
'image meta activity';
}

@media only screen and (max-width: 650px) {
grid-template-columns: 100px 300px 100px;
}

@media only screen and (max-width: 540px) {
grid-template-columns: 100px 200px 100px;
margin: 1rem;

.novel-details {
padding: 0 1rem;
}

h5 {
margin-bottom: 0.7rem;
font-size: 1.2em;
}

p {
max-width: 85ch;
font-size: 0.8em;
}

.novel-meta {
font-size: 0.7em;

div:first-of-type {
padding-right: 3rem;
padding-left: 1.3rem;
}
}

.novel-activity {
font-size: 0.7em;

div {
padding-right: 0.7rem;
}
}
}

@media only screen and (max-width: 435px) {
grid-template-columns: 90px 150px 70px;
.novel-meta {
font-size: 60%;

div:first-of-type {
padding-right: 1rem;
padding-left: 1.3rem;
}
}

.novel-activity {
font-size: 60%;

div {
padding-right: 0.4rem;
}
}
}
}
32 changes: 32 additions & 0 deletions src/components/ProfilePage/NovelListItem/novelListItem.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import NovelListItem from './NovelListItem';

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

describe('Novel-list Component', () => {
const props = {
title: 'Some text',
summary: 'Some text',
thumbImgUrl: 'https://some-image.com',
likes: 2,
readTime: '1',
comments: 3,
genre: 'action',
};
it('should render properly', () => {
const wrapper = shallow(
<NovelListItem
title={props.title}
summary={props.summary}
thumbImgUrl={props.thumbImgUrl}
likes={props.likes}
readTime={props.readTime}
comments={props.comments}
genre={props.genre}
/>,
);
expect(wrapper).toMatchSnapshot();
});
});
33 changes: 33 additions & 0 deletions src/components/ProfilePage/ProfileContent/ProfileContent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import PropTypes from 'prop-types';
import Stats from '../Stats/Stats';
import './profileContent.scss';

const ProfileContent = ({
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>
<Stats following={following} followers={followers} written={written} />
<button className="generic-btn" type="button">
Edit Profile
</button>
</div>
</div>
);

ProfileContent.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 ProfileContent;
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 {}`;
68 changes: 68 additions & 0 deletions src/components/ProfilePage/ProfileContent/profileContent.scss
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;
}
}
}
Loading

0 comments on commit d448c22

Please sign in to comment.