diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 5d126348471c348decba17143ce128130c9f4104..0000000000000000000000000000000000000000
--- a/.editorconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# editorconfig.org
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-end_of_line = lf
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[*.md]
-trim_trailing_whitespace = false
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000000000000000000000000000000000000..dfbed09e1c64aa913fc77c2479dcdd7c30fd130d
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,16 @@
+{
+	"arrowParens": "always",
+	"bracketSpacing": true,
+	"bracketSameLine": true,
+	"embeddedLanguageFormatting": "auto",
+	"endOfLine": "lf",
+	"htmlWhitespaceSensitivity": "css",
+	"printWidth": 80,
+	"quoteProps": "as-needed",
+	"semi": false,
+	"singleQuote": false,
+	"tabWidth": 2,
+	"trailingComma": "none",
+	"useTabs": true,
+	"vueIndentScriptAndStyle": false
+}
diff --git a/README.md b/README.md
index 1997f6709baf56d853684acd6b9f29cd21b50ca5..cca8eb709d283e9cfcad13c6aece68a42fe4b943 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,28 @@
 # wotwizard-ui
 
+## Prerequisite
+
+This project needs NodeJS v16
+
 ## Contribute
+
 ```bash
 $ git clone https://git.duniter.org/paidge/wotwizard-ui.git
 $ cd wotwizard-ui
+$ nvm use 16
 $ git checkout -b my-branch
 $ npm install
 $ npm run dev
+... Development...
 $ npm run analyze
 $ git commit
 $ git push
 ```
+
 Then create a merge request.
 
 ### Add a new page
+
 Copy/paste the file `./pages/template.vue` and rename it to create a new page.
 
 This template is extremly commented for beginners so you can create an apollo query and display the response very easily even using i18n !
@@ -21,11 +30,11 @@ This template is extremly commented for beginners so you can create an apollo qu
 If you want to add your page in the menu, edit the `menus` variable in the `./layouts/default.vue` file.
 
 ### ChartJS
+
 There is an example to use component graph lazyly in `./pages/chartjs.vue`.
 
 ### GraphQL
 
-
 All files concerning Apollo Graphql are stored in `./graphql`.
 
 The schema documentation is stored in the `./graphql/doc/graphQLschema.txt` file.
@@ -35,6 +44,7 @@ In `queries.js` you'll find all queries.
 If you want to add a 2nd graphQL server, edit `./graphql/clients/endpoints.js` to put your URL and uncomment the line concerning the `apollo.clientConfigs.myotherclient` option in `nuxt.config.js`. I have not tested this functionnality.
 
 ### Special Directories
+
 For detailed explanation on how things work, check out the [documentation](https://nuxtjs.org).
 
 You can create the following extra directories, some of which have special behaviors. Only `pages` is required; you can delete them if you don't want to use their functionality.
@@ -57,7 +67,6 @@ Layouts are a great help when you want to change the look and feel of your Nuxt
 
 More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/layouts).
 
-
 #### `pages`
 
 This directory contains your application views and routes. Nuxt will read all the `*.vue` files inside this directory and setup Vue Router automatically.
@@ -93,19 +102,10 @@ $ nvm use 16
 # install dependencies
 $ npm install
 
-# serve with hot reload at localhost:3000
-$ npm run dev
-
-# Analyze assets to check bundle's size
-$ npm run analyze
-
 # build for production and launch server for Server Side Rendering (SSR)
 $ npm run build
 $ npm run start
 
-# generate static project
-$ npm run generate
-
-# update introspection schema for graphql server
-$ npm run build-fragment
-```
\ No newline at end of file
+# Or generate static project
+$ npm run generates
+```
diff --git a/assets/css/_bootstrap.scss b/assets/css/_bootstrap.scss
index 19a1e159f2e0f6e07225bca78dbc896716d9d7bd..8b120fc5e3a1fabed32fa6d871d8b0a2647211ef 100644
--- a/assets/css/_bootstrap.scss
+++ b/assets/css/_bootstrap.scss
@@ -1,39 +1,37 @@
-
- @import "~bootstrap/scss/functions";
- @import "~bootstrap/scss/variables";
- @import "~bootstrap/scss/mixins";
- @import "~bootstrap/scss/root";
- @import "~bootstrap/scss/reboot";
- @import "~bootstrap/scss/type";
- @import "~bootstrap/scss/images";
- @import "~bootstrap/scss/code";
- @import "~bootstrap/scss/grid";
- @import "~bootstrap/scss/tables";
- @import "~bootstrap/scss/forms";
- @import "~bootstrap/scss/buttons";
- @import "~bootstrap/scss/transitions";
+@import "~bootstrap/scss/functions";
+@import "~bootstrap/scss/variables";
+@import "~bootstrap/scss/mixins";
+@import "~bootstrap/scss/root";
+@import "~bootstrap/scss/reboot";
+@import "~bootstrap/scss/type";
+@import "~bootstrap/scss/images";
+@import "~bootstrap/scss/code";
+@import "~bootstrap/scss/grid";
+@import "~bootstrap/scss/tables";
+@import "~bootstrap/scss/forms";
+@import "~bootstrap/scss/buttons";
+@import "~bootstrap/scss/transitions";
 //  @import "~bootstrap/scss/dropdown";
 //  @import "~bootstrap/scss/button-group";
- @import "~bootstrap/scss/input-group";
+@import "~bootstrap/scss/input-group";
 //  @import "~bootstrap/scss/custom-forms";
- @import "~bootstrap/scss/nav";
- @import "~bootstrap/scss/navbar";
- @import "~bootstrap/scss/card";
- @import "~bootstrap/scss/breadcrumb";
+@import "~bootstrap/scss/nav";
+@import "~bootstrap/scss/navbar";
+@import "~bootstrap/scss/card";
+@import "~bootstrap/scss/breadcrumb";
 //  @import "~bootstrap/scss/pagination";
- @import "~bootstrap/scss/badge";
+@import "~bootstrap/scss/badge";
 //  @import "~bootstrap/scss/jumbotron";
- @import "~bootstrap/scss/alert";
+@import "~bootstrap/scss/alert";
 //  @import "~bootstrap/scss/progress";
 //  @import "~bootstrap/scss/media";
- @import "~bootstrap/scss/list-group";
- @import "~bootstrap/scss/close";
+@import "~bootstrap/scss/list-group";
+@import "~bootstrap/scss/close";
 //  @import "~bootstrap/scss/toasts";
 //  @import "~bootstrap/scss/modal";
- @import "~bootstrap/scss/tooltip";
+@import "~bootstrap/scss/tooltip";
 //  @import "~bootstrap/scss/popover";
 //  @import "~bootstrap/scss/carousel";
 //  @import "~bootstrap/scss/spinners";
- @import "~bootstrap/scss/utilities";
- @import "~bootstrap/scss/print";
- 
\ No newline at end of file
+@import "~bootstrap/scss/utilities";
+@import "~bootstrap/scss/print";
diff --git a/assets/css/_font.scss b/assets/css/_font.scss
index 373e3c180fa994a4f2c0782ab8f48308bf54b0f5..be9b73a2669e40ab4487cc2a5fcbc538ba01c590 100644
--- a/assets/css/_font.scss
+++ b/assets/css/_font.scss
@@ -1,69 +1,69 @@
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-Light.otf") format("truetype");
-    font-weight: 300;
-    font-style: normal;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-Light.otf") format("truetype");
+	font-weight: 300;
+	font-style: normal;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-LightItalic.otf") format("truetype");
-    font-weight: 300;
-    font-style: italic;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-LightItalic.otf") format("truetype");
+	font-weight: 300;
+	font-style: italic;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-Regular.otf") format("truetype");
-    font-weight: normal;
-    font-style: normal;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-Regular.otf") format("truetype");
+	font-weight: normal;
+	font-style: normal;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-Italic.otf") format("truetype");
-    font-weight: normal;
-    font-style: italic;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-Italic.otf") format("truetype");
+	font-weight: normal;
+	font-style: italic;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-SemiBold.otf") format("truetype");
-    font-weight: 500;
-    font-style: normal;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-SemiBold.otf") format("truetype");
+	font-weight: 500;
+	font-style: normal;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-SemiBoldItalic.otf") format("truetype");
-    font-weight: 500;
-    font-style: italic;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-SemiBoldItalic.otf") format("truetype");
+	font-weight: 500;
+	font-style: italic;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-Bold.otf") format("truetype");
-    font-weight: bold;
-    font-style: normal;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-Bold.otf") format("truetype");
+	font-weight: bold;
+	font-style: normal;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-BoldItalic.otf") format("truetype");
-    font-weight: bold;
-    font-style: italic;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-BoldItalic.otf") format("truetype");
+	font-weight: bold;
+	font-style: italic;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-ExtraBold.otf") format("truetype");
-    font-weight: 800;
-    font-style: normal;
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-ExtraBold.otf") format("truetype");
+	font-weight: 800;
+	font-style: normal;
 }
 
 @font-face {
-    font-family: "Montserrat";
-    src: url("~assets/fonts/Montserrat-ExtraBoldItalic.otf") format("truetype");
-    font-weight: 800;
-    font-style: italic;
-}
\ No newline at end of file
+	font-family: "Montserrat";
+	src: url("~assets/fonts/Montserrat-ExtraBoldItalic.otf") format("truetype");
+	font-weight: 800;
+	font-style: italic;
+}
diff --git a/assets/css/style.scss b/assets/css/style.scss
index 41df29462ae98d3a6002b4b81c3de0f59bddfdb9..b36e7b567c99ccd35d0f023476a74cfb4a43deab 100644
--- a/assets/css/style.scss
+++ b/assets/css/style.scss
@@ -36,9 +36,9 @@ $card-bg: var(--background-color-secondary);
 $close-color: var(--text-primary-color);
 $close-font-weight: 500;
 
-@import 'font';
-@import 'bootstrap';
+@import "font";
+@import "bootstrap";
 
-.table-hover tbody tr{
-    cursor: pointer;
-}
\ No newline at end of file
+.table-hover tbody tr {
+	cursor: pointer;
+}
diff --git a/components/Graph.vue b/components/Graph.vue
index aa2f218d4535da83c749fd07a6ff99c7d4685493..fac93ad92333446027cbf5b32b8452477936167a 100644
--- a/components/Graph.vue
+++ b/components/Graph.vue
@@ -1,85 +1,85 @@
 <template>
-    <div>
-        <canvas :id="id" @click="test($event)"></canvas>
-    </div>
+	<div>
+		<canvas :id="id" @click="test($event)"></canvas>
+	</div>
 </template>
 
 <script>
