diff --git a/api/src/graphql/TeamsConnectionsFragment.js b/api/src/graphql/TeamsConnectionsFragment.js
new file mode 100644
index 000000000..89a22a8c4
--- /dev/null
+++ b/api/src/graphql/TeamsConnectionsFragment.js
@@ -0,0 +1,33 @@
+const gql = require('graphql-tag')
+
+const TEAMS_CONNECTIONS_FRAGMENT = gql`{
+ edges {
+ node {
+ id
+ name
+ slug
+ owner
+ status {
+ status
+ reason
+ createdAt
+ }
+ createdAt
+ profile {
+ avatar
+ description
+ motto
+ updatedAt
+ }
+ members {
+ role
+ member {
+ alias
+ authId
+ }
+ }
+ }
+ }
+}`
+
+module.exports = TEAMS_CONNECTIONS_FRAGMENT
diff --git a/api/src/index.js b/api/src/index.js
index 0386ba61b..6b4a5167d 100644
--- a/api/src/index.js
+++ b/api/src/index.js
@@ -14,6 +14,7 @@ const { validateIdToken } = require('./auth/validateIdToken')
const { directiveResolvers } = require('./auth/authDirectives')
const TEAMS_FRAGMENT = require('./graphql/TeamsFragment')
+const TEAMS_CONNECTIONS_FRAGMENT = require('./graphql/TeamsConnectionsFragment')
const createMember = async function (ctx, info, idToken) {
console.log('createMember', idToken)
@@ -47,36 +48,7 @@ const resolvers = {
return ctx.db.query.member({ where: { authId } }, info)
},
teams(parent, args, ctx, info) {
- return ctx.db.query.teamsConnection({},
- `{
- edges {
- node {
- id
- name
- slug
- owner
- status {
- status
- reason
- createdAt
- }
- createdAt
- profile {
- avatar
- description
- motto
- updatedAt
- }
- members {
- role
- member {
- alias
- authId
- }
- }
- }
- }
- }`)
+ return ctx.db.query.teamsConnection({}, TEAMS_CONNECTIONS_FRAGMENT)
},
async teamById(parent, { id }, ctx, info) {
return ctx.db.query.team({ where: { id } }, info)
@@ -128,6 +100,13 @@ const resolvers = {
return err
})
},
+ async updateTeamProfile(parent, { slug, owner, description, motto, avatar }, ctx, info) {
+ return ctx.db.mutation.updateTeam({data:{profile: {update: {description: description, motto: motto, avatar: avatar}}}, where:{slug: slug}}), TEAMS_FRAGMENT)
+ .catch((err) => {
+ console.log('createTeam error: ', err)
+ return err
+ })
+ },
async deleteTeam(parent, { id }, ctx, info) {
return ctx.db.mutation.deleteTeam({ where: { id } }, info)
.catch((res) => {
diff --git a/api/src/schema.graphql b/api/src/schema.graphql
index 9e315174c..8b5d48d77 100644
--- a/api/src/schema.graphql
+++ b/api/src/schema.graphql
@@ -18,7 +18,8 @@ type Query {
type Mutation {
authenticate(idToken: String!): Member
- createTeam(name: String!, slug: String, owner: String): Team @isAuthenticated
+ createTeam(name: String!, slug: String!, owner: String!): Team @isAuthenticated
+ updateTeamProfile(slug: String!, owner: String!, description: String, motto: String, avatar: String): Team @isAuthenticated
deleteTeam(id: ID!): Team @isAuthenticated @isOwner(type: "Team")
}
diff --git a/client/src/graphql/teams/UpdateTeamProfileMutation.js b/client/src/graphql/teams/UpdateTeamProfileMutation.js
new file mode 100644
index 000000000..6672a7a24
--- /dev/null
+++ b/client/src/graphql/teams/UpdateTeamProfileMutation.js
@@ -0,0 +1,34 @@
+/* eslint-disable no-unused-vars */
+import gql from 'graphql-tag'
+
+const CREATE_TEAM = gql`
+ mutation UpdateTeamMutation($slug: String!, $owner: String!, $description: String, $motto: String) {
+ createTeam(slug: $slug, owner: $owner, description: $description, motto: $motto) {
+ id
+ name
+ slug
+ owner
+ status {
+ status
+ reason
+ createdAt
+ }
+ createdAt
+ profile {
+ avatar
+ description
+ motto
+ updatedAt
+ }
+ members {
+ role
+ member {
+ alias
+ authId
+ }
+ }
+ }
+ }
+`
+
+export default CREATE_TEAM
diff --git a/client/src/views/dashboard/ManageTeams.js b/client/src/views/dashboard/ManageTeams.js
index ecf65c9db..175c4aded 100644
--- a/client/src/views/dashboard/ManageTeams.js
+++ b/client/src/views/dashboard/ManageTeams.js
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import Typography from '@material-ui/core/Typography'
import { withStyles } from '@material-ui/core/styles'
-import TeamTable from './components/TeamTable'
+import ManageTeamsList from './components/ManageTeamsList'
const styles = theme => ({
tableContainer: {
@@ -15,10 +15,10 @@ const styles = theme => ({
const ManageTeams = ({ classes }) => (
- Teams
+ Manage Your Teams
-
+
)
diff --git a/client/src/views/dashboard/components/ManageTeamEdit.js b/client/src/views/dashboard/components/ManageTeamEdit.js
new file mode 100644
index 000000000..d10dd5728
--- /dev/null
+++ b/client/src/views/dashboard/components/ManageTeamEdit.js
@@ -0,0 +1,133 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import { withRouter } from 'react-router-dom'
+import Button from '@material-ui/core/Button'
+import AddIcon from '@material-ui/icons/Add'
+import TextField from '@material-ui/core/TextField'
+import Dialog from '@material-ui/core/Dialog'
+import DialogActions from '@material-ui/core/DialogActions'
+import DialogContent from '@material-ui/core/DialogContent'
+import DialogContentText from '@material-ui/core/DialogContentText'
+import DialogTitle from '@material-ui/core/DialogTitle'
+import Typography from '@material-ui/core/Typography'
+
+import { getItem } from '../../../utils/local-storage'
+
+export class ManageTeamEdit extends Component {
+ constructor (props) {
+ super(props)
+
+ this.handleClickOpen = this.handleClickOpen.bind(this)
+ this.handleClose = this.handleClose.bind(this)
+ this.handlePost = this.handlePost.bind(this)
+ this.slugify = this.slugify.bind(this)
+ this.handleChange = this.handleChange.bind(this)
+
+ this.state = {
+ open: false,
+ motto: '',
+ description: ''
+ }
+ }
+
+ handleClickOpen () {
+ this.setState({ open: true })
+ }
+
+ handleClose () {
+ this.setState({ open: false })
+ }
+
+ handleChange (e) {
+ this.setState({ name: e.target.value })
+ }
+
+ render () {
+ console.log(this.props, this.props.team)
+ return (
+
+
+
+
+ )
+ }
+
+ slugify (string) {
+ const a = 'àáäâãåèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;'
+ const b = 'aaaaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------'
+ const p = new RegExp(a.split('').join('|'), 'g')
+
+ return string
+ .toString()
+ .toLowerCase()
+ .replace(/\s+/g, '-') // Replace spaces with -
+ .replace(p, c => b.charAt(a.indexOf(c))) // Replace special characters
+ .replace(/&/g, '-and-') // Replace & with 'and'
+ .replace(/[^\w-]+/g, '') // Remove all non-word characters
+ .replace(/--+/g, '-') // Replace multiple - with single -
+ .replace(/^-+/, '') // Trim - from start of text
+ .replace(/-+$/, '') // Trim - from end of text
+ }
+
+ async handlePost (e) {
+ e.preventDefault()
+ const { name } = this.state
+ const slug = this.slugify(name)
+ const currentUser = await getItem('user')
+ let authId = JSON.parse(currentUser)
+ authId = authId.sub
+ console.log('createPage cu:', JSON.parse(currentUser))
+ await this.props.createTeamMutation({
+ variables: {
+ name,
+ slug,
+ owner: authId
+ }
+ })
+ this.setState({ open: false })
+ }
+}
+
+ManageTeamEdit.propTypes = {
+ classes: PropTypes.object.isRequired,
+ team: PropTypes.object.isRequired,
+ createTeamMutation: PropTypes.function
+}
+
+export default withRouter(ManageTeamEdit)
diff --git a/client/src/views/dashboard/components/ManageTeamsDetails.js b/client/src/views/dashboard/components/ManageTeamsDetails.js
new file mode 100644
index 000000000..65a988215
--- /dev/null
+++ b/client/src/views/dashboard/components/ManageTeamsDetails.js
@@ -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 ManageTeamsDetails = ({ classes, team }) => (
+
+
+
+
+
+ ← Back to all teams
+
+ {team.name}
+
+
+ {team.createdAt}
+
+
+ Members: {team.members.length}
+
+
+ Team Admin:
+ {
+ team.members.map(member => {
+ if (member.role === 'OWNER' || member.role === 'ADMIN') {
+ return member.member.alias
+ }
+ })
+ }
+
+
+
+
+
+)
+ManageTeamsDetails.propTypes = {
+ classes: PropTypes.object.isRequired,
+ team: PropTypes.object.isRequired
+}
+
+export default withStyles(styles)(ManageTeamsDetails)
diff --git a/client/src/views/dashboard/components/ManageTeamsItem.js b/client/src/views/dashboard/components/ManageTeamsItem.js
new file mode 100644
index 000000000..7c00639d9
--- /dev/null
+++ b/client/src/views/dashboard/components/ManageTeamsItem.js
@@ -0,0 +1,55 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+
+import Grid from '@material-ui/core/Grid'
+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 Typography from '@material-ui/core/Typography'
+
+import { Link } from 'react-router-dom'
+
+export const ManageTeamsItem = ({ classes, team }) => (
+
+
+
+
+
+
+ {team.name}
+
+
+ {team.createdAt}
+
+
+ Members: 1
+
+
+ Now recruiting!
+
+
+
+
+
+
+
+
+
+
+)
+
+ManageTeamsItem.propTypes = {
+ classes: PropTypes.object.isRequired,
+ team: PropTypes.object.isRequired
+}
+
+export default ManageTeamsItem
diff --git a/client/src/views/dashboard/components/ManageTeamsList.js b/client/src/views/dashboard/components/ManageTeamsList.js
new file mode 100644
index 000000000..b02592c8e
--- /dev/null
+++ b/client/src/views/dashboard/components/ManageTeamsList.js
@@ -0,0 +1,128 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+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_TEAMS_BY_OWNER from '../../../graphql/teams/GetTeamsByOwnerQuery'
+
+import { isEmpty } from '../../../utils/js-helpers'
+
+import ManageTeamsItem from './ManageTeamsItem'
+import ManageTeamsDetails from './ManageTeamsDetails'
+
+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 ManageTeamsList = ({ classes, match }) => (
+
+ {({ 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 (
+
+ {message}
+
+ )
+ })
+ }
+ if (!loading && !error) {
+ if (data.teams.edges.length > 0) {
+ if (slug !== null) {
+ return (
+
+ {!loading &&
+ data.teams.edges.map(team => {
+ if (team.node.slug === slug) {
+ return (
+
+ )
+ }
+ })}
+ {queryLoader}
+ {errors}
+
+ )
+ } else {
+ return (
+
+
+
+ Teams
+
+
+
+ {!loading &&
+ data.teams.edges.map(team => (
+
+ ))}
+ {queryLoader}
+ {errors}
+
+
+ )
+ }
+ }
+ } else {
+ return (
+
+
+ Loading...
+
+ {queryLoader}
+ {errors}
+
+ )
+ }
+ }}
+
+)
+
+ManageTeamsList.propTypes = {
+ classes: PropTypes.object.isRequired,
+ match: PropTypes.object
+}
+
+export default withStyles(styles)(ManageTeamsList)
diff --git a/client/src/views/teams/components/TeamsList.js b/client/src/views/teams/components/TeamsList.js
index 8ae962ead..64493cdff 100644
--- a/client/src/views/teams/components/TeamsList.js
+++ b/client/src/views/teams/components/TeamsList.js
@@ -41,7 +41,7 @@ const styles = theme => ({
export const TeamsList = ({ classes, match }) => (
{({ loading, error, data }) => {
- console.log('GET_TEAMS_BY_OWNER: ', loading, error, data, match)
+ console.log('GET_ALL_TEAMS: ', loading, error, data, match)
let slug = null
if (!isEmpty(match.params) && match.params.slug) slug = match.params.slug