- 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>
124 lines
3.6 KiB
Vue
124 lines
3.6 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* Cadrage form component for creating or editing a decision.
|
|
*
|
|
* Provides all fields needed for the initial decision setup:
|
|
* title, description, context, decision type, and voting protocol.
|
|
*/
|
|
import type { DecisionCreate } from '~/stores/decisions'
|
|
|
|
const props = defineProps<{
|
|
modelValue: DecisionCreate
|
|
submitting?: boolean
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
'update:modelValue': [value: DecisionCreate]
|
|
'submit': []
|
|
}>()
|
|
|
|
const decisionTypeOptions = [
|
|
{ label: 'Runtime upgrade', value: 'runtime_upgrade' },
|
|
{ label: 'Modification de document', value: 'document_change' },
|
|
{ label: 'Vote de mandat', value: 'mandate_vote' },
|
|
{ label: 'Changement de parametre', value: 'parameter_change' },
|
|
{ label: 'Autre', value: 'other' },
|
|
]
|
|
|
|
function updateField<K extends keyof DecisionCreate>(field: K, value: DecisionCreate[K]) {
|
|
emit('update:modelValue', { ...props.modelValue, [field]: value })
|
|
}
|
|
|
|
const isValid = computed(() => {
|
|
return props.modelValue.title?.trim() && props.modelValue.decision_type
|
|
})
|
|
|
|
function onSubmit() {
|
|
if (isValid.value) {
|
|
emit('submit')
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<form class="space-y-6" @submit.prevent="onSubmit">
|
|
<!-- Titre -->
|
|
<div class="space-y-1">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
Titre <span class="text-red-500">*</span>
|
|
</label>
|
|
<UInput
|
|
:model-value="modelValue.title"
|
|
placeholder="Titre de la decision..."
|
|
required
|
|
@update:model-value="updateField('title', $event as string)"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Description -->
|
|
<div class="space-y-1">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
Description <span class="text-red-500">*</span>
|
|
</label>
|
|
<UTextarea
|
|
:model-value="modelValue.description ?? ''"
|
|
placeholder="Decrivez l'objet de cette decision..."
|
|
:rows="4"
|
|
@update:model-value="updateField('description', $event as string)"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Contexte -->
|
|
<div class="space-y-1">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
Contexte
|
|
</label>
|
|
<UTextarea
|
|
:model-value="modelValue.context ?? ''"
|
|
placeholder="Contexte, motivations, liens utiles..."
|
|
:rows="3"
|
|
@update:model-value="updateField('context', $event as string)"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Type de decision -->
|
|
<div class="space-y-1">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
Type de decision <span class="text-red-500">*</span>
|
|
</label>
|
|
<USelect
|
|
:model-value="modelValue.decision_type"
|
|
:items="decisionTypeOptions"
|
|
placeholder="Selectionnez un type..."
|
|
@update:model-value="updateField('decision_type', $event as string)"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Protocole de vote -->
|
|
<div class="space-y-1">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
Protocole de vote
|
|
</label>
|
|
<ProtocolPicker
|
|
:model-value="modelValue.voting_protocol_id ?? null"
|
|
@update:model-value="updateField('voting_protocol_id', $event)"
|
|
/>
|
|
<p class="text-xs text-gray-500">
|
|
Optionnel. Peut etre defini ulterieurement pour chaque etape.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Submit -->
|
|
<div class="flex justify-end pt-4 border-t border-gray-200 dark:border-gray-700">
|
|
<UButton
|
|
type="submit"
|
|
label="Creer la decision"
|
|
icon="i-lucide-plus"
|
|
color="primary"
|
|
:loading="submitting"
|
|
:disabled="!isValid"
|
|
/>
|
|
</div>
|
|
</form>
|
|
</template>
|