-import Chart from 'chart.js/auto'
+import Chart from "chart.js/auto"
 
 export const chartTypes = [
-    'line',
-    'bar',
-    'doughnut',
-    'bubble',
-    'scatter',
-    // 'radar',
-    // 'polarArea'
+	"line",
+	"bar",
+	"doughnut",
+	"bubble",
+	"scatter"
+	// 'radar',
+	// 'polarArea'
 ]
 
 export default {
-    props: {
-        id: {
-            type: String,
-            default : 'my-chart',
-            required: true
-        },
-        type: {
-            type: String,
-            default: 'line',
-            required: true,
-            validator: function (value) {
-                return chartTypes.indexOf(value) !== -1
-            }
-        },
-        data: {
-            type: Object,
-            default: undefined,
-            required: true
-        },
-        options: {
-            type: Object,
-            default: undefined
-        }
-    },
-    data() {
-        return {
-            chart: undefined,
-            chartData: {
-                type: this.type,
-                data: this.data,
-                options: this.options
-            }
-        }
-    },
-    methods: {
-        createChart() {
-            this.chart?.destroy()
-            this.chart = new Chart(document.getElementById(this.id), this.chartData)
-        }
-    },
-    mounted() {
-        this.createChart()
-    },
-    watch: {
-        type: {
-            handler(n,o) {
-                this.chartData.type = n
-                this.createChart()
-            }
-        },
-        data: {
-            handler(n,o){
-                this.chartData.data = n
-                this.createChart()
-            }
-        },
-        options: {
-            handler(n,o) {
-                this.chartData.options = n
-                this.createChart()
-            }
-        }
-    }
+	props: {
+		id: {
+			type: String,
+			default: "my-chart",
+			required: true
+		},
+		type: {
+			type: String,
+			default: "line",
+			required: true,
+			validator: function (value) {
+				return chartTypes.indexOf(value) !== -1
+			}
+		},
+		data: {
+			type: Object,
+			default: undefined,
+			required: true
+		},
+		options: {
+			type: Object,
+			default: undefined
+		}
+	},
+	data() {
+		return {
+			chart: undefined,
+			chartData: {
+				type: this.type,
+				data: this.data,
+				options: this.options
+			}
+		}
+	},
+	methods: {
+		createChart() {
+			this.chart?.destroy()
+			this.chart = new Chart(document.getElementById(this.id), this.chartData)
+		}
+	},
+	mounted() {
+		this.createChart()
+	},
+	watch: {
+		type: {
+			handler(n, o) {
+				this.chartData.type = n
+				this.createChart()
+			}
+		},
+		data: {
+			handler(n, o) {
+				this.chartData.data = n
+				this.createChart()
+			}
+		},
+		options: {
+			handler(n, o) {
+				this.chartData.options = n
+				this.createChart()
+			}
+		}
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/badge/CertifStatus.vue b/components/badge/CertifStatus.vue
index 3dcfa43403540e08d60f7957d3fb2b27e15c206e..c24c6716e92320f6ef706ba657509bbf0b22e6cf 100644
--- a/components/badge/CertifStatus.vue
+++ b/components/badge/CertifStatus.vue
@@ -1,34 +1,46 @@
 <template>
-    <span class="danger font-weight-normal" :class="classWarning" :title="textWarning" v-if="($options.filters.dateStatus(limitDate) != 'success') && (['MEMBER', 'MISSING'].includes(memberStatus))">âš 
-        <span class="sr-only">{{ textWarning }}</span>
-    </span>
+	<span
+		class="danger font-weight-normal"
+		:class="classWarning"
+		:title="textWarning"
+		v-if="
+			$options.filters.dateStatus(limitDate) != 'success' &&
+			['MEMBER', 'MISSING'].includes(memberStatus)
+		"
+		>âš 
+		<span class="sr-only">{{ textWarning }}</span>
+	</span>
 </template>
 
 <script>
 export default {
-    props: {
-        limitDate : {
-            type: Number,
-            default: 0
-        },
-        memberStatus : String
-    },
-    computed: {
-        classWarning() {
-            return {
-                'text-danger' : this.$options.filters.dateStatus(this.limitDate) == 'danger',
-                'text-warning' : this.$options.filters.dateStatus(this.limitDate) == 'warning'
-            }
-        },
-        textWarning() {
-            return (this.$options.filters.dateStatus(this.limitDate) == 'danger') ? this.$i18n.t('statut.manquecertif') : this.$i18n.t('statut.bientotmanquecertif')
-        }
-    }
+	props: {
+		limitDate: {
+			type: Number,
+			default: 0
+		},
+		memberStatus: String
+	},
+	computed: {
+		classWarning() {
+			return {
+				"text-danger":
+					this.$options.filters.dateStatus(this.limitDate) == "danger",
+				"text-warning":
+					this.$options.filters.dateStatus(this.limitDate) == "warning"
+			}
+		},
+		textWarning() {
+			return this.$options.filters.dateStatus(this.limitDate) == "danger"
+				? this.$i18n.t("statut.manquecertif")
+				: this.$i18n.t("statut.bientotmanquecertif")
+		}
+	}
 }
 </script>
 
 <style lang="scss" scoped>
 .danger {
-    cursor: default;
+	cursor: default;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/components/badge/Dispo.vue b/components/badge/Dispo.vue
index ad18eb31a9fe0dbcf7cd8f1273fcc3856d4c2e98..82581a67428cab47660970cf7403a03e2af18728 100644
--- a/components/badge/Dispo.vue
+++ b/components/badge/Dispo.vue
@@ -1,25 +1,32 @@
 <template>
-    <small>
-        <span class="badge"
-          :class="{
-              'badge-success': isDispo,
-              'badge-danger': !isDispo,
-          }">
-            {{ isDispo ? $t('membre.dispo') : $t('membre.nodispo') + ' >&nbsp;' + $d(new Date(dateDispo*1000), 'short') }}
-        </span>
-    </small>
+	<small>
+		<span
+			class="badge"
+			:class="{
+				'badge-success': isDispo,
+				'badge-danger': !isDispo
+			}">
+			{{
+				isDispo
+					? $t("membre.dispo")
+					: $t("membre.nodispo") +
+					  " >&nbsp;" +
+					  $d(new Date(dateDispo * 1000), "short")
+			}}
+		</span>
+	</small>
 </template>
 
 <script>
 export default {
-    props: {
-        isDispo: {
-            type: Boolean,
-            required: true
-        },
-        dateDispo: {
-            type: Number
-        }
-    }
+	props: {
+		isDispo: {
+			type: Boolean,
+			required: true
+		},
+		dateDispo: {
+			type: Number
+		}
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/badge/Quality.vue b/components/badge/Quality.vue
index 261bb7444b53bfbbc846cb4e06614597d6563f43..0f9c0007e67a122da5a3a7480a4e9c6bbe8651a3 100644
--- a/components/badge/Quality.vue
+++ b/components/badge/Quality.vue
@@ -1,22 +1,23 @@
 <template>
-    <small>
-        <span class="badge"
-          :class="{
-              'badge-success': quality>=80,
-              'badge-warning': quality<80,
-          }">
-            {{ Math.round(quality*100)/100 }}
-        </span>
-    </small>
+	<small>
+		<span
+			class="badge"
+			:class="{
+				'badge-success': quality >= 80,
+				'badge-warning': quality < 80
+			}">
+			{{ Math.round(quality * 100) / 100 }}
+		</span>
+	</small>
 </template>
 
 <script>
 export default {
-    props: {
-        quality: {
-            type: Number,
-            required: true
-        }
-    }
+	props: {
+		quality: {
+			type: Number,
+			required: true
+		}
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/badge/Status.vue b/components/badge/Status.vue
index ed5e7948c7392bfe07268269f201e8066c4a81e8..086493d0cfbfd74adbd6b30ea8cd12225d434fdb 100644
--- a/components/badge/Status.vue
+++ b/components/badge/Status.vue
@@ -1,38 +1,44 @@
 <template>
-    <small>
-        <span class="badge" :class="this.displayStatus(membre).class">
-            {{ this.displayStatus(membre).str }}
-        </span>
-    </small>
+	<small>
+		<span class="badge" :class="this.displayStatus(membre).class">
+			{{ this.displayStatus(membre).str }}
+		</span>
+	</small>
 </template>
 
 <script>
 export default {
-    props: {
-        membre: {
-            type: Object,
-            required: true
-        }
-    },
-    methods: {
-        displayStatus: function(member){
-            switch (member.status) {
-                case 'NEWCOMER':
-                    return {str: this.$i18n.t('statut.newcomer'),class: 'badge-info'}
-                case 'MISSING':
-                    return {str: this.$i18n.t('statut.missing'),class: 'badge-danger'}
-                case 'MEMBER':
-                    if (this.$options.filters.dateStatus(member.limitDate) == 'warning') {
-                        return {str: this.$i18n.t('statut.renew'),class: 'badge-warning'}
-                    } else {
-                        return {str: this.$i18n.t('statut.member'),class: 'badge-success'}
-                    }
-                case 'REVOKED':
-                    return {str: this.$i18n.t('statut.revoked'),class: 'badge-secondary'}
-                default:
-                    return 'N/A'
-            }
-        }
-    }
+	props: {
+		membre: {
+			type: Object,
+			required: true
+		}
+	},
+	methods: {
+		displayStatus: function (member) {
+			switch (member.status) {
+				case "NEWCOMER":
+					return { str: this.$i18n.t("statut.newcomer"), class: "badge-info" }
+				case "MISSING":
+					return { str: this.$i18n.t("statut.missing"), class: "badge-danger" }
+				case "MEMBER":
+					if (this.$options.filters.dateStatus(member.limitDate) == "warning") {
+						return { str: this.$i18n.t("statut.renew"), class: "badge-warning" }
+					} else {
+						return {
+							str: this.$i18n.t("statut.member"),
+							class: "badge-success"
+						}
+					}
+				case "REVOKED":
+					return {
+						str: this.$i18n.t("statut.revoked"),
+						class: "badge-secondary"
+					}
+				default:
+					return "N/A"
+			}
+		}
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/btn/Clipboard.vue b/components/btn/Clipboard.vue
index 212b3114cdea39d66868d0f9aa13a5f323bcfc5a..eb8c5f06a7145d3b127733689e08e70d69c2ff57 100644
--- a/components/btn/Clipboard.vue
+++ b/components/btn/Clipboard.vue
@@ -1,43 +1,51 @@
 <template>
-<div class="clipboard input-group input-group-sm mb-3 mx-auto">
-    <div class="input-group-prepend">
-        <button id="btncopy" class="btn btn-outline-secondary px-4 py-1" type="button" @click="copyText"></button>
-    </div>
-    <input type="text" class="form-control text-truncate" :value="textContent" disabled>
-</div>
+	<div class="clipboard input-group input-group-sm mb-3 mx-auto">
+		<div class="input-group-prepend">
+			<button
+				id="btncopy"
+				class="btn btn-outline-secondary px-4 py-1"
+				type="button"
+				@click="copyText"></button>
+		</div>
+		<input
+			type="text"
+			class="form-control text-truncate"
+			:value="textContent"
+			disabled />
+	</div>
 </template>
 
 <script>
 export default {
-    props: {
-        textContent: {
-            type: String,
-            required: true
-        }
-    },
-    methods: {
-        copyText() {
-            navigator.clipboard.writeText(this.textContent)
-                        $('#btncopy').tooltip({
-                title: this.$t('copie') + ' !',
-                trigger: 'manual'
-            })
-            $('#btncopy').tooltip('show')
-            setTimeout(() => {
-                $('#btncopy').tooltip('hide')
-            },500)
-        }
-    }
+	props: {
+		textContent: {
+			type: String,
+			required: true
+		}
+	},
+	methods: {
+		copyText() {
+			navigator.clipboard.writeText(this.textContent)
+			$("#btncopy").tooltip({
+				title: this.$t("copie") + " !",
+				trigger: "manual"
+			})
+			$("#btncopy").tooltip("show")
+			setTimeout(() => {
+				$("#btncopy").tooltip("hide")
+			}, 500)
+		}
+	}
 }
 </script>
 
 <style lang="scss">
 .clipboard {
-    max-width:500px;
+	max-width: 500px;
 
-    button {
-        background: url("~assets/img/clipboard.svg") no-repeat 50% 50% #fff;
-        background-size: 40%;
-    }
+	button {
+		background: url("~assets/img/clipboard.svg") no-repeat 50% 50% #fff;
+		background-size: 40%;
+	}
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/components/btn/Loading.vue b/components/btn/Loading.vue
index 1a54f4428c1ec9530f5de9ced761a373c61ed3ee..2937b4ce5b40849ce49489d8e56018e62d4707d3 100644
--- a/components/btn/Loading.vue
+++ b/components/btn/Loading.vue
@@ -1,18 +1,24 @@
 <template>
-    <button type="submit" class="btn btn-primary" :disabled="isWaiting || disabled">
-        <span v-if="isWaiting">
-            <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
-            Chargement...
-        </span>
-        <span v-else>Go !</span>
-    </button>
+	<button
+		type="submit"
+		class="btn btn-primary"
+		:disabled="isWaiting || disabled">
+		<span v-if="isWaiting">
+			<span
+				class="spinner-border spinner-border-sm"
+				role="status"
+				aria-hidden="true"></span>
+			{{ $t("chargement") }}...
+		</span>
+		<span v-else>Go !</span>
+	</button>
 </template>
 
 <script>
 export default {
-    props: {
-        isWaiting: Boolean,
-        disabled: Boolean
-    }
+	props: {
+		isWaiting: Boolean,
+		disabled: Boolean
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/btn/Theme.vue b/components/btn/Theme.vue
index 9282fd799fb50dd96ff1972ca10d582d9bf1a996..0c46a7c91ddd091a5c4a43420991e4159d2d342e 100644
--- a/components/btn/Theme.vue
+++ b/components/btn/Theme.vue
@@ -1,76 +1,88 @@
 <template>
-  <div>
-    <input @change="toggleTheme" id="checkbox" type="checkbox" class="switch-checkbox" />
-    <label for="checkbox" class="switch-label d-flex align-items-center justify-content-between position-relative mb-0 ">
-      <span>🌙</span>
-      <span>☀️</span>
-      <div class="switch-toggle position-absolute rounded-circle" :class="{ 'switch-toggle-checked': userTheme === 'dark-theme' }"></div>
-    </label>
-  </div>
+	<div>
+		<input
+			@change="toggleTheme"
+			id="checkbox"
+			type="checkbox"
+			class="switch-checkbox" />
+		<label
+			for="checkbox"
+			class="switch-label d-flex align-items-center justify-content-between position-relative mb-0">
+			<span>🌙</span>
+			<span>☀️</span>
+			<div
+				class="switch-toggle position-absolute rounded-circle"
+				:class="{ 'switch-toggle-checked': userTheme === 'dark-theme' }"></div>
+		</label>
+	</div>
 </template>
 
 <script>
 export default {
-  mounted() {
-    this.setTheme(localStorage.getItem("user-theme"))
-  },
+	mounted() {
+		this.setTheme(localStorage.getItem("user-theme"))
+	},
 
-  data() {
-    return {
-      userTheme: "light-theme",
-    };
-  },
+	data() {
+		return {
+			userTheme: "light-theme"
+		}
+	},
 
-  methods: {
-    toggleTheme() {
-      if (this.userTheme === "light-theme") {
-        this.setTheme("dark-theme")
-      } else {
-        this.setTheme("light-theme")
-      }
-    },
+	methods: {
+		toggleTheme() {
+			if (this.userTheme === "light-theme") {
+				this.setTheme("dark-theme")
+			} else {
+				this.setTheme("light-theme")
+			}
+		},
 
-    setTheme(theme) {
-      if (theme == null) {theme="light-theme"}
-      localStorage.setItem("user-theme", theme)
-      this.userTheme = theme
-      document.documentElement.className = theme
-    }
-  },
-};
+		setTheme(theme) {
+			if (theme == null) {
+				theme = "light-theme"
+			}
+			localStorage.setItem("user-theme", theme)
+			this.userTheme = theme
+			document.documentElement.className = theme
+		}
+	}
+}
 </script>
 
 <style scoped>
-*, ::before, ::after {
-    box-sizing: initial;
+*,
+::before,
+::after {
+	box-sizing: initial;
 }
 .switch-checkbox {
-  display: none;
+	display: none;
 }
 
 .switch-label {
-  background: var(--text-primary-color);
-  border-radius: var(--element-size);
-  cursor: pointer;
-  font-size: calc(var(--element-size) * 0.3);
-  height: calc(var(--element-size) * 0.35);
-  padding: calc(var(--element-size) * 0.1);
-  transition: background 0.5s ease;
-  width: var(--element-size);
-  z-index: 1;
+	background: var(--text-primary-color);
+	border-radius: var(--element-size);
+	cursor: pointer;
+	font-size: calc(var(--element-size) * 0.3);
+	height: calc(var(--element-size) * 0.35);
+	padding: calc(var(--element-size) * 0.1);
+	transition: background 0.5s ease;
+	width: var(--element-size);
+	z-index: 1;
 }
 
 .switch-toggle {
-  background-color: var(--background-color-primary);
-  top: calc(var(--element-size) * 0.07);
-  left: calc(var(--element-size) * 0.07);
-  height: calc(var(--element-size) * 0.4);
-  width: calc(var(--element-size) * 0.4);
-  transform: translateX(0);
-  transition: transform 0.3s ease, background-color 0.5s ease;
+	background-color: var(--background-color-primary);
+	top: calc(var(--element-size) * 0.07);
+	left: calc(var(--element-size) * 0.07);
+	height: calc(var(--element-size) * 0.4);
+	width: calc(var(--element-size) * 0.4);
+	transform: translateX(0);
+	transition: transform 0.3s ease, background-color 0.5s ease;
 }
 
 .switch-toggle-checked {
-  transform: translateX(calc(var(--element-size) * 0.6)) !important;
+	transform: translateX(calc(var(--element-size) * 0.6)) !important;
 }
 </style>
diff --git a/components/certif/List.vue b/components/certif/List.vue
index f409b6efb3fbf66c9a58f8347792f1433af3602d..b0728854bca74f483c2a55ce07f9e7608e31bc50 100644
--- a/components/certif/List.vue
+++ b/components/certif/List.vue
@@ -1,154 +1,241 @@
 <template>
-    <div class="table-responsive">
-        <table class="table table-striped table-hover" v-if="certifsPending.length > 0">
-            <tbody>
-                <tr v-for="certif in certifsPending" :key="getNeighbor(certif).uid + certif.expires_on"
-                    @click="$router.push(localePath({name:'membres-hash', params: {hash: getNeighbor(certif).hash}}))">
-                    <th scope="row" class="py-1">
-                        <div>
-                            {{ getNeighbor(certif).uid }}
-                            <BadgeCertifStatus :limitDate="getNeighbor(certif).received_certifications.limit" :memberStatus="getNeighbor(certif).status" />
-                            <BadgeQuality :quality="getNeighbor(certif).quality.ratio" v-if="getNeighbor(certif).status != 'REVOKED'" />
-                        </div>
-                        <div>
-                            <BadgeStatus :membre="getNeighbor(certif)" />
-                            <BadgeDispo :isDispo="getNeighbor(certif).minDatePassed" :dateDispo="getNeighbor(certif).minDate" v-if="getNeighbor(certif).status == 'MEMBER'" />
-                        </div>
-                    </th>
-                    <td class="text-right py-1">
-                        <small><span class="badge" :class="'badge-'+ $options.filters.dateStatus(certif.expires_on)">{{ $d(new Date(certif.expires_on*1000), 'short') }}</span></small>
-                        <small class="d-block"><span class="badge badge-secondary">{{ $t('traitement') }}</span></small>
-                    </td>
-                </tr>
-            </tbody>
-        </table>
-        <hr v-if="(certifsPending.length > 0) && (certifsTriees.length > 0)" />
-        <table class="table table-striped table-hover" v-if="certifsTriees.length > 0">
-            <thead>
-                <th @click="sort('uid')">
-                    {{ $t('membres') }}
-                    <div class="d-inline-block position-absolute ml-2">
-                        <div class="up" :class="{
-                            'sorted' : currentSortDir == 'desc' && currentSort == 'uid',
-                            'invisible' : currentSortDir == 'asc' && currentSort == 'uid'
-                        }">â–²</div>
-                        <div class="down" :class="{
-                            'sorted' : currentSortDir == 'asc' && currentSort == 'uid',
-                            'invisible' : currentSortDir == 'desc' && currentSort == 'uid'
-                        }">â–¼</div>
-                    </div>
-                </th>
-                <th @click="sort('expires_on')">
-                    {{ $t('expire') }}
-                    <div class="d-inline-block position-absolute ml-2">
-                        <div class="up" :class="{
-                            'sorted' : currentSortDir == 'desc' && currentSort == 'expires_on',
-                            'invisible' : currentSortDir == 'asc' && currentSort == 'expires_on'
-                        }">â–²</div>
-                        <div class="down" :class="{
-                            'sorted' : currentSortDir == 'asc' && currentSort == 'expires_on',
-                            'invisible' : currentSortDir == 'desc' && currentSort == 'expires_on'
-                        }">â–¼</div>
-                    </div>
-                </th>
-            </thead>
-            <tbody>
-                <tr v-for="certif in certifsTriees" :key="getNeighbor(certif).uid + certif.expires_on"
-                    @click="$router.push(localePath({name:'membres-hash', params: {hash: getNeighbor(certif).hash}}))">
-                    <th scope="row" class="py-1">
-                        <div>
-                            {{ getNeighbor(certif).uid }}
-                            <BadgeCertifStatus :limitDate="getNeighbor(certif).received_certifications.limit" :memberStatus="getNeighbor(certif).status" />
-                            <BadgeQuality :quality="getNeighbor(certif).quality.ratio" v-if="getNeighbor(certif).status != 'REVOKED'" />
-                        </div>
-                        <div>
-                            <BadgeStatus :membre="getNeighbor(certif)" />
-                            <BadgeDispo :isDispo="getNeighbor(certif).minDatePassed" :dateDispo="getNeighbor(certif).minDate" v-if="getNeighbor(certif).status == 'MEMBER'" />
-                        </div>
-                    </th>
-                    <td class="text-right py-1">
-                        <small><span class="badge" :class="'badge-'+ $options.filters.dateStatus(certif.expires_on)">{{ $d(new Date(certif.expires_on*1000), 'long') }}</span></small>
-                    </td>
-                </tr>
-            </tbody>
-        </table>
-    </div>
+	<div class="table-responsive">
+		<table
+			class="table table-striped table-hover"
+			v-if="certifsPending.length > 0">
+			<tbody>
+				<tr
+					v-for="certif in certifsPending"
+					:key="getNeighbor(certif).uid + certif.expires_on"
+					@click="
+						$router.push(
+							localePath({
+								name: 'membres-hash',
+								params: { hash: getNeighbor(certif).hash }
+							})
+						)
+					">
+					<th scope="row" class="py-1">
+						<div>
+							{{ getNeighbor(certif).uid }}
+							<BadgeCertifStatus
+								:limitDate="getNeighbor(certif).received_certifications.limit"
+								:memberStatus="getNeighbor(certif).status" />
+							<BadgeQuality
+								:quality="getNeighbor(certif).quality.ratio"
+								v-if="getNeighbor(certif).status != 'REVOKED'" />
+						</div>
+						<div>
+							<BadgeStatus :membre="getNeighbor(certif)" />
+							<BadgeDispo
+								:isDispo="getNeighbor(certif).minDatePassed"
+								:dateDispo="getNeighbor(certif).minDate"
+								v-if="getNeighbor(certif).status == 'MEMBER'" />
+						</div>
+					</th>
+					<td class="text-right py-1">
+						<small
+							><span
+								class="badge"
+								:class="
+									'badge-' + $options.filters.dateStatus(certif.expires_on)
+								"
+								>{{ $d(new Date(certif.expires_on * 1000), "short") }}</span
+							></small
+						>
+						<small class="d-block"
+							><span class="badge badge-secondary">{{
+								$t("traitement")
+							}}</span></small
+						>
+					</td>
+				</tr>
+			</tbody>
+		</table>
+		<hr v-if="certifsPending.length > 0 && certifsTriees.length > 0" />
+		<table
+			class="table table-striped table-hover"
+			v-if="certifsTriees.length > 0">
+			<thead>
+				<th @click="sort('uid')">
+					{{ $t("membres") }}
+					<div class="d-inline-block position-absolute ml-2">
+						<div
+							class="up"
+							:class="{
+								sorted: currentSortDir == 'desc' && currentSort == 'uid',
+								invisible: currentSortDir == 'asc' && currentSort == 'uid'
+							}">
+							â–²
+						</div>
+						<div
+							class="down"
+							:class="{
+								sorted: currentSortDir == 'asc' && currentSort == 'uid',
+								invisible: currentSortDir == 'desc' && currentSort == 'uid'
+							}">
+							â–¼
+						</div>
+					</div>
+				</th>
+				<th @click="sort('expires_on')">
+					{{ $t("expire") }}
+					<div class="d-inline-block position-absolute ml-2">
+						<div
+							class="up"
+							:class="{
+								sorted: currentSortDir == 'desc' && currentSort == 'expires_on',
+								invisible:
+									currentSortDir == 'asc' && currentSort == 'expires_on'
+							}">
+							â–²
+						</div>
+						<div
+							class="down"
+							:class="{
+								sorted: currentSortDir == 'asc' && currentSort == 'expires_on',
+								invisible:
+									currentSortDir == 'desc' && currentSort == 'expires_on'
+							}">
+							â–¼
+						</div>
+					</div>
+				</th>
+			</thead>
+			<tbody>
+				<tr
+					v-for="certif in certifsTriees"
+					:key="getNeighbor(certif).uid + certif.expires_on"
+					@click="
+						$router.push(
+							localePath({
+								name: 'membres-hash',
+								params: { hash: getNeighbor(certif).hash }
+							})
+						)
+					">
+					<th scope="row" class="py-1">
+						<div>
+							{{ getNeighbor(certif).uid }}
+							<BadgeCertifStatus
+								:limitDate="getNeighbor(certif).received_certifications.limit"
+								:memberStatus="getNeighbor(certif).status" />
+							<BadgeQuality
+								:quality="getNeighbor(certif).quality.ratio"
+								v-if="getNeighbor(certif).status != 'REVOKED'" />
+						</div>
+						<div>
+							<BadgeStatus :membre="getNeighbor(certif)" />
+							<BadgeDispo
+								:isDispo="getNeighbor(certif).minDatePassed"
+								:dateDispo="getNeighbor(certif).minDate"
+								v-if="getNeighbor(certif).status == 'MEMBER'" />
+						</div>
+					</th>
+					<td class="text-right py-1">
+						<small
+							><span
+								class="badge"
+								:class="
+									'badge-' + $options.filters.dateStatus(certif.expires_on)
+								"
+								>{{ $d(new Date(certif.expires_on * 1000), "long") }}</span
+							></small
+						>
+					</td>
+				</tr>
+			</tbody>
+		</table>
+	</div>
 </template>
 
 <script>
 export default {
-    data() {
-        return {
-            currentSort:'expires_on',
-            currentSortDir:'asc'
-        }
-    },
-    props : {
-        certifs : Array,
-        type : {
-            type: String,
-            required: true,
-            validator: function (value) {
-                const types = ['received','sent']
-                return types.indexOf(value) !== -1
-            }
-        }
-    },
-    methods : {
-        getNeighbor(certif) {
-            return this.type == "received" ? certif.from : certif.to
-        },
-        sort(s) {
-            if(s === this.currentSort) {
-                this.currentSortDir = this.currentSortDir==='asc'?'desc':'asc';
-            }
-            this.currentSort = s;
-        }
-    },
-    computed : {
-        certifsTriees() {
-            return this.certifs.slice().sort((a, b) => {
-                let modifier = this.currentSortDir === 'desc' ? -1 : 1
-                let sens = this.type == 'received' ? "from" : "to"
+	data() {
+		return {
+			currentSort: "expires_on",
+			currentSortDir: "asc"
+		}
+	},
+	props: {
+		certifs: Array,
+		type: {
+			type: String,
+			required: true,
+			validator: function (value) {
+				const types = ["received", "sent"]
+				return types.indexOf(value) !== -1
+			}
+		}
+	},
+	methods: {
+		getNeighbor(certif) {
+			return this.type == "received" ? certif.from : certif.to
+		},
+		sort(s) {
+			if (s === this.currentSort) {
+				this.currentSortDir = this.currentSortDir === "asc" ? "desc" : "asc"
+			}
+			this.currentSort = s
+		}
+	},
+	computed: {
+		certifsTriees() {
+			return this.certifs
+				.slice()
+				.sort((a, b) => {
+					let modifier = this.currentSortDir === "desc" ? -1 : 1
+					let sens = this.type == "received" ? "from" : "to"
 
-                if (this.currentSort == 'expires_on') {
-                    if(a['expires_on'] < b['expires_on']) return -1 * modifier
-                    if(a['expires_on'] > b['expires_on']) return 1 * modifier
-                } else {
-                    if(a[sens]['uid'].toLowerCase() < b[sens]['uid'].toLowerCase()) return -1 * modifier
-                    if(a[sens]['uid'].toLowerCase() > b[sens]['uid'].toLowerCase()) return 1 * modifier
-                }
+					if (this.currentSort == "expires_on") {
+						if (a["expires_on"] < b["expires_on"]) return -1 * modifier
+						if (a["expires_on"] > b["expires_on"]) return 1 * modifier
+					} else {
+						if (a[sens]["uid"].toLowerCase() < b[sens]["uid"].toLowerCase())
+							return -1 * modifier
+						if (a[sens]["uid"].toLowerCase() > b[sens]["uid"].toLowerCase())
+							return 1 * modifier
+					}
 
-                return 0
-            }).filter((el) => {return el.pending == false})
-        },
-        certifsPending() {
-            return this.certifs.slice().sort((a, b) => a.expires_on - b.expires_on).filter((el) => {return el.pending == true})
-        }
-    }
+					return 0
+				})
+				.filter((el) => {
+					return el.pending == false
+				})
+		},
+		certifsPending() {
+			return this.certifs
+				.slice()
+				.sort((a, b) => a.expires_on - b.expires_on)
+				.filter((el) => {
+					return el.pending == true
+				})
+		}
+	}
 }
 </script>
 
 <style lang="scss" scoped>
 thead th {
-    position: relative;
-    cursor:pointer;
-    background: var(--background-color-secondary);
+	position: relative;
+	cursor: pointer;
+	background: var(--background-color-secondary);
 
-    &:last-child {
-        padding-right: 1.5rem;
-        text-align: right;
-    }
+	&:last-child {
+		padding-right: 1.5rem;
+		text-align: right;
+	}
 }
 
