Setup Profile page

This commit is contained in:
Onuwa Nnachi Isaac 2019-04-26 09:54:33 +01:00
parent e507c4ad33
commit c878c7f366
7 changed files with 334 additions and 0 deletions

View File

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 1C5.02944 1 1 5.02944 1 10V14V17.0004C1 18.105 1.89503 19 2.9996 19H6H10C14.9706 19 19 14.9706 19 10C19 5.02944 14.9706 1 10 1ZM7.99999 10C7.99999 10.2761 7.77613 10.5 7.49999 10.5C7.22385 10.5 6.99999 10.2761 6.99999 10C6.99999 9.72386 7.22385 9.5 7.49999 9.5C7.77613 9.5 7.99999 9.72386 7.99999 10ZM13 10C13 10.2761 12.7761 10.5 12.5 10.5C12.2238 10.5 12 10.2761 12 10C12 9.72386 12.2238 9.5 12.5 9.5C12.7761 9.5 13 9.72386 13 10Z" fill="#4360DF" stroke="white" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 599 B

View File

@ -0,0 +1,6 @@
const profile = {
visible: false,
dapp: '',
}
export default profile

View File

@ -0,0 +1,7 @@
import { connect } from 'react-redux'
import Profile from './Profile'
const mapStateToProps = state => state
export default connect(mapStateToProps)(Profile)

View File

@ -0,0 +1,129 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import ReactImageFallback from 'react-image-fallback'
import Modal from '../../common/components/Modal'
import styles from './Profile.module.scss'
import icon from '../../common/assets/images/icon.svg'
import chat from '../../common/assets/images/chat.svg'
import { Redirect } from 'react-router-dom'
const DesktopScreen = props => {
return <Modal visible={props.visible}>{props.children}</Modal>
}
const MobileScreen = props => {
return (
<>
{props.router.location.state &&
props.router.location.state.name === props.profile.dapp.name ? (
props.children
) : (
<Redirect to={'/'} />
)}
</>
)
}
const ProfileContent = ({
name,
url,
description,
image,
isRanked,
position,
category,
}) => {
return (
<>
<div className={styles.container}>
<div className={styles.banner}>
<ReactImageFallback
className={styles.image}
src={image}
fallbackImage={icon}
alt="App icon"
/>
</div>
<div className={styles.information}>
<h4 className={styles.header}>{name}</h4>
<span className={styles.category}>{category}</span>
<a href="#" target="_blank" className={styles.button}>
Open
</a>
</div>
<div className={styles.description}>
<span className={styles.heading}>Description</span>
<p>{description}</p>
</div>
<div className={styles.chat}>
<ReactImageFallback
className={styles.chat_image}
src={image}
fallbackImage={icon}
alt="App icon"
/>
<img src={chat} className={styles.chat_icon} alt="Chat" />
<a
href="#"
target="_blank"
className={styles.chat_link}
>{`Open ${name} chat`}</a>
</div>
<div className={styles.url}>
<span className={styles.heading}>URL</span>
<p>
<a href={url}>
{url}
&nbsp;&rarr;
</a>
</p>
</div>
<div className={styles.ranking}>
<span className={styles.heading}>Ranking</span>
<div className={styles.rank}>
<div className={styles.rank_position_1}>
<span className={styles.rank_position_span}>{position}</span>
</div>
<span className={styles.rank_position_text}>
<span></span>
{position} in {category}
</span>
</div>
<div className={styles.rank}>
<span className={styles.rank_position_2}>
<span className={styles.rank_position_span}>{position}</span>
</span>
<span className={styles.rank_position_text}>
<span></span>
{position} in highest ranked DApps
</span>
</div>
</div>
</div>
</>
)
}
const Profile = props => {
const { innerWidth } = window
return innerWidth >= 1024 ? (
<DesktopScreen {...props.profile}>
<ProfileContent {...props.profile.dapp} />
</DesktopScreen>
) : (
<MobileScreen {...props}>
<ProfileContent {...props.profile.dapp} />
</MobileScreen>
)
}
Profile.propTypes = {
visible: PropTypes.bool.isRequired,
dapp: PropTypes.object,
}
Profile.defaultProps = {
visible: false,
}
export default Profile

View File

