From dc60394ee2cdb38107505607d337286e7ed623e6 Mon Sep 17 00:00:00 2001
From: paidge <paidge_cs@hotmail.com>
Date: Fri, 18 Feb 2022 00:39:57 +0100
Subject: [PATCH] improve MemberList

---
 assets/css/style.scss                  |   4 +-
 components/badge/Danger.vue            |   3 +-
 components/badge/Date.vue              |   3 +-
 components/badge/Dispo.vue             |  27 +++---
 components/member/Card.vue             |  12 ++-
 components/member/List.vue             | 125 +++++++++++++++++--------
 components/navigation/menu/Sidebar.vue |  24 ++++-
 i18n/locales/de.json                   |   3 +-
 i18n/locales/en.json                   |   3 +-
 i18n/locales/es.json                   |   3 +-
 i18n/locales/fr.json                   |   3 +-
 pages/previsions/futures_sorties.vue   |   8 +-
 12 files changed, 150 insertions(+), 68 deletions(-)

diff --git a/assets/css/style.scss b/assets/css/style.scss
index 764c6f8..3a4fba2 100644
--- a/assets/css/style.scss
+++ b/assets/css/style.scss
@@ -86,8 +86,8 @@ body {
 		width: 165px;
 	}
 
-	.td-pubkey {
-		width: 200px;
+	.td-quality {
+		width: 120px;
 	}
 }
 
diff --git a/components/badge/Danger.vue b/components/badge/Danger.vue
index be8ee94..1cbd112 100644
--- a/components/badge/Danger.vue
+++ b/components/badge/Danger.vue
@@ -4,7 +4,8 @@
 		:title="title"
 		v-if="
 			$options.filters.dateStatus(limitDate) != 'success' &&
-			['MEMBER', 'MISSING'].includes(memberStatus)
+			['MEMBER', 'MISSING'].includes(memberStatus) &&
+			limitDate != 0
 		"
 		><outline-exclamation-icon class="icon" />
 		<span class="sr-only" v-if="title">{{ title }}</span>
