unify page
This commit is contained in:
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
@@ -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
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user