@ -0,0 +1,144 @@
@import '../../common/styles/variables';
a {
text-decoration: none;
}
.container {
font-family: $font;
background-color: #ffffff;
}
.banner {
height: calculateRem(140);
background-color: $blue-bg;
display: flex;
justify-content: center;
}
.image {
border-radius: calculateRem(100);
width: calculateRem(100);
height: calculateRem(100);
margin: calculateRem(80) auto;
z-index: 99;
box-shadow: 0px 4px 12px rgba(0, 34, 51, 0.08),
0px 2px 4px rgba(0, 34, 51, 0.16);
}
.header {
color: $headline-color;
font-size: calculateRem(15);
line-height: calculateRem(22);
margin-bottom: calculateRem(4);
margin-top: calculateRem(12);
font-weight: 600;
cursor: pointer;
}
.category {
margin-bottom: calculateRem(20);
}
.heading {
color: $text-color;
font-size: calculateRem(13);
line-height: calculateRem(18);
margin-bottom: calculateRem(2);
margin-top: 0;
max-height: calculateRem(40);
overflow-y: hidden;
cursor: pointer;
}
.information {
display: flex;
flex-direction: column;
align-items: center;
margin: calculateRem(40) auto;
}
.button {
border-radius: 20px;
background-color: #4360df;
color: #ffffff;
padding: calculateRem(12) calculateRem(20);
}
.description {
border-bottom: 1px solid #eef2f5;
box-shadow: inset 0px 1px 0px #eef2f5;
padding: calculateRem(10) calculateRem(20);
}
.chat {
display: flex;
align-items: center;
border-bottom: 1px solid #eef2f5;
box-shadow: inset 0px 1px 0px #eef2f5;
padding: calculateRem(10) calculateRem(20);
}
.chat_image {
width: calculateRem(40);
height: calculateRem(40);
margin-top: calculateRem(20);
border-radius: 20px;
}
.chat_link {
margin: calculateRem(10);
margin-top: calculateRem(25);
}
.chat_icon {
margin-left: calculateRem(-10);
margin-bottom: calculateRem(10);
}
.url {
border-bottom: 1px solid #eef2f5;
box-shadow: inset 0px 1px 0px #eef2f5;
padding: calculateRem(10) calculateRem(20);
}
.ranking {
border-bottom: 1px solid #eef2f5;
box-shadow: inset 0px 1px 0px #eef2f5;
padding: calculateRem(10) calculateRem(20);
}
.rank {
display: flex;
margin-top: calculateRem(10);
}
.rank_position_1 {
border-radius: 40px;
width: calculateRem(40);
margin-right: calculateRem(15);
height: calculateRem(40);
background-color: $blue;
display: flex;
justify-content: center;
}
.rank_position_2 {
border-radius: 40px;
width: calculateRem(40);
margin-right: calculateRem(15);
height: calculateRem(40);
background-color: $red;
display: flex;
justify-content: center;
}
.rank_position_span {
padding: calculateRem(10);
color: #ffffff;
font-weight: 600;
}
.rank_position_text {
margin-top: calculateRem(10);
}

View File

@ -0,0 +1,42 @@
import profileState from '../../common/data/profile'
import reducerUtil from '../../common/utils/reducer'
import { history } from '../../common/redux/store'
const DESKTOP_NAVIGATE = 'DESKTOP_NAVIGATE'
const MOBILE_NAVIGATE = 'MOBILE_NAVIGATE'
export const toggleProfileModalAction = dapp => {
const { innerWidth } = window
if (innerWidth <= 1024) {
history.push(`/${dapp.name.toLowerCase()}`, dapp)
return {
type: MOBILE_NAVIGATE,
payload: dapp,
}
} else {
return {
type: DESKTOP_NAVIGATE,
payload: dapp,
}
}
}
const toggleProfileModal = (state, payload) => {
return Object.assign({}, state, {
visible: !state.visible,
dapp: payload,
})
}
const navigateProfile = (state, payload) => {
return Object.assign({}, state, {
visible: false,
dapp: payload,
})
}
const map = {
[DESKTOP_NAVIGATE]: toggleProfileModal,
[MOBILE_NAVIGATE]: navigateProfile,
}
export default reducerUtil(map, profileState)

View File

@ -0,0 +1,3 @@
import Profile from './Profile.container'
export default Profile