link settings and projects

This commit is contained in:
Sérgio Ramos 2016-12-15 14:10:36 +00:00
parent 1f62fa5fd5
commit 297c15db98
15 changed files with 347 additions and 119 deletions

View File

@ -1,4 +1,9 @@
{ {
"your-dashboard": "Your Dashboard", "your-dashboard": "Your Dashboard",
"welcome-to": "Welcome to" "settings": "Settings",
"projects": "Projects",
"people": "People",
"no-personal-projects": "You don't have any personal projects at the moment.",
"create-new": "Create new",
"your-settings": "Your settings"
} }

View File

@ -1,4 +1,9 @@
{ {
"your-dashboard": "O seu painel", "your-dashboard": "O seu painel",
"welcome-to": "Bem vindo a" "settings": "Preferências",
"projects": "Projectos",
"people": "Pessoas",
"no-personal-projects": "No momento não tem projectos pessoais",
"create-new": "Criar novo",
"your-settings": "As suas preferências"
} }

View File

@ -23,6 +23,7 @@
"express": "^4.14.0", "express": "^4.14.0",
"inherits": "^2.0.3", "inherits": "^2.0.3",
"locale": "^0.1.0", "locale": "^0.1.0",
"lodash.isempty": "^4.4.0",
"lodash.template": "^4.4.0", "lodash.template": "^4.4.0",
"lodash.uniq": "^4.5.0", "lodash.uniq": "^4.5.0",
"param-case": "^2.1.0", "param-case": "^2.1.0",

View File

@ -72,7 +72,7 @@ module.exports = (props) => {
<App {...props}> <App {...props}>
<Header /> <Header />
<Article> <Article>
<Match component={Home} pattern='/' /> <Match component={Home} pattern='/:org?/:section?' />
<Miss component={NotFound} /> <Miss component={NotFound} />
</Article> </Article>
<Footer /> <Footer />

View File

@ -1,38 +1,72 @@
const React = require('react'); const React = require('react');
const ReactIntl = require('react-intl'); const ReactIntl = require('react-intl');
// const ReactRedux = require('react-redux'); const ReactRedux = require('react-redux');
// const ReactRouter = require('react-router'); const ReactRouter = require('react-router');
// const Styled = require('styled-components');
const H1 = require('@ui/components/h1');
const Li = require('@ui/components/horizontal-list/li');
const Redirect = require('@components/redirect');
const Ul = require('@ui/components/horizontal-list/ul');
const Projects = require('./projects');
const Settings = require('./settings');
// const fns = require('@ui/shared/functions');
//
const { const {
FormattedMessage FormattedMessage
} = ReactIntl; } = ReactIntl;
//
// const {
// connect
// } = ReactRedux;
// const { const {
// Link, connect
// Match } = ReactRedux;
// } = ReactRouter;
// const { const {
// default: styled Link,
// } = Styled; Match,
// Miss
// const { } = ReactRouter;
// remcalc
// } = fns;
const Dashboard = (props) => { const Dashboard = ({
pathname = '',
user = {}
}) => {
return ( return (
<h1> <div>
<FormattedMessage id='your-dashboard' /> <H1>
</h1> <FormattedMessage id='your-dashboard' />
</H1>
<Ul>
<Li>
<Link activeClassName='active' to={`/${user.id}/projects`}>
<FormattedMessage id='projects' />
</Link>
</Li>
<Li>
<Link activeClassName='active' to={`/${user.id}/settings`}>
<FormattedMessage id='settings' />
</Link>
</Li>
</Ul>
<Match component={Projects} pattern={`/${user.id}/projects`} />
<Match component={Settings} pattern={`/${user.id}/settings`} />
<Miss component={Redirect(`/${user.id}/projects`)} />
</div>
); );
}; };
module.exports = Dashboard; Dashboard.propTypes = {
pathname: React.PropTypes.string,
user: React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string
})
};
const mapStateToProps = (state) => ({
projects: state.session.data.projects,
user: {
id: state.session.data.name,
name: state.session.data.name
}
});
module.exports = connect(mapStateToProps)(Dashboard);

View File

