unify page
This commit is contained in:
@@ -1,5 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
</div>
|
|
||||||
</template>
|
</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>
|
<template>
|
||||||
<table class="emphased">
|
<div class="emphased">
|
||||||
<tbody>
|
<div v-for="(val, index) in values" :id="`${questionId}-${val}`" :key="index">
|
||||||
<tr>
|
|
||||||
<td v-for="(val, index) in values" :id="`${questionId}-${val}`" :key="index">
|
|
||||||
<input type="radio" :value="val" :name="String(questionId)">
|
<input type="radio" :value="val" :name="String(questionId)">
|
||||||
<label :for="`${questionId}-${val}`">{{ val }}</label>
|
<label :for="`${questionId}-${val}`">{{ val }}</label>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
@@ -25,16 +21,27 @@ const { values = ["Très bien", "Bien", "Passable", "Insuffisant", "À rejeter"]
|
|||||||
|
|
||||||
<style scoped="true" lang="css">
|
<style scoped="true" lang="css">
|
||||||
.emphased {
|
.emphased {
|
||||||
border: 1px solid #444;
|
position: relative;
|
||||||
padding: 1em;
|
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
table-layout: fixed;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
display: inline-flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.emphased td {
|
.emphased div {
|
||||||
border: 1px solid;
|
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>
|
</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
|
// @ts-check
|
||||||
import withNuxt from './.nuxt/eslint.config.mjs'
|
import withNuxt from "./.nuxt/eslint.config.mjs";
|
||||||
|
|
||||||
export default withNuxt(
|
export default withNuxt({
|
||||||
// Your custom configs here
|
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>
|
<template>
|
||||||
|
<MainPoll :question-component="QuestionChoice" @submit="submitForm">
|
||||||
<body>
|
<template #submit>
|
||||||
<h1>Compte-rendu de la réunion AMAP</h1>
|
<button type="submit">Submit</button>
|
||||||
<h2>Les permanences de distribution</h2>
|
</template>
|
||||||
<div>
|
</MainPoll>
|
||||||
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>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { MainPoll } from '#components';
|
||||||
|
import QuestionChoice from '~/components/QuestionChoice.vue';
|
||||||
|
|
||||||
<style>
|
async function submitForm(e: Event) {
|
||||||
body {
|
const target = e.target
|
||||||
margin: 40px auto;
|
if (!target || !(target instanceof HTMLFormElement)) {
|
||||||
max-width: 650px;
|
throw Error("Form target not found")
|
||||||
line-height: 1.6;
|
}
|
||||||
font-size: 18px;
|
await $fetch("http://localhost:3000/vote/beautifulAccessCode", {
|
||||||
color: #444;
|
method: "POST",
|
||||||
padding: 0 10px;
|
body: Object.fromEntries(new FormData(target))
|
||||||
font-family: 'Arial'
|
})
|
||||||
}
|
}
|
||||||
|
</script>
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3 {
|
|
||||||
line-height: 1.2;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emphased {
|
|
||||||
border: 1px solid #444;
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -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