From 9f7700b49b0f9addf09377f80e34f328ba49fa5c Mon Sep 17 00:00:00 2001
From: paidge <paidge_cs@hotmail.com>
Date: Mon, 20 Dec 2021 20:56:49 +0100
Subject: [PATCH] explorateur de wot

---
 assets/css/style.scss               |   4 +-
 components/{chart.vue => Graph.vue} |   0
 components/badge/Status.vue         |  36 +++++++++
 components/certif/List.vue          |  16 +++-
 components/member/Card.vue          |  75 +++++++++++++++++++
 components/navigation/Bar.vue       |   6 +-
 layouts/default.vue                 |   1 -
 pages/appolo.vue                    | 112 ----------------------------
 pages/chartjs.vue                   |   4 +-
 pages/hash/_hash.vue                |  26 +------
 pages/membres.vue                   |   6 +-
 plugins/filters.js                  |  31 +++++++-
 12 files changed, 167 insertions(+), 150 deletions(-)
 rename components/{chart.vue => Graph.vue} (100%)
 create mode 100644 components/badge/Status.vue
 create mode 100644 components/member/Card.vue
 delete mode 100644 pages/appolo.vue

diff --git a/assets/css/style.scss b/assets/css/style.scss
index 5fc0e9e..4dfd2f2 100644
--- a/assets/css/style.scss
+++ b/assets/css/style.scss
@@ -11,8 +11,8 @@ $body-bg: var(--background-color-primary);
 $body-color: var(--text-primary-color);
 
 // Tables
-$table-bg: var(--text-primary-color);
-$table-color: var(--background-color-primary);
+$table-bg: var(--background-color-primary);
+$table-color: var(--text-primary-color);
 $table-head-bg: red;
 
 // Breadcrumb
diff --git a/components/chart.vue b/components/Graph.vue
similarity index 100%
rename from components/chart.vue
rename to components/Graph.vue
diff --git a/components/badge/Status.vue b/components/badge/Status.vue
new file mode 100644
index 0000000..b9fa364
--- /dev/null
+++ b/components/badge/Status.vue
@@ -0,0 +1,36 @@
+<template>
+    <small>
+        <span class="badge badge-secondary"
+            :class="{
+                'badge-danger' : statut == 'REVOKED',
+                'badge-success' : statut == 'MEMBER',
+                'badge-info' : statut == 'NEWCOMER',
+                'badge-warning' : statut == 'MISSING'
+            }">{{ this.statut | formatStatus }}</span>
+    </small>
+</template>
+
+<script>
+const statuses = [
+    'NEWCOMER',
+    'MISSING',
+    'MEMBER',
+    'REVOKED'
+]
+
+export default {
+    props: {
+        statut: {
+            type: String,
+            required: true,
+            validator: function (value) {
+                return statuses.indexOf(value) !== -1
+            }
+        }
+    }
+}
+</script>
+
+<style>
+
+</style>
\ No newline at end of file
diff --git a/components/certif/List.vue b/components/certif/List.vue
index 63b4e29..a35277c 100644
--- a/components/certif/List.vue
+++ b/components/certif/List.vue
@@ -1,7 +1,13 @@
 <template>
 <div class="list-group">
-    <NuxtLink :to="'/hash/'+getNeighbor(certif).hash" class="list-group-item list-group-item-action" v-for="certif in certifs" :key="getNeighbor(certif).uid">
+    <NuxtLink
+      :to="'/hash/'+getNeighbor(certif).hash"
+      class="list-group-item list-group-item-action"
+      :class="'list-group-item-'+ $options.filters.dateStatus(certif.expires_on)"
+      v-for="certif in certifsTriees"
+      :key="getNeighbor(certif).uid">
         {{ getNeighbor(certif).uid }}
+        <BadgeStatus :statut="getNeighbor(certif).status" />
         <small class="text-muted">Expire le {{ certif.expires_on | formatDate }}</small>
     </NuxtLink>
 </div>
@@ -24,6 +30,14 @@ export default {
         getNeighbor(certif) {
             return this.type == "recieved" ? certif.from : certif.to
         }
+    },
+    computed : {
+        certifsTriees() {
+            return this.certifs.sort(
+                (a, b) => a.expires_on - b.expires_on
+            )
+
+        }
     }
 }
 </script>
