Permalink
Browse files

psychic waffles

1 parent 10aaa3e commit fe1e146fafa155a76a9251097ad9a67a2a8335ef maccyber committed Feb 14, 2017
Showing with 411 additions and 187 deletions.
  1. +5 −0 Dockerfile
  2. +3 −0 README.md
  3. +18 −0 components/loading.js
  4. +2 −2 components/navbuttons.js
  5. +89 −0 components/person-info.js
  6. +29 −20 components/thetest.js
  7. +1 −1 components/timer.js
  8. +4 −2 config/index.js
  9. +3 −4 lib/get-data.js
  10. +3 −1 lib/is-all-checked.js
  11. +8 −0 lib/post-data.js
  12. +2 −1 package.json
  13. +15 −0 pages/100.js
  14. +15 −0 pages/120.js
  15. +15 −0 pages/50.js
  16. +7 −1 pages/index.js
  17. +21 −0 pages/info.js
  18. +1 −0 static/loading.svg
  19. +170 −155 yarn.lock
View
@@ -23,6 +23,11 @@ WORKDIR "/src"
# Env variables
ENV SERVER_PORT 3000
+ENV DATA_URL https://micro-bigfive-questions-olegrjzdba.now.sh/getQuestions
+ENV GENERATOR_URL https://micro-bigfive-generator.maccyber.io/post
+ENV DEFAULT_LANG en
+ENV DEFAULT_LIMIT 5
+ENV DEFAULT_TEST 50
# Install dependencies
RUN npm install --production
View
@@ -9,7 +9,10 @@ Website for five factor model of personality based on work at https://github.com
Using [next.js](https://github.com/zeit/next.js) framework and [micro](https://github.com/zeit/micro) services:
* [micro-bigfive-questions](https://github.com/maccyber/micro-bigfive-questions)
+ * [micro-bigfive-results-generator](https://github.com/maccyber/micro-bigfive-results-generator)
* [micro-bigfive-evaluator](https://github.com/maccyber/micro-bigfive-evaluator)
+ * [micro-bigfive-results](https://github.com/maccyber/micro-bigfive-results)
+ * [micro-bigfive-save](https://github.com/maccyber/micro-bigfive-save)
## Example
See https://bigfive.maccyber.io (not finished)
View
@@ -0,0 +1,18 @@
+import React from 'react'
+
+export default ({loading}) => (
+ <span style={{display: loading ? 'block' : 'none'}} className='loading'>
+ <p>
+ <img src='static/loading.svg' style={{width: 100}} />
+ </p>
+ <p>
+ <big>LOADING ...</big></p>
+ <style>
+ {`
+ .loading {
+ text-align: center;
+ }
+ `}
+ </style>
+ </span>
+)
View
@@ -3,12 +3,12 @@ import React from 'react'
export default ({prevPage, previous, submitDisabled}) => (
<p>
<button type='button' className='navButton navButtonBack' onClick={prevPage} disabled={!previous}>
- <i className='material-icons material-icons' style={{ fontSize: '40px' }}>
+ <i className='material-icons' style={{ fontSize: '40px' }}>
navigate_before
</i>
</button>
<button className='navButton' type='submit' disabled={submitDisabled}>
- <i className='material-icons material-icons' style={{ fontSize: '40px' }}>
+ <i className='material-icons' style={{ fontSize: '40px' }}>
navigate_next
</i>
</button>
View
@@ -0,0 +1,89 @@
+import React from 'react'
+const countries = require('country-list')()
+
+export default ({loading}) => (
+ <div>
+ <form>
+ <p className='question'>Information</p>
+ By taking the test you are agreeing that the input you provide will be saved and used for statistics.
+ <ul>
+ <li className='infoText'>
+ Answer honestly, even if you don't like the answer.
+ </li>
+ <li className='infoText'>
+ Describe yourself as you generally are now, not as you wish to be in the future.
+ </li>
+ <li className='infoText'>
+ Compare yourself in relation to other people of the same sex and roughly the same age.
+ </li>
+ <li className='infoText'>
+ Your spontaneous answer is usually the most accurate.
+ </li>
+ </ul>
+ <p className='question'>Age</p>
+ <input name='age' className='age' type='text' placeholder='Age' pattern="\d*" maxLength='2' min='10' max='100' />
+ <p className='question'>Gender</p>
+ <span className='choiseBox'>
+ <i name='female' className='material-icons checked-female'>radio_button_checked</i>
+ <span className='choiseText'>Female</span>
+ <i name='male' className='material-icons checked-male'>radio_button_unchecked</i>
+ <span className='choiseText'>Male</span>
+ </span>
+ <span className='choiseBox'>
+ <p className='question'>Nationality</p>
+ <select className='countries'>
+ {countries.getData().map(country => {
+ return (
+ <option key={country.code} value={country.code}>{country.name}</option>
+ )
+ })}
+ </select>
+ </span>
+ <span>
+ <p style={{marginTop: '50px'}}>
+ <button className='navButton' type='submit'>
+ <i className='material-icons' style={{ fontSize: '40px' }}>navigate_next</i>
+ </button>
+ </p>
+ </span>
+ </form>
+ <style>
+ {`
+ .age {
+ font-size: 24px;
+ background-color: #fff;
+ color: #828282;
+ width: 64px;
+ }
+ .countries {
+ font-size: 24px;
+ background-color: #fff;
+ color: #828282;
+ }
+ .checked-female {
+ color: #dfa7e8;
+ }
+ .checked-male {
+ color: #a7cfe8;
+ }
+ .infoText { padding-bottom: 8px; }
+ .navButton {
+ background-color: #94d696;
+ border-radius: 5px;
+ border: transparent;
+ color: white;
+ margin-right: 10px;
+ }
+ .question {
+ font-size: 28px;
+ margin-bottom: 10px;
+ }
+ .choiseText {
+ line-height: 24px;
+ padding: 4px;
+ vertical-align: top;
+ }
+ `}
+ </style>
+ </div>
+)
View
@@ -1,26 +1,28 @@
import React from 'react'
import config from '../config'
import getData from '../lib/get-data'
+import postData from '../lib/post-data'
import isAllChecked from '../lib/is-all-checked'
import Progressbar from './progressbar'
import Questions from './questions'
import Languagebar from './languagebar'
+import Loading from './loading'
import Navbuttons from './navbuttons'
import TimerExample from './timer'
export default class TheTest extends React.Component {
constructor (props) {
super(props)
this.state = {
- loading: '',
+ loading: true,
choises: [],
questions: [],
languages: [],
radios: [],
lang: config.defaultLanguage,
- choosenTest: config.defaultTest,
+ choosenTest: props.test || config.defaultTest,
submitDisabled: true,
- now: Date.now()
+ now: Date.now(),
}
this.handleRadioChange = this.handleRadioChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
@@ -29,15 +31,15 @@ export default class TheTest extends React.Component {
}
async componentDidMount () {
- const data = await getData(`${config.dataUrl}?lang=${this.state.lang}&testType=${this.state.choosenTest}`)
- this.setState({ ...data, loading: 'Not' })
+ const data = await getData(`${config.dataUrl}?lang=${this.state.lang}&testType=${this.state.choosenTest}&limit=${config.defaultLimit}`)
+ this.setState({ ...data, loading: false })
}
handleRadioChange (e) {
let radioStore = this.state.radios
const selectedName = parseInt(e.currentTarget.getAttribute('name'))
const selectedValue = parseInt(e.currentTarget.getAttribute('value'))
- const {domain, facet} = this.state.questions.filter(c => c.id === selectedName)[0]
+ const {domain, facet} = this.state.questions.find(c => c.id === selectedName)
radioStore[selectedName] = {score: selectedValue, domain: domain, facet: facet}
this.setState({radios: radioStore})
const allChecked = isAllChecked(radioStore, this.state.from, this.state.to)
@@ -46,37 +48,51 @@ export default class TheTest extends React.Component {
async switchLanguage (e) {
const lang = e.target.getAttribute('name')
- const data = await getData(`${config.dataUrl}?page=${this.state.page}&lang=${lang}&testType=${this.state.choosenTest}`)
+ const data = await getData(`${config.dataUrl}?page=${this.state.page}&lang=${lang}&testType=${this.state.choosenTest}&limit=${config.defaultLimit}`)
this.setState({ ...data, lang: lang })
}
async prevPage (e) {
if (this.state.previous) {
- const data = await getData(`${this.state.previous}&lang=${this.state.lang}&testType=${this.state.choosenTest}`)
+ const data = await getData(`${this.state.previous}&lang=${this.state.lang}&testType=${this.state.choosenTest}&limit=${config.defaultLimit}`)
this.setState({ ...data, submitDisabled: false })
}
}
async handleSubmit (e) {
e.preventDefault()
if (this.state.next) {
- const data = await getData(`${this.state.next}&lang=${this.state.lang}&testType=${this.state.choosenTest}`)
+ const data = await getData(`${this.state.next}&lang=${this.state.lang}&testType=${this.state.choosenTest}&limit=${config.defaultLimit}`)
this.setState({ ...data, submitDisabled: true })
window.scrollTo(0, 0) // Scrolls to top of page
} else {
console.log('To be posted')
- console.log(JSON.stringify(this.state.radios, null, 2))
+ this.state.radios.shift()
+ const answers = {
+ timeElapsed: Math.round((this.state.now - Date.now()) / 1000),
+ ip: this.props.ip,
+ browserAgent: this.props.browserAgent,
+ lang: this.state.lang,
+ test: this.state.testInfo.test,
+ totalQuestions: this.state.totalQuestions,
+ answers: this.state.radios
+ }
+ console.log(JSON.stringify(answers, null, 2))
+ const postRes = await postData(config.generatorUrl, answers)
+ console.log(postRes.id)
console.log('finished. do something')
}
}
render () {
return (
<form onSubmit={this.handleSubmit}>
- <TimerExample start={this.state.now} />
- <Languagebar switchLanguage={this.switchLanguage} selectedLanguage={this.state.lang} languages={this.state.languages} />
+ <div>
+ <TimerExample start={this.state.now} />
+ <Languagebar switchLanguage={this.switchLanguage} selectedLanguage={this.state.lang} languages={this.state.languages} />
+ </div>
<Progressbar progress={this.state.percentDone} />
- <span className={'loading' + this.state.loading}><big>LOADING ...</big></span>
+ <Loading loading={this.state.loading} />
{this.state.questions.map(q => {
return (
<Questions key={'Q' + q.id} {...q} radioSelected={this.state.radios} handleRadioChange={this.handleRadioChange} />
@@ -126,13 +142,6 @@ export default class TheTest extends React.Component {
.timer {
float: right;
}
- .loading {
- font-size: 40px;
- line-height: 200px;
- }
- .loadingNot {
- display: none;
- }
`}</style>
</form>
)
View
@@ -19,6 +19,6 @@ export default class Timer extends React.Component {
}
render () {
let seconds = Math.round(this.state.elapsed / 1000)
- return <p className='timer'>Test started <b>{seconds} seconds</b> ago</p>
+ return <div className='timer'>Test started <b>{seconds} seconds</b> ago</div>
}
}
View
@@ -1,8 +1,10 @@
'use strict'
module.exports = {
- dataUrl: process.env.DATA_URL || 'https://micro-bigfive-questions-olegrjzdba.now.sh/getQuestions',
+ dataUrl: process.env.DATA_URL || 'https://bigfive-questions.maccyber.io/getQuestions',
+ generatorUrl: process.env.GENERATOR_URL || 'https://micro-bigfive-save-cmfdczkdwn.now.sh',
defaultLanguage: process.env.DEFAULT_LANG || 'en',
- defaultTest: process.env.DEFAULT_TEST || '50'
+ defaultLimit: parseInt(process.env.DEFAULT_LIMIT) || 5,
+ defaultTest: process.env.DEFAULT_TEST || 50
}
View
@@ -1,9 +1,8 @@
'use strict'
-import fetch from 'isomorphic-fetch'
+import axios from 'axios'
module.exports = async (url) => {
- const dataResponse = await fetch(url)
- const data = await dataResponse.json()
- return data
+ const res = await axios.get(url)
+ return res.data
}
View
@@ -1,6 +1,8 @@
'use strict'
+import config from '../config'
+
module.exports = (radios, from, to) => {
const currentQuestions = radios.slice(from, to)
- return Object.keys(currentQuestions).length === 5
+ return Object.keys(currentQuestions).length === config.defaultLimit
}
View
@@ -0,0 +1,8 @@
+'use strict'
+
+import axios from 'axios'
+
+module.exports = async (url, data) => {
+ const res = await axios.post(url, data)
+ return res.data
+}
View
@@ -31,7 +31,8 @@
"start": "next start"
},
"dependencies": {
- "isomorphic-fetch": "2.2.1",
+ "axios": "0.15.3",
+ "country-list": "1.1.0",
"next": "1.2.3"
}
}
View
@@ -0,0 +1,15 @@
+'use strict'
+
+import React from 'react'
+import TheTest from '../components/thetest'
+import Page from '../layouts'
+
+export default class Index extends React.Component {
+ render () {
+ return (
+ <Page pageTitle='BigFive Personality Test'>
+ <TheTest test='100' />
+ </Page>
+ )
+ }
+}
View
@@ -0,0 +1,15 @@
+'use strict'
+
+import React from 'react'
+import TheTest from '../components/thetest'
+import Page from '../layouts'
+
+export default class Index extends React.Component {
+ render () {
+ return (
+ <Page pageTitle='BigFive Personality Test'>
+ <TheTest test='120' />
+ </Page>
+ )
+ }
+}
View
@@ -0,0 +1,15 @@
+'use strict'
+
+import React from 'react'
+import TheTest from '../components/thetest'
+import Page from '../layouts'
+
+export default class Index extends React.Component {
+ render () {
+ return (
+ <Page pageTitle='BigFive Personality Test'>
+ <TheTest test='50' />
+ </Page>
+ )
+ }
+}
View
@@ -5,10 +5,16 @@ import TheTest from '../components/thetest'
import Page from '../layouts'
export default class Index extends React.Component {
+ static async getInitialProps ({ req }) {
+ return {
+ userAgent: req ? req.headers['user-agent'] : navigator.userAgent,
+ ip: req.headers['x-forwarded-for'] || req.socket.remoteAddress
+ }
+ }
render () {
return (
<Page pageTitle='BigFive Personality Test'>
- <TheTest />
+ <TheTest userAgent={this.props.userAgent} ip={this.props.ip} />
</Page>
)
}
Oops, something went wrong.

0 comments on commit fe1e146

Please sign in to comment.