some minimal V1 for a part of the frontend
This commit is contained in:
1 parent
708ab25a74
commit
c9ede0f0d9
11 files changed
+1239
-7
No files matched your search
Generated
+894
File diff suppressed because it is too large.
Load diff
@@ -12,8 +12,10 @@
|
||||
"react-hot-loader": "^4.3.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"@advancedalgos/web-components": "0.0.13",
|
||||
"@material-ui/core": "^3.2.0",
|
||||
"@material-ui/icons": "^3.0.1",
|
||||
"classnames": "^2.2.6",
|
||||
"graphql-tag": "^2.10.0",
|
||||
"react": "^16.5.2",
|
||||
"react-apollo": "^2.2.4",
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
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)
|
||||
@@ -0,0 +1,67 @@
|
||||
import React from 'react'
|
||||
import gql from 'graphql-tag'
|
||||
import { Query } from 'react-apollo'
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
class Search extends React.Component {
|
||||
render () {
|
||||
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>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(styles)(Search)
|
||||
@@ -0,0 +1,4 @@
|
||||
const styles = theme => ({
|
||||
})
|
||||
|
||||
export default styles
|
||||
@@ -0,0 +1,11 @@
|
||||
import GamesIcon from '@material-ui/icons/Games'
|
||||
import SearchIcon from '@material-ui/icons/Search'
|
||||
import LibraryAddIcon from '@material-ui/icons/LibraryAdd'
|
||||
|
||||
const data = [
|
||||
{ title: 'Look for competitions', to: '/', icon: SearchIcon, text: '' },
|
||||
{ title: 'Competitions you applied for', to: '/competitions', icon: GamesIcon, text: '' },
|
||||
{ title: 'Host your own competition', to: '/host-your-own', icon: LibraryAddIcon, text: '' }
|
||||
]
|
||||
|
||||
export default data
|
||||
@@ -0,0 +1,45 @@
|
||||
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 { withStyles } from '@material-ui/core/styles'
|
||||
|
||||
import datas from './data'
|
||||
import styles from './styles'
|
||||
|
||||
const TopBar = ({ classes, user, match }) => {
|
||||
const buttons = datas.map((data, index) => {
|
||||
const Icon = data.icon
|
||||
return (
|
||||
<Button
|
||||
key={index}
|
||||
variant='text'
|
||||
size='small'
|
||||
className={classNames(classes.button, classes.cssRoot)}
|
||||
title={data.title}
|
||||
component={Link}
|
||||
to={data.to}>
|
||||
<Icon className={classNames(classes.leftIcon, classes.iconSmall)} />
|
||||
{data.text}
|
||||
</Button>)
|
||||
}
|
||||
)
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<AppBar position='static' color='secondary'>
|
||||
<Toolbar>
|
||||
<Typography variant='h5' color='inherit' className={classes.flex}>
|
||||
Manage competition
|
||||
</Typography>
|
||||
{buttons}
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withStyles(styles)(TopBar)
|
||||
@@ -0,0 +1,37 @@
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
flexGrow: 1
|
||||
},
|
||||
flex: {
|
||||
flexGrow: 1,
|
||||
marginLeft: 30
|
||||
},
|
||||
menuButton: {
|
||||
marginLeft: -12,
|
||||
marginRight: 20
|
||||
},
|
||||
cssRoot: {
|
||||
color: '#FFFFFF',
|
||||
backgroundColor: theme.palette.secondary,
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.dark
|
||||
},
|
||||
whiteSpace: 'nowrap',
|
||||
paddingRight: 2 * theme.spacing.unit,
|
||||
paddingLeft: 2 * theme.spacing.unit
|
||||
},
|
||||
button: {
|
||||
margin: theme.spacing.unit
|
||||
},
|
||||
leftIcon: {
|
||||
marginRight: theme.spacing.unit
|
||||
},
|
||||
rightIcon: {
|
||||
marginLeft: theme.spacing.unit
|
||||
},
|
||||
iconSmall: {
|
||||
fontSize: 20
|
||||
}
|
||||
})
|
||||
|
||||
export default styles
|
||||
+41
-7
@@ -1,10 +1,19 @@
|
||||
import React, { Component } from 'react'
|
||||
import { Route, BrowserRouter, Switch } from 'react-router-dom'
|
||||
|
||||
import { MessageCard } from '@advancedalgos/web-components'
|
||||
import { getItem } from './utils/local-storage'
|
||||
|
||||
import TopBar from './Components/TopBar'
|
||||
import Search from './Components/Search'
|
||||
|
||||
const Base = () => (
|
||||
<p>
|
||||
Base component
|
||||
</p>
|
||||
<div>
|
||||
<p>Base component</p>
|
||||
<MessageCard message='That can also wrap other components' >
|
||||
<div className='loader'>Loading...</div>
|
||||
</MessageCard>
|
||||
</div>
|
||||
)
|
||||
|
||||
const Added = () => (
|
||||
@@ -14,13 +23,38 @@ const Added = () => (
|
||||
)
|
||||
|
||||
class App extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
user: null
|
||||
}
|
||||
}
|
||||
|
||||
async componentDidMount () {
|
||||
let user = await getItem('user')
|
||||
|
||||
if (user !== null && user !== undefined && user !== 'undefined') {
|
||||
user = JSON.parse(user)
|
||||
this.setState({ user: user })
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
let loggedIn
|
||||
if (this.state.user !== null) {
|
||||
loggedIn = (<TopBar match={this.props.match} user={this.state.user} />)
|
||||
} else {
|
||||
loggedIn = ''
|
||||
}
|
||||
return (
|
||||
<BrowserRouter basename={this.props.match.path}>
|
||||
<Switch>
|
||||
<Route exact path='/' component={Base} />
|
||||
<Route path='/added' component={Added} />
|
||||
</Switch>
|
||||
<div>
|
||||
{loggedIn}
|
||||
<Switch>
|
||||
<Route exact path='/' component={Search} />
|
||||
<Route path='/added' component={Added} />
|
||||
</Switch>
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export const toLocalTime = (epoch) => {
|
||||
let localDate = new Date(0)
|
||||
localDate.setUTCSeconds(epoch)
|
||||
return localDate.toString()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
const getItem = async name => window.localStorage.getItem(name)
|
||||
const setItem = async (name, value) => window.localStorage.setItem(name, value)
|
||||
const removeItem = async name => window.localStorage.removeItem(name)
|
||||
|
||||
export {
|
||||
getItem,
|
||||
setItem,
|
||||
removeItem
|
||||
}
|
||||
Reference in new issue
Block a user