Skip to content
Snippets Groups Projects
Commit 60234b64 authored by Pierre-Jean CHANCELLIER's avatar Pierre-Jean CHANCELLIER
Browse files

prettier configuration

parent 3dd357f8
Branches
Tags
No related merge requests found
Showing
with 1077 additions and 839 deletions
# 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
{
"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
}
# 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
# Or generate static project
$ npm run generates
```
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
......@@ -36,4 +35,3 @@
// @import "~bootstrap/scss/spinners";
@import "~bootstrap/scss/utilities";
@import "~bootstrap/scss/print";
\ No newline at end of file
......@@ -36,8 +36,8 @@ $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;
......
......@@ -5,14 +5,14 @@
</template>
<script>
import Chart from 'chart.js/auto'
import Chart from "chart.js/auto"
export const chartTypes = [
'line',
'bar',
'doughnut',
'bubble',
'scatter',
"line",
"bar",
"doughnut",
"bubble",
"scatter"
// 'radar',
// 'polarArea'
]
......@@ -21,12 +21,12 @@ export default {
props: {
id: {
type: String,
default : 'my-chart',
default: "my-chart",
required: true
},
type: {
type: String,
default: 'line',
default: "line",
required: true,
validator: function (value) {
return chartTypes.indexOf(value) !== -1
......
<template>
<span class="danger font-weight-normal" :class="classWarning" :title="textWarning" v-if="($options.filters.dateStatus(limitDate) != 'success') && (['MEMBER', 'MISSING'].includes(memberStatus))">
<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>
......@@ -16,12 +24,16 @@ export default {
computed: {
classWarning() {
return {
'text-danger' : this.$options.filters.dateStatus(this.limitDate) == 'danger',
'text-warning' : this.$options.filters.dateStatus(this.limitDate) == 'warning'
"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')
return this.$options.filters.dateStatus(this.limitDate) == "danger"
? this.$i18n.t("statut.manquecertif")
: this.$i18n.t("statut.bientotmanquecertif")
}
}
}
......
<template>
<small>
<span class="badge"
<span
class="badge"
:class="{
'badge-success': isDispo,
'badge-danger': !isDispo,
'badge-danger': !isDispo
}">
{{ isDispo ? $t('membre.dispo') : $t('membre.nodispo') + ' >&nbsp;' + $d(new Date(dateDispo*1000), 'short') }}
{{
isDispo
? $t("membre.dispo")
: $t("membre.nodispo") +
" >&nbsp;" +
$d(new Date(dateDispo * 1000), "short")
}}
</span>
</small>
</template>
......
<template>
<small>
<span class="badge"
<span
class="badge"
:class="{
'badge-success': quality >= 80,
'badge-warning': quality<80,
'badge-warning': quality < 80
}">
{{ Math.round(quality * 100) / 100 }}
</span>
......
......@@ -17,20 +17,26 @@ export default {
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'}
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'}
return {
str: this.$i18n.t("statut.member"),
class: "badge-success"
}
}
case "REVOKED":
return {
str: this.$i18n.t("statut.revoked"),
class: "badge-secondary"
}
case 'REVOKED':
return {str: this.$i18n.t('statut.revoked'),class: 'badge-secondary'}
default:
return 'N/A'
return "N/A"
}
}
}
......
<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>
<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>
<input
type="text"
class="form-control text-truncate"
:value="textContent"
disabled />
</div>
</template>
......@@ -18,13 +26,13 @@ export default {
methods: {
copyText() {
navigator.clipboard.writeText(this.textContent)
$('#btncopy').tooltip({
title: this.$t('copie') + ' !',
trigger: 'manual'
$("#btncopy").tooltip({
title: this.$t("copie") + " !",
trigger: "manual"
})
$('#btncopy').tooltip('show')
$("#btncopy").tooltip("show")
setTimeout(() => {
$('#btncopy').tooltip('hide')
$("#btncopy").tooltip("hide")
}, 500)
}
}
......
<template>
<button type="submit" class="btn btn-primary" :disabled="isWaiting || disabled">
<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
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"></span>
{{ $t("chargement") }}...
</span>
<span v-else>Go !</span>
</button>
......
<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 ">
<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>
<div
class="switch-toggle position-absolute rounded-circle"
:class="{ 'switch-toggle-checked': userTheme === 'dark-theme' }"></div>
</label>
</div>
</template>
......@@ -17,8 +25,8 @@ export default {
data() {
return {
userTheme: "light-theme",
};
userTheme: "light-theme"
}
},
methods: {
......@@ -31,17 +39,21 @@ export default {
},
setTheme(theme) {
if (theme == null) {theme="light-theme"}
if (theme == null) {
theme = "light-theme"
}
localStorage.setItem("user-theme", theme)
this.userTheme = theme
document.documentElement.className = theme
}
},
};
}
}
</script>
<style scoped>
*, ::before, ::after {
*,
::before,
::after {
box-sizing: initial;
}
.switch-checkbox {
......
<template>
<div class="table-responsive">
<table class="table table-striped table-hover" v-if="certifsPending.length > 0">
<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}}))">
<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'" />
<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'" />
<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>
<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">
<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') }}
{{ $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
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') }}
{{ $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
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}}))">
<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'" />
<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'" />
<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>
<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>
......@@ -79,8 +153,8 @@
export default {
data() {
return {
currentSort:'expires_on',
currentSortDir:'asc'
currentSort: "expires_on",
currentSortDir: "asc"
}
},
props: {
......@@ -89,7 +163,7 @@ export default {
type: String,
required: true,
validator: function (value) {
const types = ['received','sent']
const types = ["received", "sent"]
return types.indexOf(value) !== -1
}
}
......@@ -100,30 +174,42 @@ export default {
},
sort(s) {
if (s === this.currentSort) {
this.currentSortDir = this.currentSortDir==='asc'?'desc':'asc';
this.currentSortDir = this.currentSortDir === "asc" ? "desc" : "asc"
}
this.currentSort = s;
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"
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
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 (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})
})
.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 this.certifs
.slice()
.sort((a, b) => a.expires_on - b.expires_on)
.filter((el) => {
return el.pending == true
})
}
}
}
......@@ -141,11 +227,12 @@ thead th {
}
}
.up, .down {
.up,
.down {
line-height: 10px;
font-size: 1.1rem;
transform: scale(1.5, 1);
opacity: .3;
opacity: 0.3;
}
.sorted {
......
......@@ -7,48 +7,110 @@
</h2>
<BtnClipboard :textContent="this.hash.pubkey" />
<div class="table-responsive">
<table class="table table-sm table-borderless" v-if="hash.status != 'REVOKED'">
<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>
<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="{
<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>
'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>
<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>
<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>
<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="{
<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>
'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>
<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>
......@@ -82,9 +144,15 @@ export default {
@media (min-width: 576px) {
.member {
.table {
tr {display: table-row;}
th {text-align: right;}
td {text-align: left;}
tr {
display: table-row;
}
th {
text-align: right;
}
td {
text-align: left;
}
}
}
}
......
......@@ -4,18 +4,26 @@
<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>
<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"
<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" />
<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>
<td class="d-none d-xl-table-cell" v-if="displayPubkey">
{{ member.pubkey }}
</td>
</tr>
</tbody>
</table>
......@@ -40,8 +48,10 @@ export default {
},
methods: {
redirect(hash) {
this.$router.push(this.localePath({name:'membres-hash', params: {hash}}))
this.$router.push(
this.localePath({ name: "membres-hash", params: { hash } })
)
}
}
},
}
</script>
<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>
<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" />
......@@ -22,7 +26,7 @@ export default {
},
methods: {
toggleMenu() {
document.querySelector('.app').classList.toggle('open')
document.querySelector(".app").classList.toggle("open")
console.log(this.isOpen)
this.isOpen = !this.isOpen
......@@ -32,13 +36,12 @@ export default {
}
},
mounted() {
this.isOpen = (localStorage.getItem("menu-open") == "true")
this.isOpen = localStorage.getItem("menu-open") == "true"
if (this.isOpen) {
document.querySelector('.app').classList.add('open')
document.querySelector(".app").classList.add("open")
}
}
}
</script>
<style lang="scss">
......@@ -49,7 +52,7 @@ $btn-width: 50px;
width: 100%;
z-index: 100;
background: var(--background-color-primary);
transition: width .5s ease-in-out;
transition: width 0.5s ease-in-out;
.open & {
--menu-width: 320px;
......@@ -67,10 +70,12 @@ nav.breadcrumb-wrapper {
gap: 1rem;
background: var(--background-color-secondary);
a {color: var(--text-primary-color)}
a {
color: var(--text-primary-color);
}
.breadcrumb-item.active {
opacity: .7;
opacity: 0.7;
}
@media (min-width: 768px) {
......@@ -83,7 +88,7 @@ nav.breadcrumb-wrapper {
%hamburger-line {
display: block;
height: 4px;
width: .8 * $btn-width;
width: 0.8 * $btn-width;
background: var(--text-primary-color);
content: "";
position: absolute;
......@@ -100,7 +105,7 @@ nav.breadcrumb-wrapper {
@extend %hamburger-line;
top: 50%;
transform: translateY(-50%);
transition-timing-function: cubic-bezier(.55,.055,.675,.19);
transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
transition-duration: 75ms;
.open & {
......@@ -110,7 +115,7 @@ nav.breadcrumb-wrapper {
}
&::before {
transition: top 75ms ease .12s,opacity 75ms ease;
transition: top 75ms ease 0.12s, opacity 75ms ease;
@extend %hamburger-line;
top: -10px;
......@@ -120,7 +125,8 @@ nav.breadcrumb-wrapper {
}
&::after {
transition: bottom 75ms ease .12s,transform 75ms cubic-bezier(.55,.055,.675,.19);
transition: bottom 75ms ease 0.12s,
transform 75ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
@extend %hamburger-line;
bottom: -10px;
......@@ -142,10 +148,12 @@ nav.breadcrumb-wrapper {
overflow-y: scroll;
scrollbar-color: #6969dd #e0e0e0;
scrollbar-width: thin;
transition: left .5s ease-in-out;
transition: left 0.5s ease-in-out;
left: -400px;
h1 {color: var(--text-primary-color);}
h1 {
color: var(--text-primary-color);
}
.list-group-item {
&-action:not(.active) {
......@@ -158,17 +166,17 @@ nav.breadcrumb-wrapper {
}
div {
transition: left .3s ease-in-out;
transition: left 0.3s ease-in-out;
left: 0;
&::before {
content: "›";
position: relative;
left: -.5em;
left: -0.5em;
}
&:hover {
left: .5em;
left: 0.5em;
}
}
}
......@@ -181,7 +189,7 @@ nav.breadcrumb-wrapper {
--size: 50px;
width: var(--size);
height: var(--size);
top: .8rem;
top: 0.8rem;
right: 0;
font-size: 2rem;
}
......@@ -199,8 +207,8 @@ nav.breadcrumb-wrapper {
z-index: 1100;
visibility: hidden;
opacity: 0;
transition: all .5s ease;
background-color: rgba(34,41,47,.5);
transition: all 0.5s ease;
background-color: rgba(34, 41, 47, 0.5);
.open & {
opacity: 1;
......
<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>
<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>
......
<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
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>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment