Finished creating result statistic views
This commit is contained in:
parent
187c52cd44
commit
96d751843a
23
client/src/components/icons/ChevronDoubleRight.vue
Normal file
23
client/src/components/icons/ChevronDoubleRight.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<svg-icon type="mdi" :path="path"></svg-icon>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import SvgIcon from '@jamescoyle/vue-icon'
|
||||
import { mdiChevronDoubleRight } from '@mdi/js'
|
||||
|
||||
export default {
|
||||
name: "mdiChefronDoubleRight",
|
||||
|
||||
components: {
|
||||
SvgIcon
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
path: mdiChevronDoubleRight,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -50,7 +50,7 @@
|
||||
<transition enter-active-class="transition ease-out duration-100" enter-from-class="transform opacity-0 scale-95" enter-to-class="transform opacity-100 scale-100" leave-active-class="transition ease-in duration-75" leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
|
||||
<MenuItems class="origin-top-right absolute right-0 mt-2 p-1 space-y-2 w-56 rounded-md shadow-lg bg-lime-700 ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||
<div class="py-1">
|
||||
<MenuItem v-slot="{ active }" v-for="route in $router.options.routes" :key="route.path" >
|
||||
<MenuItem v-slot="{ active }" v-for="route in $router.options.routes.filter( value => value.meta.index >= 0 )" :key="route.path" >
|
||||
<a :href="route.path" target="_blank" rel="noopener noreferrer" :class="[active ? 'text-orange-300' : 'text-white', 'flex px-4 py-2 active:text-orange-500 rounded-lg h-fit align-middle transition-all ease-in-out duration-500']" v-if="route.path.startsWith('http')">
|
||||
<div class="inline-flex px-3 py-1 space-x-1">
|
||||
<span class="scale-75">
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { mdiAccountBoxMultiple, mdiAccountGroupOutline, mdiAccountQuestion, mdiChartBox, mdiCodeTags, mdiCounter, mdiEarth, mdiHandCoin, mdiHome, mdiInformation, mdiWeb } from '@mdi/js'
|
||||
import { mdiAccountBoxMultiple, mdiAccountGroupOutline, mdiAccountQuestion, mdiChartBox, mdiCodeTags, mdiCompare, mdiCounter, mdiEarth, mdiHandCoin, mdiHome, mdiInformation, mdiWeb } from '@mdi/js'
|
||||
import About from '@/views/about/Index.vue'
|
||||
import AboutPage from '@/views/about/About.vue'
|
||||
import Acknowledgements from '@/views/about/Acknowledgements.vue'
|
||||
@ -13,8 +13,9 @@ import Refused from '@/views/errors/Refused.vue'
|
||||
import Results from '@/views/results/Index.vue'
|
||||
import ResultsPage from '@/views/results/Results.vue'
|
||||
import Scores from '@/views/results/Scores.vue'
|
||||
import Answers from '@/views/results/Answers.vue'
|
||||
import CompareAnswers from '@/views/results/CompareAnswers.vue'
|
||||
import Statistics from '@/views/results/Statistics.vue'
|
||||
import CompareResults from '@/views/results/CompareResults.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@ -144,17 +145,28 @@ const routes = [
|
||||
component: Scores,
|
||||
meta: {
|
||||
index: 1,
|
||||
title: 'All Scores',
|
||||
title: 'Your Scores',
|
||||
svgPath: mdiCounter,
|
||||
parentIndex: -1
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'compare',
|
||||
name: 'CompareResults',
|
||||
component: CompareResults,
|
||||
meta: {
|
||||
index: 2,
|
||||
title: 'Compare Results',
|
||||
svgPath: mdiCompare,
|
||||
parentIndex: -1
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'statistics',
|
||||
name: 'Statistics',
|
||||
component: Statistics,
|
||||
meta: {
|
||||
index: 2,
|
||||
index: 3,
|
||||
title: 'Statistics',
|
||||
svgPath: mdiChartBox,
|
||||
parentIndex: -1
|
||||
@ -163,10 +175,10 @@ const routes = [
|
||||
{
|
||||
path: 'answers',
|
||||
name: 'Answers',
|
||||
component: Answers,
|
||||
component: CompareAnswers,
|
||||
meta: {
|
||||
index: 3,
|
||||
title: 'Global Answers',
|
||||
index: 4,
|
||||
title: 'Compare Answers',
|
||||
svgPath: mdiEarth,
|
||||
parentIndex: -1
|
||||
}
|
||||
|
@ -4,15 +4,19 @@ export const useAppStore = defineStore({
|
||||
id: 'app',
|
||||
state: () => ({
|
||||
hasData: false,
|
||||
results: {}
|
||||
answers: [],
|
||||
playbooks: {},
|
||||
results: {},
|
||||
scores: {},
|
||||
count: null
|
||||
}),
|
||||
actions: {
|
||||
toggleData() {
|
||||
this.hasData = !this.hasData
|
||||
console.log('Toggled Has Data. New value', this.hasData)
|
||||
},
|
||||
storeResults(results) {
|
||||
this.results = JSON.parse(JSON.stringify(results))
|
||||
store(key, data) {
|
||||
this[key] = JSON.parse(JSON.stringify(data))
|
||||
}
|
||||
}
|
||||
})
|
@ -93,7 +93,7 @@
|
||||
}
|
||||
}
|
||||
).then( (response) => {
|
||||
this.appStore.storeResults(response.data)
|
||||
this.appStore.store('results', response.data)
|
||||
console.log('Results fetched from the server.')
|
||||
this.$router.push('/results')
|
||||
}).catch( (error) => {
|
||||
@ -125,7 +125,7 @@
|
||||
<div v-for="(answer, index) in questionStore.questions[this.id].answers" :key="`q${this.id}-o${index}`" class="inline-flex">
|
||||
<input :type="this.questionStore.questions[this.id].select > 1 ? 'checkbox' : 'radio'" class="checkbox" :id="`q${this.id}-o${index}`" :value=index :key="`q${this.id}-o${index}`" v-model="answersStore.answers[this.id]" :disabled="this.questionStore.questions[this.id].select > 1 && this.answersStore.answers[this.id].length == this.questionStore.questions[this.id].select && !this.answersStore.answers[this.id].includes(index)">
|
||||
<label :for="`q${this.id}-o${index}`">
|
||||
<div v-html="answer" class="uncial-antiqua w-full h-full p-2 transition-all duration-100 ease-in-out hover:bg-lime-200 hover:text-orange-600 hover:cursor-pointer" :aria-label="answer" :title="answer"></div>
|
||||
<div v-html="answer" class="uncial-antiqua w-full h-full p-2 select-none transition-all duration-100 ease-in-out hover:bg-lime-200 hover:text-orange-600 hover:cursor-pointer" :aria-label="answer" :title="answer"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -14,7 +14,7 @@
|
||||
<template>
|
||||
<TextFrame>
|
||||
<Header>
|
||||
Global Answers
|
||||
Compare Answers
|
||||
</Header>
|
||||
<Content>
|
||||
|
101
client/src/views/results/CompareResults.vue
Normal file
101
client/src/views/results/CompareResults.vue
Normal file
@ -0,0 +1,101 @@
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import Config from '@/config.js'
|
||||
import Content from '@/components/Content.vue'
|
||||
import Header from '@/components/Header.vue'
|
||||
import TextFrame from '@/components/TextFrame.vue'
|
||||
import { useAppStore } from '@/stores/app.js'
|
||||
import ChevronDoubleRight from '@/components/icons/ChevronDoubleRight.vue'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const appStore = useAppStore()
|
||||
|
||||
return {
|
||||
appStore
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getResults()
|
||||
},
|
||||
name: 'CompareResults',
|
||||
components: {
|
||||
ChevronDoubleRight,
|
||||
Content,
|
||||
Header,
|
||||
TextFrame
|
||||
},
|
||||
methods: {
|
||||
getResults() {
|
||||
axios.get(`${Config.SERVER}api/playbooks/`)
|
||||
.then((response) => {
|
||||
this.error = false
|
||||
this.appStore.store('playbooks', response.data)
|
||||
})
|
||||
.catch( error => {
|
||||
this.$router.push('/err_refused')
|
||||
})
|
||||
axios.get(`${Config.SERVER}api/count/`)
|
||||
.then((response) => {
|
||||
this.error = false
|
||||
this.appStore.store('count', response.data)
|
||||
})
|
||||
.catch( error => {
|
||||
this.$router.push('/err_refused')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<TextFrame>
|
||||
<Header>
|
||||
Compare Results
|
||||
</Header>
|
||||
<Content>
|
||||
<p class="text-leader">
|
||||
Based on others who have taken this quiz, here are the playbooks of fellow travellers you are likely to meet along the way.
|
||||
</p>
|
||||
<table class="table-auto w-full max-w-sm mx-auto text-left">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-lime-100 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th>
|
||||
|
||||
</th>
|
||||
<th>
|
||||
Playbook
|
||||
</th>
|
||||
<th>
|
||||
Number
|
||||
</th>
|
||||
<th>
|
||||
Percentage
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(number, playbook, index) in this.appStore.playbooks" :key="playbook" class="hover:bg-yellow-50" :class="index % 2 == 0? `bg-lime-50 border-b dark:bg-gray-900 dark:border-gray-700` : `bg-lime-100 border-b dark:bg-gray-800 dark:border-gray-700`">
|
||||
<td v-if="this.appStore.results.playbooks.some(obj => obj.hasOwnProperty(playbook))">
|
||||
<ChevronDoubleRight/>
|
||||
</td>
|
||||
<td v-else>
|
||||
|
||||
</td>
|
||||
<td scope="col" class="py-1 capitalize">
|
||||
The {{ playbook }}
|
||||
</td>
|
||||
<td scope="col" class="py-1">
|
||||
{{ number }}
|
||||
</td>
|
||||
<td scope="col" class="py-1">
|
||||
{{ Math.round(100*number/this.appStore.count) }} %
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-lg">Out of a total {{ this.appStore.count }} users</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Content>
|
||||
</TextFrame>
|
||||
</template>
|
@ -49,12 +49,11 @@
|
||||
<section v-for="playbook in this.appStore.results.playbooks" :key="Object.keys(playbook)[0]" class="border-solid border-b-2 border-lime-600 border-opacity-25">
|
||||
<h2 class="flex justify-between">
|
||||
<span class="uncial-antiqua align-bottom">
|
||||
<span class="text-xl">The</span> <span class="text-3xl">{{ Object.keys(playbook)[0].slice(0,1).toUpperCase()+Object.keys(playbook)[0].slice(1) }}</span>
|
||||
<span class="text-xl">The</span> <span class="text-3xl capitalize">{{ Object.keys(playbook)[0] }}</span>
|
||||
</span>
|
||||
<span class="text-sm">Pages {{ Object.values(playbook)[0].pages }}</span>
|
||||
</h2>
|
||||
<p class="text-leader">
|
||||
{{ Object.values(playbook)[0].flavour }}
|
||||
<p class="text-leader" v-html="Object.values(playbook)[0].flavour">
|
||||
</p>
|
||||
<p>
|
||||
{{ Object.values(playbook)[0].blurb }}
|
||||
|
@ -23,16 +23,16 @@
|
||||
<template>
|
||||
<TextFrame>
|
||||
<Header>
|
||||
Scores
|
||||
Your Scores
|
||||
</Header>
|
||||
<Content>
|
||||
<p>
|
||||
The following are your scores for each playbook:
|
||||
<p class="text-leader">
|
||||
While the playbook you are is the one most reflected by your answers, here are the other playbooks and the extent to which they have a bearing upon your journey.
|
||||
</p>
|
||||
<table class="table-auto w-full max-w-xs mx-auto">
|
||||
<thead>
|
||||
<table class="table-auto w-full max-w-sm mx-auto text-left">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-lime-100 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th>
|
||||
<th class="pl-10">
|
||||
Playbook
|
||||
</th>
|
||||
<th>
|
||||
@ -41,11 +41,11 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(score, playbook) in this.appStore.results.all_playbooks" :key="playbook">
|
||||
<td>
|
||||
The {{ playbook.slice(0,1).toUpperCase() + playbook.slice(1) }}
|
||||
<tr v-for="(score, playbook, index) in this.appStore.results.all_playbooks" :key="playbook" class="hover:bg-yellow-50" :class="index % 2 == 0? `bg-lime-50 border-b dark:bg-gray-900 dark:border-gray-700` : `bg-lime-100 border-b dark:bg-gray-800 dark:border-gray-700`">
|
||||
<td scope="col" class="py-1 pl-10 capitalize">
|
||||
The {{ playbook }}
|
||||
</td>
|
||||
<td>
|
||||
<td scope="col" class="py-1">
|
||||
{{ Math.round(100*score/this.appStore.results.max_score) }} %
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,13 +1,49 @@
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import Config from '@/config.js'
|
||||
import Content from '@/components/Content.vue'
|
||||
import Header from '@/components/Header.vue'
|
||||
import TextFrame from '@/components/TextFrame.vue'
|
||||
import { useAppStore } from '@/stores/app.js'
|
||||
import ChevronDoubleRight from '@/components/icons/ChevronDoubleRight.vue'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const appStore = useAppStore()
|
||||
|
||||
return {
|
||||
appStore
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getScores()
|
||||
},
|
||||
name: 'Statistics',
|
||||
components: {
|
||||
ChevronDoubleRight,
|
||||
Content,
|
||||
Header,
|
||||
TextFrame
|
||||
},
|
||||
methods: {
|
||||
getScores() {
|
||||
axios.get(`${Config.SERVER}api/scores/`)
|
||||
.then((response) => {
|
||||
this.error = false
|
||||
this.appStore.store('scores', response.data)
|
||||
})
|
||||
.catch( error => {
|
||||
this.$router.push('/err_refused')
|
||||
})
|
||||
axios.get(`${Config.SERVER}api/count/`)
|
||||
.then((response) => {
|
||||
this.error = false
|
||||
this.appStore.store('count', response.data)
|
||||
})
|
||||
.catch( error => {
|
||||
this.$router.push('/err_refused')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -17,7 +53,62 @@
|
||||
Statistics
|
||||
</Header>
|
||||
<Content>
|
||||
<p class="text-leader">
|
||||
Sometimes, it can help to have some additional insight into the likelihood of meeting different people.
|
||||
Or, indeed, it can provide insight into how the questions we ask of each other bias the way we perceive the world.
|
||||
</p>
|
||||
<table class="table-auto w-full max-w-lg mx-auto text-left">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-lime-100 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th>
|
||||
|
||||
</th>
|
||||
<th>
|
||||
Playbook
|
||||
</th>
|
||||
<th>
|
||||
Your Score
|
||||
</th>
|
||||
<th>
|
||||
Mean Score
|
||||
</th>
|
||||
<th>
|
||||
Median Score
|
||||
</th>
|
||||
<th>
|
||||
Standard Deviation
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(stats, playbook, index) in this.appStore.scores" :key="playbook" class="hover:bg-yellow-50" :class="index % 2 == 0? `bg-lime-50 border-b dark:bg-gray-900 dark:border-gray-700` : `bg-lime-100 border-b dark:bg-gray-800 dark:border-gray-700`">
|
||||
<td v-if="this.appStore.results.playbooks.some(obj => obj.hasOwnProperty(playbook))">
|
||||
<ChevronDoubleRight/>
|
||||
</td>
|
||||
<td v-else>
|
||||
|
||||
</td>
|
||||
<td scope="col" class="py-1 capitalize">
|
||||
The {{ playbook }}
|
||||
</td>
|
||||
<td>
|
||||
{{ Math.round(100*this.appStore.results.all_playbooks[playbook]/this.appStore.results.max_score) }}
|
||||
</td>
|
||||
<td scope="col" class="py-1">
|
||||
{{ Math.round(stats.mean * 100) / 100 }}
|
||||
</td>
|
||||
<td scope="col" class="py-1">
|
||||
{{ Math.round(stats.median * 100) / 100 }}
|
||||
</td>
|
||||
<td>
|
||||
{{ Math.round(stats.standard_deviation * 100) / 100 }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-lg">Out of a total {{ this.appStore.count }} users</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Content>
|
||||
</TextFrame>
|
||||
</template>
|
Loading…
Reference in New Issue
Block a user