diff --git a/components/member/Card.vue b/components/member/Card.vue
new file mode 100644
index 0000000..cb94a52
--- /dev/null
+++ b/components/member/Card.vue
@@ -0,0 +1,75 @@
+<template>
+<div class="card member">
+    <div class="card-body">
+        <h2 class="card-title">
+        {{ hash.uid }}
+        <BadgeStatus :statut="hash.status" />
+        </h2>
+        <div class="card-subtitle mb-2 text-muted">{{ hash.pubkey }}</div>
+        <table class="table table-sm" v-if="hash.status != 'REVOKED'">
+        <tbody>
+            <tr v-if="hash.status == 'MEMBER'">
+                <th scope="row">Référent :</th>
+                <td :class="{'table-success': isReferent, 'table-danger': !isReferent}">{{ isReferent ? 'Oui' : 'Non' }}</td>
+            </tr>
+            <tr v-if="hash.status != 'NEWCOMER'">
+                <th scope="row">Qualité :</th>
+                <td :class="{
+                    'table-success': hash.quality.ratio >= 80,
+                    'table-warning': hash.quality.ratio < 80,
+                }">{{ Math.round(hash.quality.ratio*100)/100 }}</td>
+            </tr>
+            <tr v-if="hash.status != 'NEWCOMER'">
+                <th scope="row">Distance :</th>
+                <td :class="{
+                    'table-success': hash.distance.value.ratio >= 80,
+                    'table-danger': hash.distance.value.ratio < 80,
+                }">{{ Math.round(hash.distance.value.ratio*100)/100 }}</td>
+            </tr>
+            <tr>
+                <th scope="row">Date limite d'adhésion :</th>
+                <td :class="'table-'+ $options.filters.dateStatus(hash.limitDate)">{{ hash.limitDate | formatDate }}</td>
+            </tr>
+            <tr v-if="hash.status == 'MEMBER'">
+                <th scope="row">Date avant de manquer de certifs :</th>
+                <td :class="'table-'+ $options.filters.dateStatus(hash.received_certifications.limit)">{{ hash.received_certifications.limit | formatDate }}</td>
+            </tr>
+            <tr v-if="hash.status == 'MEMBER'">
+                <th scope="row">Disponible pour certifier :</th>
+                <td :class="{
+                    'table-success': hash.minDatePassed,
+                    'table-danger': !hash.minDatePassed,
+                }">{{ hash.minDatePassed ? 'Oui' : 'Non'  }} <small v-if="!hash.minDatePassed">( > {{ hash.minDate | formatDate }} )</small></td>
+            </tr>
+            <tr v-if="hash.status == 'MEMBER'">
+                <th scope="row">Nbre de certifs disponibles :</th>
+                <td :class="{
+                    'table-success': hash.sent_certifications.length<=80,
+                    'table-warning': hash.sent_certifications.length>80,
+                    'table-danger': hash.sent_certifications.length>90,
+                }">{{ 100-hash.sent_certifications.length }}</td>
+            </tr>
+        </tbody>
+        </table>
+    </div>
+</div>
+</template>
+
+<script>
+export default {
+    props: {
+        hash: Object
+    },
+  computed: {
+    isReferent () {
+      const nb_certifs_referent = 5
+      return this.hash.received_certifications.certifications.length > nb_certifs_referent && this.hash.sent_certifications.length > nb_certifs_referent
+    }
+  },
+}
+</script>
+
+<style lang="sass" scoped>
+.member th
+  text-align: right
+</style>
\ No newline at end of file
diff --git a/components/navigation/Bar.vue b/components/navigation/Bar.vue
index cf3689b..8acd6b1 100644
--- a/components/navigation/Bar.vue
+++ b/components/navigation/Bar.vue
@@ -103,10 +103,8 @@ nav.breadcrumb {
 
   h1 {color: var(--text-primary-color);}
 
-  .list-group-item {
-    background: var(--background-color-primary);
-    
-    &-action:not(.active):hover {background: transparent;}
+  .list-group-item {    
+    &-action:not(.active) {background: transparent;}
 
     div {
       transition: left .3s ease-in-out;
diff --git a/layouts/default.vue b/layouts/default.vue
index 7fa0b45..be3d546 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -14,7 +14,6 @@ export default {
           {
           title: 'Développement',
           items : [
-              {path: '/appolo',title: 'Appolo'},
               {path: '/chartjs',title: 'ChartJS'},
               {path: '/membres',title: 'Membres'}
           ]},
diff --git a/pages/appolo.vue b/pages/appolo.vue
deleted file mode 100644
index c4c3712..0000000
--- a/pages/appolo.vue
+++ /dev/null
@@ -1,112 +0,0 @@
-<template>
-<main class="content">
-  <h2 class="display-2 text-center mb-5">Test Appolo</h2>
-  <div class="row mb-4">
-    <div class="col-6 m-auto text-center">
-      <p>Cette page uilise la bibliothèque <a href="https://apollo.vuejs.org/" target="_blank">Apollo</a> pour requêter graphQL</p>
-      <p>Le endpoint se configure dans le fichier <code>./nuxt.config.js</code></p>
-      <p>Il est possible de <a href="https://apollo.vuejs.org/guide/components/query.html#query-with-gql-files" target="_blank">mettre les requêtes dans des fichiers séparés</a> et de faire <a href="https://apollo.vuejs.org/guide/apollo/pagination.html" target="_blank">de la pagination</a></p>
-      <label for="rech" class="form-label">Votre recherche</label>
-      <input type="text" class="form-control" id="rech" aria-describedby="rechHelp" v-model="param" autocomplete="off">
-      <small id="rechHelp" class="form-text text-muted">Saisissez le début d'un pseudo ou d'une clé publique</small>
-    </div>
-  </div>
-  <NavigationLoader :isLoading="$apollo.queries.idSearch.loading" class="d-block mx-auto" />
-  <div class="row" v-if="idSearch && !$apollo.queries.idSearch.loading && param.length > 2">
-    <div class="col-8 m-auto">
-      <div class="table-responsive">
-        <table class="table striped">
-          <thead>
-            <tr>
-              <th scope="col">UID</th>
-              <th scope="col" class="d-none d-xl-table-cell">PUBKEY</th>
-              <th scope="col" class="d-none d-sm-table-cell">STATUS</th>
-            </tr>
-          </thead>
-          <tbody>
-            <tr v-for="member in idSearch.ids" :key="member.uid"
-              @click="redirect('/hash/' + member.hash)"
-              :class="{
-                'table-danger' : member.status == 'REVOKED',
-                'table-success' : member.status == 'MEMBER',
-                'table-info' : member.status == 'NEWCOMER',
-                'table-warning' : member.status == 'MISSING',
-            }">
-              <th scope="row">{{ member.uid }}</th>
-              <td class="d-none d-xl-table-cell">{{ member.pubkey }}</td>
-              <td class="d-none d-sm-table-cell">{{ member.status }}</td>
-            </tr>
-          </tbody>
-        </table>
-      </div>
-    </div>
-  </div>
-</main>
-</template>
-
-<script>
-import gql from 'graphql-tag'
-
-export default {
-  data() {
-    // Variables locales
-    return {
-      // Fil d'ariane
-      breadcrumb: [
-        {
-          text: 'Accueil',
-          to: '/'
-        },
-        {
-          text: 'Appolo',
-          active: true
-        }
-      ],
-      // Requête graphQL
-      param: '',
-    }
-  },
-  // Fonctions locales
-  methods: {
-    redirect(path) {
-      this.$router.push({ path: path })
-    }
-  },
-  apollo: {
-    idSearch : {
-      query: gql`
-      query Search($hint: String) {
-        idSearch(with: {hint: $hint}) {
-          ids {
-            pubkey
-            uid
-            status
-            hash
-          }
-        }
-      } `,
-      variables(){return {hint:this.param}},
-      skip() {return this.param.length < 3}
-    } 
-  },
-  mounted () {
-    // Mise à jour du fil d'ariane au chargement
-    $nuxt.$emit('changeRoute',this.breadcrumb)
-  }
-}
-</script>
-
-<style lang="sass" scoped>
-// CSS Lié au composant
-.table.striped tbody
-  color: var(--dark)
-  tr
-    opacity: .9
-    cursor: pointer
-
-  &:nth-child(2n+1)
-    opacity: .7
-
-  &:hover
-    opacity: 1
-</style>
\ No newline at end of file
diff --git a/pages/chartjs.vue b/pages/chartjs.vue
index ec069f1..063ca88 100644
--- a/pages/chartjs.vue
+++ b/pages/chartjs.vue
@@ -6,13 +6,13 @@
         <option v-for="type in allTypes" :key="type">{{ type }}</option>
       </select>
       <button @click="fillData()" class="btn btn-primary mb-5">Randomize</button>
-      <LazyChart id="monGraph" :type="chartType" :data="data" :options="options" />
+      <LazyGraph id="monGraph" :type="chartType" :data="data" :options="options" />
     </div>
   </main>
 </template>
 
 <script>
-import {chartTypes} from "@/components/chart.vue"
+import {chartTypes} from "~/components/Graph.vue"
 
 export default {
     data () {
diff --git a/pages/hash/_hash.vue b/pages/hash/_hash.vue
index a563c0f..7cd7374 100644
--- a/pages/hash/_hash.vue
+++ b/pages/hash/_hash.vue
@@ -4,20 +4,7 @@
     <div v-if="!$apollo.queries.idFromHash.loading">
       <div class="row">
         <div class="col-6 mx-auto mt-3">
-          <div class="card">
-            <div class="card-body">
-              <h2 class="card-title">{{ idFromHash.uid }} <small><span class="badge badge-secondary">{{ idFromHash.status }}</span></small></h2>
-              <div v-if="idFromHash.status != 'REVOKED'">
-                <div class="card-subtitle mb-2 text-muted">{{ idFromHash.pubkey }}</div>
-                <div> Référent : {{ isReferent ? 'Oui' : 'Non' }}</div>
-                <div> Qualité : {{ Math.round(idFromHash.quality.ratio*100)/100 }}</div>
-                <div> Date limite d'adhésion : {{ idFromHash.limitDate | formatDate }}</div>
-                <div v-if="idFromHash.status != 'NEWCOMER'"> Date avant de manquer de certifs : {{ idFromHash.received_certifications.limit | formatDate }}</div>
-                <div v-if="idFromHash.status != 'NEWCOMER'"> Pourra certifier à partir du : {{ idFromHash.minDatePassed || 'Déjà dispo' }}</div>
-                <div> Nbre de certifs disponibles  : {{ 100-idFromHash.sent_certifications.length }}</div>
-              </div>
-            </div>
-          </div>
+          <MemberCard :hash="idFromHash" />
         </div>
       </div>
       <div class="row mt-3"  v-if="idFromHash.status != 'REVOKED' && idFromHash.status != 'NEWCOMER'">
@@ -58,8 +45,7 @@ export default {
     };
   },
   // Fonctions locales
-  methods: {
-  },
+  methods: {},
   apollo: {
     idFromHash: {
       query: gql`
@@ -113,12 +99,6 @@ export default {
       },
     },
   },
-  computed: {
-    isReferent () {
-      const nb_certifs_referent = 5
-      return this.idFromHash.received_certifications.certifications.length > nb_certifs_referent && this.idFromHash.sent_certifications.length > nb_certifs_referent
-    }
-  },
   watch: {
     idFromHash: {
       handler(n,o) {
@@ -131,5 +111,5 @@ export default {
 </script>
 
 <style lang="sass" scoped>
-// CSS Lié au composant
+
 </style>
diff --git a/pages/membres.vue b/pages/membres.vue
index 5e00676..296e5e5 100644
--- a/pages/membres.vue
+++ b/pages/membres.vue
@@ -17,7 +17,7 @@
             <tr>
               <th scope="col">UID</th>
               <th scope="col" class="d-none d-xl-table-cell">PUBKEY</th>
-              <th scope="col" class="d-none d-sm-table-cell">STATUS</th>
+              <th scope="col" class="d-none d-sm-table-cell">STATUT</th>
             </tr>
           </thead>
           <tbody>
@@ -26,12 +26,12 @@
               :class="{
                 'table-danger' : member.status == 'REVOKED',
                 'table-success' : member.status == 'MEMBER',
-                'table-info' : member.status == 'NEWCOMER',
                 'table-warning' : member.status == 'MISSING',
+                'table-info' : member.status == 'NEWCOMER'
             }">
               <th scope="row">{{ member.uid }}</th>
               <td class="d-none d-xl-table-cell">{{ member.pubkey }}</td>
-              <td class="d-none d-sm-table-cell">{{ member.status }}</td>
+              <td class="d-none d-sm-table-cell">{{ member.status | formatStatus }}</td>
             </tr>
           </tbody>
         </table>
diff --git a/plugins/filters.js b/plugins/filters.js
index 1b62a42..c491b1c 100644
--- a/plugins/filters.js
+++ b/plugins/filters.js
@@ -4,6 +4,33 @@ import 'dayjs/locale/fr'
 
 dayjs.locale('fr')
 
-Vue.filter('formatDate', (value) => {
-    return dayjs(value*1000).format('D MMMM YYYY')
+Vue.filter('formatDate', (val) => {
+    return dayjs(val*1000).format('D MMMM YYYY')
+})
+
+Vue.filter('dateStatus', (val) => {
+    const diff = val - dayjs().unix()
+    switch (true) {
+        case diff<2592000:
+            return 'danger'
+        case diff<5184000:
+            return 'warning'
+        case diff>=5184000:
+            return 'success'
+    }
+})
+
+Vue.filter('formatStatus', (val) => {
+    switch (val) {
+        case 'NEWCOMER':
+            return 'Futur membre'
+        case 'MISSING':
+            return 'Adhésion perdue'
+        case 'MEMBER':
+            return 'Membre'
+        case 'REVOKED':
+            return 'Membre revoqué'
+        default:
+            return 'N/A'
+    }
 })
\ No newline at end of file
-- 
GitLab