Standalone sketch list and asset page
This commit is contained in:
parent
1b461d33cf
commit
0193ee8297
9 changed files with 241 additions and 31 deletions
|
@ -29,8 +29,6 @@ import * as ToastActions from '../actions/toast';
|
||||||
import * as ConsoleActions from '../actions/console';
|
import * as ConsoleActions from '../actions/console';
|
||||||
import { getHTMLFile } from '../reducers/files';
|
import { getHTMLFile } from '../reducers/files';
|
||||||
import Overlay from '../../App/components/Overlay';
|
import Overlay from '../../App/components/Overlay';
|
||||||
import SketchList from '../components/SketchList';
|
|
||||||
import AssetList from '../components/AssetList';
|
|
||||||
import About from '../components/About';
|
import About from '../components/About';
|
||||||
import Feedback from '../components/Feedback';
|
import Feedback from '../components/Feedback';
|
||||||
|
|
||||||
|
@ -365,30 +363,6 @@ class IDEView extends React.Component {
|
||||||
createFolder={this.props.createFolder}
|
createFolder={this.props.createFolder}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{ this.props.location.pathname.match(/sketches$/) &&
|
|
||||||
<Overlay
|
|
||||||
ariaLabel="project list"
|
|
||||||
title="Open a Sketch"
|
|
||||||
previousPath={this.props.ide.previousPath}
|
|
||||||
>
|
|
||||||
<SketchList
|
|
||||||
username={this.props.params.username}
|
|
||||||
user={this.props.user}
|
|
||||||
/>
|
|
||||||
</Overlay>
|
|
||||||
}
|
|
||||||
{ this.props.location.pathname.match(/assets$/) &&
|
|
||||||
<Overlay
|
|
||||||
title="Assets"
|
|
||||||
ariaLabel="asset list"
|
|
||||||
previousPath={this.props.ide.previousPath}
|
|
||||||
>
|
|
||||||
<AssetList
|
|
||||||
username={this.props.params.username}
|
|
||||||
user={this.props.user}
|
|
||||||
/>
|
|
||||||
</Overlay>
|
|
||||||
}
|
|
||||||
{ this.props.location.pathname === '/about' &&
|
{ this.props.location.pathname === '/about' &&
|
||||||
<Overlay
|
<Overlay
|
||||||
previousPath={this.props.ide.previousPath}
|
previousPath={this.props.ide.previousPath}
|
||||||
|
|
47
client/modules/User/components/DashboardTabSwitcher.jsx
Normal file
47
client/modules/User/components/DashboardTabSwitcher.jsx
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
|
const TabKey = {
|
||||||
|
assets: 'assets',
|
||||||
|
sketches: 'sketches',
|
||||||
|
};
|
||||||
|
|
||||||
|
const Tab = ({ children, isSelected, to }) => {
|
||||||
|
const selectedClassName = 'dashboard-header__tab--selected';
|
||||||
|
|
||||||
|
const location = { pathname: to, state: { skipSavingPath: true } };
|
||||||
|
const content = isSelected ? children : <Link to={location}>{children}</Link>;
|
||||||
|
return (
|
||||||
|
<li className={`dashboard-header__tab ${isSelected && selectedClassName}`}>
|
||||||
|
<h4 className="dashboard-header__tab__title">
|
||||||
|
{content}
|
||||||
|
</h4>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Tab.propTypes = {
|
||||||
|
children: PropTypes.element.isRequired,
|
||||||
|
isSelected: PropTypes.bool.isRequired,
|
||||||
|
to: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
const DashboardTabSwitcher = ({ currentTab, isOwner, username }) => {
|
||||||
|
return (
|
||||||
|
<ul className="dashboard-header__switcher">
|
||||||
|
<div className="dashboard-header__tabs">
|
||||||
|
<Tab to={`/${username}/sketches`} isSelected={currentTab === 'sketches'}>Sketches</Tab>
|
||||||
|
{isOwner && <Tab to={`/${username}/assets`} isSelected={currentTab === 'assets'}>Assets</Tab>}
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardTabSwitcher.propTypes = {
|
||||||
|
currentTab: PropTypes.string.isRequired,
|
||||||
|
isOwner: PropTypes.bool.isRequired,
|
||||||
|
username: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export { DashboardTabSwitcher as default, TabKey };
|
123
client/modules/User/pages/DashboardView.jsx
Normal file
123
client/modules/User/pages/DashboardView.jsx
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
import { browserHistory, Link } from 'react-router';
|
||||||
|
import { Helmet } from 'react-helmet';
|
||||||
|
import { updateSettings, initiateVerification, createApiKey, removeApiKey } from '../actions';
|
||||||
|
import NavBasic from '../../../components/NavBasic';
|
||||||
|
|
||||||
|
import AssetList from '../../IDE/components/AssetList';
|
||||||
|
import SketchList from '../../IDE/components/SketchList';
|
||||||
|
|
||||||
|
import DashboardTabSwitcher, { TabKey } from '../components/DashboardTabSwitcher';
|
||||||
|
|
||||||
|
class DashboardView extends React.Component {
|
||||||
|
static defaultProps = {
|
||||||
|
user: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.closeAccountPage = this.closeAccountPage.bind(this);
|
||||||
|
this.gotoHomePage = this.gotoHomePage.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
document.body.className = this.props.theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeAccountPage() {
|
||||||
|
browserHistory.push(this.props.previousPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
gotoHomePage() {
|
||||||
|
browserHistory.push('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedTabName() {
|
||||||
|
const path = this.props.location.pathname;
|
||||||
|
|
||||||
|
if (/assets/.test(path)) {
|
||||||
|
return TabKey.assets;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TabKey.sketches;
|
||||||
|
}
|
||||||
|
|
||||||
|
ownerName() {
|
||||||
|
if (this.props.params.username) {
|
||||||
|
return this.props.params.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.props.user.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
isOwner() {
|
||||||
|
return this.props.user.username === this.props.params.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationItem() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const currentTab = this.selectedTabName();
|
||||||
|
const isOwner = this.isOwner();
|
||||||
|
const { username } = this.props.params;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="dashboard">
|
||||||
|
<Helmet>
|
||||||
|
<title>p5.js Web Editor | Account</title>
|
||||||
|
</Helmet>
|
||||||
|
|
||||||
|
<NavBasic onBack={this.closeAccountPage} />
|
||||||
|
|
||||||
|
<section className="dashboard-header">
|
||||||
|
<div className="dashboard-header__header">
|
||||||
|
<h2 className="dashboard-header__header__title">{this.ownerName()}</h2>
|
||||||
|
|
||||||
|
<DashboardTabSwitcher currentTab={currentTab} isOwner={isOwner} username={username} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="dashboard-content">
|
||||||
|
{
|
||||||
|
currentTab === TabKey.sketches ? <SketchList username={username} /> : <AssetList username={username} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToProps(state) {
|
||||||
|
return {
|
||||||
|
previousPath: state.ide.previousPath,
|
||||||
|
user: state.user,
|
||||||
|
theme: state.preferences.theme
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapDispatchToProps(dispatch) {
|
||||||
|
return bindActionCreators({
|
||||||
|
updateSettings, initiateVerification, createApiKey, removeApiKey
|
||||||
|
}, dispatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
DashboardView.propTypes = {
|
||||||
|
location: PropTypes.shape({
|
||||||
|
pathname: PropTypes.string.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
params: PropTypes.shape({
|
||||||
|
username: PropTypes.string.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
previousPath: PropTypes.string.isRequired,
|
||||||
|
theme: PropTypes.string.isRequired,
|
||||||
|
user: PropTypes.shape({
|
||||||
|
username: PropTypes.string.isRequired,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(DashboardView);
|
|
@ -9,6 +9,7 @@ import ResetPasswordView from './modules/User/pages/ResetPasswordView';
|
||||||
import EmailVerificationView from './modules/User/pages/EmailVerificationView';
|
import EmailVerificationView from './modules/User/pages/EmailVerificationView';
|
||||||
import NewPasswordView from './modules/User/pages/NewPasswordView';
|
import NewPasswordView from './modules/User/pages/NewPasswordView';
|
||||||
import AccountView from './modules/User/pages/AccountView';
|
import AccountView from './modules/User/pages/AccountView';
|
||||||
|
import DashboardView from './modules/User/pages/DashboardView';
|
||||||
// import SketchListView from './modules/Sketch/pages/SketchListView';
|
// import SketchListView from './modules/Sketch/pages/SketchListView';
|
||||||
import { getUser } from './modules/User/actions';
|
import { getUser } from './modules/User/actions';
|
||||||
import { stopSketch } from './modules/IDE/actions/ide';
|
import { stopSketch } from './modules/IDE/actions/ide';
|
||||||
|
@ -35,11 +36,11 @@ const routes = store => (
|
||||||
<Route path="/projects/:project_id" component={IDEView} />
|
<Route path="/projects/:project_id" component={IDEView} />
|
||||||
<Route path="/:username/full/:project_id" component={FullView} />
|
<Route path="/:username/full/:project_id" component={FullView} />
|
||||||
<Route path="/full/:project_id" component={FullView} />
|
<Route path="/full/:project_id" component={FullView} />
|
||||||
<Route path="/sketches" component={IDEView} />
|
<Route path="/sketches" component={DashboardView} />
|
||||||
<Route path="/assets" component={IDEView} />
|
<Route path="/assets" component={DashboardView} />
|
||||||
<Route path="/account" component={AccountView} />
|
<Route path="/account" component={AccountView} />
|
||||||
<Route path="/:username/sketches/:project_id" component={IDEView} />
|
<Route path="/:username/sketches/:project_id" component={IDEView} />
|
||||||
<Route path="/:username/sketches" component={IDEView} />
|
<Route path="/:username/sketches" component={DashboardView} />
|
||||||
<Route path="/about" component={IDEView} />
|
<Route path="/about" component={IDEView} />
|
||||||
<Route path="/feedback" component={IDEView} />
|
<Route path="/feedback" component={IDEView} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
.asset-table {
|
.asset-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: #{10 / $base-font-size}rem #{20 / $base-font-size}rem;
|
padding: #{10 / $base-font-size}rem 0;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
& .asset-list__delete-column {
|
& .asset-list__delete-column {
|
||||||
|
@ -53,4 +53,5 @@
|
||||||
.asset-table__empty {
|
.asset-table__empty {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: #{16 / $base-font-size}rem;
|
font-size: #{16 / $base-font-size}rem;
|
||||||
|
padding: #{42 / $base-font-size}rem 0;
|
||||||
}
|
}
|
||||||
|
|
53
client/styles/components/_dashboard-header.scss
Normal file
53
client/styles/components/_dashboard-header.scss
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
.dashboard-header {
|
||||||
|
padding: 24px 66px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-header__tabs {
|
||||||
|
display: flex;
|
||||||
|
padding-top: #{24 / $base-font-size}rem;
|
||||||
|
padding-bottom: #{24 / $base-font-size}rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-header__tab {
|
||||||
|
@include themify() {
|
||||||
|
color: getThemifyVariable('inactive-text-color');
|
||||||
|
border-right: 2px solid getThemifyVariable('inactive-text-color');
|
||||||
|
|
||||||
|
padding: 0 13px;
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
color: getThemifyVariable('primary-text-color');
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
&:focus {
|
||||||
|
color: getThemifyVariable('primary-text-color');
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
font-size: #{21 / $base-font-size}rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.dashboard-header__tab:first-child {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-header__tab:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-header__tab--selected {
|
||||||
|
@include themify() {
|
||||||
|
color: getThemifyVariable('primary-text-color');
|
||||||
|
}
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-header__tab a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-header__tab__title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
.sketches-table {
|
.sketches-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: #{10 / $base-font-size}rem #{20 / $base-font-size}rem;
|
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
& .sketch-list__dropdown-column {
|
& .sketch-list__dropdown-column {
|
||||||
|
@ -106,4 +105,5 @@
|
||||||
.sketches-table__empty {
|
.sketches-table__empty {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: #{16 / $base-font-size}rem;
|
font-size: #{16 / $base-font-size}rem;
|
||||||
|
padding: #{42 / $base-font-size}rem 0;
|
||||||
}
|
}
|
||||||
|
|
9
client/styles/layout/_dashboard.scss
Normal file
9
client/styles/layout/_dashboard.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
.dashboard {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
@include themify() {
|
||||||
|
color: getThemifyVariable('primary-text-color');
|
||||||
|
background-color: getThemifyVariable('background-color');
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,7 +46,9 @@
|
||||||
@import 'components/loader';
|
@import 'components/loader';
|
||||||
@import 'components/uploader';
|
@import 'components/uploader';
|
||||||
@import 'components/tabs';
|
@import 'components/tabs';
|
||||||
|
@import 'components/dashboard-header';
|
||||||
|
|
||||||
|
@import 'layout/dashboard';
|
||||||
@import 'layout/ide';
|
@import 'layout/ide';
|
||||||
@import 'layout/fullscreen';
|
@import 'layout/fullscreen';
|
||||||
@import 'layout/user';
|
@import 'layout/user';
|
||||||
|
|
Loading…
Reference in a new issue