Skip to content

Commit 2cc137f

Browse files
author
Mat Brown
committed
Move remaining dashboard functionality into top bar hamburger menu
Moves the following from the dashboard into the hamburger menu: * Export gist * Export repo * Send feedback * Social links Dashboard is now entirely empty other than instructions.
1 parent 9b00652 commit 2cc137f

8 files changed

Lines changed: 192 additions & 160 deletions

File tree

locales/en/translation.json

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
{
22
"top-bar": {
33
"create-snapshot": "Snapshot",
4+
"export-gist": "Export Gist",
5+
"export-repo": "Export Repo",
46
"libraries": "Libraries",
57
"load-project": "My Projects",
68
"new-project": "New Project",
9+
"send-feedback": "Send Feedback",
710
"session": {
811
"log-in-prompt": "Log in to save",
912
"log-out-prompt": "Log out"
1013
}
1114
},
12-
"dashboard": {
13-
"menu": {
14-
"export-gist": "Export Gist",
15-
"send-feedback": "Send Feedback",
16-
"export-repo": "Export Repo"
17-
}
18-
},
1915
"editors": {
2016
"help-text": "Type in your $t(languages.{{language}}) code here."
2117
},

src/components/Dashboard.jsx

Lines changed: 16 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2,118 +2,32 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import remark from 'remark';
44
import remarkReact from 'remark-react';
5-
import {t} from 'i18next';
65
import classnames from 'classnames';
7-
import config from '../config';
86

9-
class Dashboard extends React.Component {
10-
_renderMenu() {
11-
let exportRepoButton;
12-
13-
if (this.props.isExperimental && this.props.currentUser.authenticated) {
14-
exportRepoButton = (
15-
<div
16-
className="dashboard__menu-item dashboard__menu-item_grid"
17-
onClick={this.props.onExportRepo}
18-
>
19-
{t('dashboard.menu.export-repo')}
20-
</div>
21-
);
22-
}
23-
24-
return (
25-
<div className="dashboard__menu dashboard__menu_grid">
26-
<div
27-
className={
28-
classnames(
29-
'dashboard__menu-item',
30-
'dashboard__menu-item_grid',
31-
{
32-
'dashboard__menu-item_spinner':
33-
this.props.gistExportInProgress,
34-
},
35-
)
36-
}
37-
onClick={this.props.onExportGist}
38-
>
39-
{t('dashboard.menu.export-gist')}
40-
</div>
41-
<a
42-
className="dashboard__menu-item dashboard__menu-item_grid"
43-
href={config.feedbackUrl}
44-
rel="noopener noreferrer"
45-
target="_blank"
46-
>
47-
{t('dashboard.menu.send-feedback')}
48-
</a>
49-
{exportRepoButton}
50-
</div>
51-
);
7+
function Dashboard({instructions, isOpen}) {
8+
if (!isOpen) {
9+
return null;
5210
}
5311

54-
_renderLinks() {
55-
return (
56-
<div className="dashboard__links">
57-
<a
58-
className="dashboard__link u__icon"
59-
href="https://github.com/popcodeorg/popcode"
60-
rel="noopener noreferrer"
61-
target="_blank"
62-
>&#xf09b;</a>
63-
<a
64-
className="dashboard__link u__icon"
65-
href="https://twitter.com/popcodeorg"
66-
rel="noopener noreferrer"
67-
target="_blank"
68-
>&#xf099;</a>
69-
<a
70-
className="dashboard__link u__icon"
71-
href="https://slack.popcode.org/"
72-
rel="noopener noreferrer"
73-
target="_blank"
74-
>&#xf198;</a>
12+
const sidebarClassnames = classnames(
13+
'layout__dashboard',
14+
'dashboard',
15+
'u__flex-container',
16+
'u__flex-container_column',
17+
);
18+
19+
return (
20+
<div className={sidebarClassnames}>
21+
<div className="dashboard__instructions">
22+
{remark().use(remarkReact).processSync(instructions).contents}
7523
</div>
76-
);
77-
}
78-
79-
render() {
80-
const {instructions, isOpen} = this.props;
81-
if (!isOpen) {
82-
return null;
83-
}
84-
85-
const sidebarClassnames = classnames(
86-
'layout__dashboard',
87-
'dashboard',
88-
'u__flex-container',
89-
'u__flex-container_column',
90-
);
91-
92-
return (
93-
<div className={sidebarClassnames}>
94-
{this._renderMenu()}
95-
<div className="dashboard__instructions">
96-
{remark().use(remarkReact).processSync(instructions).contents}
97-
</div>
98-
<div className="dashboard__spacer" />
99-
{this._renderLinks()}
100-
</div>
101-
);
102-
}
24+
</div>
25+
);
10326
}
10427

10528
Dashboard.propTypes = {
106-
currentUser: PropTypes.object.isRequired,
107-
gistExportInProgress: PropTypes.bool.isRequired,
10829
instructions: PropTypes.string.isRequired,
109-
isExperimental: PropTypes.bool.isRequired,
11030
isOpen: PropTypes.bool.isRequired,
111-
onExportGist: PropTypes.func.isRequired,
112-
onExportRepo: PropTypes.func.isRequired,
113-
};
114-
115-
Dashboard.defaultProps = {
116-
currentProject: null,
11731
};
11832

11933
export default Dashboard;
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import classnames from 'classnames';
2+
import {noop} from 'lodash/noop';
3+
import {t} from 'i18next';
4+
import PropTypes from 'prop-types';
5+
import React from 'react';
6+
import config from '../../config';
7+
8+
export default function HamburgerMenu({
9+
isExperimental,
10+
isGistExportInProgress,
11+
isOpen,
12+
isUserAuthenticated,
13+
onExportGist,
14+
onExportRepo,
15+
}) {
16+
if (!isOpen) {
17+
return null;
18+
}
19+
20+
21+
return (
22+
<div className="top-bar__menu">
23+
<div
24+
className="top-bar__menu-item"
25+
onClick={isGistExportInProgress ? noop : onExportGist}
26+
>
27+
{t('top-bar.export-gist')}
28+
</div>
29+
<div
30+
className={
31+
classnames(
32+
'top-bar__menu-item',
33+
{u__hidden: !(isUserAuthenticated && isExperimental)},
34+
)
35+
}
36+
onClick={onExportRepo}
37+
>
38+
{t('top-bar.export-repo')}
39+
</div>
40+
<a
41+
className="top-bar__menu-item"
42+
href={config.feedbackUrl}
43+
rel="noopener noreferrer"
44+
target="blank"
45+
>
46+
{t('top-bar.send-feedback')}
47+
</a>
48+
<div className="top-bar__menu-item top-bar__menu-item_icons">
49+
<a
50+
className="u__icon"
51+
href="https://github.com/popcodeorg/popcode"
52+
rel="noopener noreferrer"
53+
target="_blank"
54+
>&#xf09b;</a>
55+
<a
56+
className="u__icon"
57+
href="https://twitter.com/popcodeorg"
58+
rel="noopener noreferrer"
59+
target="_blank"
60+
>&#xf099;</a>
61+
<a
62+
className="u__icon"
63+
href="https://slack.popcode.org/"
64+
rel="noopener noreferrer"
65+
target="_blank"
66+
>&#xf198;</a>
67+
</div>
68+
</div>
69+
);
70+
}
71+
72+
HamburgerMenu.propTypes = {
73+
isExperimental: PropTypes.bool.isRequired,
74+
isGistExportInProgress: PropTypes.bool.isRequired,
75+
isOpen: PropTypes.bool.isRequired,
76+
isUserAuthenticated: PropTypes.bool.isRequired,
77+
onExportGist: PropTypes.func.isRequired,
78+
onExportRepo: PropTypes.func.isRequired,
79+
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import classnames from 'classnames';
2+
import React from 'react';
3+
import PropTypes from 'prop-types';
4+
import HamburgerMenu from './HamburgerMenu';
5+
6+
export default function HamburgerMenuButton({
7+
isExperimental,
8+
isGistExportInProgress,
9+
isOpen,
10+
isUserAuthenticated,
11+
onClick,
12+
onExportGist,
13+
onExportRepo,
14+
}) {
15+
return (
16+
<div
17+
className={classnames(
18+
'top-bar__menu-button',
19+
'top-bar__menu-button_hamburger',
20+
{'top-bar__menu-button_active': isOpen},
21+
)}
22+
onClick={onClick}
23+
>
24+
<span className="u__icon top-bar__hamburger">&#xf0c9;</span>
25+
<HamburgerMenu
26+
isExperimental={isExperimental}
27+
isGistExportInProgress={isGistExportInProgress}
28+
isOpen={isOpen}
29+
isUserAuthenticated={isUserAuthenticated}
30+
onExportGist={onExportGist}
31+
onExportRepo={onExportRepo}
32+
/>
33+
</div>
34+
);
35+
}
36+
37+
HamburgerMenuButton.propTypes = {
38+
isExperimental: PropTypes.bool.isRequired,
39+
isGistExportInProgress: PropTypes.bool.isRequired,
40+
isOpen: PropTypes.bool.isRequired,
41+
isUserAuthenticated: PropTypes.bool.isRequired,
42+
onClick: PropTypes.func.isRequired,
43+
onExportGist: PropTypes.func.isRequired,
44+
onExportRepo: PropTypes.func.isRequired,
45+
};

src/components/TopBar/index.jsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import partial from 'lodash/partial';
55
import Wordmark from '../../static/images/wordmark.svg';
66
import Pop from '../Pop';
77
import CurrentUser from './CurrentUser';
8+
import HamburgerMenuButton from './HamburgerMenuButton';
89
import LibraryPickerButton from './LibraryPickerButton';
910
import NewProjectButton from './NewProjectButton';
1011
import ProjectsButton from './ProjectsButton';
@@ -28,18 +29,20 @@ export default function TopBar({
2829
currentProjectKey,
2930
currentUser,
3031
enabledLibraries,
31-
isHamburgerMenuActive,
32+
isExperimental,
33+
isGistExportInProgress,
3234
isUserAuthenticated,
3335
isUserTyping,
3436
isSnapshotInProgress,
3537
isTextSizeLarge,
3638
openMenu,
3739
projectKeys,
3840
validationState,
39-
onClickHamburgerMenu,
4041
onClickMenu,
4142
onCreateNewProject,
4243
onCreateSnapshot,
44+
onExportGist,
45+
onExportRepo,
4346
onLibraryToggled,
4447
onLogOut,
4548
onStartLogIn,
@@ -49,16 +52,15 @@ export default function TopBar({
4952

5053
return (
5154
<div className={classnames('top-bar', modifier)}>
52-
<div
53-
className={classnames(
54-
'top-bar__hamburger',
55-
'u__icon',
56-
{'top-bar__hamburger_active': isHamburgerMenuActive},
57-
)}
58-
onClick={onClickHamburgerMenu}
59-
>
60-
&#xf0c9;
61-
</div>
55+
<HamburgerMenuButton
56+
isExperimental={isExperimental}
57+
isGistExportInProgress={isGistExportInProgress}
58+
isOpen={openMenu === 'hamburger'}
59+
isUserAuthenticated={isUserAuthenticated}
60+
onClick={partial(onClickMenu, 'hamburger')}
61+
onExportGist={onExportGist}
62+
onExportRepo={onExportRepo}
63+
/>
6264
<div className="top-bar__logo-container">
6365
<Pop variant={popVariant} />
6466
</div>
@@ -101,18 +103,20 @@ TopBar.propTypes = {
101103
currentProjectKey: PropTypes.string,
102104
currentUser: PropTypes.object.isRequired,
103105
enabledLibraries: PropTypes.arrayOf(PropTypes.string).isRequired,
104-
isHamburgerMenuActive: PropTypes.bool.isRequired,
106+
isExperimental: PropTypes.bool.isRequired,
107+
isGistExportInProgress: PropTypes.bool.isRequired,
105108
isSnapshotInProgress: PropTypes.bool.isRequired,
106109
isTextSizeLarge: PropTypes.bool.isRequired,
107110
isUserAuthenticated: PropTypes.bool.isRequired,
108111
isUserTyping: PropTypes.bool.isRequired,
109112
openMenu: PropTypes.string,
110113
projectKeys: PropTypes.arrayOf(PropTypes.string).isRequired,
111114
validationState: PropTypes.string.isRequired,
112-
onClickHamburgerMenu: PropTypes.func.isRequired,
113115
onClickMenu: PropTypes.func.isRequired,
114116
onCreateNewProject: PropTypes.func.isRequired,
115117
onCreateSnapshot: PropTypes.func.isRequired,
118+
onExportGist: PropTypes.func.isRequired,
119+
onExportRepo: PropTypes.func.isRequired,
116120
onLibraryToggled: PropTypes.func.isRequired,
117121
onLogOut: PropTypes.func.isRequired,
118122
onStartLogIn: PropTypes.func.isRequired,

0 commit comments

Comments
 (0)