Permalink
Please sign in to comment.
Showing
with
3,109 additions
and 0 deletions.
- +3 −0 .dockerignore
- +46 −0 .gitignore
- +36 −0 Dockerfile
- +26 −0 README.md
- +18 −0 components/languagebar.js
- +26 −0 components/progressbar.js
- +12 −0 components/quest.js
- +78 −0 components/questions.js
- +7 −0 config/index.js
- +73 −0 layouts/index.js
- +9 −0 lib/get-data.js
- +15 −0 package.json
- +15 −0 pages/index.js
- +2,745 −0 yarn.lock
| @@ -0,0 +1,3 @@ | ||
| +node_modules | ||
| +.next | ||
| +README.md |
46
.gitignore
| @@ -0,0 +1,46 @@ | ||
| +# IDE | ||
| +.idea | ||
| + | ||
| +# OS X | ||
| +.DS_Store | ||
| + | ||
| +# Logs | ||
| +logs | ||
| +*.log | ||
| +npm-debug.log* | ||
| + | ||
| +# Runtime data | ||
| +pids | ||
| +*.pid | ||
| +*.seed | ||
| + | ||
| +# Directory for instrumented libs generated by jscoverage/JSCover | ||
| +lib-cov | ||
| + | ||
| +# Coverage directory used by tools like istanbul | ||
| +coverage | ||
| +.nyc_output | ||
| + | ||
| +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
| +.grunt | ||
| + | ||
| +# node-waf configuration | ||
| +.lock-wscript | ||
| + | ||
| +# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
| +build/Release | ||
| + | ||
| +# Dependency directory | ||
| +node_modules | ||
| + | ||
| +# Optional npm cache directory | ||
| +.npm | ||
| + | ||
| +# Optional REPL history | ||
| +.node_repl_history | ||
| + | ||
| +# Coverage | ||
| +coverage | ||
| + | ||
| +# next | ||
| +.next |
36
Dockerfile
| @@ -0,0 +1,36 @@ | ||
| +########################################################### | ||
| +# | ||
| +# Dockerfile for bigfive-web | ||
| +# | ||
| +########################################################### | ||
| + | ||
| +# Setting the base to nodejs 7 | ||
| +FROM mhart/alpine-node:7 | ||
| + | ||
| +# Maintainer | ||
| +MAINTAINER Jonas Enge | ||
| + | ||
| +#### Begin setup #### | ||
| + | ||
| +# Extra tools for native dependencies | ||
| +RUN apk add --no-cache make gcc g++ python | ||
| + | ||
| +# Bundle app source | ||
| +COPY . /src | ||
| + | ||
| +# Change working directory | ||
| +WORKDIR "/src" | ||
| + | ||
| +# Env variables | ||
| +ENV SERVER_PORT 3000 | ||
| + | ||
| +# Install dependencies | ||
| +RUN npm install --production | ||
| + | ||
| +RUN npm run build | ||
| + | ||
| +# Expose 3000 | ||
| +EXPOSE ${SERVER_PORT} | ||
| + | ||
| +# Startup | ||
| +ENTRYPOINT npm run start |
26
README.md
| @@ -0,0 +1,26 @@ | ||
| +[](https://travis-ci.org/maccyber/bigfive-web) | ||
| +[](https://github.com/feross/standard) | ||
| +[](https://coveralls.io/github/maccyber/bigfive-web) | ||
| +[](https://codeclimate.com/github/maccyber/bigfive-web) | ||
| + | ||
| +# bigfive-web | ||
| + | ||
| +Website for five factor model of personality based on work at https://github.com/kholia/IPIP-NEO-PI | ||
| + | ||
| +## Example | ||
| +See https://bigfive.now.sh/ | ||
| + | ||
| +## Deploy using [Now](https://zeit.co/now) | ||
| + | ||
| +```sh | ||
| +$ now https://github.com/maccyber/bigfive-web | ||
| +``` | ||
| + | ||
| +## Development | ||
| + | ||
| +```sh | ||
| +git clone http://github.com/maccyber/bigfive-web | ||
| +cd bigfive-web | ||
| +npm i | ||
| +npm run dev | ||
| +``` |
| @@ -0,0 +1,18 @@ | ||
| +import React from 'react' | ||
| + | ||
| +export default ({switchLanguage, selectedLanguage}) => ( | ||
| + <div> | ||
| + Language: | ||
| + <span name='no' onClick={switchLanguage} className='lang' style={{ backgroundColor: selectedLanguage === 'no' ? '#e6e6e6' : '' }}>no</span> | ||
| + <span name='en' onClick={switchLanguage} className='lang' style={{ backgroundColor: selectedLanguage === 'en' ? '#e6e6e6' : '' }}>en</span> | ||
| + <style> | ||
| + {` | ||
| + .lang { | ||
| + padding: 2px; | ||
| + cursor: pointer; | ||
| + margin-left: 4px; | ||
| + } | ||
| + `} | ||
| + </style> | ||
| + </div> | ||
| +) |
| @@ -0,0 +1,26 @@ | ||
| +import React from 'react' | ||
| + | ||
| +export default ({progress}) => ( | ||
| + <div className='progress'> | ||
| + <span className='percent'>{progress}%</span> | ||
| + <div style={{width: progress + '%'}} className='bar' /> | ||
| + <style> | ||
| + {` | ||
| + .progress { | ||
| + background-color: #f1f1f1; | ||
| + padding: 3px; | ||
| + margin-top: 3%; | ||
| + } | ||
| + .percent { | ||
| + position: absolute; | ||
| + left: 50%; | ||
| + } | ||
| + .bar { | ||
| + height: 20px; | ||
| + background-color: #94d696; | ||
| + } | ||
| + `} | ||
| + </style> | ||
| + </div> | ||
| + | ||
| +) |
| @@ -0,0 +1,12 @@ | ||
| +import React from 'react' | ||
| + | ||
| +export default ({id, text, choises, handleRadioChange}) => ( | ||
| + <div onChange={handleRadioChange}> | ||
| + <p className='question'>{id}. {text}</p> | ||
| + {choises.map(c => { | ||
| + return ( | ||
| + <span key={id+c.val}><input name={id} type='radio' value={c.val} required /><label>{c.text}</label></span> | ||
| + ) | ||
| + })} | ||
| + </div> | ||
| +) |
| @@ -0,0 +1,78 @@ | ||
| +import config from '../config' | ||
| +import React from 'react' | ||
| +import getData from '../lib/get-data' | ||
| +import Progressbar from './progressbar' | ||
| +import Quest from './quest' | ||
| +import Languagebar from './languagebar' | ||
| + | ||
| +export default class Questions extends React.Component { | ||
| + constructor (props) { | ||
| + super(props) | ||
| + this.state = { | ||
| + data: [], | ||
| + choises: [], | ||
| + questions: [], | ||
| + radios: [], | ||
| + lang: config.defaultLanguage | ||
| + } | ||
| + this.handleRadioChange = this.handleRadioChange.bind(this) | ||
| + this.handleSubmit = this.handleSubmit.bind(this) | ||
| + this.switchLanguage = this.switchLanguage.bind(this) | ||
| + } | ||
| + | ||
| + async componentDidMount () { | ||
| + const data = await getData(`${config.dataUrl}?lang=${this.state.lang}`) | ||
| + this.setState({ data: data, questions: data.questions, choises: data.choises }) | ||
| + } | ||
| + | ||
| + handleRadioChange (e) { | ||
| + let arr = this.state.radios | ||
| + arr[e.target.name] = e.target.value | ||
| + this.setState({radios: arr}) | ||
| + } | ||
| + | ||
| + async switchLanguage (e) { | ||
| + const lang = e.target.getAttribute('name') | ||
| + const data = await getData(`${config.dataUrl}?page=${this.state.data.page}&lang=${lang}`) | ||
| + this.setState({ data: data, questions: data.questions, lang: lang, choises: data.choises }) | ||
| + } | ||
| + | ||
| + async handleSubmit (e) { | ||
| + e.preventDefault() | ||
| + console.log(this.state.radios) | ||
| + if (this.state.data.next) { | ||
| + const data = await getData(`${this.state.data.next}&lang=${this.state.lang}`) | ||
| + this.setState({ data: data, questions: data.questions }) | ||
| + } else { | ||
| + console.log('finished. do something') | ||
| + } | ||
| + } | ||
| + | ||
| + render () { | ||
| + return ( | ||
| + <form onSubmit={this.handleSubmit}> | ||
| + <Languagebar switchLanguage={this.switchLanguage} selectedLanguage={this.state.lang} /> | ||
| + <Progressbar progress={this.state.data.percentDone} /> | ||
| + {this.state.questions.map(q => { | ||
| + return ( | ||
| + <Quest key={q.id} id={q.id} text={q.text} choises={this.state.choises} handleRadioChange={this.handleRadioChange} /> | ||
| + ) | ||
| + })} | ||
| + <p> | ||
| + <button className='nextButton' type='submit'><i className='material-icons material-icons' style={{ fontSize: '48px' }}>navigate_next</i></button> | ||
| + </p> | ||
| + <style>{` | ||
| + .nextButton { | ||
| + background-color: #94d696; | ||
| + border-radius: 5px; | ||
| + border: transparent; | ||
| + color: white; | ||
| + } | ||
| + .question { | ||
| + font-size: 28px; | ||
| + } | ||
| + `}</style> | ||
| + </form> | ||
| + ) | ||
| + } | ||
| +} |
| @@ -0,0 +1,7 @@ | ||
| +'use strict' | ||
| + | ||
| +module.exports = { | ||
| + dataUrl: process.env.DATA_URL || 'https://bigfive-questions.now.sh/', | ||
| + defaultLanguage: process.env.DEFAULT_LANG || 'en' | ||
| +} | ||
| + |
| @@ -0,0 +1,73 @@ | ||
| +import React from 'react' | ||
| +import Head from 'next/head' | ||
| + | ||
| +export default ({pageTitle, children}) => ( | ||
| + <div> | ||
| + <Head> | ||
| + <meta charSet='utf-8' /> | ||
| + <meta name='viewport' content='width=device-width,initial-scale=1' /> | ||
| + <link href='https://fonts.googleapis.com/css?family=Oswald|Rubik:300' rel='stylesheet' /> | ||
| + <link href='https://fonts.googleapis.com/icon?family=Material+Icons' rel='stylesheet' /> | ||
| + <title>{pageTitle}</title> | ||
| + <style>{` | ||
| + body { | ||
| + font-family: 'Rubik', sans-serif; | ||
| + background: #eee; | ||
| + padding: 0; | ||
| + } | ||
| + a { | ||
| + text-transform: uppercase; | ||
| + color: #fff; | ||
| + } | ||
| + h1 { | ||
| + font-family: 'Oswald'; | ||
| + color: #fff; | ||
| + text-transform: uppercase; | ||
| + letter-spacing: 5px; | ||
| + } | ||
| + h2 { | ||
| + font-family: 'Oswald'; | ||
| + color: #fff; | ||
| + text-transform: uppercase; | ||
| + letter-spacing: 1px; | ||
| + font-size: 30px; | ||
| + color: #868686; | ||
| + } | ||
| + .container { | ||
| + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); | ||
| + width: 85%; | ||
| + margin: auto; | ||
| + } | ||
| + .header { | ||
| + background: #7eaf87; | ||
| + padding-left: 2%; | ||
| + padding-top: 7px; | ||
| + padding-bottom: 7px; | ||
| + border-bottom: 1px solid #6f6f6f; | ||
| + } | ||
| + .header a { | ||
| + padding: 0px 10px; | ||
| + word-wrap: normal; | ||
| + display: inline-block; | ||
| + } | ||
| + .page { | ||
| + color: #828282; | ||
| + background: #fff; | ||
| + } | ||
| + .page-text { | ||
| + padding: 2%; | ||
| + } | ||
| + `}</style> | ||
| + </Head> | ||
| + <div className='container'> | ||
| + <header className='header'> | ||
| + <h1></h1> | ||
| + </header> | ||
| + <div className='page'> | ||
| + <div className='page-text'> | ||
| + {children} | ||
| + </div> | ||
| + </div> | ||
| + </div> | ||
| + </div> | ||
| +) |
| @@ -0,0 +1,9 @@ | ||
| +'use strict' | ||
| + | ||
| +import fetch from 'isomorphic-fetch' | ||
| + | ||
| +module.exports = async (url) => { | ||
| + const dataResponse = await fetch(url) | ||
| + const data = await dataResponse.json() | ||
| + return data | ||
| +} |
15
package.json
| @@ -0,0 +1,15 @@ | ||
| +{ | ||
| + "name": "next-bigfive-web", | ||
| + "version": "1.0.0", | ||
| + "scripts": { | ||
| + "dev": "next", | ||
| + "build": "next build", | ||
| + "start": "next start" | ||
| + }, | ||
| + "dependencies": { | ||
| + "isomorphic-fetch": "2.2.1", | ||
| + "next": "1.2.3" | ||
| + }, | ||
| + "author": "", | ||
| + "license": "ISC" | ||
| +} |
| @@ -0,0 +1,15 @@ | ||
| +'use strict' | ||
| + | ||
| +import React from 'react' | ||
| +import Questions from '../components/questions' | ||
| +import Page from '../layouts' | ||
| + | ||
| +export default class Index extends React.Component { | ||
| + render () { | ||
| + return ( | ||
| + <Page pageTitle='Personality test'> | ||
| + <Questions /> | ||
| + </Page> | ||
| + ) | ||
| + } | ||
| +} |
Oops, something went wrong.
0 comments on commit
6461532