|
|
@@ -0,0 +1,199 @@
|
|
|
+<template>
|
|
|
+ <c-header title="BDLG Inscription Benevole" />
|
|
|
+ <div style="display: flex; justify-content: center">
|
|
|
+ <dots v-if="status == 'Loading'" />
|
|
|
+ <h2 v-if="status.startsWith('Error')">{{ status }}</h2>
|
|
|
+ <div v-if="status == 'Loaded'" class="inscription-container">
|
|
|
+ <h2>Formulaire d'inscription en tant que bénévole pour {{ evtName }}</h2>
|
|
|
+ <div class="persona">
|
|
|
+ <styled-input class="s6" label="Prénom" id="last_name" type="text" v-model="name" />
|
|
|
+ <styled-input class="s6" label="Nom" id="family_name" type="text" v-model="surname" />
|
|
|
+ <styled-input class="s6" label="Email" id="email" type="email" v-model="email" />
|
|
|
+ <styled-input class="s6" label="Téléphone" id="phone" type="text" v-model="phone" />
|
|
|
+ <styled-input label="Commentaire" id="comment" type="textarea" v-model="comment" />
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <h3>Fanfares</h3>
|
|
|
+ <check-box
|
|
|
+ v-for="f in fanfares"
|
|
|
+ :help="f.description"
|
|
|
+ :id="f.id"
|
|
|
+ :label="f.name"
|
|
|
+ :key="f.id"
|
|
|
+ @input="toggle($event, f.id)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <h3>Preference</h3>
|
|
|
+ <check-box
|
|
|
+ v-for="f in preferences"
|
|
|
+ :help="f.description"
|
|
|
+ :id="f.id"
|
|
|
+ :label="f.name"
|
|
|
+ :key="f.id"
|
|
|
+ @input="toggle($event, f.id)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <h3>Competences & contrainte</h3>
|
|
|
+ <check-box
|
|
|
+ v-for="f in contraintes"
|
|
|
+ :help="f.description"
|
|
|
+ :id="f.id"
|
|
|
+ :label="f.name"
|
|
|
+ :key="f.id"
|
|
|
+ @input="toggle($event, f.id)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <button class="btn success small" @click="saveBenevole">
|
|
|
+ <i class="material-icons">send</i>S'inscrire
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <c-footer />
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+import { defineComponent } from "vue";
|
|
|
+import { validate as validateUuid } from "uuid";
|
|
|
+import cHeader from "@/components/Header.vue";
|
|
|
+import cFooter from "@/components/Footer.vue";
|
|
|
+import styledInput from "@/components/input.vue";
|
|
|
+import checkBox from "@/components/checkBox.vue";
|
|
|
+
|
|
|
+import dots from "@/components/Dots.vue";
|
|
|
+
|
|
|
+import { StateJSON } from "@/store/State";
|
|
|
+import Benevole, { BenevoleJSON } from "@/models/Benevole";
|
|
|
+import Toast from "./utils/Toast";
|
|
|
+import Competence, { ICompetence } from "@/models/Competence";
|
|
|
+
|
|
|
+const API_URL = process.env.VUE_APP_API_URL;
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ components: { cHeader, cFooter, styledInput, checkBox, dots },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ uuid: location.pathname.split("/").pop(),
|
|
|
+ status: "Loading",
|
|
|
+ data: null as StateJSON | null,
|
|
|
+ registration: [] as Array<Benevole>,
|
|
|
+ name: "",
|
|
|
+ surname: "",
|
|
|
+ phone: "",
|
|
|
+ email: "",
|
|
|
+ comment: "",
|
|
|
+ competenceIdList: [] as Array<number>,
|
|
|
+ competences: [] as Array<Competence>,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ evtName(): string {
|
|
|
+ return this.data?.evenement.name ?? "";
|
|
|
+ },
|
|
|
+ fanfares(): Array<ICompetence> {
|
|
|
+ return this.competences.filter((o) => o.isFanfare);
|
|
|
+ },
|
|
|
+ preferences(): Array<ICompetence> {
|
|
|
+ return this.competences.filter((o) => !o.isFanfare && o.isPreference);
|
|
|
+ },
|
|
|
+ contraintes(): Array<ICompetence> {
|
|
|
+ return this.competences.filter((o) => !o.isFanfare && !o.isPreference);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ toggle(value: boolean, id: number) {
|
|
|
+ if (value) {
|
|
|
+ this.competenceIdList.push(id);
|
|
|
+ } else {
|
|
|
+ this.competenceIdList = this.competenceIdList.filter((o) => o != id);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ addBenevoles(data: Array<BenevoleJSON>) {
|
|
|
+ this.registration.push(...data.map((o) => Benevole.fromJSON(o)));
|
|
|
+ },
|
|
|
+ saveBenevole() {
|
|
|
+ const benevole: BenevoleJSON = {
|
|
|
+ name: this.name,
|
|
|
+ surname: this.surname,
|
|
|
+ phone: this.phone,
|
|
|
+ email: this.email,
|
|
|
+ comment: this.comment,
|
|
|
+ competenceIdList: this.competenceIdList,
|
|
|
+ };
|
|
|
+ fetch(`${API_URL}api/inscription/${this.uuid}`, {
|
|
|
+ method: "PUT",
|
|
|
+ body: JSON.stringify(benevole),
|
|
|
+ headers: { "Content-Type": "application/json" },
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ if (res.status == 200) {
|
|
|
+ return res.json();
|
|
|
+ } else {
|
|
|
+ if (res.status == 409) {
|
|
|
+ Toast({
|
|
|
+ html: "Cette addresse mail à déjà été utiliser pour une autre inscription",
|
|
|
+ classes: "error",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ throw new Error(res.statusText);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .then((data: BenevoleJSON) => {
|
|
|
+ this.registration.push(Benevole.fromJSON(data));
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ // Get event data
|
|
|
+ const uuid = this.uuid;
|
|
|
+ if (uuid && validateUuid(uuid)) {
|
|
|
+ fetch(`${API_URL}api/evenements/${uuid}`)
|
|
|
+ .then((res) => {
|
|
|
+ if (res.status == 200) {
|
|
|
+ this.status = "Loaded";
|
|
|
+ return res.json();
|
|
|
+ } else {
|
|
|
+ this.status = "Error 404";
|
|
|
+ throw new Error(res.statusText);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .then((data: StateJSON) => {
|
|
|
+ this.data = data;
|
|
|
+ this.competences = data.competences.map((o) => Competence.fromJSON(o));
|
|
|
+ this.addBenevoles(data.benevoles);
|
|
|
+ });
|
|
|
+ // Get existing registration
|
|
|
+ fetch(`${API_URL}api/inscription/${uuid}`)
|
|
|
+ .then((res) => {
|
|
|
+ if (res.status == 200) {
|
|
|
+ return res.json();
|
|
|
+ } else {
|
|
|
+ throw new Error(res.statusText);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .then((data: Array<BenevoleJSON>) => this.addBenevoles(data));
|
|
|
+ } else {
|
|
|
+ this.status = "Error 404";
|
|
|
+ }
|
|
|
+ },
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.inscription-container {
|
|
|
+ max-width: 600px;
|
|
|
+ padding: 8px;
|
|
|
+}
|
|
|
+.persona {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+.s6 {
|
|
|
+ width: calc(50% - 8px);
|
|
|
+}
|
|
|
+#comment {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+</style>
|