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>
49 lines
992 B
TypeScript
49 lines
992 B
TypeScript
import { defineStore } from 'pinia'
|
|
|
|
interface Commune {
|
|
id: number
|
|
name: string
|
|
slug: string
|
|
description: string
|
|
is_active: boolean
|
|
}
|
|
|
|
interface TariffParams {
|
|
abop: number
|
|
abos: number
|
|
recettes: number
|
|
pmax: number
|
|
vmax: number
|
|
}
|
|
|
|
export const useCommuneStore = defineStore('commune', {
|
|
state: () => ({
|
|
communes: [] as Commune[],
|
|
current: null as Commune | null,
|
|
params: null as TariffParams | null,
|
|
loading: false,
|
|
}),
|
|
|
|
actions: {
|
|
async fetchCommunes() {
|
|
this.loading = true
|
|
try {
|
|
const api = useApi()
|
|
this.communes = await api.get<Commune[]>('/communes/')
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
async fetchCommune(slug: string) {
|
|
const api = useApi()
|
|
this.current = await api.get<Commune>(`/communes/${slug}`)
|
|
},
|
|
|
|
async fetchParams(slug: string) {
|
|
const api = useApi()
|
|
this.params = await api.get<TariffParams>(`/communes/${slug}/params`)
|
|
},
|
|
},
|
|
})
|