Files
sejeteralo/frontend/app/pages/admin/communes/[slug]/params.vue
Yvv b30e54a8f7 Initial commit: SejeteralO water tarification platform
Full-stack app for participatory water pricing using Bezier curves.
- Backend: FastAPI + SQLAlchemy + SQLite with JWT auth
- Frontend: Nuxt 4 + TypeScript with interactive SVG editor
- Math engine: cubic Bezier tarification with Cardano solver
- Admin: commune management, household import, vote monitoring, CMS
- Citizen: interactive curve editor, vote submission
- Docker-compose deployment ready

Includes fixes for:
- Impact table snake_case/camelCase property mismatch
- CMS content backend API + frontend editor (was stub)
- Admin route protection middleware
- Public content display on commune page
- Vote confirmation page link fix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 15:26:02 +01:00

78 lines
2.4 KiB
Vue

<template>
<div>
<div class="page-header">
<NuxtLink :to="`/admin/communes/${slug}`" style="color: var(--color-text-muted);">&larr; {{ slug }}</NuxtLink>
<h1>Paramètres tarifs</h1>
</div>
<div v-if="saved" class="alert alert-success">Paramètres enregistrés.</div>
<div v-if="error" class="alert alert-error">{{ error }}</div>
<div class="card" style="max-width: 600px;">
<form @submit.prevent="save">
<div class="form-group">
<label>Recettes cibles ()</label>
<input v-model.number="form.recettes" type="number" class="form-input" step="1000" min="0" />
</div>
<div class="grid grid-2">
<div class="form-group">
<label>Abonnement RP/PRO ()</label>
<input v-model.number="form.abop" type="number" class="form-input" step="1" min="0" />
</div>
<div class="form-group">
<label>Abonnement RS ()</label>
<input v-model.number="form.abos" type="number" class="form-input" step="1" min="0" />
</div>
</div>
<div class="grid grid-2">
<div class="form-group">
<label>Prix max/ ()</label>
<input v-model.number="form.pmax" type="number" class="form-input" step="0.5" min="0" />
</div>
<div class="form-group">
<label>Volume max ()</label>
<input v-model.number="form.vmax" type="number" class="form-input" step="100" min="0" />
</div>
</div>
<button type="submit" class="btn btn-primary" :disabled="loading">
Enregistrer
</button>
</form>
</div>
</div>
</template>
<script setup lang="ts">
definePageMeta({ middleware: 'admin' })
const route = useRoute()
const api = useApi()
const slug = route.params.slug as string
const form = reactive({ recettes: 75000, abop: 100, abos: 100, pmax: 20, vmax: 2100 })
const loading = ref(false)
const saved = ref(false)
const error = ref('')
onMounted(async () => {
try {
const params = await api.get<typeof form>(`/communes/${slug}/params`)
Object.assign(form, params)
} catch {}
})
async function save() {
loading.value = true
saved.value = false
error.value = ''
try {
await api.put(`/communes/${slug}/params`, form)
saved.value = true
} catch (e: any) {
error.value = e.message
} finally {
loading.value = false
}
}
</script>