2020-04-09 00:29:13 +03:00
|
|
|
import * as React from "react";
|
|
|
|
import * as Constants from "~/common/constants";
|
2020-08-08 03:10:28 +03:00
|
|
|
import * as System from "~/components/system";
|
2020-04-09 00:29:13 +03:00
|
|
|
import * as SVG from "~/common/svg";
|
|
|
|
|
|
|
|
import { css } from "@emotion/react";
|
|
|
|
|
2020-08-08 03:10:28 +03:00
|
|
|
import ApplicationControlMenu from "~/components/core/ApplicationControlMenu";
|
2020-04-09 00:29:13 +03:00
|
|
|
|
|
|
|
const IconMap = {
|
|
|
|
HOME: <SVG.Home height="20px" />,
|
2020-08-18 22:51:16 +03:00
|
|
|
NETWORK: <SVG.Activity height="20px" />,
|
2020-08-18 22:28:33 +03:00
|
|
|
DIRECTORY: <SVG.Directory height="20px" />,
|
2020-04-09 00:29:13 +03:00
|
|
|
FOLDER: <SVG.Folder height="20px" />,
|
|
|
|
WALLET: <SVG.Wallet height="20px" />,
|
|
|
|
DEALS: <SVG.Deals height="20px" />,
|
2020-08-10 04:22:52 +03:00
|
|
|
SLATES: <SVG.Layers height="20px" />,
|
2020-07-27 07:26:41 +03:00
|
|
|
SLATE: <SVG.Slates height="20px" />,
|
2020-07-21 08:45:15 +03:00
|
|
|
LOCAL_DATA: <SVG.HardDrive height="20px" />,
|
2020-07-22 10:41:29 +03:00
|
|
|
PROFILE_PAGE: <SVG.ProfileUser height="20px" />,
|
2020-07-29 02:24:15 +03:00
|
|
|
SETTINGS_DEVELOPER: <SVG.SettingsDeveloper height="20px" />,
|
2020-04-09 00:29:13 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
const STYLES_NAVIGATION = css`
|
|
|
|
width: 100%;
|
2020-08-08 23:13:47 +03:00
|
|
|
display: block;
|
2020-04-09 00:29:13 +03:00
|
|
|
padding: 24px 0 0 0;
|
|
|
|
font-size: 18px;
|
|
|
|
`;
|
|
|
|
|
2020-08-08 03:10:28 +03:00
|
|
|
const STYLES_NAVIGATION_HEADER = css`
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: flex-start;
|
2020-08-22 02:36:14 +03:00
|
|
|
padding: 64px 24px 48px 42px;
|
2020-08-08 23:13:47 +03:00
|
|
|
|
2020-08-09 01:04:17 +03:00
|
|
|
@media (max-width: ${Constants.sizes.mobile}px) {
|
2020-08-08 23:13:47 +03:00
|
|
|
padding: 64px 0 48px 16px;
|
|
|
|
}
|
2020-08-08 03:10:28 +03:00
|
|
|
`;
|
|
|
|
|
2020-04-09 00:29:13 +03:00
|
|
|
const STYLES_NAVIGATION_ITEM = css`
|
|
|
|
display: flex;
|
|
|
|
align-items: flex-start;
|
|
|
|
justify-content: space-between;
|
|
|
|
cursor: pointer;
|
|
|
|
color: ${Constants.system.black};
|
2020-08-09 11:08:46 +03:00
|
|
|
user-select: none;
|
2020-08-08 23:13:47 +03:00
|
|
|
padding-right: 24px;
|
2020-04-09 00:29:13 +03:00
|
|
|
|
|
|
|
:hover {
|
2020-08-08 23:13:47 +03:00
|
|
|
padding-right: 0px;
|
2020-04-09 00:29:13 +03:00
|
|
|
color: ${Constants.system.brand};
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
2020-08-08 03:10:28 +03:00
|
|
|
const STYLES_PROFILE = css`
|
|
|
|
font-family: ${Constants.font.semiBold};
|
|
|
|
color: ${Constants.system.pitchBlack};
|
2020-08-25 05:31:42 +03:00
|
|
|
background-color: ${Constants.system.white};
|
2020-08-08 03:10:28 +03:00
|
|
|
font-size: 12px;
|
|
|
|
line-height: 12px;
|
|
|
|
text-decoration: none;
|
|
|
|
flex-shrink: 0;
|
|
|
|
padding-right: 24px;
|
2020-08-22 02:36:14 +03:00
|
|
|
height: 38px;
|
|
|
|
border-radius: 38px;
|
2020-08-08 03:10:28 +03:00
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: flex-start;
|
|
|
|
transition: 200ms ease all;
|
2020-08-25 05:31:42 +03:00
|
|
|
/*
|
2020-08-08 03:10:28 +03:00
|
|
|
:hover {
|
|
|
|
color: ${Constants.system.white};
|
|
|
|
background-color: ${Constants.system.brand};
|
|
|
|
}
|
2020-08-25 05:31:42 +03:00
|
|
|
*/
|
2020-08-09 01:04:17 +03:00
|
|
|
@media (max-width: ${Constants.sizes.mobile}px) {
|
2020-08-08 23:13:47 +03:00
|
|
|
display: none;
|
|
|
|
}
|
2020-08-08 03:10:28 +03:00
|
|
|
`;
|
|
|
|
|
2020-08-08 23:13:47 +03:00
|
|
|
const STYLES_PROFILE_IMAGE = css`
|
2020-08-08 03:10:28 +03:00
|
|
|
background-size: cover;
|
|
|
|
background-position: 50% 50%;
|
|
|
|
flex-shrink: 0;
|
|
|
|
height: 32px;
|
|
|
|
width: 32px;
|
|
|
|
border-radius: 32px;
|
|
|
|
margin-right: 16px;
|
2020-08-22 02:36:14 +03:00
|
|
|
margin-left: 4px;
|
2020-08-08 03:10:28 +03:00
|
|
|
`;
|
|
|
|
|
2020-04-09 00:29:13 +03:00
|
|
|
const STYLES_EXPANDER = css`
|
|
|
|
flex-shrink: 0;
|
2020-08-08 23:13:47 +03:00
|
|
|
|
2020-08-09 01:04:17 +03:00
|
|
|
@media (max-width: ${Constants.sizes.mobile}px) {
|
2020-08-08 23:13:47 +03:00
|
|
|
display: none;
|
|
|
|
}
|
2020-04-09 00:29:13 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
const STYLES_ICON = css`
|
|
|
|
flex-shrink: 0;
|
|
|
|
position: relative;
|
|
|
|
`;
|
|
|
|
|
2020-08-08 23:13:47 +03:00
|
|
|
// NOTE(jim): Adjusts on mobile.
|
2020-04-09 00:29:13 +03:00
|
|
|
const STYLES_CHILDREN = css`
|
|
|
|
min-width: 10%;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
overflow-wrap: break-word;
|
|
|
|
padding: 11px 0px 14px 8px;
|
2020-07-02 11:24:14 +03:00
|
|
|
font-family: ${Constants.font.semiBold};
|
2020-04-09 00:29:13 +03:00
|
|
|
font-weight: 400;
|
|
|
|
font-size: 14px;
|
|
|
|
line-height: 1.225;
|
|
|
|
position: relative;
|
|
|
|
display: flex;
|
|
|
|
align-items: flex-start;
|
|
|
|
justify-content: flex-start;
|
2020-08-08 23:13:47 +03:00
|
|
|
|
2020-08-09 01:04:17 +03:00
|
|
|
@media (max-width: ${Constants.sizes.mobile}px) {
|
2020-08-08 23:13:47 +03:00
|
|
|
display: none;
|
|
|
|
}
|
2020-04-09 00:29:13 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
const STYLES_ICON_ELEMENT = css`
|
|
|
|
height: 40px;
|
|
|
|
width: 40px;
|
|
|
|
display: inline-flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
user-select: none;
|
|
|
|
|
|
|
|
svg {
|
|
|
|
transform: rotate(0deg);
|
|
|
|
transition: 200ms ease transform;
|
|
|
|
}
|
2020-08-08 23:13:47 +03:00
|
|
|
|
2020-08-09 01:04:17 +03:00
|
|
|
@media (max-width: ${Constants.sizes.mobile}px) {
|
2020-08-22 02:36:14 +03:00
|
|
|
margin: 0 8px 0 12px;
|
2020-08-08 23:13:47 +03:00
|
|
|
}
|
2020-04-09 00:29:13 +03:00
|
|
|
`;
|
|
|
|
|
2020-08-26 11:08:17 +03:00
|
|
|
const Item = (props) => {
|
2020-04-09 00:29:13 +03:00
|
|
|
return (
|
2020-08-18 22:28:33 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_NAVIGATION_ITEM}
|
2020-08-26 11:08:17 +03:00
|
|
|
style={{ padding: `0 0 0 ${props.level * 16}px` }}
|
2020-08-18 22:28:33 +03:00
|
|
|
>
|
2020-08-26 11:08:17 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_EXPANDER}
|
|
|
|
onClick={props.onToggleShow ? props.onToggleShow : null}
|
|
|
|
>
|
2020-04-09 00:29:13 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_ICON_ELEMENT}
|
|
|
|
style={{
|
2020-08-26 11:08:17 +03:00
|
|
|
color: props.activeIds[props.id] ? Constants.system.brand : null,
|
2020-08-18 22:28:33 +03:00
|
|
|
}}
|
|
|
|
>
|
2020-08-26 11:08:17 +03:00
|
|
|
{props.treeChildren && props.treeChildren.length ? (
|
2020-08-18 22:28:33 +03:00
|
|
|
<SVG.ExpandArrow
|
|
|
|
height="8px"
|
2020-08-26 11:08:17 +03:00
|
|
|
style={props.expanded ? { transform: `rotate(90deg)` } : null}
|
2020-08-18 22:28:33 +03:00
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
) : null}
|
|
|
|
</span>
|
|
|
|
</span>
|
2020-08-26 11:08:17 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_ICON}
|
|
|
|
onClick={() => props.onNavigateTo({ id: props.id }, props.data)}
|
|
|
|
>
|
2020-04-09 00:29:13 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_ICON_ELEMENT}
|
2020-08-26 11:08:17 +03:00
|
|
|
children={IconMap[props.decorator]}
|
2020-04-09 00:29:13 +03:00
|
|
|
style={{
|
2020-08-26 11:08:17 +03:00
|
|
|
color: props.activeIds[props.id] ? Constants.system.brand : null,
|
2020-08-18 22:28:33 +03:00
|
|
|
}}
|
2020-08-26 11:08:17 +03:00
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
</span>
|
|
|
|
<span
|
|
|
|
css={STYLES_CHILDREN}
|
2020-08-26 11:08:17 +03:00
|
|
|
children={props.children}
|
|
|
|
onClick={() => props.onNavigateTo({ id: props.id }, props.data)}
|
2020-04-09 00:29:13 +03:00
|
|
|
style={{
|
2020-08-26 11:08:17 +03:00
|
|
|
color: props.activeIds[props.id] ? Constants.system.brand : null,
|
2020-08-18 22:28:33 +03:00
|
|
|
}}
|
2020-08-26 11:08:17 +03:00
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
</span>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
class NodeReference extends React.Component {
|
2020-08-26 11:08:17 +03:00
|
|
|
static defaultProps = {
|
|
|
|
treeChildren: [],
|
|
|
|
};
|
|
|
|
|
2020-04-09 00:29:13 +03:00
|
|
|
state = {
|
|
|
|
showTreeChildren: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
_handleToggleShow = () => {
|
|
|
|
this.setState({ showTreeChildren: !this.state.showTreeChildren });
|
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<React.Fragment>
|
|
|
|
<Item
|
2020-08-26 11:08:17 +03:00
|
|
|
id={this.props.id}
|
|
|
|
data={this.props.data}
|
|
|
|
activeId={this.props.activeId}
|
|
|
|
activeIds={this.props.activeIds}
|
|
|
|
level={this.props.level}
|
|
|
|
treeChildren={this.props.treeChildren}
|
|
|
|
onNavigateTo={this.props.onNavigateTo}
|
|
|
|
decorator={this.props.decorator}
|
|
|
|
onToggleShow={this._handleToggleShow}
|
|
|
|
expanded={this.state.showTreeChildren}
|
|
|
|
children={this.props.children}
|
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
|
2020-08-26 11:08:17 +03:00
|
|
|
{this.state.showTreeChildren
|
|
|
|
? this.props.treeChildren.map((child) => {
|
|
|
|
if (!child || child.ignore) {
|
2020-04-09 00:29:13 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<NodeReference
|
2020-08-26 11:08:17 +03:00
|
|
|
key={child.id}
|
2020-04-09 00:29:13 +03:00
|
|
|
data={child}
|
|
|
|
id={child.id}
|
2020-08-26 11:08:17 +03:00
|
|
|
activeId={this.props.activeId}
|
|
|
|
activeIds={this.props.activeIds}
|
|
|
|
onNavigateTo={this.props.onNavigateTo}
|
|
|
|
level={this.props.level + 1}
|
2020-04-09 00:29:13 +03:00
|
|
|
treeChildren={child.children}
|
2020-08-18 22:28:33 +03:00
|
|
|
decorator={child.decorator}
|
2020-08-26 11:08:17 +03:00
|
|
|
children={child.name}
|
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
);
|
|
|
|
})
|
|
|
|
: null}
|
|
|
|
</React.Fragment>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default class ApplicationNavigation extends React.Component {
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<nav css={STYLES_NAVIGATION}>
|
2020-08-08 03:10:28 +03:00
|
|
|
<div css={STYLES_NAVIGATION_HEADER}>
|
2020-08-18 22:28:33 +03:00
|
|
|
<a
|
|
|
|
css={STYLES_PROFILE}
|
2020-08-25 05:31:42 +03:00
|
|
|
style={{ marginRight: 16 }}
|
2020-08-18 22:28:33 +03:00
|
|
|
href={`/${this.props.viewer.username}`}
|
|
|
|
target="_blank"
|
|
|
|
>
|
2020-08-08 23:44:27 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_PROFILE_IMAGE}
|
|
|
|
style={{
|
|
|
|
backgroundImage: `url('${this.props.viewer.data.photo}')`,
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
{this.props.viewer.username}
|
|
|
|
</a>
|
2020-08-25 05:31:42 +03:00
|
|
|
<ApplicationControlMenu
|
|
|
|
onNavigateTo={this.props.onNavigateTo}
|
|
|
|
onAction={this.props.onAction}
|
|
|
|
onSignOut={this.props.onSignOut}
|
|
|
|
/>
|
2020-08-08 03:10:28 +03:00
|
|
|
</div>
|
2020-08-26 13:03:39 +03:00
|
|
|
|
2020-04-09 00:29:13 +03:00
|
|
|
{this.props.navigation.map((each) => {
|
2020-08-26 11:08:17 +03:00
|
|
|
if (!each || each.ignore) {
|
2020-04-09 00:29:13 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<NodeReference
|
|
|
|
data={each}
|
|
|
|
id={each.id}
|
|
|
|
acitveId={this.props.activeId}
|
|
|
|
activeIds={this.props.activeIds}
|
|
|
|
key={each.id}
|
|
|
|
onNavigateTo={this.props.onNavigateTo}
|
|
|
|
level={0}
|
|
|
|
treeChildren={each.children}
|
2020-08-18 22:28:33 +03:00
|
|
|
decorator={each.decorator}
|
2020-08-26 11:08:17 +03:00
|
|
|
children={each.name}
|
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
);
|
|
|
|
})}
|
|
|
|
</nav>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|