Client: Team Details subpage

This commit is contained in:
Barry Low committed 2018-09-14 07:35:25 -07:00
1 parent ba5a321127
commit 5b90eb8923
5 files changed
+242 -155

No files matched your search

+1
View File
@@ -150,6 +150,7 @@ class App extends Component {
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/teams' component={Teams} />
<Route exact path='/teams/:slug' component={Teams} />
<Route
exact
path='/(dashboard|manage-teams|team-members|settings)/'
@@ -0,0 +1,89 @@
import React from 'react'
import PropTypes from 'prop-types'
import CssBaseline from '@material-ui/core/CssBaseline'
import Typography from '@material-ui/core/Typography'
import Paper from '@material-ui/core/Paper'
import { withStyles } from '@material-ui/core/styles'
import { Link } from 'react-router-dom'
const styles = theme => ({
root: {
flexGrow: 1
},
'@global': {
body: {
backgroundColor: theme.palette.common.white
}
},
layout: {
width: 'auto',
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
marginBottom: theme.spacing.unit * 6,
[theme.breakpoints.up(900 + theme.spacing.unit * 3 * 2)]: {
width: 900,
marginLeft: 'auto',
marginRight: 'auto'
}
},
paper: {
marginTop: theme.spacing.unit * 3,
marginBottom: theme.spacing.unit * 3,
padding: theme.spacing.unit * 2,
[theme.breakpoints.up(600 + theme.spacing.unit * 3 * 2)]: {
marginTop: theme.spacing.unit * 6,
marginBottom: theme.spacing.unit * 6,
padding: theme.spacing.unit * 3
}
},
heroContent: {
maxWidth: 600,
margin: '0 auto',
padding: `${theme.spacing.unit * 8}px 0 ${theme.spacing.unit * 6}px`
}
})
const TeamsDetails = ({ classes, team }) => (
<React.Fragment>
<CssBaseline />
<main className={classes.layout}>
<Paper className={classes.paper}>
<div className={classes.heroContent}>
<Link to='/teams'>&larr; Back to all teams</Link>
<Typography
variant='display3'
align='center'
color='textPrimary'
gutterBottom
>
{team.name}
</Typography>
<Typography variant='subheading' color='textSecondary'>
{team.createdAt}
</Typography>
<Typography variant='subheading' paragraph gutterBottom>
Members: {team.members.length}
</Typography>
<Typography variant='subheading' color='primary'>
Team Admin:
{
team.members.map(member => {
if (member.role === 'OWNER' || member.role === 'ADMIN') {
return member.member.alias
}
})
}
</Typography>
</div>
</Paper>
</main>
</React.Fragment>
)
TeamsDetails.propTypes = {
classes: PropTypes.object.isRequired,
team: PropTypes.object.isRequired
}
export default withStyles(styles)(TeamsDetails)
+39 -95
View File
@@ -1,105 +1,49 @@
import React from 'react'
import PropTypes from 'prop-types'
import Typography from '@material-ui/core/Typography'
import { withStyles } from '@material-ui/core/styles'
import Grid from '@material-ui/core/Grid'
import Paper from '@material-ui/core/Paper'
import Card from '@material-ui/core/Card'
import CardActionArea from '@material-ui/core/CardActionArea'
import CardActions from '@material-ui/core/CardActions'
import CardContent from '@material-ui/core/CardContent'
import CardMedia from '@material-ui/core/CardMedia'
import Button from '@material-ui/core/Button'
import ButtonBase from '@material-ui/core/ButtonBase'
import Typography from '@material-ui/core/Typography'
const styles = theme => ({
layout: {
width: 'auto',
marginLeft: theme.spacing.unit * 2,
marginRight: theme.spacing.unit * 2,
[theme.breakpoints.up(600 + theme.spacing.unit * 2 * 2)]: {
width: 600,
marginLeft: 'auto',
marginRight: 'auto'
}
},
paper: {
marginTop: theme.spacing.unit * 0.1,
marginBottom: theme.spacing.unit * 0.1,
padding: theme.spacing.unit * 2,
[theme.breakpoints.up(600 + theme.spacing.unit * 3 * 2)]: {
marginTop: theme.spacing.unit * 1,
marginBottom: theme.spacing.unit * 1,
padding: theme.spacing.unit * 3
}
},
card: {
display: 'block',
width: '100%'
},
cardDetails: {
display: 'flex',
flex: 1
},
cardContent: {
flex: 1
},
buttonRight: {
justifyContent: 'flex-end'
},
image: {
width: 140,
height: 140
},
img: {
margin: 'auto',
display: 'block',
maxWidth: '100%',
maxHeight: '100%'
}
})
import { Link } from 'react-router-dom'
export const TeamsItem = ({ classes, team }) => (
<Grid item>
<main className={classes.layout}>
<Paper className={classes.paper}>
<Grid container spacing={16}>
<Grid item>
<ButtonBase className={classes.image}>
<img
className={classes.img}
alt='complex'
src='data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E'
/>
</ButtonBase>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction='column' spacing={16}>
<Grid item xs>
<Typography variant='headline'>{team.name}</Typography>
<Typography variant='caption' color='textSecondary'>
{team.createdAt}
</Typography>
<Typography variant='caption' paragraph>
Members: 1
</Typography>
</Grid>
<Grid item>
<Typography variant='subheading' color='primary'>
Now recruiting!
</Typography>
</Grid>
</Grid>
<Grid item>
<Button
size='small'
color='primary'
className={classes.buttonRight}
>
Details
</Button>
</Grid>
</Grid>
</Grid>
</Paper>
</main>
<Grid item sm={6} md={4} lg={3}>
<Card className={classes.card}>
<CardActionArea>
<CardMedia
className={classes.cardMedia}
image='data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' // eslint-disable-line max-len
title='Image title'
/>
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant='headline' component='h2'>
{team.name}
</Typography>
<Typography variant='caption' color='textSecondary'>
{team.createdAt}
</Typography>
<Typography variant='caption' paragraph gutterBottom>
Members: 1
</Typography>
<Typography variant='subheading' color='primary'>
Now recruiting!
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Link to={`/teams/${team.slug}`} >
<Button size='small' color='primary' className={classes.buttonRight}>
Details
</Button>
</Link>
</CardActions>
</Card>
</Grid>
)
@@ -108,4 +52,4 @@ TeamsItem.propTypes = {
team: PropTypes.object.isRequired
}
export default withStyles(styles)(TeamsItem)
export default TeamsItem
+105 -38
View File
@@ -4,58 +4,125 @@ import { Query } from 'react-apollo'
import Typography from '@material-ui/core/Typography'
import Grid from '@material-ui/core/Grid'
import { withStyles } from '@material-ui/core/styles'
import GET_ALL_TEAMS_QUERY from '../../../graphql/teams/GetAllTeamsQuery'
import TeamsItem from './TeamsItem'
import { isEmpty } from '../../../utils/js-helpers'
export const TeamsList = ({ classes }) => (
<Grid item md={12}>
<Query query={GET_ALL_TEAMS_QUERY}>
{({ loading, error, data }) => {
console.log('GET_TEAMS_BY_OWNER: ', loading, error, data)
let errors
let queryLoader
if (error) {
errors = error.graphQLErrors.map(({ message }, i) => {
import TeamsItem from './TeamsItem'
import TeamsDetails from './TeamsDetails'
const styles = theme => ({
heroContent: {
maxWidth: 600,
margin: '0 auto',
padding: `${theme.spacing.unit * 8}px 0 ${theme.spacing.unit * 6}px`
},
cardGrid: {
padding: `${theme.spacing.unit * 8}px 0`
},
card: {
height: '100%',
display: 'flex',
flexDirection: 'column'
},
cardMedia: {
paddingTop: '56.25%' // 16:9
},
cardContent: {
flexGrow: 1
},
buttonRight: {
justifyContent: 'flex-end'
}
})
export const TeamsList = ({ classes, match }) => (
<Query query={GET_ALL_TEAMS_QUERY} fetchPolicy='cache-and-network' >
{({ loading, error, data }) => {
console.log('GET_TEAMS_BY_OWNER: ', loading, error, data, match)
let slug = null
if (!isEmpty(match.params) && match.params.slug) slug = match.params.slug
let errors
let queryLoader
if (error) {
errors = error.graphQLErrors.map(({ message }, i) => {
return (
<Typography key={i} variant='caption'>
{message}
</Typography>
)
})
}
if (!loading && !error) {
if (data.teams.edges.length > 0) {
if (slug !== null) {
return (
<Typography key={i} variant='caption'>
{message}
</Typography>
)
})
}
if (!loading && !error) {
if (data.teams.edges.length > 0) {
return (
<Grid container spacing={24}>
<Grid container spacing={40}>
{!loading &&
data.teams.edges.map(team => (
<TeamsItem key={team.node.id} team={team.node} />
))}
data.teams.edges.map(team => {
if (team.node.slug === slug) {
return (
<TeamsDetails
key={team.node.id}
team={team.node}
/>
)
}
})}
{queryLoader}
{errors}
</Grid>
)
} else {
return (
<React.Fragment>
<div className={classes.heroContent}>
<Typography
variant='display3'
align='center'
color='textPrimary'
gutterBottom
>
Teams
</Typography>
</div>
<Grid container spacing={40}>
{!loading &&
data.teams.edges.map(team => (
<TeamsItem
key={team.node.id}
team={team.node}
classes={classes}
/>
))}
{queryLoader}
{errors}
</Grid>
</React.Fragment>
)
}
} else {
return (
<Grid container spacing={24}>
<Typography variant='subheading' gutterBottom>
Loading...
</Typography>
{queryLoader}
{errors}
</Grid>
)
}
}}
</Query>
</Grid>
} else {
return (
<Grid container spacing={40}>
<Typography variant='subheading' gutterBottom>
Loading...
</Typography>
{queryLoader}
{errors}
</Grid>
)
}
}}
</Query>
)
TeamsList.propTypes = {
classes: PropTypes.object.isRequired
classes: PropTypes.object.isRequired,
match: PropTypes.object
}
export default TeamsList
export default withStyles(styles)(TeamsList)
+8 -22
View File
@@ -2,13 +2,14 @@ import React from 'react'
import PropTypes from 'prop-types'
import CssBaseline from '@material-ui/core/CssBaseline'
import Typography from '@material-ui/core/Typography'
import Grid from '@material-ui/core/Grid'
import { withStyles } from '@material-ui/core/styles'
import TeamsList from './components/TeamsList'
const styles = theme => ({
root: {
flexGrow: 1
},
'@global': {
body: {
backgroundColor: theme.palette.common.white
@@ -18,42 +19,27 @@ const styles = theme => ({
width: 'auto',
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
marginBottom: theme.spacing.unit * 6,
[theme.breakpoints.up(900 + theme.spacing.unit * 3 * 2)]: {
width: 900,
marginLeft: 'auto',
marginRight: 'auto'
}
},
heroContent: {
maxWidth: 600,
margin: '0 auto',
padding: `${theme.spacing.unit * 8}px 0 ${theme.spacing.unit * 6}px`
}
})
const Teams = ({ classes }) => (
const Teams = ({ classes, match }) => (
<React.Fragment>
<CssBaseline />
<main className={classes.layout}>
<div className={classes.heroContent}>
<Typography
variant='display3'
align='center'
color='textPrimary'
gutterBottom
>
Teams
</Typography>
<Grid container spacing={24}>
<TeamsList classes={classes} />
</Grid>
</div>
<TeamsList match={match} />
</main>
</React.Fragment>
)
Teams.propTypes = {
classes: PropTypes.object.isRequired
classes: PropTypes.object.isRequired,
match: PropTypes.object
}
export default withStyles(styles)(Teams)