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