Files
decision/frontend/app/components/common/StatusBadge.vue
Yvv 77dceb49c3 Refonte design : 4 humeurs, onboarding, sections avec boite a outils
- Systeme de themes adaptatifs : Peps (light chaud), Zen (light calme),
  Chagrine (dark violet), Grave (dark ambre) avec CSS custom properties
- Dashboard d'accueil orienté onboarding avec cartes-portes et teaser
  boite a outils
- SectionLayout reutilisable : liste + sidebar toolbox + status pills
  cliquables (En prepa / En vote / En vigueur / Clos)
- ToolboxVignette : vignettes Contexte / Tutos / Choisir / Demarrer
- Seed : Acte engagement certification + forgeron, Runtime Upgrade
  (decision on-chain), 3 modalites de vote (majoritaire, quadratique,
  permanent)
- Backend adapte SQLite (Uuid portable, 204 fix, pool conditionnel)
- Correction noms composants (pathPrefix: false), pinia/nuxt ^0.11

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 17:44:48 +01:00

151 lines
3.9 KiB
Vue

<script setup lang="ts">
const props = withDefaults(defineProps<{
status: string
type?: 'document' | 'decision' | 'mandate' | 'vote' | 'version'
clickable?: boolean
active?: boolean
}>(), {
clickable: true,
active: false,
})
const emit = defineEmits<{
click: []
}>()
const STATUS_MAP: Record<string, { label: string; cssClass: string }> = {
// Universal statuses
draft: { label: 'En prepa', cssClass: 'status-prepa' },
active: { label: 'En vigueur', cssClass: 'status-vigueur' },
closed: { label: 'Clos', cssClass: 'status-clos' },
// Decision/vote specific
qualification: { label: 'En prepa', cssClass: 'status-prepa' },
review: { label: 'En prepa', cssClass: 'status-prepa' },
voting: { label: 'En vote', cssClass: 'status-vote' },
open: { label: 'En vote', cssClass: 'status-vote' },
executed: { label: 'En vigueur', cssClass: 'status-vigueur' },
// Version specific
pending: { label: 'En prepa', cssClass: 'status-prepa' },
accepted: { label: 'En vigueur', cssClass: 'status-vigueur' },
rejected: { label: 'Clos', cssClass: 'status-clos' },
// Mandate specific
formulation: { label: 'En prepa', cssClass: 'status-prepa' },
candidature: { label: 'En prepa', cssClass: 'status-prepa' },
investiture: { label: 'En vote', cssClass: 'status-vote' },
revoked: { label: 'Clos', cssClass: 'status-clos' },
completed: { label: 'Clos', cssClass: 'status-clos' },
}
const resolved = computed(() => {
return STATUS_MAP[props.status] ?? { label: props.status, cssClass: 'status-prepa' }
})
function handleClick() {
if (props.clickable) {
emit('click')
}
}
</script>
<template>
<button
v-if="clickable"
type="button"
class="status-pill"
:class="[resolved.cssClass, { 'status-pill--active': active }]"
@click="handleClick"
>
{{ resolved.label }}
</button>
<span
v-else
class="status-pill"
:class="[resolved.cssClass]"
>
{{ resolved.label }}
</span>
</template>
<style scoped>
.status-pill {
display: inline-flex;
align-items: center;
padding: 2px 10px;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
line-height: 1.5;
border: 1px solid transparent;
cursor: default;
transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
button.status-pill {
cursor: pointer;
}
button.status-pill:hover {
opacity: 0.85;
}
.status-pill--active {
box-shadow: 0 0 0 2px currentColor;
}
/* --- En prepa (amber/warning) --- */
.status-prepa {
background-color: var(--ui-color-amber-50, #fffbeb);
color: var(--ui-color-amber-700, #b45309);
border-color: var(--ui-color-amber-200, #fde68a);
}
/* --- En vigueur (green/success) --- */
.status-vigueur {
background-color: var(--ui-color-green-50, #f0fdf4);
color: var(--ui-color-green-700, #15803d);
border-color: var(--ui-color-green-200, #bbf7d0);
}
/* --- En vote (blue/primary) --- */
.status-vote {
background-color: var(--ui-color-blue-50, #eff6ff);
color: var(--ui-color-blue-700, #1d4ed8);
border-color: var(--ui-color-blue-200, #bfdbfe);
}
/* --- Clos (gray/neutral) --- */
.status-clos {
background-color: var(--ui-color-gray-50, #f9fafb);
color: var(--ui-color-gray-500, #6b7280);
border-color: var(--ui-color-gray-200, #e5e7eb);
}
/* Dark mode overrides */
.dark .status-prepa {
background-color: var(--ui-color-amber-950, #451a03);
color: var(--ui-color-amber-300, #fcd34d);
border-color: var(--ui-color-amber-800, #92400e);
}
.dark .status-vigueur {
background-color: var(--ui-color-green-950, #052e16);
color: var(--ui-color-green-300, #86efac);
border-color: var(--ui-color-green-800, #166534);
}
.dark .status-vote {
background-color: var(--ui-color-blue-950, #172554);
color: var(--ui-color-blue-300, #93c5fd);
border-color: var(--ui-color-blue-800, #1e40af);
}
.dark .status-clos {
background-color: var(--ui-color-gray-900, #111827);
color: var(--ui-color-gray-400, #9ca3af);
border-color: var(--ui-color-gray-700, #374151);
}
</style>