From 0abeab8207c31f95411525b6536fd01ec317e273 Mon Sep 17 00:00:00 2001 From: Antoine Rochebois <antoine.rochebois@insa-lyon.fr> Date: Sun, 27 Dec 2020 17:27:59 +0100 Subject: [PATCH] added encoded frontend --- client/package-lock.json | 59 +++++++++++++++++++++ client/package.json | 3 ++ client/src/App.vue | 23 +++++--- client/src/components/Encoder.vue | 70 +++++++++++++++++++++++++ client/src/components/PageFooter.vue | 20 +++---- client/src/components/SchoolManager.vue | 12 ++--- client/src/components/TeamElement.vue | 30 ++++++++--- client/src/main.js | 6 +++ 8 files changed, 192 insertions(+), 31 deletions(-) create mode 100644 client/src/components/Encoder.vue diff --git a/client/package-lock.json b/client/package-lock.json index 3b137fd..608d2b0 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -2264,6 +2264,17 @@ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true }, + "clipboard": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", + "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "clipboardy": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", @@ -2320,6 +2331,11 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "codejar": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/codejar/-/codejar-3.2.3.tgz", + "integrity": "sha512-zgWotUNz9c+nvYtGxmhwu4RxK1QWPRJvCjGk6LNm7pSwXEaEkY8Q6CQs8uZTNvoGyBVtKrt7C24OdXTyNZ17Xg==" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -3261,6 +3277,12 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "optional": true + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -4683,6 +4705,15 @@ "minimatch": "~3.0.2" } }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -8580,6 +8611,14 @@ "renderkid": "^2.0.4" } }, + "prismjs": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.22.0.tgz", + "integrity": "sha512-lLJ/Wt9yy0AiSYBf212kK3mM5L8ycwlyTlSxHBAneXLR0nzFMlZ5y7riFPF3E33zXOF2IH95xdY5jIyZbM9z/w==", + "requires": { + "clipboard": "^2.0.0" + } + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -9429,6 +9468,12 @@ } } }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "optional": true + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -10546,6 +10591,12 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "optional": true + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -11207,6 +11258,14 @@ } } }, + "vue-prismjs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vue-prismjs/-/vue-prismjs-1.2.0.tgz", + "integrity": "sha512-1mICbMknMiKw4mfM1AU7vkFT3VX4Cq8ySyDU7IBr9tYW1fzxIPkfLoERkRMbQLBc+J74K3FIiuuZ+WfBjO3SCQ==", + "requires": { + "prismjs": "^1.6.0" + } + }, "vue-router": { "version": "3.4.9", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.9.tgz", diff --git a/client/package.json b/client/package.json index 52ef741..1fe03d4 100644 --- a/client/package.json +++ b/client/package.json @@ -11,9 +11,12 @@ "@fortawesome/fontawesome-free": "^5.15.1", "axios": "^0.21.1", "bulma": "^0.9.1", + "codejar": "^3.2.3", "js-cookie": "^2.2.1", + "prismjs": "^1.22.0", "vue": "^2.6.11", "vue-axios": "^3.2.0", + "vue-prismjs": "^1.2.0", "vue-router": "^3.4.9", "vuex": "^3.6.0", "vuex-persistedstate": "^4.0.0-beta.1" diff --git a/client/src/App.vue b/client/src/App.vue index f7eaf3a..a6928f0 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -18,9 +18,15 @@ </div> <div id="navMenu" class="navbar-menu" :class="{ 'is-active': showNav }"> <div class="navbar-start"> + <a class="navbar-item" + ><router-link to="/encoder" + ><i class="fas fa-code" /> Encodeur NFC</router-link + ></a + > <a class="navbar-item" ><router-link to="/legal" - ><i class="fas fa-balance-scale" /> Mentions légales</router-link + ><i class="fas fa-balance-scale" /> Mentions + légales</router-link ></a > <a v-if="$store.state.isLoggedIn" class="navbar-item" @@ -46,12 +52,15 @@ ><router-link to="/login" ><span ><i class="fas fa-sign-in-alt"></i> Connexion</span - ></router-link></a> + ></router-link + ></a + > <a v-if="$store.state.isLoggedIn" class="navbar-item button is-danger" @click="logout()" - ><span><i class="fas fa-sign-out-alt"></i> Déconnexion</span></a> + ><span><i class="fas fa-sign-out-alt"></i> Déconnexion</span></a + > </div> </div> </div> @@ -93,12 +102,12 @@ export default { <style scoped> .page-wrapper { - display: flex; - min-height: 100vh; - flex-direction: column; + display: flex; + min-height: 100vh; + flex-direction: column; } .content-wrapper { - flex: 1; + flex: 1; } </style> diff --git a/client/src/components/Encoder.vue b/client/src/components/Encoder.vue new file mode 100644 index 0000000..eaba1f1 --- /dev/null +++ b/client/src/components/Encoder.vue @@ -0,0 +1,70 @@ +<template> + <div class="section"> + <div class="message is-warning"> + <div class="message-header"> + <p>Encodeur de TAG/cartes NFC (outil de développement)</p> + </div> + <div class="message-body"> + <p>Entrez un objet JSON valide dans le champs ci-dessous pour l'écrire sur le tag NFC présenté au lecteur. Attention à ne pas dépasser la longueur mémoire maximale de votre tag !</p> + <div ref="editor" class="language-js"></div> + <div> + <p>Longueur : {{jsonText.length}}</p> + <p :class="isJsonTextValid ? 'has-text-success' : 'has-text-danger'"><strong>JSON généré : </strong>{{jsonText}}</p> + </div> + <button class = "button is-warning" :disabled="!isJsonTextValid"><span><i class="fas fa-upload"></i> Ecrire sur la carte/le tag</span></button> + </div> + </div> + + + + </div> +</template> + +<script> +import {CodeJar} from 'codejar'; +import {withLineNumbers} from 'codejar/linenumbers'; +import Prism from 'prismjs'; +import 'prismjs/themes/prism.css' +export default { + name: "Encoder", + components: {}, + data() { + return { + jsonText : "" + } + }, + + computed : { + isJsonTextValid : function() { + try { + JSON.parse(this.jsonText); + return true; + } catch (e) { + return false; + } + } + }, + + mounted() { + const sampleCode = `{\n \t "type" : "<objet ? carte ?>", \n \t "puzzle" : "<nom d'énigme>", \n \t custom params...\n}`; + this.jsonText = sampleCode; + const node = this.$refs.editor; + const jar = CodeJar(node, withLineNumbers(Prism.highlightElement)); + jar.onUpdate(code => { + try { + var jsonObject = JSON.parse(code); + this.jsonText = JSON.stringify(jsonObject, null, 0) + } catch (e) { + this.jsonText = code; + } + + + }) + jar.updateCode(sampleCode); + + } +}; +</script> + +<style scoped> +</style> diff --git a/client/src/components/PageFooter.vue b/client/src/components/PageFooter.vue index d58579d..cf1150e 100644 --- a/client/src/components/PageFooter.vue +++ b/client/src/components/PageFooter.vue @@ -1,20 +1,22 @@ <template> <footer class="footer has-text-centered"> <div class="content level"> - <a class="level-item has-text-centered" href="https://www.insa-lyon.fr"> - <img src="../assets/img/insa.png"> + <a class="level-item has-text-centered" href="https://www.insa-lyon.fr"> + <img src="../assets/img/insa.png" /> </a> <a class="level-item has-text-centered" href="https://www.clubelek.fr"> - <img src="../assets/img/clubelek.png"> + <img src="../assets/img/clubelek.png" /> </a> <a class="level-item has-text-centered"> - <img src="../assets/img/objectif21.png"> - </a> + <img src="../assets/img/objectif21.png" /> + </a> </div> <div class="content"> - <p>Conçu et développé par les associations Clubelek et Objectif21, de l'INSA Lyon - Saison 2020/2021</p> + <p> + Conçu et développé par les associations Clubelek et Objectif21, de + l'INSA Lyon - Saison 2020/2021 + </p> </div> - </footer> </template> @@ -26,8 +28,6 @@ export default { <style scoped> img { - height:64px; + height: 64px; } - - </style> diff --git a/client/src/components/SchoolManager.vue b/client/src/components/SchoolManager.vue index 4767daf..0836eb9 100644 --- a/client/src/components/SchoolManager.vue +++ b/client/src/components/SchoolManager.vue @@ -2,14 +2,14 @@ <div id="app" class="content"> <div class="message is-medium"> <div class="message-header">Mes équipes</div> - </div> - <div class="message-body"> - <div v-for="team in teams" :key="team._id"> - <TeamElement :team="team" :teamArray="teams" /> + <div class="message-body"> + <div v-for="team in teams" :key="team._id"> + <TeamElement :team="team" :teamArray="teams" /> + </div> + <TeamAdder :teamArray="teams"></TeamAdder> </div> - <TeamAdder :teamArray="teams"></TeamAdder> </div> - <button id="request-any">Test</button> + </div> </template> diff --git a/client/src/components/TeamElement.vue b/client/src/components/TeamElement.vue index 82cd87d..6849db6 100644 --- a/client/src/components/TeamElement.vue +++ b/client/src/components/TeamElement.vue @@ -22,7 +22,7 @@ Aucune carte associée ! </p> <button v-if="team.cardId" class="button is-danger"> - Dissocier la carte + Dissocier la carte </button> <button v-else @@ -34,16 +34,32 @@ </div> </div> <div> - <p v-if="team.donePuzzles.length > 0" class="is-size-4"><strong>Puzzles effectués :</strong></p> + <p v-if="team.donePuzzles.length > 0" class="is-size-4"> + <strong>Puzzles effectués :</strong> + </p> <div v-for="puzzle in team.donePuzzles" :key="puzzle.name"> <div class="level" v-if="puzzle.score"> - <div class="level-item level-left"><p><strong>{{puzzle.name}}</strong> ({{puzzle.room}}) : </p></div> - <div class="level-item level-right"><progress class="progress is-small" :value="puzzle.score" :max="puzzle.maxScore"></progress></div> - <div class="level-item level-right"><p>{{puzzle.score}}/{{puzzle.maxScore}}</p></div> + <div class="level-item level-left"> + <p> + <strong>{{ puzzle.name }}</strong> ({{ puzzle.room }}) : + </p> + </div> + <div class="level-item level-right"> + <progress + class="progress is-small" + :value="puzzle.score" + :max="puzzle.maxScore" + ></progress> + </div> + <div class="level-item level-right"> + <p>{{ puzzle.score }}/{{ puzzle.maxScore }}</p> + </div> </div> <div v-else class="level "> <div class="level-item level-left"> - <p><strong>{{puzzle.name}}</strong> ({{puzzle.room}}) : </p> + <p> + <strong>{{ puzzle.name }}</strong> ({{ puzzle.room }}) : + </p> </div> <div class="level-item level-right"> <span v-if="puzzle.validated" class="icon has-text-success"> @@ -53,13 +69,11 @@ <i class="fas fa-times-circle"></i> </span> </div> - </div> </div> </div> </div> - <div class="modal" :class="{ 'is-active': showPairingModal }"> <div class="modal-background"></div> <div class="modal-content"> diff --git a/client/src/main.js b/client/src/main.js index 02a2183..9b4846d 100644 --- a/client/src/main.js +++ b/client/src/main.js @@ -11,6 +11,7 @@ import SchoolManager from "./components/SchoolManager.vue"; import MentionsLegales from "./components/MentionsLegales.vue"; import Login from "./components/Login.vue"; import Register from "./components/Register.vue"; +import Encoder from "./components/Encoder.vue"; require("@/assets/main.scss"); import "@fortawesome/fontawesome-free/css/all.css"; import "@fortawesome/fontawesome-free/js/all.js"; @@ -27,6 +28,11 @@ const routes = [ path: "/", component: HomeComponent }, + { + name: "encoder", + path: "/encoder", + component: Encoder + }, { name: "schoolManager", path: "/school", -- GitLab