@ -0,0 +1,13 @@
const ReactRedux = require('react-redux');
const Projects = require('@components/projects');
const {
connect
} = ReactRedux;
const mapStateToProps = (state) => ({
projects: state.session.data.projects
});
module.exports = connect(mapStateToProps)(Projects);

View File

@ -0,0 +1,43 @@
const React = require('react');
const ReactIntl = require('react-intl');
const ReactRedux = require('react-redux');
// const ReactRouter = require('react-router');
//
const Column = require('@ui/components/column');
// const Button = require('@ui/components/button');
const Row = require('@ui/components/row');
const {
FormattedMessage
} = ReactIntl;
const {
connect
} = ReactRedux;
// const {
// Link,
// Match,
// Miss,
// Redirect
// } = ReactRouter;
const Settings = () => {
return (
<Row>
<Column xs={12}>
<FormattedMessage id='your-settings' />
</Column>
</Row>
);
};
Settings.propTypes = {
Settings: React.PropTypes.array
};
const mapStateToProps = (state) => ({
Settings: state.session.data.Settings
});
module.exports = connect(mapStateToProps)(Settings);

View File

@ -1,4 +1,3 @@
const paramCase = require('param-case');
const React = require('react'); const React = require('react');
const ReactIntl = require('react-intl'); const ReactIntl = require('react-intl');
const ReactRedux = require('react-redux'); const ReactRedux = require('react-redux');
@ -7,8 +6,10 @@ const Styled = require('styled-components');
const Container = require('@ui/components/container'); const Container = require('@ui/components/container');
const Dashboard = require('@containers/dashboard'); const Dashboard = require('@containers/dashboard');
const fns = require('@ui/shared/functions'); const Li = require('@ui/components/horizontal-list/li');
const Org = require('@containers/org'); const Org = require('@containers/org');
const Redirect = require('@components/redirect');
const Ul = require('@ui/components/horizontal-list/ul');
const { const {
FormattedMessage FormattedMessage
@ -20,63 +21,35 @@ const {
const { const {
Link, Link,
Match Match,
Miss
} = ReactRouter; } = ReactRouter;
const { const {
default: styled default: styled
} = Styled; } = Styled;
const {
remcalc
} = fns;
const StyledNav = styled.div` const StyledNav = styled.div`
background-color: #f2f2f2; background-color: #f2f2f2;
`; `;
const StyledUl = styled.ul`
list-style-type: none;
`;
const StyledLi = styled.li`
display: inline-block;
margin-right: ${remcalc(10)};
padding-top: ${remcalc(10)};
padding-bottom: ${remcalc(10)};
& a.active {
cursor: default;
color: #373A3C;
text-decoration: none;
}
`;
const Home = ({ const Home = ({
orgs = [], orgs = [],
pathname = '/' pathname = '/',
user = {}
}) => { }) => {
const parent = pathname.replace(/\/$/, '');
const links = orgs.map((org) => `${parent}/${paramCase(org.name)}`);
const isDashboardActive = (location) => {
return !links.some((link) => location.pathname.indexOf(link) >= 0);
};
const navLinks = orgs.map(({ const navLinks = orgs.map(({
id,
name name
}) => { }) => {
const to = `${parent}/${paramCase(name)}`; const to = `/${id}`;
return ( return (
<StyledLi key={to}> <Li key={to}>
<Link <Link activeClassName='active' to={to}>
activeClassName='active'
to={to}
>
{name} {name}
</Link> </Link>
</StyledLi> </Li>
); );
}); });
@ -84,30 +57,20 @@ const Home = ({
<div> <div>
<StyledNav> <StyledNav>
<Container> <Container>
<StyledUl> <Ul>
<StyledLi key={pathname}> <Li key={pathname}>
<Link <Link activeClassName='active' to={`/${user.id}`}>
activeClassName='active'
isActive={isDashboardActive}
to={pathname}
>
<FormattedMessage id='your-dashboard' /> <FormattedMessage id='your-dashboard' />
</Link> </Link>
</StyledLi> </Li>
{navLinks} {navLinks}
</StyledUl> </Ul>
</Container> </Container>
</StyledNav> </StyledNav>
<Container> <Container>
<Match <Match component={Dashboard} pattern={`/${user.id}/:section?`} />
exactly <Match component={Org} pattern='/:org' />
pattern={parent} <Miss component={Redirect(`/${user.id}`)} />
render={Dashboard}
/>
<Match
component={Org}
pattern={`${parent}/:org`}
/>
</Container> </Container>
</div> </div>
); );
@ -115,13 +78,22 @@ const Home = ({
Home.propTypes = { Home.propTypes = {
orgs: React.PropTypes.arrayOf(React.PropTypes.shape({ orgs: React.PropTypes.arrayOf(React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string name: React.PropTypes.string
})), })),
pathname: React.PropTypes.string pathname: React.PropTypes.string,
user: React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string
})
}; };
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
orgs: state.session.data.orgs orgs: state.session.data.orgs,
user: {
id: state.session.data.name,
name: state.session.data.name
}
}); });
module.exports = connect(mapStateToProps)(Home); module.exports = connect(mapStateToProps)(Home);

