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