diff --git a/components/badge/Date.vue b/components/badge/Date.vue
index 45463dd..51755b8 100644
--- a/components/badge/Date.vue
+++ b/components/badge/Date.vue
@@ -8,8 +8,7 @@
 export default {
 	props: {
 		date: {
-			type: Number,
-			required: true
+			type: Number
 		},
 		styleDate: {
 			type: String,
diff --git a/components/badge/Dispo.vue b/components/badge/Dispo.vue
index ad4dbaa..2c8e227 100644
--- a/components/badge/Dispo.vue
+++ b/components/badge/Dispo.vue
@@ -5,15 +5,18 @@
 			'bg-success': isDispo,
 			'bg-danger': !isDispo
 		}">
-		{{
-			isDispo
-				? $t("membre.dispo")
-				: "⏱&nbsp;" +
-				  nbPendingCertifs +
-				  " (&nbsp;" +
-				  $d(new Date(dateDispo * 1000), "short") +
-				  ")"
-		}}
+		<span v-if="isDispo">{{ $t("membre.dispo") }}</span>
+		<span v-else
+			>⏱&nbsp;
+			{{
+				dateDispo == null
+					? "N/A"
+					: nbPendingCertifs +
+					  " (&nbsp;" +
+					  $d(new Date(dateDispo * 1000), "short") +
+					  ")"
+			}}</span
+		>
 	</span>
 </template>
 
@@ -21,12 +24,10 @@
 export default {
 	props: {
 		isDispo: {
-			type: Boolean,
-			required: true
+			type: Boolean
 		},
 		dateDispo: {
-			type: Number,
-			required: true
+			type: Number
 		},
 		certifs: {
 			type: Array,
diff --git a/components/member/Card.vue b/components/member/Card.vue
index 19efd13..e4a6995 100644
--- a/components/member/Card.vue
+++ b/components/member/Card.vue
@@ -3,7 +3,7 @@
 		<div class="card-body">
 			<div
 				class="uid-wrapper d-flex align-items-center justify-content-between mb-4">
-				<h2 class="h3 card-title text-center d-flex align-items-center">
+				<h2 class="h3 card-title text-center d-flex align-items-center m-0">
 					<span class="text-truncate d-inline-block">
 						{{ hash.uid }}
 					</span>
@@ -144,7 +144,11 @@ export default {
 
 <style lang="scss">
 .uid-wrapper {
-	flex-direction: column;
+	flex-direction: column-reverse;
+
+	button {
+		margin-bottom: 1rem;
+	}
 
 	.text-truncate {
 		max-width: 300px;
@@ -152,6 +156,10 @@ export default {
 
 	@media (min-width: 576px) {
 		flex-direction: row;
+
+		button {
+			margin-bottom: 0;
+		}
 	}
 }
 
diff --git a/components/member/List.vue b/components/member/List.vue
index 353a796..7743b7e 100644
--- a/components/member/List.vue
+++ b/components/member/List.vue
@@ -18,12 +18,34 @@
 					</th>
 					<th
 						scope="col"
-						class="td-pubkey d-none d-lg-table-cell p-0"
-						@click="sort('pubkey')"
-						v-if="['search', 'favoris'].includes(type)">
+						class="d-none d-lg-table-cell p-0"
+						v-if="['favoris', 'search'].includes(type)"
+						@click="sort('statut')">
 						<BtnSort
-							fieldName="pubkey"
-							:title="$t('cle.publique.title')"
+							fieldName="statut"
+							:title="$t('statut.title')"
+							:currentSort="currentSort"
+							:currentSortDir="currentSortDir" />
+					</th>
+					<th
+						scope="col"
+						class="td-quality d-none d-lg-table-cell p-0"
+						v-if="['favoris', 'search'].includes(type)"
+						@click="sort('quality')">
+						<BtnSort
+							fieldName="quality"
+							:title="$t('membre.qualite.title')"
+							:currentSort="currentSort"
+							:currentSortDir="currentSortDir" />
+					</th>
+					<th
+						scope="col"
+						class="d-none d-xl-table-cell p-0"
+						v-if="['favoris', 'search'].includes(type)"
+						@click="sort('dispo')">
+						<BtnSort
+							fieldName="dispo"
+							:title="$t('membre.dispo')"
 							:currentSort="currentSort"
 							:currentSortDir="currentSortDir" />
 					</th>
@@ -50,7 +72,7 @@
 							'd-md-table-cell': type != 'certif'
 						}"
 						@click="sort('date_certs')"
-						v-if="['certif', 'favoris'].includes(type)">
+						v-if="['certif', 'favoris', 'search'].includes(type)">
 						<BtnSort
 							fieldName="date_certs"
 							:title="
@@ -67,32 +89,61 @@
 			<tbody>
 				<tr v-for="member in membersSorted" :key="member.uid">
 					<td @click="redirect(member.hash)">
-						<div class="d-flex justify-content-center">
-							<span v-if="$favourites.list.includes(member.uid)">★&nbsp;</span>
-							<div class="text-truncate">{{ member.uid }}</div>
-							&nbsp;
-							<BadgeDanger
-								:limitDate="member.certsLimit"
-								:memberStatus="member.status" />
+						<div class="d-flex uid-content">
+							<div
+								class="d-flex flex-column align-items-center justify-content-evenly flex-grow-1">
+								<div class="d-flex justify-content-center mw-100">
+									<span v-if="$favourites.list.includes(member.uid)"
+										>★&nbsp;</span
+									>
+									<div class="text-truncate">{{ member.uid }}</div>
+									&nbsp;
+									<BadgeDanger
+										:limitDate="Math.min(member.certsLimit, member.limitDate)"
+										:memberStatus="member.status" />
+								</div>
+								<div class="text-muted small">
+									{{ member.pubkey.substring(0, 10) }}
+								</div>
+								<div
+									v-if="['adhesion', 'certif'].includes(type)"
+									class="d-sm-none">
+									<BadgeDate :date="getDate(member)" styleDate="short" />
+								</div>
+							</div>
+							<div
+								class="w-50 d-flex flex-column align-items-center justify-content-evenly gap-1 d-lg-none"
+								v-if="['favoris', 'search'].includes(type)">
+								<BadgeStatus :membre="member" class="mw-100 text-truncate" />
+								<BadgeQuality :quality="member.quality.ratio" />
+								<BadgeDispo
+									:isDispo="member.minDatePassed"
+									:dateDispo="member.minDate"
+									:certifs="member.sent_certifications"
+									class="mw-100 text-truncate" />
+							</div>
 						</div>
+					</td>
+					<td
+						class="d-none d-lg-table-cell"
+						v-if="['favoris', 'search'].includes(type)"
+						@click="redirect(member.hash)">
 						<BadgeStatus :membre="member" />
-						<BadgeQuality
-							:quality="member.quality.ratio"
-							v-if="!['REVOKED', 'NEWCOMER'].includes(member.status)" />
-						<BadgeDispo
-							:isDispo="member.minDatePassed"
-							:dateDispo="member.minDate"
-							:certifs="member.sent_certifications"
-							v-if="member.status == 'MEMBER'" />
-						<div v-if="['adhesion', 'certif'].includes(type)" class="d-sm-none">
-							<BadgeDate :date="getDate(member)" styleDate="short" />
-						</div>
 					</td>
 					<td
 						class="d-none d-lg-table-cell"
-						v-if="['search', 'favoris'].includes(type)"
+						v-if="['favoris', 'search'].includes(type)"
 						@click="redirect(member.hash)">
-						{{ member.pubkey.substring(0, 10) }}
+						<BadgeQuality :quality="member.quality.ratio" />
+					</td>
+					<td
+						class="d-none d-xl-table-cell"
+						v-if="['favoris', 'search'].includes(type)"
+						@click="redirect(member.hash)">
+						<BadgeDispo
+							:isDispo="member.minDatePassed"
+							:dateDispo="member.minDate"
+							:certifs="member.sent_certifications" />
 					</td>
 					<td
 						class="d-none d-sm-table-cell"
@@ -106,7 +157,7 @@
 							'd-sm-table-cell': type == 'certif',
 							'd-md-table-cell': type != 'certif'
 						}"
-						v-if="['certif', 'favoris'].includes(type)"
+						v-if="['certif', 'favoris', 'search'].includes(type)"
 						@click="redirect(member.hash)">
 						<BadgeDate :date="member.certsLimit" styleDate="short" />
 					</td>
@@ -197,12 +248,14 @@ export default {
 							b["uid"].toLowerCase(),
 							modifier
 						)
-					} else if (this.currentSort == "pubkey") {
-						return this.getOrder(
-							a["pubkey"].toLowerCase(),
-							b["pubkey"].toLowerCase(),
-							modifier
-						)
+					} else if (this.currentSort == "dispo") {
+						if (a.minDate == null) return 1 * modifier
+						if (b.minDate == null) return -1 * modifier
+						return this.getOrder(a.minDate, b.minDate, modifier)
+					} else if (this.currentSort == "quality") {
+						return this.getOrder(a.quality.ratio, b.quality.ratio, modifier)
+					} else if (this.currentSort == "statut") {
+						return this.getOrder(a["status"], b["status"], modifier)
 					} else if (this.currentSort == "date_membership") {
 						return this.getOrder(a["limitDate"], b["limitDate"], modifier)
 					} else if (this.currentSort == "date_certs") {
@@ -219,9 +272,3 @@ export default {
 	}
 }
 </script>
-
-<style lang="scss" scoped>
-tbody tr {
-	height: 90px;
-}
-</style>
diff --git a/components/navigation/menu/Sidebar.vue b/components/navigation/menu/Sidebar.vue
index be3e415..173625c 100644
--- a/components/navigation/menu/Sidebar.vue
+++ b/components/navigation/menu/Sidebar.vue
@@ -1,7 +1,14 @@
 <template>
 	<aside class="menu position-fixed d-flex flex-column border-end">
 		<div class="mb-4">
-			<nuxt-link :to="localePath('/')" class="d-flex px-3 pt-3">
+			<nuxt-link
+				@click.native="
+					if (sreenwidth < 1200) {
+						toggleMenu()
+					}
+				"
+				:to="localePath('/')"
+				class="d-flex px-3 pt-3">
 				<img :src="$icon(512)" alt="Accueil" class="logo" />
 				<div>
 					<h1 class="h3">Wotwizard</h1>
@@ -44,12 +51,20 @@ import { LAST_BLOCK } from "@/graphql/queries.js"
 import { VERSION } from "@/graphql/queries.js"
 
 export default {
+	data() {
+		return {
+			sreenwidth: 0
+		}
+	},
 	props: {
 		menus: Array
 	},
 	methods: {
 		toggleMenu() {
 			this.$emit("toggleMenu")
+		},
+		onResize() {
+			this.sreenwidth = window.screen.width
 		}
 	},
 	apollo: {
@@ -59,6 +74,13 @@ export default {
 		version: {
 			query: VERSION
 		}
+	},
+	mounted() {
+		this.sreenwidth = window.screen.width
+		this.$nextTick(function () {
+			this.onResize()
+		})
+		window.addEventListener("resize", this.onResize)
 	}
 }
 </script>
diff --git a/i18n/locales/de.json b/i18n/locales/de.json
index b9a20a2..7e1b2ea 100644
--- a/i18n/locales/de.json
+++ b/i18n/locales/de.json
@@ -195,7 +195,8 @@
 		"missing": "Verlorene Mitgliedschaft",
 		"newcomer": "Zukünftiges Mitglied",
 		"renew": "Zu verlängernde Mitgliedschaft",
-		"revoked": "Widerrufenes Mitglied"
+		"revoked": "Widerrufenes Mitglied",
+		"title": "Status"
 	},
 	"time": {
 		"a": "um"
diff --git a/i18n/locales/en.json b/i18n/locales/en.json
index f4257f5..e11f4db 100644
--- a/i18n/locales/en.json
+++ b/i18n/locales/en.json
@@ -196,7 +196,8 @@
 		"missing": "Membership lost",
 		"newcomer": "Future member",
 		"renew": "Membership to renew",
-		"revoked": "Revoked member"
+		"revoked": "Revoked member",
+		"title": "Status"
 	},
 	"time": {
 		"a": "at"
diff --git a/i18n/locales/es.json b/i18n/locales/es.json
index 0413411..e3a51f9 100644
--- a/i18n/locales/es.json
+++ b/i18n/locales/es.json
@@ -196,7 +196,8 @@
 		"missing": "Membresía perdida",
 		"newcomer": "Futur@ miembro",
 		"renew": "Membresía por renovar",
-		"revoked": "Membresía revocada"
+		"revoked": "Membresía revocada",
+		"title": "Estado"
 	},
 	"time": {
 		"a": "a"
diff --git a/i18n/locales/fr.json b/i18n/locales/fr.json
index 69cd8db..fce5a05 100644
--- a/i18n/locales/fr.json
+++ b/i18n/locales/fr.json
@@ -196,7 +196,8 @@
 		"missing": "Adhésion perdue",
 		"newcomer": "Futur membre",
 		"renew": "Adhésion à renouveler",
-		"revoked": "Membre révoqué"
+		"revoked": "Membre révoqué",
+		"title": "Statut"
 	},
 	"time": {
 		"a": "à"
diff --git a/pages/previsions/futures_sorties.vue b/pages/previsions/futures_sorties.vue
index 42384b5..eb0e97a 100644
--- a/pages/previsions/futures_sorties.vue
+++ b/pages/previsions/futures_sorties.vue
@@ -19,8 +19,8 @@
 		</transition>
 		<transition name="fade">
 			<div class="row" v-if="!$apollo.loading">
-				<div class="col-lg-6 mb-5" v-if="memEnds">
-					<h2 class="h4 text-danger text-center">
+				<div class="col-md-6 mb-5" v-if="memEnds">
+					<h2 class="h4 text-danger text-center text-truncate">
 						{{ $t("statut.renew") }}
 					</h2>
 					<MemberList
@@ -28,8 +28,8 @@
 						:members="memEnds"
 						type="adhesion" />
 				</div>
-				<div class="col-lg-6 mb-5" v-if="certEnds">
-					<h2 class="h4 text-danger text-center">
+				<div class="col-md-6 mb-5" v-if="certEnds">
+					<h2 class="h4 text-danger text-center text-truncate">
 						{{ $t("statut.bientotmanquecertif") }}
 					</h2>
 					<MemberList
-- 
GitLab