View File

@ -1,48 +1,99 @@
const isEmpty = require('lodash.isempty');
const React = require('react'); const React = require('react');
const ReactIntl = require('react-intl'); const ReactIntl = require('react-intl');
// const ReactRedux = require('react-redux'); const ReactRedux = require('react-redux');
// const ReactRouter = require('react-router'); const ReactRouter = require('react-router');
// const Styled = require('styled-components');
// const H1 = require('@ui/components/h1');
// const Container = require('@ui/components/container'); const Li = require('@ui/components/horizontal-list/li');
// const fns = require('@ui/shared/functions'); const Ul = require('@ui/components/horizontal-list/ul');
//
const NotFound = require('@containers/not-found');
const People = require('./people');
const Projects = require('./projects');
const Settings = require('./settings');
const { const {
FormattedMessage FormattedMessage
} = ReactIntl; } = ReactIntl;
//
// const { const {
// connect connect
// } = ReactRedux; } = ReactRedux;
//
// const { const {
// Link, Link,
// Match Match,
// } = ReactRouter; Miss,
// Redirect
// const { } = ReactRouter;
// default: styled
// } = Styled;
//
// const {
// remcalc
// } = fns;
const Org = ({ const Org = ({
params org = {},
params = {},
user = {}
}) => { }) => {
if (user.id === params.org) {
return null;
}
if (isEmpty(org)) {
return (
<NotFound />
);
}
return ( return (
<h1> <div>
<FormattedMessage id='welcome-to' /> <H1>{org.name}</H1>
<span> {params.org}</span> <Ul>
</h1> <Li>
<Link activeClassName='active' to={`/${org.id}/projects`}>
<FormattedMessage id='projects' />
</Link>
</Li>
<Li>
<Link activeClassName='active' to={`/${org.id}/people`}>
<FormattedMessage id='people' />
</Link>
</Li>
<Li>
<Link activeClassName='active' to={`/${org.id}/settings`}>
<FormattedMessage id='settings' />
</Link>
</Li>
</Ul>
<Match component={Projects} pattern='/:org/projects' />
<Match component={People} pattern='/:org/people' />
<Match component={Settings} pattern='/:org/settings' />
<Miss component={Redirect(`/${org.id}/projects`)} />
</div>
); );
}; };
Org.propTypes = { Org.propTypes = {
org: React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string
}),
params: React.PropTypes.shape({ params: React.PropTypes.shape({
org: React.PropTypes.string org: React.PropTypes.string
}),
user: React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string
}) })
}; };
module.exports = Org; const mapStateToProps = (state, ownProps) => ({
org: state.session.data.orgs.filter((org) => {
return org.id === ownProps.params.org;
}).pop(),
user: {
id: state.session.data.name,
name: state.session.data.name
}
});
module.exports = connect(mapStateToProps)(Org);

View File

@ -0,0 +1,29 @@
const React = require('react');
// const ReactIntl = require('react-intl');
const ReactRedux = require('react-redux');
// const ReactRouter = require('react-router');
// const {
// FormattedMessage
// } = ReactIntl;
const {
connect
} = ReactRedux;
// const {
// Link,
// Match,
// Miss,
// Redirect
// } = ReactRouter;
const People = () => {
return <p>people</p>;
};
People.propTypes = {};
const mapStateToProps = (state) => ({});
module.exports = connect(mapStateToProps)(People);

View File

