diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 8e0c52d..7753a6d 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -9,7 +9,9 @@
"version": "0.0.0",
"dependencies": {
"axios": "^1.6.7",
+ "chart.js": "^4.4.2",
"vue": "^3.4.15",
+ "vue-chartjs": "^5.3.1",
"vue-router": "^4.2.5"
},
"devDependencies": {
@@ -402,6 +404,11 @@
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
+ "node_modules/@kurkle/color": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
+ "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
+ },
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz",
@@ -700,6 +707,17 @@
"proxy-from-env": "^1.1.0"
}
},
+ "node_modules/chart.js": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
+ "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
+ "dependencies": {
+ "@kurkle/color": "^0.3.0"
+ },
+ "engines": {
+ "pnpm": ">=8"
+ }
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -1035,6 +1053,15 @@
}
}
},
+ "node_modules/vue-chartjs": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.1.tgz",
+ "integrity": "sha512-rZjqcHBxKiHrBl0CIvcOlVEBwRhpWAVf6rDU3vUfa7HuSRmGtCslc0Oc8m16oAVuk0erzc1FCtH1VCriHsrz+A==",
+ "peerDependencies": {
+ "chart.js": "^4.1.1",
+ "vue": "^3.0.0-0 || ^2.7.0"
+ }
+ },
"node_modules/vue-router": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 7453b7d..5f8fecf 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -10,7 +10,9 @@
},
"dependencies": {
"axios": "^1.6.7",
+ "chart.js": "^4.4.2",
"vue": "^3.4.15",
+ "vue-chartjs": "^5.3.1",
"vue-router": "^4.2.5"
},
"devDependencies": {
diff --git a/frontend/src/api_client.js b/frontend/src/api_client.js
index 03ed6c7..3b0f5be 100644
--- a/frontend/src/api_client.js
+++ b/frontend/src/api_client.js
@@ -60,7 +60,7 @@ export default
}
return btoa(binary);
}
-
+
const response = await axios.get(`/api/category/${category_id}/image/`,
{
responseType: 'arraybuffer'
@@ -68,12 +68,20 @@ export default
return 'data:image/jpeg;base64,' + arrayBufferToBase64(response.data);
}
+ /**
+ * Get the current user IQ. It's the best players average IQ in all categories
+ * @returns {Object} {user_iq: Number}
+ */
+ static async getUserIQ(category_id) {
+ const response = await axios.get(`/api/category/${category_id}/user_iq`);
+ return response.data;
+ }
+
/**
* Get the global leaderboard. It's the best players average IQ in all categories
* @returns {Array} [{user_id: Number, user_name: String, user_score: Number}]
*/
- static async getGlobalLeaderboard()
- {
+ static async getGlobalLeaderboard() {
const response = await axios.get(`/api/rank/global_leaderboard/`);
return response.data;
}
@@ -81,8 +89,7 @@ export default
* Get the global leaderboard specific to a category. It's the players with the best IQ in this category id
* @returns {Array} [{user_id: Number, user_name: String, user_score: Number}]
*/
- static async getCategoryLeaderboard(category_id)
- {
+ static async getCategoryLeaderboard(category_id) {
const response = await axios.get(`/api/rank/${category_id}/leaderboard/`);
return response.data;
}
@@ -91,8 +98,7 @@ export default
* Get the global user rank based on average IQ in all categories of the connected player
* @returns {Object} {user_rank: Number, user_score: Number}
*/
- static async getGlobalUserRank()
- {
+ static async getGlobalUserRank() {
const response = await axios.get(`/api/rank/global_user/`);
return response.data;
}
@@ -101,8 +107,7 @@ export default
* Get the user rank specific to a category.
* @returns {Object} {user_rank: Number, user_score: Number}
*/
- static async getCategoryUserRank(category_id)
- {
+ static async getCategoryUserRank(category_id) {
const response = await axios.get(`/api/rank/${category_id}/user/`);
return response.data;
}
diff --git a/frontend/src/components/AnswerForm.vue b/frontend/src/components/AnswerForm.vue
index 8f0cd71..9722cb8 100644
--- a/frontend/src/components/AnswerForm.vue
+++ b/frontend/src/components/AnswerForm.vue
@@ -4,7 +4,7 @@ import { defineEmits, onMounted, ref, defineProps, watch } from 'vue';
import AnswerMessage from '@/components/AnswerMessage.vue';
// variables specific to this component
-const emit = defineEmits(['newQuestion'])
+const emit = defineEmits(['newQuestion', 'updateUserIq'])
const answer_sent = ref(false);
const show_text_form = ref(true);
const answer_text = ref("");
@@ -23,11 +23,13 @@ const props = defineProps({
const submitAnswerText = async () => {
response_to_answer.value = await APIClient.postAnswerText(answer_text.value);
answer_sent.value = true;
+ emit('updateUserIq');
}
const submitAnswerOption = async (id) => {
response_to_answer.value = await APIClient.postAnswerOption(id);
answer_sent.value = true;
+ emit('updateUserIq');
}
const fetchOptions = async () => {
diff --git a/frontend/src/components/GraphSection.vue b/frontend/src/components/GraphSection.vue
new file mode 100644
index 0000000..0211902
--- /dev/null
+++ b/frontend/src/components/GraphSection.vue
@@ -0,0 +1,68 @@
+
+
+
+ Progression
+
{{ question }}
-