diff --git a/client/package-lock.json b/client/package-lock.json index 76ab3adfe..01e8e63e4 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -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" + } } } } diff --git a/client/package.json b/client/package.json index 44309081a..9d800caa2 100644 --- a/client/package.json +++ b/client/package.json @@ -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" } } diff --git a/client/src/Components/Event/Edit/index.js b/client/src/Components/Event/Edit/index.js new file mode 100644 index 000000000..803c9e2cc --- /dev/null +++ b/client/src/Components/Event/Edit/index.js @@ -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 ( + + + Enroll in an competition {this.props.match.params.slug} + + + {({ loading, error, data }) => { + if (loading) return 'Loading...' + if (error) return `Error! ${error.message}` + return ( +

+ {data.hosts_Event.description} +

+ ) + }} +
+
+ ) + } +} + +export default withStyles(styles)(Edit) diff --git a/client/src/Components/Event/Edit/styles.js b/client/src/Components/Event/Edit/styles.js new file mode 100644 index 000000000..175dc52e5 --- /dev/null +++ b/client/src/Components/Event/Edit/styles.js @@ -0,0 +1,4 @@ +const styles = theme => ({ +}) + +export default styles diff --git a/client/src/Components/Event/Show/index.js b/client/src/Components/Event/Show/index.js new file mode 100644 index 000000000..d0e89c9d6 --- /dev/null +++ b/client/src/Components/Event/Show/index.js @@ -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 ( + + + Enroll in an competition {this.props.match.params.slug} + + + {({ loading, error, data }) => { + if (loading) return 'Loading...' + if (error) return `Error! ${error.message}` + return ( +

+ {data.hosts_Event.description} +

+ ) + }} +
+
+ ) + } +} + +export default withStyles(styles)(Show) diff --git a/client/src/Components/Event/Show/styles.js b/client/src/Components/Event/Show/styles.js new file mode 100644 index 000000000..175dc52e5 --- /dev/null +++ b/client/src/Components/Event/Show/styles.js @@ -0,0 +1,4 @@ +const styles = theme => ({ +}) + +export default styles diff --git a/client/src/Components/Events/index.js b/client/src/Components/Events/index.js new file mode 100644 index 000000000..96d83a55d --- /dev/null +++ b/client/src/Components/Events/index.js @@ -0,0 +1,9 @@ +import React from 'react' + +class Index extends React.Component { + render () { + return

Here will come a list the competitions you applied for

+ } +} + +export default Index diff --git a/client/src/Components/HostedEvent/index.js b/client/src/Components/HostedEvent/index.js deleted file mode 100644 index 46b4d95f9..000000000 --- a/client/src/Components/HostedEvent/index.js +++ /dev/null @@ -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 ( - - - {({ loading, error, data }) => { - if (loading) return 'Loading...' - if (error) return `Error! ${error.message}` - const list = data.hosts_EventsByHost.map((event, index) => { - return ( - - ) - }) - return ( - - { list } - - ) - }} - - - - - - - Host an event - - - - Here you will add just the minimal information, will be settable in the edit page of your event. - - - - - - - ) - } -} - -export default withStyles(styles)(HostedEvent) diff --git a/client/src/Components/HostedEvent/styles.js b/client/src/Components/HostedEvent/styles.js deleted file mode 100644 index 382437a4b..000000000 --- a/client/src/Components/HostedEvent/styles.js +++ /dev/null @@ -1,10 +0,0 @@ - -const styles = theme => ({ - centered: { - display: 'block', - marginLeft: 'auto', - marginRight: 'auto' - } -}) - -export default styles diff --git a/client/src/Components/HostedEvent/Event.js b/client/src/Components/HostedEvents/Event.js similarity index 74% rename from client/src/Components/HostedEvent/Event.js rename to client/src/Components/HostedEvents/Event.js index 2119f2075..37599da1b 100644 --- a/client/src/Components/HostedEvent/Event.js +++ b/client/src/Components/HostedEvents/Event.js @@ -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 ( - + {name} - From : {startDatetime} - To : {finishDatetime} + From : {toLocalTime(startDatetime)} + To : {toLocalTime(finishDatetime)} Hosted by: {host.alias} ({host.lastName} {host.firstName}) @@ -73,7 +48,7 @@ class Event extends React.Component { color='primary' size='small' component={Link} - to={'/hosted-events/' + designator} + to={`/event/${designator}/edit`} > Edit @@ -83,7 +58,7 @@ class Event extends React.Component { color='primary' size='small' component={Link} - to={'/events/' + designator} + to={'/event/' + designator} > Show diff --git a/client/src/Components/HostedEvent/New.js b/client/src/Components/HostedEvents/New.js similarity index 91% rename from client/src/Components/HostedEvent/New.js rename to client/src/Components/HostedEvents/New.js index 1080dbbf1..f5567122d 100644 --- a/client/src/Components/HostedEvent/New.js +++ b/client/src/Components/HostedEvents/New.js @@ -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 ( - { - 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() }} > { + this.props.history.push(`/event/${event.designator}/edit`) + }; + + render () { + const { classes } = this.props + return ( + + + + + {({ loading, error, data }) => { + if (loading) return 'Loading...' + if (error) return `Error! ${error.message}` + const list = data.hosts_EventsByHost.map((event, index) => { + return ( + + ) + }) + return ( + + { list } + + ) + }} + + + { this.setState({ isNewEventOpen: false }) }} + aria-labelledby='addEvent-dialog-title' + > + + Host an event + + + + Here you will add just the minimal information, will be settable in the edit page of your event. + + + + + + ) + } +} + +export default withStyles(styles)(HostedEvent) diff --git a/client/src/Components/HostedEvents/styles.js b/client/src/Components/HostedEvents/styles.js new file mode 100644 index 000000000..e867e8174 --- /dev/null +++ b/client/src/Components/HostedEvents/styles.js @@ -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 diff --git a/client/src/Components/Search/Competition.js b/client/src/Components/Search/Competition.js deleted file mode 100644 index bccb5df88..000000000 --- a/client/src/Components/Search/Competition.js +++ /dev/null @@ -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 ( - - - - { displayName } - From : {toLocalTime(startDatetime)} - To : {toLocalTime(finishDatetime)} - - - Hosted by: { host } - Formula: { formula } - First prize: { firstPrice ? firstPrice.algoPrize + ' ALGOS' : 'none' } - - - - - Description : - { description } - - - - - - - - - Edit Key - - - - You will need to complete this form with the information from - the exchange. - - -

some stuff

- -
-
- - - - Audit Log History - - -

some stuff

-
-
-
-
-
-
-
- ) - } -} -export default withStyles(styles)(Competition) diff --git a/client/src/Components/Search/Event.js b/client/src/Components/Search/Event.js new file mode 100644 index 000000000..bce6d2433 --- /dev/null +++ b/client/src/Components/Search/Event.js @@ -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 ( + + + + {name} + From : {toLocalTime(startDatetime)} + To : {toLocalTime(finishDatetime)} + + + Hosted by: {host.alias} ({host.lastName} {host.firstName}) + Formula: + First prize: + + + + + Description : + {description} + + + + + + + + + ) + } +} + +export default withStyles(styles)(Event) diff --git a/client/src/Components/Search/Tabs/Future.js b/client/src/Components/Search/Tabs/Future.js new file mode 100644 index 000000000..2a46f4995 --- /dev/null +++ b/client/src/Components/Search/Tabs/Future.js @@ -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 ( + + ) + }) + return ( + + + Future events + + {futureEvents} + + ) + } +} + +export default withStyles(styles)(Future) diff --git a/client/src/Components/Search/Tabs/History.js b/client/src/Components/Search/Tabs/History.js new file mode 100644 index 000000000..0db046e5c --- /dev/null +++ b/client/src/Components/Search/Tabs/History.js @@ -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 ( + + Your old events (maybe here, maybe not, who knows) + + ) + } +} + +export default withStyles(styles)(History) diff --git a/client/src/Components/Search/Tabs/Incoming.js b/client/src/Components/Search/Tabs/Incoming.js new file mode 100644 index 000000000..3956aa6d7 --- /dev/null +++ b/client/src/Components/Search/Tabs/Incoming.js @@ -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 ( + + ) + }) + const ongoingEvents = OngoingEvents.map((event, index) => { + return ( + + ) + }) + return ( + + + Ongoing and incoming competitions + + + Ongoing events: + + {ongoingEvents} + + Incoming events: + + {incomingEvents} + + ) + } +} + +export default withStyles(styles)(Incoming) diff --git a/client/src/Components/Search/Tabs/Past.js b/client/src/Components/Search/Tabs/Past.js new file mode 100644 index 000000000..60a6bc5aa --- /dev/null +++ b/client/src/Components/Search/Tabs/Past.js @@ -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 ( + + ) + }) + return ( + + + A list of passed events + + {pastEvents} + + ) + } +} + +export default withStyles(styles)(Past) diff --git a/client/src/Components/Search/Tabs/index.js b/client/src/Components/Search/Tabs/index.js new file mode 100644 index 000000000..a4077c1ac --- /dev/null +++ b/client/src/Components/Search/Tabs/index.js @@ -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 +} diff --git a/client/src/Components/Search/index.js b/client/src/Components/Search/index.js index 7c46f096e..e432c8a8c 100644 --- a/client/src/Components/Search/index.js +++ b/client/src/Components/Search/index.js @@ -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 ( + + {props.children} + + ) +} 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 ( - - - Enroll in an competition - - - {({ loading, error, data }) => { - if (loading) return 'Loading...' - if (error) return `Error! ${error.message}` - const list = data.hosts_Competitions.map((competition, index) => { - return ( - - ) - }) - return ( - - { list } - - ) - }} - - + + {({ 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 ( + +
+ + + } + /> + } + /> + } + /> + } + /> + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + {value === 3 && } +
+
+ ) + }} +
) } } diff --git a/client/src/Components/Search/styles.js b/client/src/Components/Search/styles.js index 175dc52e5..9981d904a 100644 --- a/client/src/Components/Search/styles.js +++ b/client/src/Components/Search/styles.js @@ -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 diff --git a/client/src/Components/TopBar/index.js b/client/src/Components/TopBar/index.js index 768485f37..06fe761f6 100644 --- a/client/src/Components/TopBar/index.js +++ b/client/src/Components/TopBar/index.js @@ -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' diff --git a/client/src/Components/HostedEvent/graphql.js b/client/src/GraphQL/Calls/hostedEvents.js similarity index 56% rename from client/src/Components/HostedEvent/graphql.js rename to client/src/GraphQL/Calls/hostedEvents.js index ac617d6a3..850290690 100644 --- a/client/src/Components/HostedEvent/graphql.js +++ b/client/src/GraphQL/Calls/hostedEvents.js @@ -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 +} diff --git a/client/src/GraphQL/Calls/index.js b/client/src/GraphQL/Calls/index.js new file mode 100644 index 000000000..d3fe57c6d --- /dev/null +++ b/client/src/GraphQL/Calls/index.js @@ -0,0 +1,9 @@ +import hostedEventsCalls from './hostedEvents' +import listEventsCalls from './listEvents' +import showEventCalls from './showEvent' + +export { + hostedEventsCalls, + listEventsCalls, + showEventCalls +} diff --git a/client/src/GraphQL/Calls/listEvents.js b/client/src/GraphQL/Calls/listEvents.js new file mode 100644 index 000000000..39084f491 --- /dev/null +++ b/client/src/GraphQL/Calls/listEvents.js @@ -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 +} diff --git a/client/src/GraphQL/Calls/showEvent.js b/client/src/GraphQL/Calls/showEvent.js new file mode 100644 index 000000000..1f06bf226 --- /dev/null +++ b/client/src/GraphQL/Calls/showEvent.js @@ -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 +} diff --git a/client/src/GraphQL/Fragments/event.js b/client/src/GraphQL/Fragments/event.js new file mode 100644 index 000000000..3b5f3c3ac --- /dev/null +++ b/client/src/GraphQL/Fragments/event.js @@ -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 + } + } + } +` diff --git a/client/src/GraphQL/Fragments/index.js b/client/src/GraphQL/Fragments/index.js new file mode 100644 index 000000000..93d8f9971 --- /dev/null +++ b/client/src/GraphQL/Fragments/index.js @@ -0,0 +1,9 @@ +import { + eventMinimalInfo, + eventFullInfo +} from './event' + +export { + eventMinimalInfo, + eventFullInfo +} diff --git a/client/src/index.js b/client/src/index.js index a0212d5fd..245f4fa01 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -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} - + + + + diff --git a/client/src/utils/index.js b/client/src/utils/index.js index 4aee66165..36ed3a467 100644 --- a/client/src/utils/index.js +++ b/client/src/utils/index.js @@ -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' }) + ) } diff --git a/server/src/schema/queries/Event.js b/server/src/schema/queries/Event.js new file mode 100644 index 000000000..64eee0855 --- /dev/null +++ b/server/src/schema/queries/Event.js @@ -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 diff --git a/server/src/schema/queries/index.js b/server/src/schema/queries/index.js index 71aef39df..5d67c43bb 100644 --- a/server/src/schema/queries/index.js +++ b/server/src/schema/queries/index.js @@ -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,