@ -0,0 +1,17 @@
const ReactRedux = require('react-redux');
const Projects = require('@components/projects');
const {
connect
} = ReactRedux;
const mapStateToProps = (state, ownProps) => {
return {
projects: (state.session.data.orgs.filter((org) => {
return org.id === ownProps.params.org;
}).pop() || {}).projects
};
};
module.exports = connect(mapStateToProps)(Projects);

View File

@ -0,0 +1,29 @@
const React = require('react');
// const ReactIntl = require('react-intl');
const ReactRedux = require('react-redux');
// const ReactRouter = require('react-router');
// const {
// FormattedMessage
// } = ReactIntl;
const {
connect
} = ReactRedux;
// const {
// Link,
// Match,
// Miss,
// Redirect
// } = ReactRouter;
const Settings = () => {
return <p>Settings</p>;
};
Settings.propTypes = {};
const mapStateToProps = (state) => ({});
module.exports = connect(mapStateToProps)(Settings);

View File

@ -26,12 +26,29 @@ const {
const store = Store({ const store = Store({
session: { session: {
data: { data: {
id: 'nicola',
name: 'Nicola', name: 'Nicola',
projects: [],
orgs: [{ orgs: [{
id: 'biz-tech',
name: 'BizTech', name: 'BizTech',
pinned: true pinned: true,
projects: [{
id: 'forest-foundation-dev',
name: 'Forest Foundation Dev',
plan: '20.05$ per day'
}, {
id: 'forest-foundation-testing',
name: 'Forest Foundation Testing',
plan: '20.05$ per day'
}, {
id: 'forest-foundation-production',
name: 'Forest Foundation Production',
plan: '100.17$ per day'
}],
}, { }, {
name: 'Make Us Proud' id: 'make-us-proud',
name: 'Make Us Proud',
}] }]
} }
} }

View File

@ -3442,6 +3442,10 @@ lodash.foreach@^4.3.0:
version "4.5.0" version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
lodash.isempty:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
lodash.isequal@^4.4.0: lodash.isequal@^4.4.0:
version "4.4.0" version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.4.0.tgz#6295768e98e14dc15ce8d362ef6340db82852031" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.4.0.tgz#6295768e98e14dc15ce8d362ef6340db82852031"

View File

@ -23,6 +23,10 @@ const {
const padding = sizes.halfGutterWidth || '0.5rem'; const padding = sizes.halfGutterWidth || '0.5rem';
const direction = (size) => (props) => {
return props[size] ? 'column-reverse' : 'column';
};
const width = (fallback) => (size) => (props) => { const width = (fallback) => (size) => (props) => {
return !isUndefined(props[size]) return !isUndefined(props[size])
? calc(`(${props[size]} / ${sizes.gridColumns}) * 100%`) ? calc(`(${props[size]} / ${sizes.gridColumns}) * 100%`)
@ -54,10 +58,12 @@ module.exports = styled.div`
flex-basis: ${flexBasis('xs')}; flex-basis: ${flexBasis('xs')};
max-width: ${maxWidth('xs')}; max-width: ${maxWidth('xs')};
margin-left: ${marginLeft('xsOffset')}; margin-left: ${marginLeft('xsOffset')};
flex-direction: ${direction('xsReverse')};
${sm` ${sm`
flex-basis: ${flexBasis('sm')}; flex-basis: ${flexBasis('sm')};
max-width: ${maxWidth('sm')}; max-width: ${maxWidth('sm')};
flex-direction: ${direction('smReverse')};
`} `}
${smOffset` ${smOffset`
@ -67,6 +73,7 @@ module.exports = styled.div`
${md` ${md`
flex-basis: ${flexBasis('md')}; flex-basis: ${flexBasis('md')};
max-width: ${maxWidth('md')}; max-width: ${maxWidth('md')};
flex-direction: ${direction('mdReverse')};
`} `}
${mdOffset` ${mdOffset`
@ -76,6 +83,7 @@ module.exports = styled.div`
${lg` ${lg`
flex-basis: ${flexBasis('lg')}; flex-basis: ${flexBasis('lg')};
max-width: ${maxWidth('lg')}; max-width: ${maxWidth('lg')};
flex-direction: ${direction('lgReverse')};
`} `}
${lgOffset` ${lgOffset`