-.up, .down {
-    line-height: 10px;
-    font-size: 1.1rem;
-    transform: scale(1.5,1);
-    opacity: .3;
+.up,
+.down {
+	line-height: 10px;
+	font-size: 1.1rem;
+	transform: scale(1.5, 1);
+	opacity: 0.3;
 }
 
 .sorted {
-    opacity: 1;
+	opacity: 1;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/components/member/Card.vue b/components/member/Card.vue
index 973b6bfd33d78c8f5b652e3e231f345780c32e5a..df502758ffa72c4f50291ac9ec4c66b3cca38c24 100644
--- a/components/member/Card.vue
+++ b/components/member/Card.vue
@@ -1,91 +1,159 @@
 <template>
-<div class="card member">
-    <div class="card-body">
-        <h2 class="card-title text-center">
-            {{ hash.uid }}
-            <BadgeStatus :membre="hash" />
-        </h2>
-        <BtnClipboard :textContent="this.hash.pubkey" />
-        <div class="table-responsive">
-            <table class="table table-sm table-borderless" v-if="hash.status != 'REVOKED'">
-            <tbody>
-                <tr v-if="hash.status == 'MEMBER'">
-                    <th scope="row">{{ $t('membre.referent') }}&nbsp;:</th>
-                    <td :class="{'list-group-item-success': hash.sentry, 'list-group-item-warning': !hash.sentry}">{{ hash.sentry ? $t('oui') : $t('non') }}</td>
-                </tr>
-                <tr v-if="hash.status != 'NEWCOMER'">
-                    <th scope="row">{{ $t('membre.qualite') }}&nbsp;:</th>
-                    <td :class="{
-                        'list-group-item-success': hash.quality.ratio >= 80,
-                        'list-group-item-warning': hash.quality.ratio < 80,
-                    }">{{ Math.round(hash.quality.ratio*100)/100 }}</td>
-                </tr>
-                <tr>
-                    <th scope="row">{{ $t('membre.distance') }}&nbsp;:</th>
-                    <td :class="{
-                        'list-group-item-success':  hash.status != 'NEWCOMER' ? hash.distance.dist_ok : hash.distanceE.dist_ok,
-                        'list-group-item-danger': hash.status != 'NEWCOMER' ? !hash.distance.dist_ok : !hash.distanceE.dist_ok,
-                    }">{{ hash.status != 'NEWCOMER' ? Math.round(hash.distance.value.ratio*100)/100 : Math.round(hash.distanceE.value.ratio*100)/100 }}</td>
-                </tr>
-                <tr>
-                    <th scope="row">{{ hash.status != 'MISSING' ? $t('membre.datelimadhesion') : $t('membre.datelimrevoc')}}&nbsp;:</th>
-                    <td :class="hash.status != 'MISSING' ? 'list-group-item-'+ $options.filters.dateStatus(hash.limitDate) : 'list-group-item-danger'">{{ $d(new Date(hash.limitDate*1000), 'long') }}</td>
-                </tr>
-                <tr v-if="hash.status == 'MEMBER'">
-                    <th scope="row">{{ $t('membre.datemanquecertifs') }}&nbsp;:</th>
-                    <td :class="'list-group-item-'+ $options.filters.dateStatus(hash.received_certifications.limit)">{{ $d(new Date(hash.received_certifications.limit*1000), 'long') }}</td>
-                </tr>
-                <tr v-if="hash.status == 'MEMBER'">
-                    <th scope="row">{{ $t('membre.dispocertif') }}&nbsp;:</th>
-                    <td :class="{
-                        'list-group-item-success': hash.minDatePassed,
-                        'list-group-item-danger': !hash.minDatePassed,
-                    }">{{ hash.minDatePassed ? $t('oui') : $t('non')  }} <small v-if="!hash.minDatePassed">( > {{ $d(new Date(hash.minDate*1000), 'long') }} )</small></td>
-                </tr>
-                <tr v-if="hash.status == 'MEMBER'">
-                    <th scope="row">{{ $t('membre.nb_certifs') }}&nbsp;:</th>
-                    <td :class="{
-                        'list-group-item-success': hash.sent_certifications.length<=80,
-                        'list-group-item-warning': hash.sent_certifications.length>80,
-                        'list-group-item-danger': hash.sent_certifications.length>90,
-                    }">{{ 100-hash.sent_certifications.length }}</td>
-                </tr>
-            </tbody>
-            </table>
-        </div>
-    </div>
-</div>
+	<div class="card member">
+		<div class="card-body">
+			<h2 class="card-title text-center">
+				{{ hash.uid }}
+				<BadgeStatus :membre="hash" />
+			</h2>
+			<BtnClipboard :textContent="this.hash.pubkey" />
+			<div class="table-responsive">
+				<table
+					class="table table-sm table-borderless"
+					v-if="hash.status != 'REVOKED'">
+					<tbody>
+						<tr v-if="hash.status == 'MEMBER'">
+							<th scope="row">{{ $t("membre.referent") }}&nbsp;:</th>
+							<td
+								:class="{
+									'list-group-item-success': hash.sentry,
+									'list-group-item-warning': !hash.sentry
+								}">
+								{{ hash.sentry ? $t("oui") : $t("non") }}
+							</td>
+						</tr>
+						<tr v-if="hash.status != 'NEWCOMER'">
+							<th scope="row">{{ $t("membre.qualite") }}&nbsp;:</th>
+							<td
+								:class="{
+									'list-group-item-success': hash.quality.ratio >= 80,
+									'list-group-item-warning': hash.quality.ratio < 80
+								}">
+								{{ Math.round(hash.quality.ratio * 100) / 100 }}
+							</td>
+						</tr>
+						<tr>
+							<th scope="row">{{ $t("membre.distance") }}&nbsp;:</th>
+							<td
+								:class="{
+									'list-group-item-success':
+										hash.status != 'NEWCOMER'
+											? hash.distance.dist_ok
+											: hash.distanceE.dist_ok,
+									'list-group-item-danger':
+										hash.status != 'NEWCOMER'
+											? !hash.distance.dist_ok
+											: !hash.distanceE.dist_ok
+								}">
+								{{
+									hash.status != "NEWCOMER"
+										? Math.round(hash.distance.value.ratio * 100) / 100
+										: Math.round(hash.distanceE.value.ratio * 100) / 100
+								}}
+							</td>
+						</tr>
+						<tr>
+							<th scope="row">
+								{{
+									hash.status != "MISSING"
+										? $t("membre.datelimadhesion")
+										: $t("membre.datelimrevoc")
+								}}&nbsp;:
+							</th>
+							<td
+								:class="
+									hash.status != 'MISSING'
+										? 'list-group-item-' +
+										  $options.filters.dateStatus(hash.limitDate)
+										: 'list-group-item-danger'
+								">
+								{{ $d(new Date(hash.limitDate * 1000), "long") }}
+							</td>
+						</tr>
+						<tr v-if="hash.status == 'MEMBER'">
+							<th scope="row">{{ $t("membre.datemanquecertifs") }}&nbsp;:</th>
+							<td
+								:class="
+									'list-group-item-' +
+									$options.filters.dateStatus(
+										hash.received_certifications.limit
+									)
+								">
+								{{
+									$d(
+										new Date(hash.received_certifications.limit * 1000),
+										"long"
+									)
+								}}
+							</td>
+						</tr>
+						<tr v-if="hash.status == 'MEMBER'">
+							<th scope="row">{{ $t("membre.dispocertif") }}&nbsp;:</th>
+							<td
+								:class="{
+									'list-group-item-success': hash.minDatePassed,
+									'list-group-item-danger': !hash.minDatePassed
+								}">
+								{{ hash.minDatePassed ? $t("oui") : $t("non") }}
+								<small v-if="!hash.minDatePassed"
+									>( > {{ $d(new Date(hash.minDate * 1000), "long") }} )</small
+								>
+							</td>
+						</tr>
+						<tr v-if="hash.status == 'MEMBER'">
+							<th scope="row">{{ $t("membre.nb_certifs") }}&nbsp;:</th>
+							<td
+								:class="{
+									'list-group-item-success':
+										hash.sent_certifications.length <= 80,
+									'list-group-item-warning':
+										hash.sent_certifications.length > 80,
+									'list-group-item-danger': hash.sent_certifications.length > 90
+								}">
+								{{ 100 - hash.sent_certifications.length }}
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</div>
+		</div>
+	</div>
 </template>
 
 <script>
 export default {
-    props: {
-        hash: Object
-    }
+	props: {
+		hash: Object
+	}
 }
 </script>
 
 <style lang="scss">
 .member {
-    .table {
-        text-align: center;
-        width: auto;
-        margin: auto;
+	.table {
+		text-align: center;
+		width: auto;
+		margin: auto;
 
-        tr {
-            display: flex;
-            flex-direction: column;
-        }
-    }
+		tr {
+			display: flex;
+			flex-direction: column;
+		}
+	}
 }
 
