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>
57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
|
|
interface AuthState {
|
|
token: string | null
|
|
role: string | null
|
|
communeSlug: string | null
|
|
}
|
|
|
|
export const useAuthStore = defineStore('auth', {
|
|
state: (): AuthState => ({
|
|
token: null,
|
|
role: null,
|
|
communeSlug: null,
|
|
}),
|
|
|
|
getters: {
|
|
isAuthenticated: (state) => !!state.token,
|
|
isAdmin: (state) => state.role === 'super_admin' || state.role === 'commune_admin',
|
|
isSuperAdmin: (state) => state.role === 'super_admin',
|
|
isCitizen: (state) => state.role === 'citizen',
|
|
},
|
|
|
|
actions: {
|
|
setAuth(token: string, role: string, communeSlug?: string) {
|
|
this.token = token
|
|
this.role = role
|
|
this.communeSlug = communeSlug || null
|
|
|
|
if (import.meta.client) {
|
|
localStorage.setItem('sejeteralo_token', token)
|
|
localStorage.setItem('sejeteralo_role', role)
|
|
if (communeSlug) localStorage.setItem('sejeteralo_commune', communeSlug)
|
|
}
|
|
},
|
|
|
|
logout() {
|
|
this.token = null
|
|
this.role = null
|
|
this.communeSlug = null
|
|
|
|
if (import.meta.client) {
|
|
localStorage.removeItem('sejeteralo_token')
|
|
localStorage.removeItem('sejeteralo_role')
|
|
localStorage.removeItem('sejeteralo_commune')
|
|
}
|
|
},
|
|
|
|
restore() {
|
|
if (import.meta.client) {
|
|
this.token = localStorage.getItem('sejeteralo_token')
|
|
this.role = localStorage.getItem('sejeteralo_role')
|
|
this.communeSlug = localStorage.getItem('sejeteralo_commune')
|
|
}
|
|
},
|
|
},
|
|
})
|