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>
This commit is contained in:
119
frontend/app/pages/index.vue
Normal file
119
frontend/app/pages/index.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Hero -->
|
||||
<section class="hero">
|
||||
<h1>Tarification participative de l'eau</h1>
|
||||
<p>
|
||||
Dessinez votre courbe de tarification idéale et participez aux choix de votre commune.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Communes publiques -->
|
||||
<section>
|
||||
<h2 style="margin-bottom: 1rem;">Communes participantes</h2>
|
||||
|
||||
<div v-if="loading" style="text-align: center; padding: 2rem;">
|
||||
<div class="spinner" style="margin: 0 auto;"></div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="error" class="alert alert-error">
|
||||
{{ error }}
|
||||
</div>
|
||||
|
||||
<div v-else-if="communes.length === 0" class="alert alert-info">
|
||||
Aucune commune active pour le moment.
|
||||
</div>
|
||||
|
||||
<div v-else class="grid grid-3">
|
||||
<NuxtLink
|
||||
v-for="commune in communes"
|
||||
:key="commune.id"
|
||||
:to="`/commune/${commune.slug}`"
|
||||
class="card commune-card"
|
||||
>
|
||||
<h3>{{ commune.name }}</h3>
|
||||
<p>{{ commune.description }}</p>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Accès administration -->
|
||||
<section style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--color-border);">
|
||||
<div class="grid grid-2">
|
||||
<div class="card">
|
||||
<h3>Espace commune</h3>
|
||||
<p style="margin: 0.75rem 0; color: var(--color-text-muted); font-size: 0.875rem;">
|
||||
Vous êtes responsable d'une commune ? Connectez-vous pour gérer vos données,
|
||||
paramétrer la tarification et consulter les votes.
|
||||
</p>
|
||||
<NuxtLink to="/login/commune" class="btn btn-secondary">Connexion commune</NuxtLink>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>Super administration</h3>
|
||||
<p style="margin: 0.75rem 0; color: var(--color-text-muted); font-size: 0.875rem;">
|
||||
Gestion globale des communes et des administrateurs.
|
||||
</p>
|
||||
<NuxtLink to="/login/admin" class="btn btn-secondary">Connexion admin</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const api = useApi()
|
||||
|
||||
const communes = ref<any[]>([])
|
||||
const loading = ref(true)
|
||||
const error = ref('')
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
communes.value = await api.get<any[]>('/communes/')
|
||||
} catch (e: any) {
|
||||
error.value = e.message
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 2rem 0 2.5rem;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 1.1rem;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.commune-card {
|
||||
cursor: pointer;
|
||||
transition: box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.commune-card:hover {
|
||||
box-shadow: var(--shadow-md);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.commune-card h3 {
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.commune-card p {
|
||||
font-size: 0.875rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user