-@media (min-width:576px) {
-    .member {
-        .table {
-            tr {display: table-row;}
-            th {text-align: right;}
-            td {text-align: left;}
-        }
-    }
+@media (min-width: 576px) {
+	.member {
+		.table {
+			tr {
+				display: table-row;
+			}
+			th {
+				text-align: right;
+			}
+			td {
+				text-align: left;
+			}
+		}
+	}
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/components/member/List.vue b/components/member/List.vue
index 5541d3d1d93baa89de28166af2e6b692773d7145..3e6814d323f364b13ba4ba690c720de6846abe53 100644
--- a/components/member/List.vue
+++ b/components/member/List.vue
@@ -1,47 +1,57 @@
 <template>
-    <div class="table-responsive">
-        <table class="table table-striped table-hover">
-          <thead v-if="displayHead">
-            <tr>
-              <th scope="col">UID</th>
-              <th scope="col" class="d-none d-xl-table-cell" v-if="displayPubkey">PUBKEY</th>
-            </tr>
-          </thead>
-          <tbody>
-            <tr v-for="member in members" :key="member.uid"
-              @click="redirect(member.hash)">
-              <th scope="row">
-                {{ member.uid }}
-                <BadgeCertifStatus :limitDate="member.received_certifications.limit" :memberStatus="member.status" />
-                <BadgeStatus :membre="member" />
-              </th>
-              <td class="d-none d-xl-table-cell" v-if="displayPubkey">{{ member.pubkey }}</td>
-            </tr>
-          </tbody>
-        </table>
-    </div>
+	<div class="table-responsive">
+		<table class="table table-striped table-hover">
+			<thead v-if="displayHead">
+				<tr>
+					<th scope="col">UID</th>
+					<th scope="col" class="d-none d-xl-table-cell" v-if="displayPubkey">
+						PUBKEY
+					</th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr
+					v-for="member in members"
+					:key="member.uid"
+					@click="redirect(member.hash)">
+					<th scope="row">
+						{{ member.uid }}
+						<BadgeCertifStatus
+							:limitDate="member.received_certifications.limit"
+							:memberStatus="member.status" />
+						<BadgeStatus :membre="member" />
+					</th>
+					<td class="d-none d-xl-table-cell" v-if="displayPubkey">
+						{{ member.pubkey }}
+					</td>
+				</tr>
+			</tbody>
+		</table>
+	</div>
 </template>
 
 <script>
 export default {
-  props: {
-      members: {
-          type: Array,
-          required: true
-      },
-      displayPubkey: {
-        type: Boolean,
-        default: true
-      },
-      displayHead: {
-        type: Boolean,
-        default: true
-      }
-  },
-  methods: {
-    redirect(hash) {
-      this.$router.push(this.localePath({name:'membres-hash', params: {hash}}))
-    }
-  },
+	props: {
+		members: {
+			type: Array,
+			required: true
+		},
+		displayPubkey: {
+			type: Boolean,
+			default: true
+		},
+		displayHead: {
+			type: Boolean,
+			default: true
+		}
+	},
+	methods: {
+		redirect(hash) {
+			this.$router.push(
+				this.localePath({ name: "membres-hash", params: { hash } })
+			)
+		}
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/navigation/Bar.vue b/components/navigation/Bar.vue
index d83bd372a1b0e9fe641b061e55e8800bde902084..8a22db92e4eebc66880b0b76c89fc3d417a15800 100644
--- a/components/navigation/Bar.vue
+++ b/components/navigation/Bar.vue
@@ -1,231 +1,239 @@
 <template>
-  <header class="header position-fixed">
-    <div class="position-relative">
-      <button class="toggle btn border-secondary position-absolute p-1 m-1 ml-3" @click="toggleMenu"><span></span></button>
-      <NavigationBreadcrumb :breadcrumb="breadcrumb" />
-    </div>
-    <NavigationMenuSidebar @toggleMenu="toggleMenu" :menus="menus" />
-    <div class="bg_overlay position-fixed" @click="toggleMenu"></div>
-  </header>
+	<header class="header position-fixed">
+		<div class="position-relative">
+			<button
+				class="toggle btn border-secondary position-absolute p-1 m-1 ml-3"
+				@click="toggleMenu">
+				<span></span>
+			</button>
+			<NavigationBreadcrumb :breadcrumb="breadcrumb" />
+		</div>
+		<NavigationMenuSidebar @toggleMenu="toggleMenu" :menus="menus" />
+		<div class="bg_overlay position-fixed" @click="toggleMenu"></div>
+	</header>
 </template>
 
 <script>
 export default {
-  data() {
-    return {
-      isOpen: false
-    }
-  },
-  props: {
-    breadcrumb: Array,
-    menus: Array
-  },
-  methods: {
-    toggleMenu() {
-      document.querySelector('.app').classList.toggle('open')
-      console.log(this.isOpen)
-
-      this.isOpen = !this.isOpen
-      console.log(this.isOpen)
-
-      localStorage.setItem("menu-open", this.isOpen)
-    }
-  },
-  mounted() {
-    this.isOpen = (localStorage.getItem("menu-open") == "true")
-    if (this.isOpen) {
-      document.querySelector('.app').classList.add('open')
-    }
-  }
+	data() {
+		return {
+			isOpen: false
+		}
+	},
+	props: {
+		breadcrumb: Array,
+		menus: Array
+	},
+	methods: {
+		toggleMenu() {
+			document.querySelector(".app").classList.toggle("open")
+			console.log(this.isOpen)
+
+			this.isOpen = !this.isOpen
+			console.log(this.isOpen)
+
+			localStorage.setItem("menu-open", this.isOpen)
+		}
+	},
+	mounted() {
+		this.isOpen = localStorage.getItem("menu-open") == "true"
+		if (this.isOpen) {
+			document.querySelector(".app").classList.add("open")
+		}
+	}
 }
-
 </script>
 
 <style lang="scss">
 $btn-width: 50px;
 
 .header {
-  --menu-width: 0px;
-  width: 100%;
-  z-index: 100;
-  background: var(--background-color-primary);
-  transition: width .5s ease-in-out;
-
-  .open & {
-    --menu-width: 320px;
-  }
-
-  @media (min-width:1200px) {
-    width: calc(99vw - var(--menu-width));
-  }
+	--menu-width: 0px;
+	width: 100%;
+	z-index: 100;
+	background: var(--background-color-primary);
+	transition: width 0.5s ease-in-out;
+
+	.open & {
+		--menu-width: 320px;
+	}
+
+	@media (min-width: 1200px) {
+		width: calc(99vw - var(--menu-width));
+	}
 }
 
 nav.breadcrumb-wrapper {
-  margin: 8px 15px 8px 80px;
-  display: flex;
-  flex-direction: column;
-  gap: 1rem;
-  background: var(--background-color-secondary);
-
-  a {color: var(--text-primary-color)}
-
-  .breadcrumb-item.active {
-      opacity: .7;
-  }
-
-  @media (min-width:768px) {
-    flex-direction: row;
-    justify-content: space-between;
-    align-items: center;
-  }
+	margin: 8px 15px 8px 80px;
+	display: flex;
+	flex-direction: column;
+	gap: 1rem;
+	background: var(--background-color-secondary);
+
+	a {
+		color: var(--text-primary-color);
+	}
+
+	.breadcrumb-item.active {
+		opacity: 0.7;
+	}
+
+	@media (min-width: 768px) {
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+	}
 }
 
 %hamburger-line {
-  display: block;
-  height: 4px;
-  width: .8 * $btn-width;
-  background: var(--text-primary-color);
-  content: "";
-  position: absolute;
-  transition-property: transform;
-  border-radius: 4px;
+	display: block;
+	height: 4px;
+	width: 0.8 * $btn-width;
+	background: var(--text-primary-color);
+	content: "";
+	position: absolute;
+	transition-property: transform;
+	border-radius: 4px;
 }
 
 .toggle {
-  height: $btn-width;
-  width: $btn-width;
-  line-height: $btn-width;
-
-  span {
-    @extend %hamburger-line;
-    top: 50%;
-    transform: translateY(-50%);
-    transition-timing-function: cubic-bezier(.55,.055,.675,.19);
-    transition-duration: 75ms;
-
-    .open & {
-      transform: rotate(45deg);
-      display: block;
-      margin-top: -2px;
-    }
-
-    &::before {
-      transition: top 75ms ease .12s,opacity 75ms ease;
-      @extend %hamburger-line;
-      top: -10px;
-
-      .open & {
-        opacity: 0;
-      }
-    }
-
-    &::after {
-      transition: bottom 75ms ease .12s,transform 75ms cubic-bezier(.55,.055,.675,.19);
-      @extend %hamburger-line;
-      bottom: -10px;
-
-      .open & {
-        top: 0;
-        transform: rotate(-90deg);
-      }
-    }
-  }
+	height: $btn-width;
+	width: $btn-width;
+	line-height: $btn-width;
+
+	span {
+		@extend %hamburger-line;
+		top: 50%;
+		transform: translateY(-50%);
+		transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+		transition-duration: 75ms;
+
+		.open & {
+			transform: rotate(45deg);
+			display: block;
+			margin-top: -2px;
+		}
+
+		&::before {
+			transition: top 75ms ease 0.12s, opacity 75ms ease;
+			@extend %hamburger-line;
+			top: -10px;
+
+			.open & {
+				opacity: 0;
+			}
+		}
+
+		&::after {
+			transition: bottom 75ms ease 0.12s,
+				transform 75ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
+			@extend %hamburger-line;
+			bottom: -10px;
+
+			.open & {
+				top: 0;
+				transform: rotate(-90deg);
+			}
+		}
+	}
 }
 
 .menu {
-  background: var(--background-color-primary);
-  width: var(--menu-size);
-  top: 0;
-  z-index: 1200;
-  height: 100vh;
-  padding: 1.1rem 0.5rem;
-  overflow-y: scroll;
-  scrollbar-color: #6969dd #e0e0e0;
-  scrollbar-width: thin;
-  transition: left .5s ease-in-out;
-  left: -400px;
-
-  h1 {color: var(--text-primary-color);}
-
-  .list-group-item {    
-    &-action:not(.active) {
-      background: transparent;
-
-      &:hover {
-        background: rgba(0, 0, 255, 0.075);
-        color: var(--text-primary-color);
-      }
-    }
-
-    div {
-      transition: left .3s ease-in-out;
-      left: 0;
-
-      &::before {
-        content: "›";
-        position: relative;
-        left: -.5em;
-      }
-
-      &:hover {
-        left: .5em;
-      }
-    }
-  }
-
-  .open & {
-    left: 0;
-  }
-
-  .close {
-    --size: 50px;
-    width: var(--size);
-    height: var(--size);
-    top: .8rem;
-    right: 0;
-    font-size: 2rem;
-  }
-
-  h2 {
-    cursor: default;
-  }
+	background: var(--background-color-primary);
+	width: var(--menu-size);
+	top: 0;
+	z-index: 1200;
+	height: 100vh;
+	padding: 1.1rem 0.5rem;
+	overflow-y: scroll;
+	scrollbar-color: #6969dd #e0e0e0;
+	scrollbar-width: thin;
+	transition: left 0.5s ease-in-out;
+	left: -400px;
+
+	h1 {
+		color: var(--text-primary-color);
+	}
+
+	.list-group-item {
+		&-action:not(.active) {
+			background: transparent;
+
+			&:hover {
+				background: rgba(0, 0, 255, 0.075);
+				color: var(--text-primary-color);
+			}
+		}
+
+		div {
+			transition: left 0.3s ease-in-out;
+			left: 0;
+
+			&::before {
+				content: "›";
+				position: relative;
+				left: -0.5em;
+			}
+
+			&:hover {
+				left: 0.5em;
+			}
+		}
+	}
+
+	.open & {
+		left: 0;
+	}
+
+	.close {
+		--size: 50px;
+		width: var(--size);
+		height: var(--size);
+		top: 0.8rem;
+		right: 0;
+		font-size: 2rem;
+	}
+
+	h2 {
+		cursor: default;
+	}
 }
 
 .bg_overlay {
-  top: 0;
-  left: 0;
-  right: 0;
-  height: 120vh;
-  z-index: 1100;
-  visibility: hidden;
-  opacity: 0;
-  transition: all .5s ease;
-  background-color: rgba(34,41,47,.5);
-
-  .open & {
-    opacity: 1;
-    visibility: visible;
-  }
+	top: 0;
+	left: 0;
+	right: 0;
+	height: 120vh;
+	z-index: 1100;
+	visibility: hidden;
+	opacity: 0;
+	transition: all 0.5s ease;
+	background-color: rgba(34, 41, 47, 0.5);
+
+	.open & {
+		opacity: 1;
+		visibility: visible;
+	}
 }
 
 .logo {
-    max-width: 75px;
+	max-width: 75px;
 }
 
-@media (min-width:1200px) {
-  .open {
-    &.app {
-      margin-left: var(--menu-size);
-    }
-
-    .menu {
-      left: 0;
-    }
-
-    .bg_overlay {
-      visibility: hidden;
-      opacity: 0;
-    }
-  }
+@media (min-width: 1200px) {
+	.open {
+		&.app {
+			margin-left: var(--menu-size);
+		}
+
+		.menu {
+			left: 0;
+		}
+
+		.bg_overlay {
+			visibility: hidden;
+			opacity: 0;
+		}
+	}
 }
 </style>
diff --git a/components/navigation/Breadcrumb.vue b/components/navigation/Breadcrumb.vue
index 30f678a47bf63cddb8a65d2b219338a574051974..db0b14dadf35d123739b07609a5b4db8d01da547 100644
--- a/components/navigation/Breadcrumb.vue
+++ b/components/navigation/Breadcrumb.vue
@@ -1,22 +1,29 @@
 <template>
-    <nav aria-label="Fil d'Ariane" class="breadcrumb-wrapper rounded p-3">
-      <ol class="breadcrumb m-0 p-0">
-          <li class="breadcrumb-item" :class="{ 'active': item.active }" :aria-current="item.active ? 'page' : null" v-for="item in breadcrumb" :key="item.text">
-              <NuxtLink :to="localePath(item.to)" v-if="item.to">{{ item.text }}</NuxtLink>
-              <span v-else>{{ item.text }}</span>
-          </li>
-      </ol>
-      <div class="d-flex justify-content-between align-items-center">
-        <NavigationLanguage class="mr-3" />
-        <BtnTheme />
-      </div>
-    </nav>
+	<nav aria-label="Fil d'Ariane" class="breadcrumb-wrapper rounded p-3">
+		<ol class="breadcrumb m-0 p-0">
+			<li
+				class="breadcrumb-item"
+				:class="{ active: item.active }"
+				:aria-current="item.active ? 'page' : null"
+				v-for="item in breadcrumb"
+				:key="item.text">
+				<NuxtLink :to="localePath(item.to)" v-if="item.to">{{
+					item.text
+				}}</NuxtLink>
+				<span v-else>{{ item.text }}</span>
+			</li>
+		</ol>
+		<div class="d-flex justify-content-between align-items-center">
+			<NavigationLanguage class="mr-3" />
+			<BtnTheme />
+		</div>
+	</nav>
 </template>
 
 <script>
 export default {
-  props: {
-    breadcrumb: Array
-  }
+	props: {
+		breadcrumb: Array
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/navigation/Language.vue b/components/navigation/Language.vue
index 2e968ba99ba9c31d1da792dd9d23c09921e8dbb8..ab88bb45f68314bba47711125699bf3552ad5658 100644
--- a/components/navigation/Language.vue
+++ b/components/navigation/Language.vue
@@ -1,19 +1,24 @@
 <template>
-<div>
-    <select class="form-control" @change="saveLocale($event)" v-model="$i18n.locale">
-        <option v-for="lang in $i18n.locales" :key="lang.code" :value="lang.code">{{ lang.name }}</option>
-    </select>
-</div>
+	<div>
+		<select
+			class="form-control"
+			@change="saveLocale($event)"
+			v-model="$i18n.locale">
+			<option v-for="lang in $i18n.locales" :key="lang.code" :value="lang.code">
+				{{ lang.name }}
+			</option>
+		</select>
+	</div>
 </template>
 
 <script>
 export default {
-    methods: {
-        saveLocale(e) {
-            this.$i18n.locale = e.target.value
-            this.$i18n.setLocaleCookie(e.target.value)
-            this.$router.push(this.switchLocalePath(e.target.value))
-        }
-    }
+	methods: {
+		saveLocale(e) {
+			this.$i18n.locale = e.target.value
+			this.$i18n.setLocaleCookie(e.target.value)
+			this.$router.push(this.switchLocalePath(e.target.value))
+		}
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/navigation/Loader.vue b/components/navigation/Loader.vue
index 1e99a26611e0739e4e15b7a23a3acbdb0d64e4fd..50314b61e400923a2afddae1907c2626348dfc16 100644
--- a/components/navigation/Loader.vue
+++ b/components/navigation/Loader.vue
@@ -1,24 +1,28 @@
 <template>
-<transition name="fade">
-  <div class="loader overflow-hidden text-center position-absolute" v-if="isLoading">
-    <img src="~@/assets/img/loader.gif">
-    <div class="text-center font-weight-bold my-3">{{ $t('chargement') }}...</div>
-  </div>
-</transition>
+	<transition name="fade">
+		<div
+			class="loader overflow-hidden text-center position-absolute"
+			v-if="isLoading">
+			<img src="~@/assets/img/loader.gif" />
+			<div class="text-center font-weight-bold my-3">
+				{{ $t("chargement") }}...
+			</div>
+		</div>
+	</transition>
 </template>
 
 <script>
 export default {
-    props: {isLoading: Boolean}
+	props: { isLoading: Boolean }
 }
 </script>
 
 <style lang="scss">
 .loader {
-  z-index: 50;
-  left: 50%;
-  transform: translateX(-50%);
-  --color: #391855;
-  color: var(--text-primary-color);
+	z-index: 50;
+	left: 50%;
+	transform: translateX(-50%);
+	--color: #391855;
+	color: var(--text-primary-color);
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/components/navigation/menu/Group.vue b/components/navigation/menu/Group.vue
index 59b285b50b8412e807979fa72f9813ca53ac472a..e6fe0a74cb4026f0421fe55ac3c4b72e440368a5 100644
--- a/components/navigation/menu/Group.vue
+++ b/components/navigation/menu/Group.vue
@@ -1,18 +1,24 @@
 <template>
-    <div class="mb-4">
-        <h2 class="small text-muted text-uppercase ml-4 mb-2 pb-3 border-bottom">{{ $t(menu.title) }}</h2>
-        <div class="nav navbar-nav list-group list-group-flush">
-            <NuxtLink class="list-group-item list-group-item-action p-0 pl-3" :to="localePath(item.path)" v-for="item in menu.items" :key="item.path">
-                <div class="position-relative py-3">{{ $t(item.title) }}</div>
-            </NuxtLink>
-        </div>
-    </div>
+	<div class="mb-4">
+		<h2 class="small text-muted text-uppercase ml-4 mb-2 pb-3 border-bottom">
+			{{ $t(menu.title) }}
+		</h2>
+		<div class="nav navbar-nav list-group list-group-flush">
+			<NuxtLink
+				class="list-group-item list-group-item-action p-0 pl-3"
+				:to="localePath(item.path)"
+				v-for="item in menu.items"
+				:key="item.path">
+				<div class="position-relative py-3">{{ $t(item.title) }}</div>
+			</NuxtLink>
+		</div>
+	</div>
 </template>
 
 <script>
 export default {
-    props: {
-        menu: Object
-    }
+	props: {
+		menu: Object
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/components/navigation/menu/Sidebar.vue b/components/navigation/menu/Sidebar.vue
index 2b837b1e5a50d319132a00c2f86eeb89387d8ab6..0a3974f0189ed41d21debacba98b9fc32a8db293 100644
--- a/components/navigation/menu/Sidebar.vue
+++ b/components/navigation/menu/Sidebar.vue
@@ -1,41 +1,59 @@
 <template>
-    <aside class="menu shadow position-fixed">
-        <div class="nav_header pb-3 mb-4">
-            <nuxt-link :to="localePath('/')" class="d-flex">
-                <img src="@/assets/img/logo.png" alt="Accueil" class="logo">
-                <div><h1 class="h2">Wotwizard</h1><small class="text-muted">{{ $t('slogan') }}</small></div>
-            </nuxt-link>
-            <div class="d-flex text-info justify-content-between align-items-baseline mt-3 mx-2">
-                <div class="">v0.02</div>
-                <div class="small" v-if="countMax">Bloc n°<span class="font-weight-bold">{{ countMax.number }}</span> ({{ $d(new Date(countMax.utc0*1000), 'short') }} {{ $t('time.a') }} {{ $d(new Date(countMax.utc0*1000), 'time') }})</div>
-            </div>
-            <button type="button" class="close position-absolute d-xl-none" aria-label="Close" @click="toggleMenu">
-                <span aria-hidden="true">&times;</span>
-            </button>
-        </div>
-        <nav>
-            <NavigationMenuGroup v-for="menu in menus" :key="menu.title" :menu="menu"/>
-        </nav>
-    </aside>
+	<aside class="menu shadow position-fixed">
+		<div class="nav_header pb-3 mb-4">
+			<nuxt-link :to="localePath('/')" class="d-flex">
+				<img src="@/assets/img/logo.png" alt="Accueil" class="logo" />
+				<div>
+					<h1 class="h2">Wotwizard</h1>
+					<small class="text-muted">{{ $t("slogan") }}</small>
+				</div>
+			</nuxt-link>
+			<div
+				class="d-flex text-info justify-content-between align-items-baseline mt-3 mx-2">
+				<div class="">v0.02</div>
+				<div class="small" v-if="countMax">
+					Bloc n°<span class="font-weight-bold">{{ countMax.number }}</span> ({{
+						$d(new Date(countMax.utc0 * 1000), "short")
+					}}
+					{{ $t("time.a") }} {{ $d(new Date(countMax.utc0 * 1000), "time") }})
+				</div>
+			</div>
+			<button
+				type="button"
+				class="close position-absolute d-xl-none"
+				aria-label="Close"
+				@click="toggleMenu">
+				<span aria-hidden="true">&times;</span>
+			</button>
+		</div>
+		<nav>
+			<NavigationMenuGroup
+				v-for="menu in menus"
+				:key="menu.title"
+				:menu="menu" />
+		</nav>
+	</aside>
 </template>
 
 <script>
-import {LAST_BLOCK} from '@/graphql/queries.js'
+import { LAST_BLOCK } from "@/graphql/queries.js"
 
 export default {
-    props: {
-        menus: Array
-    },
-    methods: {
-        toggleMenu() {
-            this.$emit('toggleMenu')
-        }
-    },
-    apollo: {
-        countMax : {
-            query: LAST_BLOCK,
-            error (err) {this.error = err.message}
-        }
-    },
+	props: {
+		menus: Array
+	},
+	methods: {
+		toggleMenu() {
+			this.$emit("toggleMenu")
+		}
+	},
+	apollo: {
+		countMax: {
+			query: LAST_BLOCK,
+			error(err) {
+				this.error = err.message
+			}
+		}
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/graphql/cache.js b/graphql/cache.js
index a8035d3c198393e5177968142328cac93b35cb06..21055e0225ac2552ebaeaf74e99473d9d76f5495 100644
--- a/graphql/cache.js
+++ b/graphql/cache.js
@@ -3,19 +3,19 @@ import introspectionQueryResultData from './fragmentTypes.json';
 
 const fragmentMatcher = new IntrospectionFragmentMatcher({
     introspectionQueryResultData
-  })
+})
 
-  // Apparemment il faut utiliser la syntaxe Apollo v2
+// Apparemment il faut utiliser la syntaxe Apollo v2
 export const cache = new InMemoryCache({
     addTypename: false,
     fragmentMatcher,
     dataIdFromObject: object => {
         switch (object.__typename) {
-        case 'Identity': return object.hash
-        case 'Event': return object.block.number
-        case 'EventId': return `${object.member.hash}:${object.inOut}`
-        case 'Forecast': return `${object.member.hash}:${object.date}:${object.after}:${object.proba}`
-        default: return defaultDataIdFromObject(object); // fall back to default handling
+            case 'Identity': return object.hash
+            case 'Event': return object.block.number
+            case 'EventId': return `${object.member.hash}:${object.inOut}`
+            case 'Forecast': return `${object.member.hash}:${object.date}:${object.after}:${object.proba}`
+            default: return defaultDataIdFromObject(object); // fall back to default handling
         }
     }
 })
\ No newline at end of file
diff --git a/graphql/clients/coindufeu.js b/graphql/clients/coindufeu.js
index f0db19e5532df85ae88b8398ebbf5cacea686497..defa9024c6a36a07ac2131e08231b0eb8821409c 100644
--- a/graphql/clients/coindufeu.js
+++ b/graphql/clients/coindufeu.js
@@ -2,8 +2,8 @@ import { HttpLink } from 'apollo-link-http'
 import { setContext } from 'apollo-link-context'
 import { from } from 'apollo-link'
 
-import {ENDPOINT1} from './endpoints'
-import {cache} from '../cache'
+import { ENDPOINT1 } from './endpoints'
+import { cache } from '../cache'
 
 export default ctx => {
   const ssrMiddleware = setContext((_, { headers }) => {
diff --git a/graphql/clients/endpoints.js b/graphql/clients/endpoints.js
index 5108540880d199f55081198080c3b35016fe0af8..c3fb96a02dbafff165f1de59391b3bb1a2ed89ac 100644
--- a/graphql/clients/endpoints.js
+++ b/graphql/clients/endpoints.js
@@ -1,4 +1,4 @@
 module.exports = {
-  ENDPOINT1 : 'https://wwgql.coinduf.eu',
-  ENDPOINT2 : 'https://myserver.com'
+  ENDPOINT1: 'https://wwgql.coinduf.eu',
+  ENDPOINT2: 'https://myserver.com'
 }
\ No newline at end of file
diff --git a/graphql/clients/otherclient.js b/graphql/clients/otherclient.js
index 1a6b095dcfdabaac9e8b4c1a92fdbf306ad16b3d..a2b2016973f3722ae8f7923c224d8f4e0beb73ff 100644
--- a/graphql/clients/otherclient.js
+++ b/graphql/clients/otherclient.js
@@ -2,8 +2,8 @@ import { HttpLink } from 'apollo-link-http'
 import { setContext } from 'apollo-link-context'
 import { from } from 'apollo-link'
 
-import {ENDPOINT2} from './endpoints'
-import {cache} from '../cache'
+import { ENDPOINT2 } from './endpoints'
+import { cache } from '../cache'
 
 export default ctx => {
   const ssrMiddleware = setContext((_, { headers }) => {
diff --git a/graphql/fragmentTypes.json b/graphql/fragmentTypes.json
index 1ee79b1ac57a409d51f36112fdaff73df1122be2..551fbb1ad77ab1713246d756b4dfd28be9ad1c64 100644
--- a/graphql/fragmentTypes.json
+++ b/graphql/fragmentTypes.json
@@ -1 +1,24 @@
-{"__schema":{"types":[{"kind":"UNION","name":"CertifOrDossier","possibleTypes":[{"name":"MarkedDatedCertification"},{"name":"MarkedDossier"}]},{"kind":"INTERFACE","name":"File","possibleTypes":[{"name":"FileS"}]},{"kind":"INTERFACE","name":"WWResult","possibleTypes":[{"name":"WWResultS"}]}]}}
\ No newline at end of file
+{
+	"__schema": {
+		"types": [
+			{
+				"kind": "UNION",
+				"name": "CertifOrDossier",
+				"possibleTypes": [
+					{ "name": "MarkedDatedCertification" },
+					{ "name": "MarkedDossier" }
+				]
+			},
+			{
+				"kind": "INTERFACE",
+				"name": "File",
+				"possibleTypes": [{ "name": "FileS" }]
+			},
+			{
+				"kind": "INTERFACE",
+				"name": "WWResult",
+				"possibleTypes": [{ "name": "WWResultS" }]
+			}
+		]
+	}
+}
diff --git a/graphql/schemaQuery.js b/graphql/schemaQuery.js
index 736bec3631da0f08197899d88b21753c161108bd..da45416839a9da9b87718dc5d44a25bc06e84a05 100644
--- a/graphql/schemaQuery.js
+++ b/graphql/schemaQuery.js
@@ -1,4 +1,4 @@
-const {ENDPOINT1} = require('./clients/endpoints');
+const { ENDPOINT1 } = require('./clients/endpoints');
 const fetch = require('node-fetch');
 const fs = require('fs');
 
@@ -22,13 +22,13 @@ fetch(ENDPOINT1, {
     `,
   }),
 })
-.then(result => result.json())
-.then(result => {
+  .then(result => result.json())
+  .then(result => {
     const filteredData = result.data.__schema.types.filter(
       type => type.possibleTypes !== null
     )
     result.data.__schema.types = filteredData;
-    
+
     fs.writeFile('./graphql/fragmentTypes.json', JSON.stringify(result.data), err => {
       if (err) {
         console.error('Error writing fragmentTypes file', err);
@@ -36,4 +36,4 @@ fetch(ENDPOINT1, {
         console.log('Fragment types successfully extracted!');
       }
     });
-});
\ No newline at end of file
+  });
\ No newline at end of file
diff --git a/i18n/index.js b/i18n/index.js
index e72ec82d8b64a3a70cb29d58cfddaeb00c13ac06..d89d1390badf13c65bb7c801448629283ba83f77 100644
--- a/i18n/index.js
+++ b/i18n/index.js
@@ -1,7 +1,7 @@
 import en from './locales/en.json'
 import fr from './locales/fr.json'
 import es from './locales/es.json'
-import {dateTimeFormats} from './locales/dateTimeFormats'
+import { dateTimeFormats } from './locales/dateTimeFormats'
 
 export default {
   fallbackLocale: 'en',
diff --git a/i18n/locales/en.json b/i18n/locales/en.json
index 79765fe21794bc224a20116c3352d8be1d0f3858..1658d6138daa2074a5fcf18d03ec806f71dc2379 100644
--- a/i18n/locales/en.json
+++ b/i18n/locales/en.json
@@ -1,98 +1,98 @@
 {
-    "accueil": "Home",
-    "aurevoir": "Goodbye to",
-    "bienvenue": "Welcome to",
-    "bloc": "Block",
-    "certifications": {
-        "envoyees" : "Certificates sent",
-        "recues" : "Certificates received "
-    },
-    "chargement" : "Loading",
-    "copie" : "Copied",
-    "description": "Description",
-    "dev": "In development",
-    "expire": "Expires",
-    "futuremembers": "Future members",
-    "infos": "Informations",
-    "inout": "Entries and exits of the web of trust for the last 2 days",
-    "inpreparation": "In preparation",
-    "membre": {
-        "datelimadhesion": "Membership deadline",
-        "datelimrevoc" : "Deadline before revocation ",
-        "datemanquecertifs": "Date before running out of certs",
-        "dispo": "Available",
-        "dispocertif": "Available to certify",
-        "distance": "Distance",
-        "nb_certifs": "Nb of available certs",
-        "nodispo": "Unavailable",
-        "qualite": "Quality",
-        "referent": "Referent"
-    },
-    "membres": "Members",
-    "nom": "Name",
-    "non": "No",
-    "oui": "Yes",
-    "params": {
-        "breadcrumb": "Parameters",
-        "name": {
-            "avgGenTime": "The average time for writing 1 block (wished time)",
-            "c": "The relative growth of the UD every <code>dtReeval</code> period",
-            "dt": "Time period between two UD",
-            "dtDiffEval": "The number of blocks required to evaluate again PoWMin value",
-            "dtReeval": "Time period between two re-evaluation of the UD",
-            "idtyWindow": "Maximum delay an identity can wait before being expired for non-writing",
-            "medianTimeBlocks": "Number of blocks used for calculating median time",
-            "msPeriod": "Minimum delay between 2 memberships of a same issuer",
-            "msValidity": "Maximum age of an active membership",
-            "msWindow": "Maximum delay a membership can wait before being expired for non-writing",
-            "percentRot": "The proportion of calculating members not excluded from the proof of work",
-            "sigPeriod": "Minimum delay between two certifications of a same issuer",
-            "sigQty": "Minimum quantity of signatures to be part of the WoT",
-            "sigReplay": "Minimum delay before replaying a certification",
-            "sigStock": "Maximum quantity of active certifications made by member",
-            "sigValidity": "Maximum age of an active certification",
-            "sigWindow": "Maximum delay a certification can wait before being expired for non-writing",
-            "stepMax": "Maximum distance between a WOT member and <code>xpercent</code> of sentries",
-            "txWindow": "Maximum delay a transaction can wait before being expired for non-writing",
-            "ud0": "UD(0), i.e. initial Universal Dividend",
-            "udReevalTime0": "Time of first reevaluation of the UD",
-            "udTime0": "Time of first UD",
-            "xpercent": "Minimum percent of sentries to reach to match the distance rule"
-        },
-        "title": "Blockchain parameters"
-    },
-    "previsions" : {
-        "certificationsinternes": "No internal certification | 1 internal certification | {n} internal certifications",
-        "dossiersattente": "No pending files | 1 pending file | {n} pending files",
-        "pardate": "Forecasts by dates",
-        "parmembre": "Forecasts by members",
-        "permutations": "No permutation | 1 permutation | {n} permutations",
-        "title": "Forecasts"
-    },
-    "recherche": {
-        "desc" : "Enter the start of a nickname or public key",
-        "title": "Your search"
-    },
-    "revoila": "Here they are again",
-    "slogan": "The Web of Trust’s wizard",
-    "statut" : {
-        "bientotmanquecertif": "Needs certifications soon",
-        "manquecertif": "Needs certifications",
-        "member": "Member",
-        "missing": "Membership lost",
-        "newcomer": "Future member",
-        "renew": "Membership to renew",
-        "revoked": "Revoked member"
-    },
-    "time": {
-        "a": "at"
-    },
-    "traitement": "Ongoing treatment",
-    "tri": {
-        "pardate": "Sort by date",
-        "parmembres": "Sort by members"
-    },
-    "type": "Type",
-    "valeur": "Value",
-    "wot": "Web of trust"
-}
\ No newline at end of file
+	"accueil": "Home",
+	"aurevoir": "Goodbye to",
+	"bienvenue": "Welcome to",
+	"bloc": "Block",
+	"certifications": {
+		"envoyees": "Certificates sent",
+		"recues": "Certificates received "
+	},
+	"chargement": "Loading",
+	"copie": "Copied",
+	"description": "Description",
+	"dev": "In development",
+	"expire": "Expires",
+	"futuremembers": "Future members",
+	"infos": "Informations",
+	"inout": "Entries and exits of the web of trust for the last 2 days",
+	"inpreparation": "In preparation",
+	"membre": {
+		"datelimadhesion": "Membership deadline",
+		"datelimrevoc": "Deadline before revocation ",
+		"datemanquecertifs": "Date before running out of certs",
+		"dispo": "Available",
+		"dispocertif": "Available to certify",
+		"distance": "Distance",
+		"nb_certifs": "Nb of available certs",
+		"nodispo": "Unavailable",
+		"qualite": "Quality",
+		"referent": "Referent"
+	},
+	"membres": "Members",
+	"nom": "Name",
+	"non": "No",
+	"oui": "Yes",
+	"params": {
+		"breadcrumb": "Parameters",
+		"name": {
+			"avgGenTime": "The average time for writing 1 block (wished time)",
+			"c": "The relative growth of the UD every <code>dtReeval</code> period",
+			"dt": "Time period between two UD",
+			"dtDiffEval": "The number of blocks required to evaluate again PoWMin value",
+			"dtReeval": "Time period between two re-evaluation of the UD",
+			"idtyWindow": "Maximum delay an identity can wait before being expired for non-writing",
+			"medianTimeBlocks": "Number of blocks used for calculating median time",
+			"msPeriod": "Minimum delay between 2 memberships of a same issuer",
+			"msValidity": "Maximum age of an active membership",
+			"msWindow": "Maximum delay a membership can wait before being expired for non-writing",
+			"percentRot": "The proportion of calculating members not excluded from the proof of work",
+			"sigPeriod": "Minimum delay between two certifications of a same issuer",
+			"sigQty": "Minimum quantity of signatures to be part of the WoT",
+			"sigReplay": "Minimum delay before replaying a certification",
+			"sigStock": "Maximum quantity of active certifications made by member",
+			"sigValidity": "Maximum age of an active certification",
+			"sigWindow": "Maximum delay a certification can wait before being expired for non-writing",
+			"stepMax": "Maximum distance between a WOT member and <code>xpercent</code> of sentries",
+			"txWindow": "Maximum delay a transaction can wait before being expired for non-writing",
+			"ud0": "UD(0), i.e. initial Universal Dividend",
+			"udReevalTime0": "Time of first reevaluation of the UD",
+			"udTime0": "Time of first UD",
+			"xpercent": "Minimum percent of sentries to reach to match the distance rule"
+		},
+		"title": "Blockchain parameters"
+	},
+	"previsions": {
+		"certificationsinternes": "No internal certification | 1 internal certification | {n} internal certifications",
+		"dossiersattente": "No pending files | 1 pending file | {n} pending files",
+		"pardate": "Forecasts by dates",
+		"parmembre": "Forecasts by members",
+		"permutations": "No permutation | 1 permutation | {n} permutations",
+		"title": "Forecasts"
+	},
+	"recherche": {
+		"desc": "Enter the start of a nickname or public key",
+		"title": "Your search"
+	},
+	"revoila": "Here they are again",
+	"slogan": "The Web of Trust’s wizard",
+	"statut": {
+		"bientotmanquecertif": "Needs certifications soon",
+		"manquecertif": "Needs certifications",
+		"member": "Member",
+		"missing": "Membership lost",
+		"newcomer": "Future member",
+		"renew": "Membership to renew",
+		"revoked": "Revoked member"
+	},
+	"time": {
+		"a": "at"
+	},
+	"traitement": "Ongoing treatment",
+	"tri": {
+		"pardate": "Sort by date",
+		"parmembres": "Sort by members"
+	},
+	"type": "Type",
+	"valeur": "Value",
+	"wot": "Web of trust"
+}
diff --git a/i18n/locales/es.json b/i18n/locales/es.json
index ca3fa9624f54f2d879b07c40d05fe88975564321..295186d5f2317937cd0dae056e5cd7776a01543a 100644
--- a/i18n/locales/es.json
+++ b/i18n/locales/es.json
@@ -1,98 +1,98 @@
 {
-    "accueil": "Página principal",
-    "aurevoir": "Salen",
-    "bienvenue": "Entran",
-    "bloc": "Bloque",
-    "certifications": {
-        "envoyees" : "Certificaciones enviadas",
-        "recues" : "Certificaciones recibidas "
-    },
-    "chargement" : "Cargando",
-    "copie" : "Copiada",
-    "description": "Descripción",
-    "dev": "En desarrollo",
-    "expire": "Expira el",
-    "futuremembers": "Futuros miembros",
-    "infos": "Informaciones",
-    "inout": "Entradas y salidas de la red de confianza en los últimos 2 días",
-    "inpreparation": "En preparación",
-    "membre": {
-        "datelimadhesion": "Fecha límite de membresía",
-        "datelimrevoc" : "Fecha límite de la autorevocación",
-        "datemanquecertifs": "Fecha antes de quedarse sin certificaciones",
-        "dispo": "Disponible",
-        "dispocertif": "Disponible para certificar",
-        "distance": "Distancia",
-        "nb_certifs": "Núm. de certificaciones disponibles",
-        "nodispo": "Indisponible",
-        "qualite": "Calidad de enlace",
-        "referent": "Referente o de control"
-    },
-    "membres": "Miembros",
-    "nom": "Nombre",
-    "non": "No",
-    "oui": "Sí",
-    "params": {
-        "breadcrumb": "Parámetros",
-        "name": {
-            "avgGenTime": "The average time for writing 1 block (wished time)",
-            "c": "The relative growth of the UD every <code>dtReeval</code> period",
-            "dt": "Time period between two UD",
-            "dtDiffEval": "The number of blocks required to evaluate again PoWMin value",
-            "dtReeval": "Time period between two re-evaluation of the UD",
-            "idtyWindow": "Maximum delay an identity can wait before being expired for non-writing",
-            "medianTimeBlocks": "Number of blocks used for calculating median time",
-            "msPeriod": "Minimum delay between 2 memberships of a same issuer",
-            "msValidity": "Maximum age of an active membership",
-            "msWindow": "Maximum delay a membership can wait before being expired for non-writing",
-            "percentRot": "The proportion of calculating members not excluded from the proof of work",
-            "sigPeriod": "Minimum delay between two certifications of a same issuer",
-            "sigQty": "Minimum quantity of signatures to be part of the WoT",
-            "sigReplay": "Minimum delay before replaying a certification",
-            "sigStock": "Maximum quantity of active certifications made by member",
-            "sigValidity": "Maximum age of an active certification",
-            "sigWindow": "Maximum delay a certification can wait before being expired for non-writing",
-            "stepMax": "Maximum distance between a WOT member and <code>xpercent</code> of sentries",
-            "txWindow": "Maximum delay a transaction can wait before being expired for non-writing",
-            "ud0": "UD(0), i.e. initial Universal Dividend",
-            "udReevalTime0": "Time of first reevaluation of the UD",
-            "udTime0": "Time of first UD",
-            "xpercent": "Minimum percent of sentries to reach to match the distance rule"
-        },
-        "title": "Parámetros de la blockchain"
-    },
-    "previsions" : {
-        "certificationsinternes": "Sin certificación interna | 1 certificación interna | {n} certificaciones internas",
-        "dossiersattente": "No hay candidaturas pendientes | 1 candidatura pendiente | {n} candidaturas pendientes",
-        "pardate": "Previsiones por fecha",
-        "parmembre": "Previsiones por miembros",
-        "permutations": "Sin permutación | 1 permutación | {n} permutaciones",
-        "title": "Pronósticos"
-    },
-    "recherche": {
-        "desc" : "Introduce el comienzo de un pseudónimo o llave pública",
-        "title": "Buscar"
-    },
-    "revoila": "Regresan",
-    "slogan": "El mago de la Red de Confianza",
-    "statut" : {
-        "bientotmanquecertif": "Pronto necesitará certificaciones",
-        "manquecertif": "Faltan certificaciones",
-        "member": "Miembro",
-        "missing": "Membresía perdida",
-        "newcomer": "Futur@ miembro",
-        "renew": "Membresía por renovar",
-        "revoked": "Membresía revocada"
-    },
-    "time": {
-        "a": "a"
-    },
-    "traitement": "Tratamiento en curso",
-    "tri": {
-        "pardate": "Ordenar por fecha",
-        "parmembres": "Clasificar por miembros"
-    },
-    "type": "Tipo",
-    "valeur": "Valor",
-    "wot": "Red de confianza"
+	"accueil": "Página principal",
+	"aurevoir": "Salen",
+	"bienvenue": "Entran",
+	"bloc": "Bloque",
+	"certifications": {
+		"envoyees": "Certificaciones enviadas",
+		"recues": "Certificaciones recibidas "
+	},
+	"chargement": "Cargando",
+	"copie": "Copiada",
+	"description": "Descripción",
+	"dev": "En desarrollo",
+	"expire": "Expira el",
+	"futuremembers": "Futuros miembros",
+	"infos": "Informaciones",
+	"inout": "Entradas y salidas de la red de confianza en los últimos 2 días",
+	"inpreparation": "En preparación",
+	"membre": {
+		"datelimadhesion": "Fecha límite de membresía",
+		"datelimrevoc": "Fecha límite de la autorevocación",
+		"datemanquecertifs": "Fecha antes de quedarse sin certificaciones",
+		"dispo": "Disponible",
+		"dispocertif": "Disponible para certificar",
+		"distance": "Distancia",
+		"nb_certifs": "Núm. de certificaciones disponibles",
+		"nodispo": "Indisponible",
+		"qualite": "Calidad de enlace",
+		"referent": "Referente o de control"
+	},
+	"membres": "Miembros",
+	"nom": "Nombre",
+	"non": "No",
+	"oui": "Sí",
+	"params": {
+		"breadcrumb": "Parámetros",
+		"name": {
+			"avgGenTime": "The average time for writing 1 block (wished time)",
+			"c": "The relative growth of the UD every <code>dtReeval</code> period",
+			"dt": "Time period between two UD",
+			"dtDiffEval": "The number of blocks required to evaluate again PoWMin value",
+			"dtReeval": "Time period between two re-evaluation of the UD",
+			"idtyWindow": "Maximum delay an identity can wait before being expired for non-writing",
+			"medianTimeBlocks": "Number of blocks used for calculating median time",
+			"msPeriod": "Minimum delay between 2 memberships of a same issuer",
+			"msValidity": "Maximum age of an active membership",
+			"msWindow": "Maximum delay a membership can wait before being expired for non-writing",
+			"percentRot": "The proportion of calculating members not excluded from the proof of work",
+			"sigPeriod": "Minimum delay between two certifications of a same issuer",
+			"sigQty": "Minimum quantity of signatures to be part of the WoT",
+			"sigReplay": "Minimum delay before replaying a certification",
+			"sigStock": "Maximum quantity of active certifications made by member",
+			"sigValidity": "Maximum age of an active certification",
+			"sigWindow": "Maximum delay a certification can wait before being expired for non-writing",
+			"stepMax": "Maximum distance between a WOT member and <code>xpercent</code> of sentries",
+			"txWindow": "Maximum delay a transaction can wait before being expired for non-writing",
+			"ud0": "UD(0), i.e. initial Universal Dividend",
+			"udReevalTime0": "Time of first reevaluation of the UD",
+			"udTime0": "Time of first UD",
+			"xpercent": "Minimum percent of sentries to reach to match the distance rule"
+		},
+		"title": "Parámetros de la blockchain"
+	},
+	"previsions": {
+		"certificationsinternes": "Sin certificación interna | 1 certificación interna | {n} certificaciones internas",
+		"dossiersattente": "No hay candidaturas pendientes | 1 candidatura pendiente | {n} candidaturas pendientes",
+		"pardate": "Previsiones por fecha",
+		"parmembre": "Previsiones por miembros",
+		"permutations": "Sin permutación | 1 permutación | {n} permutaciones",
+		"title": "Pronósticos"
+	},
+	"recherche": {
+		"desc": "Introduce el comienzo de un pseudónimo o llave pública",
+		"title": "Buscar"
+	},
+	"revoila": "Regresan",
+	"slogan": "El mago de la Red de Confianza",
+	"statut": {
+		"bientotmanquecertif": "Pronto necesitará certificaciones",
+		"manquecertif": "Faltan certificaciones",
+		"member": "Miembro",
+		"missing": "Membresía perdida",
+		"newcomer": "Futur@ miembro",
+		"renew": "Membresía por renovar",
+		"revoked": "Membresía revocada"
+	},
+	"time": {
+		"a": "a"
+	},
+	"traitement": "Tratamiento en curso",
+	"tri": {
+		"pardate": "Ordenar por fecha",
+		"parmembres": "Clasificar por miembros"
+	},
+	"type": "Tipo",
+	"valeur": "Valor",
+	"wot": "Red de confianza"
 }
diff --git a/i18n/locales/fr.json b/i18n/locales/fr.json
index 1aac9fca582a983ecd8b1effa6f7bdfd666565a7..eb3969c2ccd14991bb94486c8857bdeaef465a3b 100644
--- a/i18n/locales/fr.json
+++ b/i18n/locales/fr.json
@@ -1,98 +1,98 @@
 {
-    "accueil": "Accueil",
-    "aurevoir": "Au revoir à",
-    "bienvenue": "Bienvenue à",
-    "bloc": "Bloc",
-    "certifications": {
-        "envoyees" : "Certifications envoyées",
-        "recues" : "Certifications reçues "
-    },
-    "chargement" : "Chargement",
-    "copie" : "Copiée",
-    "description": "Description",
-    "dev": "En Développement",
-    "expire": "Expire le",
-    "futuremembers": "Futurs membres",
-    "infos": "Informations",
-    "inout": "Entrées et sorties de la toile de confiance des 2 derniers jours",
-    "inpreparation": "En préparation",
-    "membre": {
-        "datelimadhesion": "Date limite d'adhésion",
-        "datelimrevoc" : "Date limite avant révocation ",
-        "datemanquecertifs": "Date avant de manquer de certifs",
-        "dispo": "Disponible",
-        "dispocertif": "Disponible pour certifier",
-        "distance": "Distance",
-        "nb_certifs": "Nbre de certifs disponibles",
-        "nodispo": "Indisponible",
-        "qualite": "Qualité",
-        "referent": "Référent"
-    },
-    "membres": "Membres",
-    "nom": "Nom",
-    "non": "Non",
-    "oui": "Oui",
-    "params": {
-        "breadcrumb": "Paramètres",
-        "name": {
-            "avgGenTime": "Temps moyen d’écriture d’un bloc (temps espéré)",
-            "c": "Croissance relative du DU pour chaque période <code>dtReeval</code>",
-            "dt": "Délai entre deux DU",
-            "dtDiffEval": "Nombre de blocs requis avant de réévaluer à nouveau la difficulté minimale de la Preuve de Travail",
-            "dtReeval": "Délai entre deux réévaluations du DU",
-            "idtyWindow": "Délai maximum qu'une identité peut attendre en piscine avant d'être rejetée pour non-écriture dans un bloc",
-            "medianTimeBlocks": "Nombre de blocs utilisés pour le calcul du temps moyen",
-            "msPeriod": "Délai minimum entre 2 demandes d'adhésion pour une même personne",
-            "msValidity": "Durée maximale d'une adhésion",
-            "msWindow": "Délai maximum qu'une adhésion peut attendre en piscine avant d'être rejetée pour non-écriture dans un bloc",
-            "percentRot": "Proportion des membres calculants non exclus de la preuve de travail",
-            "sigPeriod": "Délai minimum entre deux certifications d'un même émetteur",
-            "sigQty": "Nombre minimal de certifications reçues pour faire partie de la Toile de Confiance",
-            "sigReplay": "Délai minimum avant le renouvellement possible d'une certification",
-            "sigStock": "Nombre de certifications actives maximum envoyées par membre",
-            "sigValidity": "Durée de vie d'une certification active",
-            "sigWindow": "Délai maximal qu'une certification peut attendre en piscine avant d'être rejetée pour non-écriture dans un bloc",
-            "stepMax": "Distance maximale entre un membre et <code>xpercent</code> des membres référents",
-            "txWindow": "Délai maximum qu'une transaction peut attendre en piscine avant d'être rejetée pour non-écriture dans un bloc",
-            "ud0": "Montant du DU initial",
-            "udReevalTime0": "Date de la première réévaluation du DU",
-            "udTime0": "Date du premier DU",
-            "xpercent": "Pourcentage minimal de membres référents à atteindre pour respecter la règle de distance"
-        },
-        "title": "Paramètres de la blockchain"
-    },
-    "previsions" : {
-        "certificationsinternes": "Aucune certification interne | 1 certification interne | {n} certifications internes",
-        "dossiersattente": "Aucun dossier en attente | 1 dossier en attente | {n} dossiers en attente",
-        "pardate": "Prévisions par date",
-        "parmembre": "Prévisions par membres",
-        "permutations": "Aucune permutation | 1 permutation | {n} permutations",
-        "title": "Prévisions"
-    },
-    "recherche": {
-        "desc" : "Saisissez le début d'un pseudo ou d'une clé publique",
-        "title": "Votre recherche"
-    },
-    "revoila": "Les revoilà",
-    "slogan": "Le magicien de la Toile de Confiance",
-    "statut" : {
-        "bientotmanquecertif": "Bientôt en manque de certifications",
-        "manquecertif": "En manque de certifications",
-        "member": "Membre",
-        "missing": "Adhésion perdue",
-        "newcomer": "Futur membre",
-        "renew": "Adhésion à renouveler",
-        "revoked": "Membre révoqué"
-    },
-    "time": {
-        "a": "à"
-    },
-    "traitement": "En cours de traitement",
-    "tri": {
-        "pardate": "Tri par date",
-        "parmembres": "Tri par membres"
-    },
-    "type": "Type",
-    "valeur": "Valeur",
-    "wot": "Toile de confiance"
-}
\ No newline at end of file
+	"accueil": "Accueil",
+	"aurevoir": "Au revoir à",
+	"bienvenue": "Bienvenue à",
+	"bloc": "Bloc",
+	"certifications": {
+		"envoyees": "Certifications envoyées",
+		"recues": "Certifications reçues "
+	},
+	"chargement": "Chargement",
+	"copie": "Copiée",
+	"description": "Description",
+	"dev": "En Développement",
+	"expire": "Expire le",
+	"futuremembers": "Futurs membres",
+	"infos": "Informations",
+	"inout": "Entrées et sorties de la toile de confiance des 2 derniers jours",
+	"inpreparation": "En préparation",
+	"membre": {
+		"datelimadhesion": "Date limite d'adhésion",
+		"datelimrevoc": "Date limite avant révocation ",
+		"datemanquecertifs": "Date avant de manquer de certifs",
+		"dispo": "Disponible",
+		"dispocertif": "Disponible pour certifier",
+		"distance": "Distance",
+		"nb_certifs": "Nbre de certifs disponibles",
+		"nodispo": "Indisponible",
+		"qualite": "Qualité",
+		"referent": "Référent"
+	},
+	"membres": "Membres",
+	"nom": "Nom",
+	"non": "Non",
+	"oui": "Oui",
+	"params": {
+		"breadcrumb": "Paramètres",
+		"name": {
+			"avgGenTime": "Temps moyen d’écriture d’un bloc (temps espéré)",
+			"c": "Croissance relative du DU pour chaque période <code>dtReeval</code>",
+			"dt": "Délai entre deux DU",
+			"dtDiffEval": "Nombre de blocs requis avant de réévaluer à nouveau la difficulté minimale de la Preuve de Travail",
+			"dtReeval": "Délai entre deux réévaluations du DU",
+			"idtyWindow": "Délai maximum qu'une identité peut attendre en piscine avant d'être rejetée pour non-écriture dans un bloc",
+			"medianTimeBlocks": "Nombre de blocs utilisés pour le calcul du temps moyen",
+			"msPeriod": "Délai minimum entre 2 demandes d'adhésion pour une même personne",
+			"msValidity": "Durée maximale d'une adhésion",
+			"msWindow": "Délai maximum qu'une adhésion peut attendre en piscine avant d'être rejetée pour non-écriture dans un bloc",
+			"percentRot": "Proportion des membres calculants non exclus de la preuve de travail",
+			"sigPeriod": "Délai minimum entre deux certifications d'un même émetteur",
+			"sigQty": "Nombre minimal de certifications reçues pour faire partie de la Toile de Confiance",
+			"sigReplay": "Délai minimum avant le renouvellement possible d'une certification",
+			"sigStock": "Nombre de certifications actives maximum envoyées par membre",
+			"sigValidity": "Durée de vie d'une certification active",
+			"sigWindow": "Délai maximal qu'une certification peut attendre en piscine avant d'être rejetée pour non-écriture dans un bloc",
+			"stepMax": "Distance maximale entre un membre et <code>xpercent</code> des membres référents",
+			"txWindow": "Délai maximum qu'une transaction peut attendre en piscine avant d'être rejetée pour non-écriture dans un bloc",
+			"ud0": "Montant du DU initial",
+			"udReevalTime0": "Date de la première réévaluation du DU",
+			"udTime0": "Date du premier DU",
+			"xpercent": "Pourcentage minimal de membres référents à atteindre pour respecter la règle de distance"
+		},
+		"title": "Paramètres de la blockchain"
+	},
+	"previsions": {
+		"certificationsinternes": "Aucune certification interne | 1 certification interne | {n} certifications internes",
+		"dossiersattente": "Aucun dossier en attente | 1 dossier en attente | {n} dossiers en attente",
+		"pardate": "Prévisions par date",
+		"parmembre": "Prévisions par membres",
+		"permutations": "Aucune permutation | 1 permutation | {n} permutations",
+		"title": "Prévisions"
+	},
+	"recherche": {
+		"desc": "Saisissez le début d'un pseudo ou d'une clé publique",
+		"title": "Votre recherche"
+	},
+	"revoila": "Les revoilà",
+	"slogan": "Le magicien de la Toile de Confiance",
+	"statut": {
+		"bientotmanquecertif": "Bientôt en manque de certifications",
+		"manquecertif": "En manque de certifications",
+		"member": "Membre",
+		"missing": "Adhésion perdue",
+		"newcomer": "Futur membre",
+		"renew": "Adhésion à renouveler",
+		"revoked": "Membre révoqué"
+	},
+	"time": {
+		"a": "à"
+	},
+	"traitement": "En cours de traitement",
+	"tri": {
+		"pardate": "Tri par date",
+		"parmembres": "Tri par membres"
+	},
+	"type": "Type",
+	"valeur": "Valeur",
+	"wot": "Toile de confiance"
+}
diff --git a/jsconfig.json b/jsconfig.json
index 29037a628aaf3b84798021584c9ca70e9552d7ac..ea02ae44a273818fa16466aec1062a87fa7bf702 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -1,12 +1,12 @@
 {
-  "compilerOptions": {
-    "baseUrl": ".",
-    "paths": {
-      "~/*": ["./*"],
-      "@/*": ["./*"],
-      "~~/*": ["./*"],
-      "@@/*": ["./*"]
-    }
-  },
-  "exclude": ["node_modules", ".nuxt", "dist"]
+	"compilerOptions": {
+		"baseUrl": ".",
+		"paths": {
+			"~/*": ["./*"],
+			"@/*": ["./*"],
+			"~~/*": ["./*"],
+			"@@/*": ["./*"]
+		}
+	},
+	"exclude": ["node_modules", ".nuxt", "dist"]
 }
diff --git a/layouts/default.vue b/layouts/default.vue
index 728447bfa5765613f27948499374216ac3265692..cc59e35426e93867092e2c757bba4c4d64955a3c 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -1,82 +1,80 @@
 <template>
-    <div class="app">
-        <NavigationBar :breadcrumb="breadcrumb" :menus="menus" />
-        <Nuxt />
-    </div>
+	<div class="app">
+		<NavigationBar :breadcrumb="breadcrumb" :menus="menus" />
+		<Nuxt />
+	</div>
 </template>
 
 <script>
 export default {
-  data() {
-    return {
-      breadcrumb: [],
-      // Les title correspondent aux chaînes de traduction dans /i18n/locales
-      menus : [
-        {
-          title: 'wot',
-          items : [
-            {path: '/membres',title: 'membres'}
-          ]
-        },
-        {
-          title: 'previsions.title',
-          items : [
-            {path: '/previsions/futurs_membres',title: 'futuremembers'}
-          ]
-        },
-        {
-          title: 'infos',
-          items : [
-            {path: '/parametres',title: 'params.title'}
-          ]
-        }
-      ]
-    }
-  },
-  created() {
-    this.$nuxt.$on('changeRoute', (breadcrumb) => {
-        this.breadcrumb = breadcrumb
-    })
-  }
+	data() {
+		return {
+			breadcrumb: [],
+			// Les title correspondent aux chaînes de traduction dans /i18n/locales
+			menus: [
+				{
+					title: "wot",
+					items: [{ path: "/membres", title: "membres" }]
+				},
+				{
+					title: "previsions.title",
+					items: [
+						{ path: "/previsions/futurs_membres", title: "futuremembers" }
+					]
+				},
+				{
+					title: "infos",
+					items: [{ path: "/parametres", title: "params.title" }]
+				}
+			]
+		}
+	},
+	created() {
+		this.$nuxt.$on("changeRoute", (breadcrumb) => {
+			this.breadcrumb = breadcrumb
+		})
+	}
 }
 </script>
 
 <style lang="scss">
 /* Define styles for the default root window element */
 :root {
-  --text-primary-color: var(--dark);
-  --text-secondary-color: #8a8a8a;
-  --background-color-primary: var(--white);
-  --background-color-secondary: #e9ecef;
-  --element-size: 4rem;
-  --menu-size: 320px;
+	--text-primary-color: var(--dark);
+	--text-secondary-color: #8a8a8a;
+	--background-color-primary: var(--white);
+	--background-color-secondary: #e9ecef;
+	--element-size: 4rem;
+	--menu-size: 320px;
 }
 
 /* Define styles for the root window with dark - mode preference */
 :root.dark-theme {
-  --text-primary-color: var(--white);
-  --text-secondary-color: #c9c9c9;
-  --background-color-primary: var(--dark);
-  --background-color-secondary: hsl(210, 16%, 60%);
+	--text-primary-color: var(--white);
+	--text-secondary-color: #c9c9c9;
+	--background-color-primary: var(--dark);
+	--background-color-secondary: hsl(210, 16%, 60%);
 }
 
 .app {
-    transition: margin .5s ease-in-out;
+	transition: margin 0.5s ease-in-out;
 }
 main {
-  padding-top: 10rem;
-  position: relative;
+	padding-top: 10rem;
+	position: relative;
 
-  @media (min-width:768px) {
-    padding-top: 8rem;
-  }
+	@media (min-width: 768px) {
+		padding-top: 8rem;
+	}
 }
 
-.fade-enter-active, .fade-leave-active {
-  transition: opacity .5s;
+.fade-enter-active,
+.fade-leave-active {
+	transition: opacity 0.5s;
 }
 
-.fade-enter, .fade-leave-to {
-  opacity: 0;
+.fade-enter,
+.fade-leave-to {
+	opacity: 0;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/layouts/error.vue b/layouts/error.vue
index 96bb5c7bd4d50fdaf54ffde79bcfdd84a3dda6f6..ca51e9cc8f215ee5408fb3345ecefeaa49303be1 100644
--- a/layouts/error.vue
+++ b/layouts/error.vue
@@ -1,33 +1,37 @@
 <template>
-<main class="content">
-    <h2 v-if="error.statusCode === 404" class="display-2 text-center mb-5">Page not found</h2>
-    <h2 v-else class="display-2 text-center mb-5">An error occurred - {{ error.statusCode }} </h2>
-    <NuxtLink to="/" class="d-block text-center">Retour à l'accueil</NuxtLink>
-</main>
+	<main class="content">
+		<h2 v-if="error.statusCode === 404" class="display-2 text-center mb-5">
+			Page not found
+		</h2>
+		<h2 v-else class="display-2 text-center mb-5">
+			An error occurred - {{ error.statusCode }}
+		</h2>
+		<NuxtLink to="/" class="d-block text-center">Retour à l'accueil</NuxtLink>
+	</main>
 </template>
 
 <script>
 export default {
-  data() {
-    return {
-      breadcrumb: [
-        {
-          text: 'Erreur ',
-          active: true
-        }
-      ]
-    }
-  },
-  mounted () {
-    $nuxt.$emit('changeRoute',this.breadcrumb)
-  },
-  props: ['error'],
-  layout: 'error'
+	data() {
+		return {
+			breadcrumb: [
+				{
+					text: "Erreur ",
+					active: true
+				}
+			]
+		}
+	},
+	mounted() {
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+	},
+	props: ["error"],
+	layout: "error"
 }
 </script>
 
 <style lang="scss">
 .app {
-    transition: margin .5s ease-in-out;
+	transition: margin 0.5s ease-in-out;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/nuxt.config.js b/nuxt.config.js
index 439bef4726bf4b4e9a992af689c2f406e4806fd8..1f08452c02d8acfefc2ac83bd877e3675885a1d3 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -50,7 +50,7 @@ export default {
     '@nuxtjs/i18n'
   ],
 
-  i18n : {
+  i18n: {
     defaultLocale: 'fr',
     locales: [
       {
diff --git a/package.json b/package.json
index 9c1faee462b1211a32a6b02eb0464d30b14ec076..67082a78f20856dfae60878a9c56d3ca08e5b011 100644
--- a/package.json
+++ b/package.json
@@ -1,34 +1,34 @@
 {
-  "name": "wotwizard-ui",
-  "version": "1.0.0",
-  "private": true,
-  "scripts": {
-    "dev": "nuxt",
-    "build": "npm-run-all -p build-fragment nuxt-build",
-    "start": "npm-run-all -p build-fragment nuxt-start",
-    "generate": "npm-run-all -p build-fragment nuxt-generate",
-    "analyze": "nuxt build --analyze",
-    "build-fragment": "node graphql/schemaQuery.js",
-    "nuxt-build": "nuxt build",
-    "nuxt-start": "nuxt start",
-    "nuxt-generate": "nuxt generate"
-  },
-  "dependencies": {
-    "@nuxtjs/apollo": "^4.0.1-rc.5",
-    "@nuxtjs/i18n": "^7.2.0",
-    "@nuxtjs/pwa": "^3.3.5",
-    "apollo-link-context": "^1.0.20",
-    "apollo-link-http": "^1.5.17",
-    "bootstrap": "^4.6.1",
-    "chart.js": "^3.6.2",
-    "core-js": "^3.15.1",
-    "graphql-tag": "^2.12.6",
-    "nuxt": "^2.15.8",
-    "vue": "^2.6.14"
-  },
-  "devDependencies": {
-    "npm-run-all": "^4.1.5",
-    "sass": "^1.45.0",
-    "sass-loader": "^10.2.0"
-  }
+	"name": "wotwizard-ui",
+	"version": "1.0.0",
+	"private": true,
+	"scripts": {
+		"dev": "nuxt",
+		"build": "npm-run-all -p build-fragment nuxt-build",
+		"start": "npm-run-all -p build-fragment nuxt-start",
+		"generate": "npm-run-all -p build-fragment nuxt-generate",
+		"analyze": "nuxt build --analyze",
+		"build-fragment": "node graphql/schemaQuery.js",
+		"nuxt-build": "nuxt build",
+		"nuxt-start": "nuxt start",
+		"nuxt-generate": "nuxt generate"
+	},
+	"dependencies": {
+		"@nuxtjs/apollo": "^4.0.1-rc.5",
+		"@nuxtjs/i18n": "^7.2.0",
+		"@nuxtjs/pwa": "^3.3.5",
+		"apollo-link-context": "^1.0.20",
+		"apollo-link-http": "^1.5.17",
+		"bootstrap": "^4.6.1",
+		"chart.js": "^3.6.2",
+		"core-js": "^3.15.1",
+		"graphql-tag": "^2.12.6",
+		"nuxt": "^2.15.8",
+		"vue": "^2.6.14"
+	},
+	"devDependencies": {
+		"npm-run-all": "^4.1.5",
+		"sass": "^1.45.0",
+		"sass-loader": "^10.2.0"
+	}
 }
diff --git a/pages/chartjs.vue b/pages/chartjs.vue
index a8483d59568e0a44193b2d979b78fc92d7ecc3e5..8101966c9ad0620bc08995393744ac6240845627 100644
--- a/pages/chartjs.vue
+++ b/pages/chartjs.vue
@@ -1,93 +1,116 @@
 <template>
-  <main class="container-fluid">
-    <h2 class="display-2 text-center mb-5">Test ChartJS</h2>
-    <div class="row">
-      <div class="col-md-6 mx-auto">
-        <div class="alert alert-danger">En développement</div>
-      </div>
-    </div>
-    <div class="demo p-5 m-auto">
-      <select class="form-control my-4" v-model="chartType">
-        <option v-for="type in allTypes" :key="type">{{ type }}</option>
-      </select>
-      <button @click="fillData" class="btn btn-primary mb-5">Randomize</button>
-      <LazyGraph id="monGraph" :type="chartType" :data="data" :options="options" />
-    </div>
-  </main>
+	<main class="container-fluid">
+		<h2 class="display-2 text-center mb-5">Test ChartJS</h2>
+		<div class="row">
+			<div class="col-md-6 mx-auto">
+				<div class="alert alert-danger">En développement</div>
+			</div>
+		</div>
+		<div class="demo p-5 m-auto">
+			<select class="form-control my-4" v-model="chartType">
+				<option v-for="type in allTypes" :key="type">{{ type }}</option>
+			</select>
+			<button @click="fillData" class="btn btn-primary mb-5">Randomize</button>
+			<LazyGraph
+				id="monGraph"
+				:type="chartType"
+				:data="data"
+				:options="options" />
+		</div>
+	</main>
 </template>
 
 <script>
-import {chartTypes} from "~/components/Graph.vue"
+import { chartTypes } from "~/components/Graph.vue"
 
 export default {
-    data () {
-      return {
-        allTypes: chartTypes,
-        chartType: "line",
-        options: {
-            responsive: true,
-            lineTension: 1
-        },
-        data: {},
-        breadcrumb: [
-          {
-            text: this.$t('accueil'),
-            to: "/"
-          },
-          {
-            text: 'ChartJS',
-            active: true
-          }
-        ]
-      }
-    },
-    methods: {
-      fillData () {
-        this.data = {
-          labels: ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"],
-          datasets: [{
-              label: "Number of Moons",
-              data: this.generateArray(8),
-              backgroundColor: this.generateColor(),
-              borderColor: this.generateColor(),
-              borderWidth: 2
-          },
-          {
-              label: "Planetary Mass (relative to the Sun x 10^-6)",
-              data: this.generateArray(8),
-              backgroundColor: this.generateColor(),
-              borderColor: this.generateColor(),
-              borderWidth: 2
-          }]
-        }
-      },
-      generateColor() {
-        return "rgba(" + this.getRandomInt(255) + "," + this.getRandomInt(255) + "," + this.getRandomInt(255) + ",.5)"
-      },
-      generateArray (nb_items) {
-        let ret = []
-        for (let i=0;i<nb_items;i++) {
-          ret[i] = this.getRandomInt(50)
-        }
-        return ret
-      },
-      getRandomInt (max) {
-        return Math.floor(Math.random() * (max - 5 + 1)) + 5
-      }
-    },
-    nuxtI18n: {
-      paths: {
-        fr: '/graphiques',
-        en: '/graphics',
-        es: '/graficos'
-      }
-    },
-    mounted () {
-      $nuxt.$emit('changeRoute',this.breadcrumb)
-      // On remplit les données dans le graph
-      this.fillData()
-    }
-  }
+	data() {
+		return {
+			allTypes: chartTypes,
+			chartType: "line",
+			options: {
+				responsive: true,
+				lineTension: 1
+			},
+			data: {},
+			breadcrumb: [
+				{
+					text: this.$t("accueil"),
+					to: "/"
+				},
+				{
+					text: "ChartJS",
+					active: true
+				}
+			]
+		}
+	},
+	methods: {
+		fillData() {
+			this.data = {
+				labels: [
+					"Mercury",
+					"Venus",
+					"Earth",
+					"Mars",
+					"Jupiter",
+					"Saturn",
+					"Uranus",
+					"Neptune"
+				],
+				datasets: [
+					{
+						label: "Number of Moons",
+						data: this.generateArray(8),
+						backgroundColor: this.generateColor(),
+						borderColor: this.generateColor(),
+						borderWidth: 2
+					},
+					{
+						label: "Planetary Mass (relative to the Sun x 10^-6)",
+						data: this.generateArray(8),
+						backgroundColor: this.generateColor(),
+						borderColor: this.generateColor(),
+						borderWidth: 2
+					}
+				]
+			}
+		},
+		generateColor() {
+			return (
+				"rgba(" +
+				this.getRandomInt(255) +
+				"," +
+				this.getRandomInt(255) +
+				"," +
+				this.getRandomInt(255) +
+				",.5)"
+			)
+		},
+		generateArray(nb_items) {
+			let ret = []
+			for (let i = 0; i < nb_items; i++) {
+				ret[i] = this.getRandomInt(50)
+			}
+			return ret
+		},
+		getRandomInt(max) {
+			return Math.floor(Math.random() * (max - 5 + 1)) + 5
+		}
+	},
+	nuxtI18n: {
+		paths: {
+			fr: "/graphiques",
+			en: "/graphics",
+			es: "/graficos"
+		}
+	},
+	mounted() {
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+		// On remplit les données dans le graph
+		this.fillData()
+	}
+}
 </script>
 
 <style lang="sass" scoped>
diff --git a/pages/index.vue b/pages/index.vue
index 85a0b27371de41a5f7dcf4cbc0a886d7122b543d..ef21b7c25fe177df691fd2fb13bb63b1bdd05cd5 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -1,94 +1,113 @@
 <template>
-<main class="container">
-  <h2 class="text-center mb-5 font-weight-light">{{ $t('inout') }}</h2>
-  <NavigationLoader :isLoading="$apollo.queries.newMembers.loading" />
-  <transition name="fade">
-    <div class="alert alert-danger" v-if="error">{{ error }}</div>
-  </transition>
-  <transition name="fade">
-    <div class="result" v-if="newMembers">
-      <div class="row text-center">
-        <div class="col-md-6 col-lg-4">
-          <h2 class="h4 text-success">{{ $t('bienvenue') }}</h2>
-          <MemberList :members="newMembers['entrees']" :displayPubkey="false" :displayHead="false" />
-        </div>
-        <div class="col-md-6 col-lg-4">
-          <h2 class="h4 text-danger">{{ $t('aurevoir') }}</h2>
-          <MemberList :members="newMembers['sorties']" :displayPubkey="false" :displayHead="false" />
-        </div>
-        <div class="col-lg-4">
-          <h2 class="h4 text-info">{{ $t('revoila') }}</h2>
-          <MemberList :members="newMembers['renew']" :displayPubkey="false" :displayHead="false" />
-        </div>
-      </div>
-    </div>
-  </transition>
-</main>
+	<main class="container">
+		<h2 class="text-center mb-5 font-weight-light">{{ $t("inout") }}</h2>
+		<NavigationLoader :isLoading="$apollo.queries.newMembers.loading" />
+		<transition name="fade">
+			<div class="alert alert-danger" v-if="error">{{ error }}</div>
+		</transition>
+		<transition name="fade">
+			<div class="result" v-if="newMembers">
+				<div class="row text-center">
+					<div class="col-md-6 col-lg-4">
+						<h2 class="h4 text-success">{{ $t("bienvenue") }}</h2>
+						<MemberList
+							:members="newMembers['entrees']"
+							:displayPubkey="false"
+							:displayHead="false" />
+					</div>
+					<div class="col-md-6 col-lg-4">
+						<h2 class="h4 text-danger">{{ $t("aurevoir") }}</h2>
+						<MemberList
+							:members="newMembers['sorties']"
+							:displayPubkey="false"
+							:displayHead="false" />
+					</div>
+					<div class="col-lg-4">
+						<h2 class="h4 text-info">{{ $t("revoila") }}</h2>
+						<MemberList
+							:members="newMembers['renew']"
+							:displayPubkey="false"
+							:displayHead="false" />
+					</div>
+				</div>
+			</div>
+		</transition>
+	</main>
 </template>
 
 <script>
-import {LAST_EVENTS} from '@/graphql/queries.js'
+import { LAST_EVENTS } from "@/graphql/queries.js"
 
-const today = Math.round(Date.now() /1000)
+const today = Math.round(Date.now() / 1000)
 
 export default {
-  data() {
-    return {
-      breadcrumb: [
-        {
-          text: this.$t('accueil'),
-          to: '/'
-        }
-      ],
-      error: null
-    }
-  },
-  methods: {
-    addValue(arr,val) {
-      if (arr.filter(function(e) { return e.uid === val.uid }).length == 0) {
-        arr.push(val)
-      }
-      return arr
-    }
-  },
-  apollo: {
-    newMembers : {
-      query: LAST_EVENTS,
-      variables() {return {start:today-86400*2,end:today}},
-      update (data) {
-        let result = {'entrees':[],'sorties':[],'renew':[]}
-        let users = []
+	data() {
+		return {
+			breadcrumb: [
+				{
+					text: this.$t("accueil"),
+					to: "/"
+				}
+			],
+			error: null
+		}
+	},
+	methods: {
+		addValue(arr, val) {
+			if (
+				arr.filter(function (e) {
+					return e.uid === val.uid
+				}).length == 0
+			) {
+				arr.push(val)
+			}
+			return arr
+		}
+	},
+	apollo: {
+		newMembers: {
+			query: LAST_EVENTS,
+			variables() {
+				return { start: today - 86400 * 2, end: today }
+			},
+			update(data) {
+				let result = { entrees: [], sorties: [], renew: [] }
+				let users = []
 
-        for (let i = 0; i < data.membersCount.length; i++) {
-          for (let j =0; j < data.membersCount[i].idList.length; j++) {
-            let member = data.membersCount[i].idList[j]
-            member.member.inOut = member.inOut
+				for (let i = 0; i < data.membersCount.length; i++) {
+					for (let j = 0; j < data.membersCount[i].idList.length; j++) {
+						let member = data.membersCount[i].idList[j]
+						member.member.inOut = member.inOut
 
-            if (!users.includes(member.member.uid)) {
-              if (member.member.history.length==1) {
-                this.addValue(result['entrees'],member.member)
-              } else if (member.inOut) {
-                this.addValue(result['renew'],member.member)
-              } else {
-                this.addValue(result['sorties'],member.member)
-              }
-            }
+						if (!users.includes(member.member.uid)) {
+							if (member.member.history.length == 1) {
+								this.addValue(result["entrees"], member.member)
+							} else if (member.inOut) {
+								this.addValue(result["renew"], member.member)
+							} else {
+								this.addValue(result["sorties"], member.member)
+							}
+						}
 
-            users.push(member.member.uid)
-          }
-        }
+						users.push(member.member.uid)
+					}
+				}
 
-        for (let list in result) {
-          result[list].sort((a, b) => (a.uid.toLowerCase() > b.uid.toLowerCase()) ? 1 : -1)
-        }
-        
-        return result
-      },
-      error (err) {this.error = err.message}
-    }
-  },
-  mounted () {
-    $nuxt.$emit('changeRoute',this.breadcrumb)
-  }
+				for (let list in result) {
+					result[list].sort((a, b) =>
+						a.uid.toLowerCase() > b.uid.toLowerCase() ? 1 : -1
+					)
+				}
+
+				return result
+			},
+			error(err) {
+				this.error = err.message
+			}
+		}
+	},
+	mounted() {
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/pages/membres/_hash.vue b/pages/membres/_hash.vue
index 035bc02663e1636d1e63647d4425d5818826b322..d9402bc4e5d411b197ca7ca0ecc1b4c71d96b4d2 100644
--- a/pages/membres/_hash.vue
+++ b/pages/membres/_hash.vue
@@ -1,105 +1,154 @@
 <template>
-  <main>
-    <NavigationLoader :isLoading="$apollo.queries.idFromHash.loading" />
-    <transition name="fade">
-      <div class="alert alert-danger" v-if="error">{{ error }}</div>
-    </transition>
-    <transition name="fade">
-      <div v-if="idFromHash">
-        <div class="container-md">
-          <div class="row">
-            <div class="col-lg-9 col-xl-8 mx-auto my-3">
-              <MemberCard :hash="idFromHash" />
-            </div>
-          </div>
-        </div>
-        <div class="container">
-          <div class="row mt-3" v-if="idFromHash.status != 'REVOKED'">
-            <div class="col-sm-10 col-md-7 col-lg-5 mb-3 mx-auto">
-              <h3 class="h4 text-center" :class="{
-                'text-success' : ['NEWCOMER','MISSING'].includes(idFromHash.status) && idFromHash.received_certifications.certifications.length>=5,
-                'text-danger' : ['NEWCOMER','MISSING'].includes(idFromHash.status) && idFromHash.received_certifications.certifications.length<5,
-              }">{{ $t('certifications.recues') }} ({{ nbCertifs('received') }}<span v-if="nbCertifsPending('received') != 0">{{ '&nbsp;+&nbsp;' + nbCertifsPending('received') }}</span>)
-                <BadgeCertifStatus :limitDate="idFromHash.received_certifications.limit" :memberStatus="idFromHash.status" />
-              </h3>
-              <CertifList :certifs="idFromHash.received_certifications.certifications" type="received" />
-            </div>
-            <div class="col-sm-10 col-md-7 col-lg-5 mx-auto" v-if="['MISSING','MEMBER'].includes(idFromHash.status)">
-              <h3 class="h4 text-center">{{ $t('certifications.envoyees') }} ({{nbCertifs('sent') }}<span v-if="nbCertifsPending('sent') != 0">{{ '&nbsp;+&nbsp;' + nbCertifsPending('sent') }}</span>)</h3>
-              <CertifList :certifs="idFromHash.sent_certifications" type="sent" />
-            </div>
-          </div>
-        </div>
-      </div>
-    </transition>
-  </main>
+	<main>
+		<NavigationLoader :isLoading="$apollo.queries.idFromHash.loading" />
+		<transition name="fade">
+			<div class="alert alert-danger" v-if="error">{{ error }}</div>
+		</transition>
+		<transition name="fade">
+			<div v-if="idFromHash">
+				<div class="container-md">
+					<div class="row">
+						<div class="col-lg-9 col-xl-8 mx-auto my-3">
+							<MemberCard :hash="idFromHash" />
+						</div>
+					</div>
+				</div>
+				<div class="container">
+					<div class="row mt-3" v-if="idFromHash.status != 'REVOKED'">
+						<div class="col-sm-10 col-md-7 col-lg-5 mb-3 mx-auto">
+							<h3
+								class="h4 text-center"
+								:class="{
+									'text-success':
+										['NEWCOMER', 'MISSING'].includes(idFromHash.status) &&
+										idFromHash.received_certifications.certifications.length >=
+											5,
+									'text-danger':
+										['NEWCOMER', 'MISSING'].includes(idFromHash.status) &&
+										idFromHash.received_certifications.certifications.length < 5
+								}">
+								{{ $t("certifications.recues") }} ({{ nbCertifs("received")
+								}}<span v-if="nbCertifsPending('received') != 0">{{
+									"&nbsp;+&nbsp;" + nbCertifsPending("received")
+								}}</span
+								>)
+								<BadgeCertifStatus
+									:limitDate="idFromHash.received_certifications.limit"
+									:memberStatus="idFromHash.status" />
+							</h3>
+							<CertifList
+								:certifs="idFromHash.received_certifications.certifications"
+								type="received" />
+						</div>
+						<div
+							class="col-sm-10 col-md-7 col-lg-5 mx-auto"
+							v-if="['MISSING', 'MEMBER'].includes(idFromHash.status)">
+							<h3 class="h4 text-center">
+								{{ $t("certifications.envoyees") }} ({{ nbCertifs("sent")
+								}}<span v-if="nbCertifsPending('sent') != 0">{{
+									"&nbsp;+&nbsp;" + nbCertifsPending("sent")
+								}}</span
+								>)
+							</h3>
+							<CertifList
+								:certifs="idFromHash.sent_certifications"
+								type="sent" />
+						</div>
+					</div>
+				</div>
+			</div>
+		</transition>
+	</main>
 </template>
 
 <script>
-import {SEARCH_MEMBER} from "@/graphql/queries"
-import CertifStatus from '~/components/badge/CertifStatus.vue';
+import { SEARCH_MEMBER } from "@/graphql/queries"
+import CertifStatus from "~/components/badge/CertifStatus.vue"
 
 export default {
-  components: { CertifStatus },
-  data() {
-    return {
-      breadcrumb: [
-        {
-          text: this.$t('accueil'),
-          to: '/'
-        },
-        {
-          text: this.$t('membres'),
-          to: '/membres'
-        },
-        {
-          text: '',
-          active: true
-        }
-      ],
-      error: null
-    };
-  },
-  methods: {
-    nbCertifs(sens) {
-      return sens == "received" ? this.idFromHash.received_certifications.certifications.filter((el) => {return el.pending == false}).length : this.idFromHash.sent_certifications.filter((el) => {return el.pending == false}).length
-    },
-    nbCertifsPending(sens) {
-      return sens == "received" ? this.idFromHash.received_certifications.certifications.filter((el) => {return el.pending == true}).length : this.idFromHash.sent_certifications.filter((el) => {return el.pending == true}).length
-    }
-  },
-  apollo: {
-    idFromHash: {
-      query: SEARCH_MEMBER,
-      variables() {return { hash: this.$route.params.hash }},
-      error (err) {this.error = err.message}
-    }
-  },
-  nuxtI18n: {
-    paths: {
-      fr: '/membres/:hash',
-      en: '/members/:hash',
-      es: '/miembros/:hash'
-    }
-  },
-  computed: {
-    classWarning() {
-      return {
-        'text-danger' : !this.idFromHash.received_certifications.limit,
-        'text-warning' : this.$options.filters.dateStatus(this.idFromHash.received_certifications.limit) == 'warning'
-      }
-    }
-  },
-  mounted() {
-    $nuxt.$emit("changeRoute", this.breadcrumb)
-  },
-  watch: {
-    idFromHash: {
-      handler(n,o) {
-          this.breadcrumb[2].text = this.idFromHash.uid
-          $nuxt.$emit("changeRoute", this.breadcrumb)
-      }
-    }
-  }
-};
-</script>
\ No newline at end of file
+	components: { CertifStatus },
+	data() {
+		return {
+			breadcrumb: [
+				{
+					text: this.$t("accueil"),
+					to: "/"
+				},
+				{
+					text: this.$t("membres"),
+					to: "/membres"
+				},
+				{
+					text: "",
+					active: true
+				}
+			],
+			error: null
+		}
+	},
+	methods: {
+		nbCertifs(sens) {
+			return sens == "received"
+				? this.idFromHash.received_certifications.certifications.filter(
+						(el) => {
+							return el.pending == false
+						}
+				  ).length
+				: this.idFromHash.sent_certifications.filter((el) => {
+						return el.pending == false
+				  }).length
+		},
+		nbCertifsPending(sens) {
+			return sens == "received"
+				? this.idFromHash.received_certifications.certifications.filter(
+						(el) => {
+							return el.pending == true
+						}
+				  ).length
+				: this.idFromHash.sent_certifications.filter((el) => {
+						return el.pending == true
+				  }).length
+		}
+	},
+	apollo: {
+		idFromHash: {
+			query: SEARCH_MEMBER,
+			variables() {
+				return { hash: this.$route.params.hash }
+			},
+			error(err) {
+				this.error = err.message
+			}
+		}
+	},
+	nuxtI18n: {
+		paths: {
+			fr: "/membres/:hash",
+			en: "/members/:hash",
+			es: "/miembros/:hash"
+		}
+	},
+	computed: {
+		classWarning() {
+			return {
+				"text-danger": !this.idFromHash.received_certifications.limit,
+				"text-warning":
+					this.$options.filters.dateStatus(
+						this.idFromHash.received_certifications.limit
+					) == "warning"
+			}
+		}
+	},
+	mounted() {
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+	},
+	watch: {
+		idFromHash: {
+			handler(n, o) {
+				this.breadcrumb[2].text = this.idFromHash.uid
+				$nuxt.$emit("changeRoute", this.breadcrumb)
+			}
+		}
+	}
+}
+</script>
diff --git a/pages/membres/index.vue b/pages/membres/index.vue
index d3676539438811fbf0080fb0cdff76e9432189be..6dfd4c987e8072e9384a67a152ce5e7c5f867dc6 100644
--- a/pages/membres/index.vue
+++ b/pages/membres/index.vue
@@ -1,73 +1,92 @@
 <template>
-<main class="container">
-  <h2 class="text-center mb-5 font-weight-light">{{ $t('membres') }}</h2>
-  <div class="row mb-4">
-    <div class="col-6 m-auto text-center">
-      <label for="rech" class="form-label">{{ $t('recherche.title') }}</label>
-      <input type="text" class="form-control" id="rech" aria-describedby="rechHelp" v-model="param" autocomplete="off" @keyup="save">
-      <small id="rechHelp" class="form-text text-muted">{{ $t('recherche.desc') }}</small>
-    </div>
-  </div>
-  <NavigationLoader :isLoading="$apollo.queries.idSearch.loading" />
-  <transition name="fade">
-    <div class="alert alert-danger" v-if="error">{{ error }}</div>
-  </transition>
-  <transition name="fade">
-    <div class="row" v-if="idSearch && param.length>2 && !$apollo.queries.idSearch.loading">
-      <div class="col-8 m-auto">
-        <MemberList :members="idSearch.ids"/>
-      </div>
-    </div>
-  </transition>
-</main>
+	<main class="container">
+		<h2 class="text-center mb-5 font-weight-light">{{ $t("membres") }}</h2>
+		<div class="row mb-4">
+			<div class="col-6 m-auto text-center">
+				<label for="rech" class="form-label">{{ $t("recherche.title") }}</label>
+				<input
+					type="text"
+					class="form-control"
+					id="rech"
+					aria-describedby="rechHelp"
+					v-model="param"
+					autocomplete="off"
+					@keyup="save" />
+				<small id="rechHelp" class="form-text text-muted">{{
+					$t("recherche.desc")
+				}}</small>
+			</div>
+		</div>
+		<NavigationLoader :isLoading="$apollo.queries.idSearch.loading" />
+		<transition name="fade">
+			<div class="alert alert-danger" v-if="error">{{ error }}</div>
+		</transition>
+		<transition name="fade">
+			<div
+				class="row"
+				v-if="
+					idSearch && param.length > 2 && !$apollo.queries.idSearch.loading
+				">
+				<div class="col-8 m-auto">
+					<MemberList :members="idSearch.ids" />
+				</div>
+			</div>
+		</transition>
+	</main>
 </template>
 
 <script>
-import {SEARCH_MEMBERS} from '@/graphql/queries'
+import { SEARCH_MEMBERS } from "@/graphql/queries"
 
 export default {
-  data() {
-    return {
-      breadcrumb: [
-        {
-          text: this.$t('accueil'),
-          to: '/'
-        },
-        {
-          text: this.$t('membres'),
-          active: true
-        }
-      ],
-      param: '',
-      error: null
-    }
-  },
-  methods: {
-      save() {
-        localStorage.setItem('search', this.param)
-      }
-  },
-  apollo: {
-    idSearch : {
-      query: SEARCH_MEMBERS,
-      variables() {return {hint:this.param}},
-      skip() {return this.param.length < 3},
-      error (err) {this.error = err.message}
-    } 
-  },
-  nuxtI18n: {
-    paths: {
-      fr: '/membres',
-      en: '/members',
-      es: '/miembros'
-    }
-  },
-  mounted () {
-    $nuxt.$emit('changeRoute',this.breadcrumb)
-    // Rechargement du input
-    if (localStorage.search) {
-      this.param = localStorage.getItem('search')
-    }
-  }
+	data() {
+		return {
+			breadcrumb: [
+				{
+					text: this.$t("accueil"),
+					to: "/"
+				},
+				{
+					text: this.$t("membres"),
+					active: true
+				}
+			],
+			param: "",
+			error: null
+		}
+	},
+	methods: {
+		save() {
+			localStorage.setItem("search", this.param)
+		}
+	},
+	apollo: {
+		idSearch: {
+			query: SEARCH_MEMBERS,
+			variables() {
+				return { hint: this.param }
+			},
+			skip() {
+				return this.param.length < 3
+			},
+			error(err) {
+				this.error = err.message
+			}
+		}
+	},
+	nuxtI18n: {
+		paths: {
+			fr: "/membres",
+			en: "/members",
+			es: "/miembros"
+		}
+	},
+	mounted() {
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+		// Rechargement du input
+		if (localStorage.search) {
+			this.param = localStorage.getItem("search")
+		}
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/pages/parametres.vue b/pages/parametres.vue
index 444f71d1c4be22c668945102865a293e1392a0ae..a7b0ddff7c9706809693c849af1b82ef83b7ecb9 100644
--- a/pages/parametres.vue
+++ b/pages/parametres.vue
@@ -1,74 +1,85 @@
 <template>
-<main class="container">
-  <h2 class="text-center mb-5 font-weight-light">{{ $t('params.title') }}</h2>
-  <NavigationLoader :isLoading="$apollo.queries.allParameters.loading" />
-  <transition name="fade">
-    <div class="alert alert-danger" v-if="error">{{ error }}</div>
-  </transition>
-  <transition name="fade">
-    <div class="table-responsive" v-if="allParameters">
-      <table class="table table-striped">
-        <thead>
-          <th>{{ $t('nom') }}</th>
-          <th class="d-none d-sm-table-cell">{{ $t('type') }}</th>
-          <th>{{ $t('valeur') }}</th>
-          <th class="d-none d-md-table-cell">{{ $t('description') }}</th>
-        </thead>
-        <tbody>
-          <tr v-for="param in allParameters" :key="param.name">
-            <th scope="row">{{ param.name }}</th>
-            <td scope="row" class="d-none d-sm-table-cell">{{ param.par_type }}</td>
-            <td scope="row">{{ param.value }}</td>
-            <td scope="row" class="d-none d-md-table-cell" v-html="$t('params.name.' + param.name)"></td>
-          </tr>
-        </tbody>
-      </table>
-    </div>
-  </transition>
-</main>
+	<main class="container">
+		<h2 class="text-center mb-5 font-weight-light">{{ $t("params.title") }}</h2>
+		<NavigationLoader :isLoading="$apollo.queries.allParameters.loading" />
+		<transition name="fade">
+			<div class="alert alert-danger" v-if="error">{{ error }}</div>
+		</transition>
+		<transition name="fade">
+			<div class="table-responsive" v-if="allParameters">
+				<table class="table table-striped">
+					<thead>
+						<th>{{ $t("nom") }}</th>
+						<th class="d-none d-sm-table-cell">{{ $t("type") }}</th>
+						<th>{{ $t("valeur") }}</th>
+						<th class="d-none d-md-table-cell">{{ $t("description") }}</th>
+					</thead>
+					<tbody>
+						<tr v-for="param in allParameters" :key="param.name">
+							<th scope="row">{{ param.name }}</th>
+							<td scope="row" class="d-none d-sm-table-cell">
+								{{ param.par_type }}
+							</td>
+							<td scope="row">{{ param.value }}</td>
+							<td
+								scope="row"
+								class="d-none d-md-table-cell"
+								v-html="$t('params.name.' + param.name)"></td>
+						</tr>
+					</tbody>
+				</table>
+			</div>
+		</transition>
+	</main>
 </template>
 
 <script>
-import {PARAMS} from '@/graphql/queries.js'
+import { PARAMS } from "@/graphql/queries.js"
 
 export default {
-  data() {
-    return {
-      breadcrumb: [
-        {
-          text: this.$t('accueil'),
-          to: '/'
-        },
-        {
-          text: this.$t('params.breadcrumb'),
-          active: true
-        }
-      ],
-      error: null
-    }
-  },
-  apollo: {
-    allParameters : {
-      query: PARAMS,
-      update (data) {
-        return data.allParameters.sort((a,b) => {
-          if (a.name < b.name) {return -1;}
-          if (a.name > b.name) {return 1;}
-          return 0;
-        })
-      },
-      error (err) {this.error = err.message}
-    }
-  },
-  nuxtI18n: {
-    paths: {
-      fr: '/parametres',
-      en: '/parameters',
-      es: '/parametros'
-    }
-  },
-  mounted () {
-    $nuxt.$emit('changeRoute',this.breadcrumb)
-  }
+	data() {
+		return {
+			breadcrumb: [
+				{
+					text: this.$t("accueil"),
+					to: "/"
+				},
+				{
+					text: this.$t("params.breadcrumb"),
+					active: true
+				}
+			],
+			error: null
+		}
+	},
+	apollo: {
+		allParameters: {
+			query: PARAMS,
+			update(data) {
+				return data.allParameters.sort((a, b) => {
+					if (a.name < b.name) {
+						return -1
+					}
+					if (a.name > b.name) {
+						return 1
+					}
+					return 0
+				})
+			},
+			error(err) {
+				this.error = err.message
+			}
+		}
+	},
+	nuxtI18n: {
+		paths: {
+			fr: "/parametres",
+			en: "/parameters",
+			es: "/parametros"
+		}
+	},
+	mounted() {
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/pages/previsions/futurs_membres.vue b/pages/previsions/futurs_membres.vue
index cc98a8bcb8379a57fc0626776478a2afd4291e3d..c40b31e49407a52932bf4f06e20853c45d205b33 100644
--- a/pages/previsions/futurs_membres.vue
+++ b/pages/previsions/futurs_membres.vue
@@ -1,199 +1,289 @@
 <template>
-<main class="container">
-  <NavigationLoader :isLoading="$apollo.queries.wwResult.loading" />
-  <transition name="fade">
-    <div class="alert alert-danger" v-if="error">{{ error }}</div>
-  </transition>
-  <transition name="fade">
-    <div v-if="wwResult">
-      <h2 class="text-center mb-5 font-weight-light">{{ $t('previsions.title') }} <small><span class="badge badge-secondary">{{ $tc('previsions.dossiersattente', wwResult.dossiers_nb) }}</span></small></h2>
-      <div class="alert alert-info" role="alert">
-        <ul class="list-unstyled m-0">
-          <li>{{ $tc('previsions.certificationsinternes', wwResult.certifs_nb) }}</li>
-          <li>{{ $tc('previsions.permutations', wwResult.permutations_nb) }}</li>
-        </ul>
-      </div>
-      <div class="row">
-        <div class="col-12 text-center mb-4">
-          <div class="form-check form-check-inline">
-            <input class="form-check-input" type="radio" id="forecastsByNames" value="forecastsByNames" checked v-model="display" @change="save">
-            <label class="form-check-label" for="forecastsByNames">
-              {{ $t('tri.parmembres') }}
-            </label>
-          </div>
-          <div class="form-check form-check-inline">
-            <input class="form-check-input" type="radio" id="forecastsByDates" value="forecastsByDates" v-model="display" @change="save">
-            <label class="form-check-label" for="forecastsByDates">
-              {{ $t('tri.pardate') }}
-            </label>
-          </div>
-        </div>
-        <div class="col-lg-8 m-auto">
-          <div v-if="display=='forecastsByNames'">
-            <h3>{{ $t('previsions.parmembre') }}</h3>
-            <div class="table-responsive">
-              <table class="table table-striped table-hover">
-                <tbody>
-                  <tr v-for="forecast in wwResult.forecastsByNames" :key="forecast.member.uid" @click="$router.push(localePath({name:'membres-hash', params:{hash:forecast.member.hash}}))">
-                    <th scope="row">
-                      {{ forecast.member.uid }}
-                      <BadgeStatus :membre="forecast.member" />
-                    </th>
-                    <td class="p-0">
-                      <div class="d-flex justify-content-between p-3" v-for="date in forecast.forecasts" :key="date.date">
-                        <div class="forecast_date mr-3" v-if="date.date<9999999999">{{ $d(new Date(date.date*1000), 'short') }} {{ $t('time.a') }} {{ $d(new Date(date.date*1000), 'hour').replace(" ", "&nbsp;") }}</div>
-                        <div class="forecast_date mr-3" v-else>N/A</div>
-                        <div>{{ Math.round(date.proba * 100) }}&nbsp;%</div>
-                      </div>
-                    </td>
-                  </tr>
-                </tbody>
-              </table>
-            </div>
-          </div>
-          <div v-if="display=='forecastsByDates'">
-            <h3>{{ $t('previsions.pardate') }}</h3>
-            <div class="table-responsive">
-              <table class="table table-striped">
-                <tbody>
-                  <tr v-for="forecast in wwResult.forecastsByDates" :key="forecast.date">
-                    <th scope="row" class="forecast_date" v-if="forecast.date<9999999999">{{ $d(new Date(forecast.date*1000), 'short') }} {{ $t('time.a') }} {{ $d(new Date(forecast.date*1000), 'hour') }}</th>
-                    <th scope="row" class="forecast_date" v-else>N/A</th>
-                    <td class="p-0">
-                      <div class="list-group rounded-0">
-                        <nuxt-link class="list-group-item list-group-item-action border-0 d-flex justify-content-between" :to="localePath('/membres/' + member.member.hash)" v-for="member in forecast.forecasts" :key="member.member.uid">
-                          <div class="mr-3">{{ member.member.uid }} <BadgeStatus :membre="member.member" /></div>
-                          <div>{{ Math.round(member.proba * 100) }}&nbsp;%</div>
-                        </nuxt-link>
-                      </div>
-                    </td>
-                  </tr>
-                </tbody>
-              </table>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </transition>
-</main>
+	<main class="container">
+		<NavigationLoader :isLoading="$apollo.queries.wwResult.loading" />
+		<transition name="fade">
+			<div class="alert alert-danger" v-if="error">{{ error }}</div>
+		</transition>
+		<transition name="fade">
+			<div v-if="wwResult">
+				<h2 class="text-center mb-5 font-weight-light">
+					{{ $t("previsions.title") }}
+					<small
+						><span class="badge badge-secondary">{{
+							$tc("previsions.dossiersattente", wwResult.dossiers_nb)
+						}}</span></small
+					>
+				</h2>
+				<div class="alert alert-info" role="alert">
+					<ul class="list-unstyled m-0">
+						<li>
+							{{
+								$tc("previsions.certificationsinternes", wwResult.certifs_nb)
+							}}
+						</li>
+						<li>
+							{{ $tc("previsions.permutations", wwResult.permutations_nb) }}
+						</li>
+					</ul>
+				</div>
+				<div class="row">
+					<div class="col-12 text-center mb-4">
+						<div class="form-check form-check-inline">
+							<input
+								class="form-check-input"
+								type="radio"
+								id="forecastsByNames"
+								value="forecastsByNames"
+								checked
+								v-model="display"
+								@change="save" />
+							<label class="form-check-label" for="forecastsByNames">
+								{{ $t("tri.parmembres") }}
+							</label>
+						</div>
+						<div class="form-check form-check-inline">
+							<input
+								class="form-check-input"
+								type="radio"
+								id="forecastsByDates"
+								value="forecastsByDates"
+								v-model="display"
+								@change="save" />
+							<label class="form-check-label" for="forecastsByDates">
+								{{ $t("tri.pardate") }}
+							</label>
+						</div>
+					</div>
+					<div class="col-lg-8 m-auto">
+						<div v-if="display == 'forecastsByNames'">
+							<h3>{{ $t("previsions.parmembre") }}</h3>
+							<div class="table-responsive">
+								<table class="table table-striped table-hover">
+									<tbody>
+										<tr
+											v-for="forecast in wwResult.forecastsByNames"
+											:key="forecast.member.uid"
+											@click="
+												$router.push(
+													localePath({
+														name: 'membres-hash',
+														params: { hash: forecast.member.hash }
+													})
+												)
+											">
+											<th scope="row">
+												{{ forecast.member.uid }}
+												<BadgeStatus :membre="forecast.member" />
+											</th>
+											<td class="p-0">
+												<div
+													class="d-flex justify-content-between p-3"
+													v-for="date in forecast.forecasts"
+													:key="date.date">
+													<div
+														class="forecast_date mr-3"
+														v-if="date.date < 9999999999">
+														{{ $d(new Date(date.date * 1000), "short") }}
+														{{ $t("time.a") }}
+														{{
+															$d(new Date(date.date * 1000), "hour").replace(
+																" ",
+																"&nbsp;"
+															)
+														}}
+													</div>
+													<div class="forecast_date mr-3" v-else>N/A</div>
+													<div>{{ Math.round(date.proba * 100) }}&nbsp;%</div>
+												</div>
+											</td>
+										</tr>
+									</tbody>
+								</table>
+							</div>
+						</div>
+						<div v-if="display == 'forecastsByDates'">
+							<h3>{{ $t("previsions.pardate") }}</h3>
+							<div class="table-responsive">
+								<table class="table table-striped">
+									<tbody>
+										<tr
+											v-for="forecast in wwResult.forecastsByDates"
+											:key="forecast.date">
+											<th
+												scope="row"
+												class="forecast_date"
+												v-if="forecast.date < 9999999999">
+												{{ $d(new Date(forecast.date * 1000), "short") }}
+												{{ $t("time.a") }}
+												{{ $d(new Date(forecast.date * 1000), "hour") }}
+											</th>
+											<th scope="row" class="forecast_date" v-else>N/A</th>
+											<td class="p-0">
+												<div class="list-group rounded-0">
+													<nuxt-link
+														class="list-group-item list-group-item-action border-0 d-flex justify-content-between"
+														:to="localePath('/membres/' + member.member.hash)"
+														v-for="member in forecast.forecasts"
+														:key="member.member.uid">
+														<div class="mr-3">
+															{{ member.member.uid }}
+															<BadgeStatus :membre="member.member" />
+														</div>
+														<div>
+															{{ Math.round(member.proba * 100) }}&nbsp;%
+														</div>
+													</nuxt-link>
+												</div>
+											</td>
+										</tr>
+									</tbody>
+								</table>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</transition>
+	</main>
 </template>
 
 <script>
-import {NEWCOMERS} from '@/graphql/queries'
+import { NEWCOMERS } from "@/graphql/queries"
 
 export default {
-  data() {
-    return {
-      breadcrumb: [
-        {
-          text: this.$t('accueil'),
-          to: '/'
-        },
-        {
-          text: this.$t('previsions.title'),
-          to: '/previsions'
-        },
-        {
-          text: this.$t('futuremembers'),
-          active: true
-        }
-      ],
-      error: null,
-      display: 'forecastsByNames'
-    }
-  },
-  methods: {
-    save() {
-      localStorage.setItem('previsions', this.display)
-    }
-  },
-  apollo: {
-    wwResult : {
-      query: NEWCOMERS,
-      update (data) {
-        let result = {'byName':[],'byDate':[]}
-        let forecasts = data.wwResult.forecastsByNames
+	data() {
+		return {
+			breadcrumb: [
+				{
+					text: this.$t("accueil"),
+					to: "/"
+				},
+				{
+					text: this.$t("previsions.title"),
+					to: "/previsions"
+				},
+				{
+					text: this.$t("futuremembers"),
+					active: true
+				}
+			],
+			error: null,
+			display: "forecastsByNames"
+		}
+	},
+	methods: {
+		save() {
+			localStorage.setItem("previsions", this.display)
+		}
+	},
+	apollo: {
+		wwResult: {
+			query: NEWCOMERS,
+			update(data) {
+				let result = { byName: [], byDate: [] }
+				let forecasts = data.wwResult.forecastsByNames
 
-        for (let i = 0; i < forecasts.length; i++) {
-          let member = forecasts[i].member
+				for (let i = 0; i < forecasts.length; i++) {
+					let member = forecasts[i].member
 
-          // On traite les forecasts par nom
-          if (result['byName'].filter(function(e) { return e.member && e.member.uid === member.uid; }).length == 0) {
-            result['byName'].push({
-              member: member,
-              forecasts: [{
-                date: forecasts[i].date,
-                after: forecasts[i].after,
-                proba: forecasts[i].proba
-              }]
-            })
-          } else {
-            result['byName'].filter(function(e) { return e.member && e.member.uid === member.uid; })[0].forecasts.push({
-              date: forecasts[i].date,
-              after: forecasts[i].after,
-              proba: forecasts[i].proba
-            })
-          }
+					// On traite les forecasts par nom
+					if (
+						result["byName"].filter(function (e) {
+							return e.member && e.member.uid === member.uid
+						}).length == 0
+					) {
+						result["byName"].push({
+							member: member,
+							forecasts: [
+								{
+									date: forecasts[i].date,
+									after: forecasts[i].after,
+									proba: forecasts[i].proba
+								}
+							]
+						})
+					} else {
+						result["byName"]
+							.filter(function (e) {
+								return e.member && e.member.uid === member.uid
+							})[0]
+							.forecasts.push({
+								date: forecasts[i].date,
+								after: forecasts[i].after,
+								proba: forecasts[i].proba
+							})
+					}
 
-          // On traite les forecasts par date
-          if (result['byDate'].filter(function(e) { return e.date === forecasts[i].date }).length == 0) {
-            result['byDate'].push({
-              date: forecasts[i].date,
-              forecasts: [{
-                member: member,
-                after: forecasts[i].after,
-                proba: forecasts[i].proba
-              }]
-            })
-          } else {
-            result['byDate'].filter(function(e) { return e.date === forecasts[i].date })[0].forecasts.push({
-              member: member,
-              after: forecasts[i].after,
-              proba: forecasts[i].proba
-            })
-          }
-        }
+					// On traite les forecasts par date
+					if (
+						result["byDate"].filter(function (e) {
+							return e.date === forecasts[i].date
+						}).length == 0
+					) {
+						result["byDate"].push({
+							date: forecasts[i].date,
+							forecasts: [
+								{
+									member: member,
+									after: forecasts[i].after,
+									proba: forecasts[i].proba
+								}
+							]
+						})
+					} else {
+						result["byDate"]
+							.filter(function (e) {
+								return e.date === forecasts[i].date
+							})[0]
+							.forecasts.push({
+								member: member,
+								after: forecasts[i].after,
+								proba: forecasts[i].proba
+							})
+					}
+				}
 
-        result['byDate'].sort((a, b) => (a.date > b.date) ? 1 : -1)
+				result["byDate"].sort((a, b) => (a.date > b.date ? 1 : -1))
 
-        return {
-          permutations_nb: data.wwResult.permutations_nb,
-          dossiers_nb: data.wwResult.dossiers_nb,
-          certifs_nb: data.wwResult.certifs_nb,
-          forecastsByNames: result['byName'],
-          forecastsByDates: result['byDate']
-        }
-      },
-      error (err) {this.error = err.message}
-    }
-  },
-  nuxtI18n: {
-    paths: {
-      fr: '/previsions/futurs_membres',
-      en: '/forecasts/future_members',
-      es: '/pronosticos/futuros_miembros'
-    }
-  },
-  mounted () {
-    $nuxt.$emit('changeRoute',this.breadcrumb)
-    if (localStorage.previsions) {
-      this.display = localStorage.getItem('previsions')
-    }
-  }
+				return {
+					permutations_nb: data.wwResult.permutations_nb,
+					dossiers_nb: data.wwResult.dossiers_nb,
+					certifs_nb: data.wwResult.certifs_nb,
+					forecastsByNames: result["byName"],
+					forecastsByDates: result["byDate"]
+				}
+			},
+			error(err) {
+				this.error = err.message
+			}
+		}
+	},
+	nuxtI18n: {
+		paths: {
+			fr: "/previsions/futurs_membres",
+			en: "/forecasts/future_members",
+			es: "/pronosticos/futuros_miembros"
+		}
+	},
+	mounted() {
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+		if (localStorage.previsions) {
+			this.display = localStorage.getItem("previsions")
+		}
+	}
 }
 </script>
 
 <style lang="scss" scoped>
 .list-group-item {
-  background: transparent;
-  &:hover {
-    background: rgba(0, 0, 255, 0.075);
-    color: var(--text-primary-color);
-  }
+	background: transparent;
+	&:hover {
+		background: rgba(0, 0, 255, 0.075);
+		color: var(--text-primary-color);
+	}
 }
 
 .forecast_date {
-  min-width: 150px;
+	min-width: 150px;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/pages/previsions/index.vue b/pages/previsions/index.vue
index ba77d5d7976e43eb40a87db2135394fe11301060..bee732cecef625f639d7e9321346a9275e65f953 100644
--- a/pages/previsions/index.vue
+++ b/pages/previsions/index.vue
@@ -1,63 +1,65 @@
 <template>
-<main class="container">
-  <h2 class="text-center mb-5 font-weight-light">En préparation</h2>
-  <div class="alert alert-danger">En développement</div>
-  <NavigationLoader :isLoading="$apollo.queries.previsions.loading" />
-  <transition name="fade">
-    <div class="alert alert-danger" v-if="error">{{ error }}</div>
-  </transition>
-  <transition name="fade">
-    <div v-if="previsions">
-      {{ previsions }}
-    </div>
-  </transition>
-</main>
+	<main class="container">
+		<h2 class="text-center mb-5 font-weight-light">En préparation</h2>
+		<div class="alert alert-danger">En développement</div>
+		<NavigationLoader :isLoading="$apollo.queries.previsions.loading" />
+		<transition name="fade">
+			<div class="alert alert-danger" v-if="error">{{ error }}</div>
+		</transition>
+		<transition name="fade">
+			<div v-if="previsions">
+				{{ previsions }}
+			</div>
+		</transition>
+	</main>
 </template>
 
 <script>
-import {PREVISIONS} from '@/graphql/queries'
+import { PREVISIONS } from "@/graphql/queries"
 
 export default {
-  data() {
-    return {
-      breadcrumb: [
-        {
-          text: this.$t('accueil'),
-          to: '/'
-        },
-        {
-          text: this.$t('previsions.title'),
-          active: true
-        }
-      ],
-      display: 'forecastsByNames',
-      error: null
-    }
-  },
-  apollo: {
-    previsions : {
-      query: PREVISIONS,
-      update (data) {
-        return {
-          // now: data.now,
-          // sigQty: data.parameter.sigQty,
-          // certifs_dossiers: data.wwFile.certifs_dossiers
-          data
-        }
-      },
-      error (err) {this.error = err.message}
-    }
-  },
-  nuxtI18n: {
-    paths: {
-      fr: '/previsions',
-      en: '/forecasts',
-      es: '/pronosticos'
-    }
-  },
-  mounted () {
-    // Mise à jour du fil d'ariane au chargement
-    $nuxt.$emit('changeRoute',this.breadcrumb)
-  }
+	data() {
+		return {
+			breadcrumb: [
+				{
+					text: this.$t("accueil"),
+					to: "/"
+				},
+				{
+					text: this.$t("previsions.title"),
+					active: true
+				}
+			],
+			display: "forecastsByNames",
+			error: null
+		}
+	},
+	apollo: {
+		previsions: {
+			query: PREVISIONS,
+			update(data) {
+				return {
+					// now: data.now,
+					// sigQty: data.parameter.sigQty,
+					// certifs_dossiers: data.wwFile.certifs_dossiers
+					data
+				}
+			},
+			error(err) {
+				this.error = err.message
+			}
+		}
+	},
+	nuxtI18n: {
+		paths: {
+			fr: "/previsions",
+			en: "/forecasts",
+			es: "/pronosticos"
+		}
+	},
+	mounted() {
+		// Mise à jour du fil d'ariane au chargement
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+	}
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/pages/template.vue b/pages/template.vue
index 38d0caf9dd40c9f0f66266af958c6944a1d45d23..33c3972c6b002f81b807a45c57770c564cc356f7 100644
--- a/pages/template.vue
+++ b/pages/template.vue
@@ -1,13 +1,18 @@
 <template>
-<main class="container">
-  <h2 class="text-center mb-5 font-weight-light">{{ myvar }}</h2>
-  <code>For internal links, use <NuxtLink :to="localePath('path/page')">My link</NuxtLink></code>
-  <p>Use <code>$t() and $d()</code> functions to translate strings and dates</p>
-  <!-- <NavigationLoader :isLoading="$apollo.queries.myresponse.loading" /> -->
-  <!-- <transition name="fade">
+	<main class="container">
+		<h2 class="text-center mb-5 font-weight-light">{{ myvar }}</h2>
+		<code
+			>For internal links, use
+			<NuxtLink :to="localePath('path/page')">My link</NuxtLink></code
+		>
+		<p>
+			Use <code>$t() and $d()</code> functions to translate strings and dates
+		</p>
+		<!-- <NavigationLoader :isLoading="$apollo.queries.myresponse.loading" /> -->
+		<!-- <transition name="fade">
     <div class="alert alert-danger" v-if="error">{{ error }}</div>
   </transition> -->
-  <!-- <transition name="fade">
+		<!-- <transition name="fade">
     <div class="result" v-if="myresponse">
       <div class="row text-center">
         <div class="col-lg-6">
@@ -16,7 +21,7 @@
       </div>
     </div>
   </transition> -->
-</main>
+	</main>
 </template>
 
 <script>
@@ -24,69 +29,67 @@
 // import {MY_QUERY} from '@/graphql/queries.js'
 
 export default {
-  data() {
-    // local variables
-    return {
-      breadcrumb: [
-        {
-          text: this.$t('accueil'),
-          to: '/'
-        },
-        {
-          // Translations are stored in ./i18n/locales folder
-          text: this.$t('mypage.mytitle'),
-          active: true
-        }
-      ],
-      error: null,
-      myvar : "Hello World !"
-    }
-  },
-  // local functions. You can use :
-  // {{ myFunction() }} in template if a value is returned
-  // - this.myFunction everywhere in the page but not in arrows functions
-  // - @event="myFunction" on Vue eventHandlers
-  // methods: {
-  //   myFunction() {
-      
-  //   }
-  // },
-  // For computed values. Use {{ myComputedValue }} in the template
-  // computed: {
-  //   myComputedValue : function() {
-  //     return this.var * 3
-  //   }
-  // },
-  // apollo: {
-  //   // Use {{ myresponse }} in the template. If update is omitted, this name should correspond to the Query Type !
-  //   myresponse : {
-  //     query: MY_QUERY,
-  //     // Optional : this is for parametered queries
-  //     // variables() {return {param1:value1,param2:value2}},
-  //     // Optional : treat the response before display. If omitted, the query name must correspond to the Query Type !
-  //     // update (data) {
-        
-  //     //   return data
-  //     // },
-  //     error (err) {this.error = err.message}
-  //   }
-  // },
-  // Route's i18n (Need to rebuild App)
-  nuxtI18n: {
-    paths: {
-      fr: '/mapage',
-      en: '/mypage',
-      es: '/mipagina'
-    }
-  },
-  mounted () {
-    // Update breadcrumb when the page is displayed
-    $nuxt.$emit('changeRoute',this.breadcrumb)
-  }
+	data() {
+		// local variables
+		return {
+			breadcrumb: [
+				{
+					text: this.$t("accueil"),
+					to: "/"
+				},
+				{
+					// Translations are stored in ./i18n/locales folder
+					text: this.$t("mypage.mytitle"),
+					active: true
+				}
+			],
+			error: null,
+			myvar: "Hello World !"
+		}
+	},
+	// local functions. You can use :
+	// {{ myFunction() }} in template if a value is returned
+	// - this.myFunction everywhere in the page but not in arrows functions
+	// - @event="myFunction" on Vue eventHandlers
+	// methods: {
+	//   myFunction() {
+
+	//   }
+	// },
+	// For computed values. Use {{ myComputedValue }} in the template
+	// computed: {
+	//   myComputedValue : function() {
+	//     return this.var * 3
+	//   }
+	// },
+	// apollo: {
+	//   // Use {{ myresponse }} in the template. If update is omitted, this name should correspond to the Query Type !
+	//   myresponse : {
+	//     query: MY_QUERY,
+	//     // Optional : this is for parametered queries
+	//     // variables() {return {param1:value1,param2:value2}},
+	//     // Optional : treat the response before display. If omitted, the query name must correspond to the Query Type !
+	//     // update (data) {
+
+	//     //   return data
+	//     // },
+	//     error (err) {this.error = err.message}
+	//   }
+	// },
+	// Route's i18n (Need to rebuild App)
+	nuxtI18n: {
+		paths: {
+			fr: "/mapage",
+			en: "/mypage",
+			es: "/mipagina"
+		}
+	},
+	mounted() {
+		// Update breadcrumb when the page is displayed
+		$nuxt.$emit("changeRoute", this.breadcrumb)
+	}
 }
 </script>
 
 <!-- Add "scoped" attribute to limit CSS to this page only -->
-<style lang="scss" scoped>
-
-</style>
\ No newline at end of file
+<style lang="scss" scoped></style>
diff --git a/plugins/filters.js b/plugins/filters.js
index d66a273a9760225900552af59e39bf03ef966c89..1654212a42b4033f0edbc265e390b44a38c6ac81 100644
--- a/plugins/filters.js
+++ b/plugins/filters.js
@@ -1,13 +1,13 @@
 import Vue from 'vue'
 
 Vue.filter('dateStatus', (val) => {
-    const diff = val - (Date.now()/1000)
+    const diff = val - (Date.now() / 1000)
     switch (true) {
-        case diff<0:
+        case diff < 0:
             return 'danger'
-        case diff<2635200:
+        case diff < 2635200:
             return 'warning'
-        case diff>=2635200:
+        case diff >= 2635200:
             return 'success'
     }
 })
\ No newline at end of file