unify page

This commit is contained in:
2025-05-31 21:05:58 +02:00
parent 29a6fcb2fb
commit 03e4a5790a
7 changed files with 245 additions and 97 deletions
+20 -3
View File
@@ -1,5 +1,22 @@
<template>
<div>
<NuxtPage />
</div>
<NuxtPage />
</template>
<style>
body {
margin: 40px auto;
max-width: 650px;
line-height: 1.6;
font-size: 18px;
color: #444;
padding: 0 10px;
font-family: 'Arial'
}
h1,
h2,
h3 {
line-height: 1.2;
text-decoration: underline;
}
</style>
+73
View File
@@ -0,0 +1,73 @@
<template>
<div>
<h1>Compte-rendu de la réunion AMAP</h1>
<form @submit.prevent="$emit('submit', $event)">
<h2>Les permanences de distribution</h2>
<div>
1) <b>La notion d’engagement</b> au sein de l’AMAP s’élargit, pour ne pas se restreindre à la
réalisation de
x
permanences par an pour les distributions, mais pour l’<b>élargir à d’autres activités</b>, notamment
pour
les
amapiens
ne pouvant réaliser, une partie ou l’ensemble de leur permanence dans l’année. Les activités possibles
sont :
<ul>
<li>
organiser et réaliser la livraison des fruits d’été et des agrumes,
</li>
<li>
réaliser la distribution des œufs,
</li>
<li>
être Référent d’un produit.
</li>
<li>
être Référent du local de distribution (si officiellement créé), Référent Impression,
Ambassadeur
Réseau
AMAP, Référent Climatologue, ou Référent des nouveaux amapiens.
</li>
<li>
être Référent panier solidaire.
</li>
</ul>
<slot>
<component :is="questionComponent" question-id="1" :results="results" />
</slot>
</div>
<div>
2) <b>Mesurer le niveau d’engagement de chacun</b> :
<br>
Propositions :
<div>
2.1) Estimer les heures que représentent chaque engagement/mission dans un souci d’égalité entre les
engagements de chacun.
<slot>
<component :is="questionComponent" question-id="2.1" :results="results" />
</slot>
</div>
</div>
<slot name="submit" />
</form>
</div>
</template>
<script setup lang="ts">
import type { Component } from 'vue';
interface Props {
questionComponent: Component
results?: { [question_id: string]: { [values: string]: number } }
}
const { questionComponent, results = {} } = defineProps<Props>()
defineEmits(['submit'])
</script>
+22 -15
View File
@@ -1,14 +1,10 @@
<template>
<table class="emphased">
<tbody>
<tr>
<td v-for="(val, index) in values" :id="`${questionId}-${val}`" :key="index">
<input type="radio" :value="val" :name="String(questionId)">
<label :for="`${questionId}-${val}`">{{ val }}</label>
</td>
</tr>
</tbody>
</table>
<div class="emphased">
<div v-for="(val, index) in values" :id="`${questionId}-${val}`" :key="index">
<input type="radio" :value="val" :name="String(questionId)">
<label :for="`${questionId}-${val}`">{{ val }}</label>
</div>
</div>
</template>
@@ -25,16 +21,27 @@ const { values = ["Très bien", "Bien", "Passable", "Insuffisant", "À rejeter"]
<style scoped="true" lang="css">
.emphased {
border: 1px solid #444;
padding: 1em;
position: relative;
margin-top: 2em;
margin-bottom: 2em;
table-layout: fixed;
width: 100%;
border-collapse: collapse;
display: inline-flex;
flex-wrap: nowrap;
}
.emphased td {
border: 1px solid;
.emphased div {
padding: 3px;
border: 1px solid #444;
border-right: none;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
flex: 1 1 0;
width: 0;
}
.emphased div:last-child {
border-right: 1px solid #444;
}
</style>
+81
View File
@@ -0,0 +1,81 @@
<template>
<div class="emphased">
<div v-for="(amount, val) in filtered_results" :id="`${questionId}-${val}`" :key="val"
:style="{ width: `${(amount / total) * 100}%` }">
<span>({{ amount }}){{ val }}</span>
</div>
</div>
</template>
<script setup lang="ts">
interface Props {
values?: string[]
results: { [question_id: string]: { [values: string]: number } }
questionId: string
}
const { values = ["Très bien", "Bien", "Passable", "Insuffisant", "À rejeter"], results, questionId } = defineProps<Props>()
const filtered_results = computed(() => {
if (!(questionId in results)) {
return values.reduce((acc, val) => {
acc[val] = 0
return acc
}, {} as { [key: string]: number })
}
const relevant = results[questionId]
return values.reduce((acc, val) => {
if (!(val in relevant)) {
acc[val] = 0
} else {
acc[val] = relevant[val]
}
return acc
}, {} as { [key: string]: number })
})
const total = computed(() => Object.values(filtered_results.value).reduce((acc, v) => v + acc, 0) ?? 1)
</script>
<style scoped="true" lang="css">
.emphased {
position: relative;
margin-top: 2em;
margin-bottom: 2em;
width: 100%;
border-collapse: collapse;
display: inline-flex;
flex-wrap: nowrap;
}
.emphased:after {
content: "";
position: absolute;
z-index: -1;
top: -10px;
bottom: -10px;
left: 50%;
border-left: 4px solid #444;
transform: translate(-50%);
}
.emphased div {
padding: 3px;
border: 1px solid #444;
border-right: none;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.emphased div:last-child {
border-right: 1px solid #444;
}
</style>
+12 -4
View File
@@ -1,6 +1,14 @@
// @ts-check
import withNuxt from './.nuxt/eslint.config.mjs'
import withNuxt from "./.nuxt/eslint.config.mjs";
export default withNuxt(
// Your custom configs here
)
export default withNuxt({
rules: {
"vue/no-irregular-whitespace": [
"error",
{
skipHTMLTextContents: true,
},
],
"no-irregular-whitespace": "off",
},
});
+18 -75
View File
@@ -1,80 +1,23 @@
<script setup lang="ts">
import QuestionChoice from '~/components/QuestionChoice.vue';
</script>
<template>
<body>
<h1>Compte-rendu de la réunion AMAP</h1>
<h2>Les permanences de distribution</h2>
<div>
1) <b>La notion d’engagement</b> au sein de l’AMAP s’élargit, pour ne pas se restreindre à la réalisation de
x
permanences par an pour les distributions, mais pour l’<b>élargir à d’autres activités</b>, notamment pour
les
amapiens
ne pouvant réaliser, une partie ou l’ensemble de leur permanence dans l’année. Les activités possibles
sont :
<ul>
<li>
organiser et réaliser la livraison des fruits d’été et des agrumes,
</li>
<li>
réaliser la distribution des œufs,
</li>
<li>
être Référent d’un produit.
</li>
<li>
être Référent du local de distribution (si officiellement créé), Référent Impression, Ambassadeur
Réseau
AMAP, Référent Climatologue, ou Référent des nouveaux amapiens.
</li>
<li>
être Référent panier solidaire.
</li>
</ul>
<QuestionChoice question-id="1" />
</div>
<div>
2) <b>Mesurer le niveau d’engagement de chacun</b> :
<br>
Propositions :
<div>
2.1) Estimer les heures que représentent chaque engagement/mission dans un souci d’égalité entre les
engagements de chacun.
<QuestionChoice question-id="2.1" />
</div>
</div>
</body>
<MainPoll :question-component="QuestionChoice" @submit="submitForm">
<template #submit>
<button type="submit">Submit</button>
</template>
</MainPoll>
</template>
<script setup lang="ts">
import { MainPoll } from '#components';
import QuestionChoice from '~/components/QuestionChoice.vue';
<style>
body {
margin: 40px auto;
max-width: 650px;
line-height: 1.6;
font-size: 18px;
color: #444;
padding: 0 10px;
font-family: 'Arial'
async function submitForm(e: Event) {
const target = e.target
if (!target || !(target instanceof HTMLFormElement)) {
throw Error("Form target not found")
}
await $fetch("http://localhost:3000/vote/beautifulAccessCode", {
method: "POST",
body: Object.fromEntries(new FormData(target))
})
}
h1,
h2,
h3 {
line-height: 1.2;
text-decoration: underline;
}
.emphased {
border: 1px solid #444;
padding: 1em;
}
</style>
</script>
+19
View File
@@ -0,0 +1,19 @@
<template>
<div v-if="data">
<MainPoll :question-component="QuestionResult" :results="data" />
</div>
<div v-else>
Couldn't fetch poll results ! Please contact the website administrator
</div>
</template>
<script setup lang="ts">
import QuestionResult from '~/components/QuestionResult.vue';
const { data, error } = await useFetch<{ [question_id: string]: { [values: string]: number } }>('http://localhost:3000/results/beautifulAccessCode', {
})
if (error) {
console.log(error.value)
}
</script>