Merge pull request #3 from nikolabjelo/master

Finally an uncomplete V1 for the hosts module
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2018-10-30 16:26:14 +01:00
commit 0ad33c5d89
33 files changed
+847 -337

No files matched your search

+100 -5
View File
@@ -184,6 +184,12 @@
}
}
},
"@types/async": {
"version": "2.0.50",
"resolved": "https://registry.npmjs.org/@types/async/-/async-2.0.50.tgz",
"integrity": "sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q==",
"optional": true
},
"@types/jss": {
"version": "9.5.7",
"resolved": "https://registry.npmjs.org/@types/jss/-/jss-9.5.7.tgz",
@@ -215,6 +221,11 @@
"@types/react": "*"
}
},
"@types/zen-observable": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz",
"integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg=="
},
"acorn": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.2.tgz",
@@ -266,6 +277,54 @@
"color-convert": "^1.9.0"
}
},
"apollo-cache": {
"version": "1.1.19",
"resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.1.19.tgz",
"integrity": "sha512-p163+GVne1Gyw2v9L5kHEQhUhih7btWvyUFOl4uKf7brieqd4tHZt8ZA3vT1SaXbCeQZNSp/tFI3yFyi8RPKzw==",
"requires": {
"apollo-utilities": "^1.0.24"
}
},
"apollo-client": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-2.4.4.tgz",
"integrity": "sha512-i29w/+aa9O4fe8NxzJNOViHdsjpN2723Q2mNl0HiOJFwG+VjA4RXdTpyZHPZqcO8FwgK1k43l8nULD4Cdlx/Ww==",
"requires": {
"@types/async": "2.0.50",
"@types/zen-observable": "^0.8.0",
"apollo-cache": "1.1.19",
"apollo-link": "^1.0.0",
"apollo-link-dedup": "^1.0.0",
"apollo-utilities": "1.0.24",
"symbol-observable": "^1.0.2",
"zen-observable": "^0.8.0"
}
},
"apollo-link": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.3.tgz",
"integrity": "sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw==",
"requires": {
"apollo-utilities": "^1.0.0",
"zen-observable-ts": "^0.8.10"
}
},
"apollo-link-dedup": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz",
"integrity": "sha512-tpUI9lMZsidxdNygSY1FxflXEkUZnvKRkMUsXXuQUNoSLeNtEvUX7QtKRAl4k9ubLl8JKKc9X3L3onAFeGTK8w==",
"requires": {
"apollo-link": "^1.2.3"
}
},
"apollo-utilities": {
"version": "1.0.24",
"resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.0.24.tgz",
"integrity": "sha512-cOXtrkio3wKfggp/zKCzQYxSZZRND/njNVmUksM1cckoJF3g/2o3bhh6z0HPhNhee8qzJzVXtl+3vmwXYGh0Gg==",
"requires": {
"fast-json-stable-stringify": "^2.0.0"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -983,8 +1042,7 @@
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
"dev": true
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"fast-levenshtein": {
"version": "2.0.6",
@@ -1132,6 +1190,14 @@
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
"dev": true
},
"graphql": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-14.0.2.tgz",
"integrity": "sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw==",
"requires": {
"iterall": "^1.2.2"
}
},
"graphql-tag": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.0.tgz",
@@ -1408,6 +1474,11 @@
"whatwg-fetch": ">=0.10.0"
}
},
"iterall": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz",
"integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2025,15 +2096,26 @@
}
},
"hoist-non-react-statics": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.0.1.tgz",
"integrity": "sha512-1kXwPsOi0OGQIZNVMPvgWJ9tSnGMiMfJdihqEzrPEXlHOBh9AAHXX/QYmAJTXztnz/K+PQ8ryCb4eGaN6HlGbQ==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.1.0.tgz",
"integrity": "sha512-MYcYuROh7SBM69xHGqXEwQqDux34s9tz+sCnxJmN18kgWh6JFdTw/5YdZtqsOdZJXddE/wUpCzfEdDrJj8p0Iw==",
"requires": {
"react-is": "^16.3.2"
}
}
}
},
"react-dom": {
"version": "16.6.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.0.tgz",
"integrity": "sha512-Stm2D9dXEUUAQdvpvhvFj/DEXwC2PAL/RwEMhoN4dvvD2ikTlJegEXf97xryg88VIAU22ZAP7n842l+9BTz6+w==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.10.0"
}
},
"react-event-listener": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.4.tgz",
@@ -2600,6 +2682,19 @@
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
"dev": true
},
"zen-observable": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.10.tgz",
"integrity": "sha512-UXEh0ekA/QWYI2NkLHc5IH0V1FstIN4qGVlVvq0DQAS3oR72mofYHkjJ2f4ysMKRAziwnACzg3c0ZuG+SMDu8w=="
},
"zen-observable-ts": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz",
"integrity": "sha512-5vqMtRggU/2GhePC9OU4sYEWOdvmayp2k3gjPf4F0mXwB3CSbbNznfDUvDJx9O2ZTa1EIXdJhPchQveFKwNXPQ==",
"requires": {
"zen-observable": "^0.8.0"
}
}
}
}
+3
View File
@@ -19,12 +19,15 @@
"dependencies": {
"@material-ui/core": "^3.2.0",
"@material-ui/icons": "^3.0.1",
"apollo-client": "^2.4.4",
"classnames": "^2.2.6",
"graphql": "^14.0.2",
"graphql-tag": "^2.10.0",
"luxon": "^1.4.4",
"material-ui-pickers": "^1.0.1",
"react": "^16.5.2",
"react-apollo": "^2.2.4",
"react-dom": "^16.6.0",
"react-router-dom": "^4.3.1"
}
}
+42
View File
@@ -0,0 +1,42 @@
import React from 'react'
import { Query } from 'react-apollo'
import Typography from '@material-ui/core/Typography'
import { withStyles } from '@material-ui/core/styles'
import styles from './styles'
import { showEventCalls } from '../../../GraphQL/Calls/index'
class Edit extends React.Component {
render () {
return (
<React.Fragment>
<Typography
variant='display1'
align='center'
color='textPrimary'
gutterBottom
>
Enroll in an competition {this.props.match.params.slug}
</Typography>
<Query
query={showEventCalls.HOSTS_EVENT}
variables={{ designator: this.props.match.params.slug }}
>
{({ loading, error, data }) => {
if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`
return (
<p>
{data.hosts_Event.description}
</p>
)
}}
</Query>
</React.Fragment>
)
}
}
export default withStyles(styles)(Edit)
@@ -0,0 +1,4 @@
const styles = theme => ({
})
export default styles
+42
View File
@@ -0,0 +1,42 @@
import React from 'react'
import { Query } from 'react-apollo'
import Typography from '@material-ui/core/Typography'
import { withStyles } from '@material-ui/core/styles'
import styles from './styles'
import { showEventCalls } from '../../../GraphQL/Calls/index'
class Show extends React.Component {
render () {
return (
<React.Fragment>
<Typography
variant='display1'
align='center'
color='textPrimary'
gutterBottom
>
Enroll in an competition {this.props.match.params.slug}
</Typography>
<Query
query={showEventCalls.HOSTS_EVENT}
variables={{ designator: this.props.match.params.slug }}
>
{({ loading, error, data }) => {
if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`
return (
<p>
{data.hosts_Event.description}
</p>
)
}}
</Query>
</React.Fragment>
)
}
}
export default withStyles(styles)(Show)
@@ -0,0 +1,4 @@
const styles = theme => ({
})
export default styles
+9
View File
@@ -0,0 +1,9 @@
import React from 'react'
class Index extends React.Component {
render () {
return <p>Here will come a list the competitions you applied for</p>
}
}
export default Index
@@ -1,85 +0,0 @@
import React from 'react'
import { Query } from 'react-apollo'
import { HOSTS_EVENTSBYHOST } from './graphql'
import {
Button,
Dialog,
DialogContent,
DialogContentText,
DialogTitle
} from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import styles from './styles'
import New from './New'
import Event from './Event'
class HostedEvent extends React.Component {
constructor (props) {
super(props)
this.state = {
isNewEventOpen: false
}
}
handleNewEventOpen = () => {
this.setState({ isNewEventOpen: true })
};
handleNewEventClose = () => {
this.setState({ isNewEventOpen: false })
};
render () {
const { classes } = this.props
return (
<React.Fragment>
<Query
query={HOSTS_EVENTSBYHOST}
>
{({ loading, error, data }) => {
if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`
const list = data.hosts_EventsByHost.map((event, index) => {
return (
<Event key={index} event={event} />
)
})
return (
<React.Fragment>
{ list }
</React.Fragment>
)
}}
</Query>
<React.Fragment>
<Button variant='contained' color='secondary'
aria-label='addNewEvent' className={classes.centered}
onClick={this.handleNewEventOpen} >
Host another event
</Button>
<Dialog
open={this.state.isNewEventOpen}
onClose={this.handleNewEventClose}
aria-labelledby='addEvent-dialog-title'
>
<DialogTitle id='addEvent-dialog-title'>
Host an event
</DialogTitle>
<DialogContent>
<DialogContentText>
Here you will add just the minimal information, will be settable in the edit page of your event.
</DialogContentText>
<New handleNewEventClose={this.handleNewEventClose} classes={classes} />
</DialogContent>
</Dialog>
</React.Fragment>
</React.Fragment>
)
}
}
export default withStyles(styles)(HostedEvent)
@@ -1,10 +0,0 @@
const styles = theme => ({
centered: {
display: 'block',
marginLeft: 'auto',
marginRight: 'auto'
}
})
export default styles
@@ -7,34 +7,9 @@ import {
Button
} from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import styles from './styles'
const styles = theme => ({
root: {
flexGrow: 1,
padding: 20,
margin: 10
},
image: {
width: 128,
height: '100%',
cursor: 'default'
},
img: {
margin: 'auto',
display: 'block',
maxWidth: '100%',
maxHeight: '100%'
},
buttonList: {
margin: theme.spacing.unit,
float: 'right'
},
buttonGrid: {
marginTop: -20
}
})
import { toLocalTime } from '../../utils'
class Event extends React.Component {
render () {
@@ -48,12 +23,12 @@ class Event extends React.Component {
description
} = this.props.event
return (
<Paper className={classes.root}>
<Paper className={classes.card}>
<Grid container spacing={16}>
<Grid item xs>
<Typography gutterBottom variant='headline'> {name} </Typography>
<Typography gutterBottom>From : {startDatetime} </Typography>
<Typography gutterBottom>To : {finishDatetime} </Typography>
<Typography gutterBottom>From : {toLocalTime(startDatetime)} </Typography>
<Typography gutterBottom>To : {toLocalTime(finishDatetime)} </Typography>
</Grid>
<Grid item xs>
<Typography gutterBottom>Hosted by: {host.alias} ({host.lastName} {host.firstName}) </Typography>
@@ -73,7 +48,7 @@ class Event extends React.Component {
color='primary'
size='small'
component={Link}
to={'/hosted-events/' + designator}
to={`/event/${designator}/edit`}
>
Edit
</Button>
@@ -83,7 +58,7 @@ class Event extends React.Component {
color='primary'
size='small'
component={Link}
to={'/events/' + designator}
to={'/event/' + designator}
>
Show
</Button>
@@ -1,6 +1,6 @@
import React from 'react'
import { Mutation } from 'react-apollo'
import { HOSTS_HOSTEVENT, HOSTS_EVENTSBYHOST } from './graphql'
import { hostedEventsCalls } from '../../GraphQL/Calls/index'
import { DateTime } from 'luxon'
import {
@@ -24,13 +24,14 @@ class New extends React.Component {
render () {
const { name, description, startDatetime, finishDatetime } = this.state
return (
<Mutation mutation={HOSTS_HOSTEVENT}
<Mutation mutation={hostedEventsCalls.HOSTS_HOSTEVENT}
update={(store, { data }) => {
const { hosts_EventsByHost: hostedEvents } = store.readQuery({ query: HOSTS_EVENTSBYHOST })
const { hosts_EventsByHost: hostedEvents } = store.readQuery({ query: hostedEventsCalls.HOSTS_EVENTSBYHOST })
store.writeQuery({
query: HOSTS_EVENTSBYHOST,
query: hostedEventsCalls.HOSTS_EVENTSBYHOST,
data: { hosts_EventsByHost: hostedEvents.concat([data.hosts_HostEvent]) }
})
this.props.handleNewEvent(data.hosts_HostEvent)
}
}
>
@@ -45,7 +46,6 @@ class New extends React.Component {
startDatetime: startDatetime.valueOf() / 1000,
finishDatetime: startDatetime.valueOf() / 1000
} })
this.props.handleNewEventClose()
}}
>
<TextField
@@ -0,0 +1,81 @@
import React from 'react'
import { Query } from 'react-apollo'
import {
Button,
Dialog,
DialogContent,
DialogContentText,
DialogTitle
} from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import styles from './styles'
import { hostedEventsCalls } from '../../GraphQL/Calls/index'
import New from './New'
import Event from './Event'
class HostedEvent extends React.Component {
constructor (props) {
super(props)
this.state = {
isNewEventOpen: false
}
}
handleNewEvent = (event) => {
this.props.history.push(`/event/${event.designator}/edit`)
};
render () {
const { classes } = this.props
return (
<React.Fragment>
<Button variant='contained' color='secondary'
aria-label='addNewEvent' className={classes.addButton}
onClick={() => { this.setState({ isNewEventOpen: true }) }} >
Host a new event
</Button>
<Query
query={hostedEventsCalls.HOSTS_EVENTSBYHOST}
>
{({ loading, error, data }) => {
if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`
const list = data.hosts_EventsByHost.map((event, index) => {
return (
<Event key={index} event={event} />
)
})
return (
<React.Fragment>
{ list }
</React.Fragment>
)
}}
</Query>
<Dialog
open={this.state.isNewEventOpen}
onClose={() => { this.setState({ isNewEventOpen: false }) }}
aria-labelledby='addEvent-dialog-title'
>
<DialogTitle id='addEvent-dialog-title'>
Host an event
</DialogTitle>
<DialogContent>
<DialogContentText>
Here you will add just the minimal information, will be settable in the edit page of your event.
</DialogContentText>
<New handleNewEvent={this.handleNewEvent} classes={classes} />
</DialogContent>
</Dialog>
</React.Fragment>
)
}
}
export default withStyles(styles)(HostedEvent)
@@ -0,0 +1,26 @@
const styles = theme => ({
card: {
flexGrow: 1,
padding: 20,
marginTop: 20,
marginBottom: 20,
marginLeft: 400,
marginRight: 400
},
buttonList: {
margin: theme.spacing.unit,
float: 'right'
},
buttonGrid: {
marginTop: -20
},
addButton: {
display: 'block',
padding: 20,
marginTop: 20,
marginRight: 20,
marginLeft: 'auto'
}
})
export default styles
-124
View File
@@ -1,124 +0,0 @@
import React from 'react'
import { toLocalTime } from '../../utils'
import {
Grid, Paper, Typography, Button,
Dialog, DialogContent, DialogContentText, DialogTitle
} from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
const styles = theme => ({
root: {
flexGrow: 1,
padding: 20,
margin: 10
},
image: {
width: 128,
height: '100%',
cursor: 'default'
},
img: {
margin: 'auto',
display: 'block',
maxWidth: '100%',
maxHeight: '100%'
},
buttonList: {
margin: theme.spacing.unit,
float: 'right'
},
buttonGrid: {
marginTop: -20
}
})
class Competition extends React.Component {
render () {
const classes = this.props.classes
const { displayName,
startDatetime,
finishDatetime,
host,
description,
formula,
prizes
} = this.props.competition
const firstPrice = prizes.find(prize => {
return prize.position === 1
})
return (
<Paper className={classes.root}>
<Grid container spacing={16}>
<Grid item xs>
<Typography gutterBottom variant='headline'> { displayName } </Typography>
<Typography gutterBottom>From : {toLocalTime(startDatetime)} </Typography>
<Typography gutterBottom>To : {toLocalTime(finishDatetime)} </Typography>
</Grid>
<Grid item xs>
<Typography gutterBottom>Hosted by: { host }</Typography>
<Typography gutterBottom>Formula: { formula }</Typography>
<Typography gutterBottom>First prize: { firstPrice ? firstPrice.algoPrize + ' ALGOS' : 'none' }</Typography>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction='column' spacing={16}>
<Grid item xs>
<Typography gutterBottom variant='headline'> Description : </Typography>
<Typography gutterBottom>{ description }</Typography>
</Grid>
<Grid item className={classes.buttonGrid}>
<Button
className={classes.buttonList}
variant='outlined' color='primary' size='small'
onClick={() => this.auditLog()}
>Apply</Button>
<Button
className={classes.buttonList}
variant='outlined' color='primary' size='small'
onClick={() => this.editKey()}
>Get details</Button>
<Button
className={classes.buttonList}
variant='outlined' color='primary' size='small'
onClick={() => this.editKey()}
>Edit</Button>
<Dialog
aria-labelledby='addKey-dialog-title'
>
<DialogTitle id='addKey-dialog-title'>
Edit Key
</DialogTitle>
<DialogContent>
<DialogContentText>
You will need to complete this form with the information from
the exchange.
</DialogContentText>
<p> some stuff </p>
</DialogContent>
</Dialog>
<Dialog
aria-labelledby='auditLog-dialog-title'
>
<DialogTitle id='auditLog-dialog-title'>
Audit Log History
</DialogTitle>
<DialogContent>
<p> some stuff </p>
</DialogContent>
</Dialog>
</Grid>
</Grid>
</Grid>
</Grid>
</Paper>
)
}
}
export default withStyles(styles)(Competition)
+64
View File
@@ -0,0 +1,64 @@
import React from 'react'
import { Link } from 'react-router-dom'
import {
Grid, Paper,
Typography,
Button
} from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import styles from './styles'
import { toLocalTime } from '../../utils'
class Event extends React.Component {
render () {
const classes = this.props.classes
const {
name,
designator,
startDatetime,
finishDatetime,
host,
description
} = this.props.event
return (
<Paper className={classes.card}>
<Grid container spacing={16}>
<Grid item xs>
<Typography gutterBottom variant='headline'> {name} </Typography>
<Typography gutterBottom>From : {toLocalTime(startDatetime)} </Typography>
<Typography gutterBottom>To : {toLocalTime(finishDatetime)} </Typography>
</Grid>
<Grid item xs>
<Typography gutterBottom>Hosted by: {host.alias} ({host.lastName} {host.firstName}) </Typography>
<Typography gutterBottom>Formula: </Typography>
<Typography gutterBottom>First prize: </Typography>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction='column' spacing={16}>
<Grid item xs>
<Typography gutterBottom variant='headline'> Description : </Typography>
<Typography gutterBottom> {description} </Typography>
</Grid>
<Grid item className={classes.buttonGrid}>
<Button
className={classes.buttonList}
variant='outlined'
color='primary'
size='small'
component={Link}
to={'/event/' + designator}
>
Show
</Button>
</Grid>
</Grid>
</Grid>
</Grid>
</Paper>
)
}
}
export default withStyles(styles)(Event)
@@ -0,0 +1,36 @@
import React from 'react'
import { Typography } from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import styles from '../styles'
import Event from '../Event'
class Future extends React.Component {
render () {
const classes = this.props.classes
const { FutureEvents } = this.props
const futureEvents = FutureEvents.map((event, index) => {
return (
<Event key={index} event={event} />
)
})
return (
<React.Fragment>
<Typography
className={classes.title}
variant='h4'
align='center'
color='textPrimary'
gutterBottom
>
Future events
</Typography>
{futureEvents}
</React.Fragment>
)
}
}
export default withStyles(styles)(Future)
@@ -0,0 +1,24 @@
import React from 'react'
import { Typography } from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import styles from '../styles'
class History extends React.Component {
render () {
const classes = this.props.classes
return (
<Typography
className={classes.title}
variant='h4'
align='center'
color='textPrimary'
gutterBottom
>
Your old events (maybe here, maybe not, who knows)
</Typography>
)
}
}
export default withStyles(styles)(History)
@@ -0,0 +1,56 @@
import React from 'react'
import { Typography } from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import styles from '../styles'
import Event from '../Event'
class Incoming extends React.Component {
render () {
const classes = this.props.classes
const { IncomingEvents, OngoingEvents } = this.props
const incomingEvents = IncomingEvents.map((event, index) => {
return (
<Event key={index} event={event} />
)
})
const ongoingEvents = OngoingEvents.map((event, index) => {
return (
<Event key={index} event={event} />
)
})
return (
<React.Fragment>
<Typography
className={classes.title}
variant='h4'
align='center'
color='textPrimary'
gutterBottom
>
Ongoing and incoming competitions
</Typography>
<Typography
variant='h5'
color='textPrimary'
gutterBottom
>
Ongoing events:
</Typography>
{ongoingEvents}
<Typography
variant='h5'
color='textPrimary'
gutterBottom
>
Incoming events:
</Typography>
{incomingEvents}
</React.Fragment>
)
}
}
export default withStyles(styles)(Incoming)
+36
View File
@@ -0,0 +1,36 @@
import React from 'react'
import { Typography } from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import styles from '../styles'
import Event from '../Event'
class Past extends React.Component {
render () {
const classes = this.props.classes
const { PastEvents } = this.props
const pastEvents = PastEvents.map((event, index) => {
return (
<Event key={index} event={event} />
)
})
return (
<React.Fragment>
<Typography
className={classes.title}
variant='display1'
align='center'
color='textPrimary'
gutterBottom
>
A list of passed events
</Typography>
{pastEvents}
</React.Fragment>
)
}
}
export default withStyles(styles)(Past)
@@ -0,0 +1,11 @@
import Future from './Future'
import History from './History'
import Incoming from './Incoming'
import Past from './Past'
export {
Future,
History,
Incoming,
Past
}
+99 -52
View File
@@ -1,65 +1,112 @@
import React from 'react'
import gql from 'graphql-tag'
import { Query } from 'react-apollo'
import { DateTime } from 'luxon'
import {
Typography,
AppBar,
Tabs,
Tab
} from '@material-ui/core'
import {
GetApp as IncomingIcon,
AlarmAdd as FutureIcon,
History as HistoryIcon
} from '@material-ui/icons'
import Typography from '@material-ui/core/Typography'
import { withStyles } from '@material-ui/core/styles'
import Competition from './Competition'
import styles from './styles'
const HOST_COMPETITIONS = gql`
query Hosts_Competitions{
hosts_Competitions {
displayName
host
startDatetime
finishDatetime
description
formula
participants {
devTeam
}
prizes {
position
algoPrize
}
}
}
`
import { listEventsCalls } from '../../GraphQL/Calls/index'
import {
Future,
History,
Incoming,
Past
} from './Tabs'
function TabContainer (props) {
return (
<Typography component='div' style={{ padding: 8 * 3 }}>
{props.children}
</Typography>
)
}
class Search extends React.Component {
constructor (props) {
super(props)
this.state = {
value: 0
}
}
handleChange = (event, value) => {
this.setState({ value })
}
render () {
const classes = this.props.classes
const { value } = this.state
return (
<React.Fragment>
<Typography
variant='display1'
align='center'
color='textPrimary'
gutterBottom
>
Enroll in an competition
</Typography>
<Query
query={HOST_COMPETITIONS}
>
{({ loading, error, data }) => {
if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`
const list = data.hosts_Competitions.map((competition, index) => {
return (
<Competition key={index} competition={competition} />
)
})
return (
<React.Fragment>
{ list }
</React.Fragment>
)
}}
</Query>
</React.Fragment>
<Query
query={listEventsCalls.HOSTS_EVENTS}
>
{({ loading, error, data }) => {
if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`
const now = ~~(DateTime.local().valueOf() / 1000)
const inTwoWeeks = ~~(DateTime.local().plus({ weeks: 2 }).valueOf() / 1000)
const IncomingEvents = data.hosts_Events.filter(event => event.startDatetime > now && event.startDatetime < inTwoWeeks)
const OngoingEvents = data.hosts_Events.filter(event => event.finishDatetime > now && event.startDatetime < now)
const FutureEvents = data.hosts_Events.filter(event => event.startDatetime > now)
const PastEvents = data.hosts_Events.filter(event => event.finishDatetime < now)
return (
<React.Fragment>
<div className={classes.root}>
<AppBar position='static' color='default'>
<Tabs
value={value}
onChange={this.handleChange}
scrollable
scrollButtons='off'
indicatorColor='primary'
textColor='primary'
>
<Tab
className={classes.tabTitle}
label='Ongoing &amp; Incoming'
icon={<IncomingIcon />}
/>
<Tab
className={classes.tabTitle}
label='Future'
icon={<FutureIcon />}
/>
<Tab
className={classes.tabTitle}
label='Your history'
icon={<HistoryIcon />}
/>
<Tab
className={classes.tabTitle}
label='Past'
icon={<HistoryIcon />}
/>
</Tabs>
</AppBar>
{value === 0 && <TabContainer><Incoming IncomingEvents={IncomingEvents} OngoingEvents={OngoingEvents} /></TabContainer>}
{value === 1 && <TabContainer><Future FutureEvents={FutureEvents} /></TabContainer>}
{value === 2 && <TabContainer><History /></TabContainer>}
{value === 3 && <TabContainer><Past PastEvents={PastEvents} /></TabContainer>}
</div>
</React.Fragment>
)
}}
</Query>
)
}
}
+29
View File
@@ -1,4 +1,33 @@
const styles = theme => ({
root: {
flexGrow: 1,
width: '100%',
backgroundColor: theme.palette.background.paper,
padding: 0,
margin: 0
},
tabTitle: {
width: '25%',
maxWidth: 'none'
},
card: {
flexGrow: 1,
padding: 20,
marginTop: 20,
marginBottom: 20,
marginLeft: 400,
marginRight: 400
},
buttonList: {
margin: theme.spacing.unit,
float: 'right'
},
buttonGrid: {
marginTop: -20
},
title: {
marginTop: 20
}
})
export default styles
+1 -4
View File
@@ -2,10 +2,7 @@ import React from 'react'
import { Link } from 'react-router-dom'
import classNames from 'classnames'
import AppBar from '@material-ui/core/AppBar'
import Toolbar from '@material-ui/core/Toolbar'
import Typography from '@material-ui/core/Typography'
import Button from '@material-ui/core/Button'
import { AppBar, Toolbar, Typography, Button } from '@material-ui/core'
import { withStyles } from '@material-ui/core/styles'
import datas from './data'
@@ -1,29 +1,23 @@
import gql from 'graphql-tag'
import { eventMinimalInfo } from '../Fragments'
const fragments = `
name
designator
startDatetime
finishDatetime
host {
alias
firstName
lastName
}
description
`
export const HOSTS_HOSTEVENT = gql`
const HOSTS_HOSTEVENT = gql`
mutation Hosts_HostEvent($name: String!, $description: String!, $startDatetime: Int!, $finishDatetime: Int!) {
hosts_HostEvent(name: $name, description: $description, startDatetime: $startDatetime, finishDatetime: $finishDatetime) {
${fragments}
...EventMinimalInfo
}
}
${eventMinimalInfo}
`
export const HOSTS_EVENTSBYHOST = gql`
const HOSTS_EVENTSBYHOST = gql`
query Hosts_EventsByHost{
hosts_EventsByHost {
${fragments}
...EventMinimalInfo
}
}
${eventMinimalInfo}
`
export default {
HOSTS_HOSTEVENT,
HOSTS_EVENTSBYHOST
}
+9
View File
@@ -0,0 +1,9 @@
import hostedEventsCalls from './hostedEvents'
import listEventsCalls from './listEvents'
import showEventCalls from './showEvent'
export {
hostedEventsCalls,
listEventsCalls,
showEventCalls
}
+14
View File
@@ -0,0 +1,14 @@
import gql from 'graphql-tag'
import { eventMinimalInfo } from '../Fragments'
const HOSTS_EVENTS = gql`
query Hosts_Events{
hosts_Events {
...EventMinimalInfo
}
}
${eventMinimalInfo}
`
export default {
HOSTS_EVENTS
}
+15
View File
@@ -0,0 +1,15 @@
import gql from 'graphql-tag'
import { eventFullInfo } from '../Fragments'
const HOSTS_EVENT = gql`
query Hosts_Event($designator: ID!) {
hosts_Event(designator: $designator) {
...EventFullInfo
}
}
${eventFullInfo}
`
export default {
HOSTS_EVENT
}
+61
View File
@@ -0,0 +1,61 @@
import gql from 'graphql-tag'
export const eventMinimalInfo = gql`
fragment EventMinimalInfo on hosts_Event {
name
designator
startDatetime
finishDatetime
host {
alias
firstName
lastName
}
description
}
`
export const eventFullInfo = gql`
fragment EventFullInfo on hosts_Event {
designator
name
host{
alias
firstName
lastName
}
description
startDatetime
finishDatetime
formula{
name
}
plotter{
name
host
repo
moduleName
}
rules{
position
title
description
}
participants{
team{
name
}
botId
releaseId
}
prizes{
rank
amount
additional{
condition
amount
asset
}
}
}
`
+9
View File
@@ -0,0 +1,9 @@
import {
eventMinimalInfo,
eventFullInfo
} from './event'
export {
eventMinimalInfo,
eventFullInfo
}
+7 -2
View File
@@ -8,7 +8,9 @@ import { getItem } from './utils/local-storage'
import TopBar from './Components/TopBar'
import Search from './Components/Search'
import HostedEvent from './Components/HostedEvent'
import Events from './Components/Events'
import HostedEvents from './Components/HostedEvents'
import EditEvent from './Components/Event/Edit'
class App extends Component {
constructor (props) {
@@ -41,7 +43,10 @@ class App extends Component {
{loggedIn}
<Switch>
<Route exact path='/' component={Search} />
<Route path='/hosted-events' component={HostedEvent} />
<Route path='/events' component={Events} />
<Route path='/event/:slug/edit' component={EditEvent} />
<Route path='/event/:slug' component={EditEvent} />
<Route path='/hosted-events' component={HostedEvents} />
</Switch>
</div>
</BrowserRouter>
+5 -1
View File
@@ -2,5 +2,9 @@ export const toLocalTime = (epoch) => {
let localDate = new Date(0)
localDate.setUTCSeconds(epoch)
var options = { year: 'numeric', month: 'long', day: '2-digit' }
return localDate.toLocaleDateString(options) + ' ' + localDate.toLocaleTimeString('en-US')
return (
localDate.toLocaleDateString(options) +
' at ' +
localDate.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })
)
}
+35
View File
@@ -0,0 +1,35 @@
import {
GraphQLNonNull,
GraphQLID
} from 'graphql'
import { DatabaseError } from '../../errors'
import { EventType } from '../types'
import { Event } from '../../models'
const args = {
designator: { type: new GraphQLNonNull(GraphQLID) }
}
const resolve = (parent, { designator }, context) => {
return new Promise((resolve, reject) => {
Event.findOne({ designator }).exec((err, event) => {
if (err) {
reject(err)
} else if (!event) {
reject(new DatabaseError('None of the events respond to that designator'))
} else {
resolve(event)
}
})
})
}
const query = {
event: {
type: EventType,
args,
resolve
}
}
export default query
+2
View File
@@ -2,6 +2,7 @@ import {
GraphQLObjectType
} from 'graphql'
import EventQuery from './Event'
import EventsQuery from './Events'
import EventsByHostQuery from './EventsByHost'
import EventsByTeamQuery from './EventsByTeam'
@@ -11,6 +12,7 @@ import PlottersQuery from './Plotters'
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: Object.assign(
EventQuery,
EventsQuery,
EventsByHostQuery,
EventsByTeamQuery,