-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit cd9cff1
Showing
13 changed files
with
5,288 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
~ | ||
.DS_Store | ||
config/database.yml | ||
config/secrets.yml | ||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: node index.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Tech stack | ||
|
||
|
||
# Commands | ||
|
||
## Data layer | ||
* yarn sequelize |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import axios from 'axios'; | ||
import _ from 'lodash'; | ||
|
||
import styles from './styles.scss'; | ||
|
||
const divisionTitles = { | ||
1: 'Individual men', | ||
2: 'Individual women', | ||
9: 'Masters men (60+)', | ||
12: 'Masters men (40-44)', | ||
13: 'Masters women (40-44)', | ||
18: 'Masters men (35-39)', | ||
}; | ||
|
||
class App extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
isLoading: true | ||
}; | ||
} | ||
|
||
componentWillMount() { | ||
const { apiBaseUrl, affiliate } = this.props; | ||
axios.get(`${apiBaseUrl}/affiliate/${affiliate}`) | ||
.then((response) => { | ||
const athletes = _.get(response, 'data.athletes'); | ||
const athletesByDivision = _.groupBy(athletes, 'divisionid'); | ||
console.log(athletesByDivision); | ||
this.setState({ | ||
isLoading: false, | ||
athletesByDivision: athletesByDivision, | ||
}); | ||
}) | ||
.catch((error) => { | ||
this.setState({ | ||
isError: true | ||
}); | ||
}); | ||
} | ||
|
||
openAthleteDetails(id) { | ||
window.open(`https://games.crossfit.com/athlete/${id}`); | ||
} | ||
|
||
render() { | ||
const { athletesByDivision } = this.state; | ||
const linkToWod = (name) => `https://games.crossfit.com/workouts/open/2017/${name}?division=2`; | ||
const linkToAthlete = (name) => `https://games.crossfit.com/workouts/open/2017/${name}?division=2`; | ||
|
||
const lists = _.map(athletesByDivision, (group, ix) => { | ||
const groupTitle = divisionTitles[ix]; | ||
const items = _.map(group, (athlete, ix) => { | ||
const rankInGroup = ix + 1; | ||
return ( | ||
<tr key={ix} onClick={this.openAthleteDetails.bind(this, athlete.userid)}> | ||
<td className="col1 center bold bigger">{rankInGroup}</td> | ||
<td className="col2"><img src={_.get(athlete, 'profilepic')} className="avatar hide-mobile"/><span>{athlete.name}</span></td> | ||
<td className="col3 center">{athlete.overallscore}</td> | ||
<td className="col4">{`${_.get(athlete, 'scores[0].workoutrank')}(${_.get(athlete, 'scores[0].scoredisplay')})`}</td> | ||
<td className="col5">{`${_.get(athlete, 'scores[1].workoutrank')}(${_.get(athlete, 'scores[1].scoredisplay')})`}</td> | ||
<td className="col6">{`${_.get(athlete, 'scores[2].workoutrank')}(${_.get(athlete, 'scores[2].scoredisplay')})`}</td> | ||
<td className="col7">{`${_.get(athlete, 'scores[3].workoutrank')}(${_.get(athlete, 'scores[3].scoredisplay')})`}</td> | ||
<td className="col8">{`${_.get(athlete, 'scores[4].workoutrank')}(${_.get(athlete, 'scores[4].scoredisplay')})`}</td> | ||
</tr> | ||
) | ||
}); | ||
return ( | ||
<div key={ix} className="division"> | ||
<div className="division__heading"> | ||
<h2>{groupTitle}</h2> | ||
</div> | ||
<table > | ||
<thead><tr> | ||
<th className="col1">Pos</th> | ||
<th className="col2">Name</th> | ||
<th className="col3">TTL PTS</th> | ||
<th className="col4"><a href={linkToWod('17.1')} target="_blank">17.1</a></th> | ||
<th className="col5"><a href={linkToWod('17.2')} target="_blank">17.2</a></th> | ||
<th className="col6"><a href={linkToWod('17.3')} target="_blank">17.3</a></th> | ||
<th className="col7"><a href={linkToWod('17.4')} target="_blank">17.4</a></th> | ||
<th className="col8"><a href={linkToWod('17.5')} target="_blank">17.5</a></th> | ||
</tr></thead> | ||
<tbody>{items}</tbody> | ||
</table> | ||
</div> | ||
); | ||
}); | ||
|
||
return ( | ||
<div> | ||
<header> | ||
<h1>Open 2017<span>Crossfit Lauttasaari</span></h1> | ||
</header> | ||
<section> | ||
{lists} | ||
</section> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
$red: #dc1d25; | ||
|
||
* { | ||
box-sizing: border-box; | ||
font-smoothing: antialiased; | ||
} | ||
|
||
body { | ||
font-family: 'Ubuntu', sans-serif; | ||
background-color: black; | ||
color: #fff; | ||
font-size: 100%; | ||
} | ||
|
||
h1, h2 { | ||
font-family: 'Raleway', sans-serif; | ||
} | ||
|
||
/** | ||
* UTILITIES | ||
*/ | ||
.center { | ||
text-align: center; | ||
} | ||
|
||
.bold { | ||
font-weight: 700; | ||
} | ||
|
||
.bigger { | ||
font-size: 1.2em; | ||
} | ||
|
||
#container { | ||
max-width: 1150px; | ||
margin: 0 auto; | ||
} | ||
|
||
h1 { | ||
font-size: 7em; | ||
line-height: 0.8em; | ||
text-transform: uppercase; | ||
letter-spacing: 0.1em; | ||
font-weight: 900; | ||
|
||
span { | ||
position: relative; | ||
top: -0.5em; | ||
display: block; | ||
letter-spacing: 0.1em; | ||
font-size: 0.2em; | ||
} | ||
} | ||
|
||
header .logo { | ||
overflow: hidden; | ||
border-radius: 50%; | ||
max-width: 150px; | ||
|
||
img { | ||
width: 100%; | ||
height: auto; | ||
} | ||
} | ||
|
||
.division__heading { | ||
h2 { | ||
position: relative; | ||
left: 1px; | ||
bottom: -1px; | ||
font-size: 1em; | ||
font-weight: normal; | ||
letter-spacing: 0.1em; | ||
font-family: 'Ubuntu', sans-serif; | ||
text-transform: uppercase; | ||
display: inline-block; | ||
padding: 1em 2em; | ||
margin: 0; | ||
border: 3px solid $red; | ||
border-bottom: 0 none; | ||
} | ||
} | ||
|
||
.division { | ||
margin-bottom: 5em; | ||
width: 100%; | ||
overflow: hidden; | ||
} | ||
|
||
table, th, td { | ||
border-collapse: collapse; | ||
border: 1px solid #101016; | ||
} | ||
|
||
table { | ||
width: 100%; | ||
border-top: 0 none; | ||
thead { | ||
background-color: $red; | ||
} | ||
th { | ||
text-align: center; | ||
text-transform: uppercase; | ||
padding: 1em; | ||
|
||
a, a:visited { | ||
font-weight: normal; | ||
text-decoration: none; | ||
color: white; | ||
border-bottom: 1px solid white; | ||
} | ||
} | ||
tr { | ||
cursor: pointer; | ||
|
||
&:nth-child(even) { | ||
background-color: #101016; | ||
} | ||
} | ||
tbody tr:hover { | ||
background-color: rgb(23, 23, 31); | ||
} | ||
td { | ||
text-transform: uppercase; | ||
padding: 0.5em; | ||
|
||
img { | ||
display: inline-block; | ||
vertical-align: middle; | ||
border-radius: 50%; | ||
border: 2px solid red; | ||
max-height: 50px; | ||
width: auto; | ||
margin-right: 1em; | ||
} | ||
} | ||
} | ||
|
||
@mixin hideColumn { | ||
display:none; | ||
width:0; | ||
height:0; | ||
opacity:0; | ||
visibility: collapse; | ||
} | ||
|
||
@media only screen and (max-width: 800px) { | ||
body { | ||
font-size: 10px; | ||
} | ||
// .hide-mobile { | ||
// display: none; | ||
// visibility: hidden; | ||
// width: 0; height: 0; | ||
// } | ||
.col4, .col5, .col6, .col7, .col8 { | ||
// @include hideColumn(); | ||
} | ||
} | ||
|
||
|
||
@media only screen and (max-width: 400px) { | ||
body { | ||
font-size: 10px; | ||
} | ||
.hide-mobile { | ||
display: none; | ||
visibility: hidden; | ||
width: 0; height: 0; | ||
} | ||
.col4, .col5, .col6, .col7, .col8 { | ||
@include hideColumn(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta name="viewport" content="width=device-width, maximum-scale=1.0" /> | ||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/images/favicon-16x16.png"> | ||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/images/favicon-32x32.png"> | ||
<link rel="shortcut icon" type="image/ico" href="/assets/images/favicon.ico"> | ||
<link href="https://fonts.googleapis.com/css?family=Raleway:400,500,600,900|Ubuntu:400,700"" rel="stylesheet"> | ||
</head> | ||
<body> | ||
<script type="text/javascript" src="/assets/js/app.js"></script> | ||
<div id="container"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import "babel-polyfill"; | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import App from './components/App'; | ||
|
||
document.addEventListener("DOMContentLoaded", () => { | ||
ReactDOM.render(<App apiBaseUrl="http://scrodde-mbp.local:8000/api" affiliate="7508" />, document.getElementById('container')); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
const _ = require('lodash'); | ||
const fs = require('fs'); | ||
const Hapi = require('hapi'); | ||
const parseArgs = require('minimist'); | ||
const path = require('path'); | ||
const yaml = require('js-yaml'); | ||
const rp = require('request-promise'); | ||
const cors = require('hapi-cors-headers'); | ||
|
||
/** | ||
* Configuration | ||
*/ | ||
const argv = parseArgs(process.argv.slice(2)); | ||
const port = process.env.PORT || 8000; | ||
const host = process.env.HOST || '0.0.0.0'; | ||
const env = process.env.NODE_ENV || 'development'; | ||
|
||
const server = new Hapi.Server(); | ||
server.connection({ | ||
host: host, | ||
port: port, | ||
}); | ||
|
||
/** | ||
* EXTENSIONS | ||
*/ | ||
server.ext('onPreResponse', cors); | ||
|
||
|
||
/** | ||
* Routes | ||
*/ | ||
server.route({ | ||
method: 'GET', | ||
path: '/api/affiliate/{id}', | ||
handler: function (request, reply) { | ||
rp(`https://games.crossfit.com/competitions/api/v1/competitions/open/2017/leaderboards?affiliate=${request.params.id}&page=1`) | ||
.then((body) => { | ||
json = JSON.parse(body); | ||
reply(json); | ||
}) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
} | ||
}); | ||
|
||
server.register(require('vision'), (err) => { | ||
if (err) { throw err; } | ||
|
||
server.views({ | ||
engines: { | ||
html: require('handlebars') | ||
}, | ||
relativeTo: __dirname, | ||
path: 'templates' | ||
}); | ||
|
||
server.route({ | ||
method: 'GET', | ||
path: '/', | ||
handler: (request, reply) => { | ||
reply.view('index'); | ||
} | ||
}); | ||
}); | ||
|
||
/** | ||
* Startup | ||
*/ | ||
server.start((err) => { | ||
if (err) { throw err }; | ||
console.log(`Server running at: ${server.info.uri}`); | ||
}); |
Oops, something went wrong.