Restructure citizen vote page + add vote deadline
Reorganize the citizen page (/commune/[slug]) for voters: full-width interactive chart with "Population" zoom by default, separate auth and vote sections, countdown timer for vote deadline. Backend: add vote_deadline column to communes with Alembic migration. Admin: add deadline configuration card with datetime-local input. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,29 @@
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<!-- Vote deadline -->
|
||||
<div class="card" style="margin-bottom: 2rem;">
|
||||
<h3 style="margin-bottom: 1rem;">Parametres du vote</h3>
|
||||
<div style="display: flex; gap: 1rem; align-items: flex-end; flex-wrap: wrap;">
|
||||
<div>
|
||||
<label style="display: block; font-size: 0.8rem; color: var(--color-text-muted); margin-bottom: 0.25rem;">
|
||||
Date limite de vote
|
||||
</label>
|
||||
<input
|
||||
v-model="voteDeadline"
|
||||
type="datetime-local"
|
||||
class="form-input"
|
||||
style="width: 260px;"
|
||||
/>
|
||||
</div>
|
||||
<button class="btn btn-primary" @click="saveDeadline" :disabled="savingDeadline">
|
||||
<span v-if="savingDeadline" class="spinner" style="width: 1rem; height: 1rem;"></span>
|
||||
Enregistrer
|
||||
</button>
|
||||
<span v-if="deadlineSaved" style="color: #059669; font-size: 0.85rem;">Enregistre !</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div v-if="stats" class="card" style="margin-bottom: 2rem;">
|
||||
<h3 style="margin-bottom: 1rem;">Statistiques foyers</h3>
|
||||
@@ -145,6 +168,26 @@ const search = ref('')
|
||||
const page = ref(1)
|
||||
const perPage = 20
|
||||
|
||||
// Vote deadline
|
||||
const voteDeadline = ref('')
|
||||
const savingDeadline = ref(false)
|
||||
const deadlineSaved = ref(false)
|
||||
|
||||
async function saveDeadline() {
|
||||
savingDeadline.value = true
|
||||
deadlineSaved.value = false
|
||||
try {
|
||||
await api.put(`/communes/${slug}`, {
|
||||
vote_deadline: voteDeadline.value ? new Date(voteDeadline.value).toISOString() : null,
|
||||
})
|
||||
deadlineSaved.value = true
|
||||
} catch (e: any) {
|
||||
alert(e.message || 'Erreur')
|
||||
} finally {
|
||||
savingDeadline.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const filteredHouseholds = computed(() => {
|
||||
if (!search.value) return households.value
|
||||
const q = search.value.toLowerCase()
|
||||
@@ -173,6 +216,10 @@ function statusBadge(status: string) {
|
||||
onMounted(async () => {
|
||||
try {
|
||||
commune.value = await api.get<any>(`/communes/${slug}`)
|
||||
if (commune.value.vote_deadline) {
|
||||
// Format for datetime-local input (YYYY-MM-DDTHH:mm)
|
||||
voteDeadline.value = commune.value.vote_deadline.slice(0, 16)
|
||||
}
|
||||
} catch (e: any) {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user