Setup Profile page
This commit is contained in:
parent
e507c4ad33
commit
c878c7f366
|
@ -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 |
|
@ -0,0 +1,6 @@
|
||||||
|
const profile = {
|
||||||
|
visible: false,
|
||||||
|
dapp: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default profile
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
import Profile from './Profile'
|
||||||
|
|
||||||
|
const mapStateToProps = state => state
|
||||||
|
|
||||||
|
export default connect(mapStateToProps)(Profile)
|
|
@ -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}
|
||||||
|
→
|
||||||
|
</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
|
|
@ -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);
|
||||||
|
}
|
|
@ -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)
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Profile from './Profile.container'
|
||||||
|
|
||||||
|
export default Profile
|
Loading…
Reference in New Issue