Accents FR, architecture modulaire, protocoles opérationnels

- Fix accents manquants dans 7 pages UI (décisions, boîte à outils, etc.)
- Titres accueil enrichis : Décisions structurantes, Documents de référence,
  Mandats et nominations, Protocoles et fonctionnement
- Retrait Embarquement Forgeron du seed (n'est pas une Decision)
- 2 protocoles opérationnels dans Protocoles : Embarquement Forgeron
  (lié à l'Acte d'engagement) + Soumission Runtime Upgrade (lié à la
  Décision Runtime Upgrade) avec timeline et liens croisés signalétiques
- Décision Runtime Upgrade : badge on-chain + lien protocole + contexte
- Document [slug] : lien protocole dans la section Qualification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-03-03 07:05:55 +01:00
parent c19c1aa55e
commit 8201e73d7c
8 changed files with 328 additions and 221 deletions

View File

@@ -3,8 +3,8 @@
* Mandats — page index.
*
* Utilise SectionLayout avec status filters, recherche,
* et sidebar "Boite a outils" affichant les protocoles de vote.
* Etat vide enrichi avec onboarding expliquant le concept de mandat.
* et sidebar "Boîte à outils" affichant les protocoles de vote.
* État vide enrichi avec onboarding expliquant le concept de mandat.
*/
import type { MandateCreate } from '~/stores/mandates'
@@ -25,9 +25,9 @@ const sortOptions = [
// Create mandate modal state
const showCreateModal = ref(false)
const mandateTypeOptions = [
{ label: 'Comite technique', value: 'techcomm' },
{ label: 'Comité technique', value: 'techcomm' },
{ label: 'Forgeron', value: 'smith' },
{ label: 'Personnalise', value: 'custom' },
{ label: 'Personnalisé', value: 'custom' },
]
const newMandate = ref<MandateCreate>({
@@ -46,7 +46,7 @@ onMounted(async () => {
/** Status filter pills with counts. */
const statuses = computed(() => [
{ id: 'draft', label: 'En prepa', count: mandates.list.filter(m => m.status === 'draft' || m.status === 'candidacy').length },
{ id: 'draft', label: 'En prépa', count: mandates.list.filter(m => m.status === 'draft' || m.status === 'candidacy').length },
{ id: 'voting', label: 'En vote', count: mandates.list.filter(m => m.status === 'voting').length },
{ id: 'active', label: 'En vigueur', count: mandates.list.filter(m => m.status === 'active' || m.status === 'reporting').length },
{ id: 'closed', label: 'Clos', count: mandates.list.filter(m => m.status === 'completed' || m.status === 'revoked').length },
@@ -95,9 +95,9 @@ const filteredMandates = computed(() => {
const typeLabel = (mandateType: string) => {
switch (mandateType) {
case 'techcomm': return 'Comite technique'
case 'techcomm': return 'Comité technique'
case 'smith': return 'Forgeron'
case 'custom': return 'Personnalise'
case 'custom': return 'Personnalisé'
default: return mandateType
}
}
@@ -133,7 +133,7 @@ async function handleCreate() {
<template>
<SectionLayout
title="Mandats"
subtitle="Un contexte, un objectif, une duree, une ou plusieurs nominations ; par defaut : nomination d'un binome."
subtitle="Un contexte, un objectif, une durée, une ou plusieurs nominations ; par défaut : nomination d'un binôme."
:statuses="statuses"
:active-status="activeStatus"
@update:active-status="activeStatus = $event"
@@ -189,17 +189,17 @@ async function handleCreate() {
Qu'est-ce qu'un mandat ?
</h3>
<p class="mandate-onboarding__text">
Un mandat definit un contexte, un objectif et une duree pour une mission de gouvernance.
Il peut porter sur le comite technique, les forgerons, ou tout role specifique de la communaute.
Un mandat définit un contexte, un objectif et une durée pour une mission de gouvernance.
Il peut porter sur le comité technique, les forgerons, ou tout rôle spécifique de la communauté.
</p>
<p class="mandate-onboarding__text">
Par defaut, un mandat nomme un binome pour assurer la continuite.
Par défaut, un mandat nomme un binôme pour assurer la continuité.
Le processus comprend : candidature, vote communautaire, periode active et rapport final.
</p>
<div class="mandate-onboarding__actions">
<UButton
v-if="auth.isAuthenticated"
label="Creer un premier mandat"
label="Créer un premier mandat"
icon="i-lucide-plus"
color="primary"
size="sm"
@@ -207,7 +207,7 @@ async function handleCreate() {
/>
<UButton
to="/protocols"
label="Decouvrir les protocoles"
label="Découvrir les protocoles"
variant="outline"
size="sm"
icon="i-lucide-wrench"
@@ -222,7 +222,7 @@ async function handleCreate() {
style="color: var(--mood-text-muted);"
>
<UIcon name="i-lucide-user-check" class="text-4xl mb-3 block mx-auto" />
<p>Aucun mandat trouve</p>
<p>Aucun mandat trouvé</p>
<p v-if="searchQuery || activeStatus" class="text-sm mt-1">
Essayez de modifier vos filtres
</p>
@@ -254,7 +254,7 @@ async function handleCreate() {
</span>
<span class="mandate-card__steps">
<UIcon name="i-lucide-layers" class="text-xs" />
{{ mandate.steps.length }} etape{{ mandate.steps.length !== 1 ? 's' : '' }}
{{ mandate.steps.length }} étape{{ mandate.steps.length !== 1 ? 's' : '' }}
</span>
<span v-if="mandate.mandatee_id" class="mandate-card__mandatee">
<UIcon name="i-lucide-user" class="text-xs" />
@@ -263,7 +263,7 @@ async function handleCreate() {
</div>
<div class="mandate-card__dates">
<span>Debut : {{ formatDate(mandate.starts_at) }}</span>
<span>Début : {{ formatDate(mandate.starts_at) }}</span>
<span>Fin : {{ formatDate(mandate.ends_at) }}</span>
</div>
</div>
@@ -274,28 +274,28 @@ async function handleCreate() {
<template #toolbox>
<ToolboxVignette
title="Ouverture"
:bullets="['Definir mission et perimetre', 'Duree et objectifs clairs']"
:bullets="['Définir mission et périmètre', 'Durée et objectifs clairs']"
:actions="[
{ label: 'Creer', icon: 'i-lucide-door-open', emit: 'create', primary: true },
{ label: 'Créer', icon: 'i-lucide-door-open', emit: 'create', primary: true },
]"
/>
<ToolboxVignette
title="Nomination"
:bullets="['Election en binome', 'Titulaire + suppleant']"
:bullets="['Élection en binôme', 'Titulaire + suppléant']"
:actions="[
{ label: 'Voir', icon: 'i-lucide-users', emit: 'nomination' },
]"
/>
<ToolboxVignette
title="Transparence"
:bullets="['Rapports d\'activite', 'Soumis au vote communautaire']"
:bullets="['Rapports d\'activité', 'Soumis au vote communautaire']"
:actions="[
{ label: 'Voir', icon: 'i-lucide-eye', emit: 'transparence' },
]"
/>
<ToolboxVignette
title="Cloture"
:bullets="['Fin de mandat ou revocation', 'Bilan et transmission']"
:bullets="['Fin de mandat ou révocation', 'Bilan et transmission']"
:actions="[
{ label: 'Voir', icon: 'i-lucide-lock', emit: 'cloture' },
]"
@@ -352,7 +352,7 @@ async function handleCreate() {
/>
<UButton
type="submit"
label="Creer"
label="Créer"
icon="i-lucide-plus"
color="primary"
:loading="creating"