ソースを参照

add close option on inscription

tripeur 4 年 前
コミット
b2601a6961

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "bdlg-scheduler",
-  "version": "1.3.3",
+  "version": "1.3.4",
   "private": true,
   "scripts": {
     "serve": "vue-cli-service serve --port 8081",

+ 5 - 0
src/Inscription.vue

@@ -5,6 +5,7 @@
     <h2 v-if="status.startsWith('Error')">{{ status }}</h2>
     <div v-if="status == 'Loaded'" class="inscription-container">
       <questionnaire
+        v-if="opened"
         :competences="competences"
         :introduction="introduction"
         :questions="questions"
@@ -13,6 +14,10 @@
         :emailList="emailList"
         @newRegistration="status = 'Completed'"
       />
+      <template v-else>
+        <h2>Insciptions cloturées</h2>
+        <p>Les inscriptions à cet événement sont terminées</p>
+      </template>
     </div>
     <div v-if="status == 'Completed'">
       <h2>Inscription Validée</h2>

+ 18 - 7
src/components/EditeurQuestionnaire.vue

@@ -2,7 +2,6 @@
   <div class="questionnaire-container">
     <div class="questionnaire-editor">
       <h4>Edition du questionnaire</h4>
-      <div></div>
       <div class="editor">
         <textarea
           ref="textarea"
@@ -27,6 +26,9 @@
           <i class="material-icons">launch</i>Lien vers le formulaire d'inscription
         </a>
       </div>
+      <div class="actions">
+        <toggle id="switch-questionnaire" label="Activer le questionnaire" v-model="opened" />
+      </div>
     </div>
     <div class="questionnaire-preview">
       <h4>Previsualisation du questionnaire</h4>
@@ -49,6 +51,7 @@ import debounce from "lodash-es/debounce";
 
 import vQuestion from "@/components/EditeurQuestionnaireQuestion.vue";
 import vQuestionnaire from "@/components/Questionaire.vue";
+import toggle from "@/components/Form/Toggle.vue";
 
 import { Question } from "@/models/Questionnaire";
 import Competence from "@/models/Competence";
@@ -58,7 +61,7 @@ import Toast from "@/utils/Toast";
 const API_URL = process.env.VUE_APP_API_URL;
 
 export default defineComponent({
-  components: { vQuestion, vQuestionnaire },
+  components: { vQuestion, vQuestionnaire, toggle },
   mixins: [getQuestionnaire],
   props: {
     competences: { type: Array as PropType<Array<Competence>>, default: () => [] },
@@ -88,19 +91,27 @@ export default defineComponent({
         a.style.height = a.scrollHeight + "px";
       });
     },
+    opened(val: boolean) {
+      const url = `${API_URL}api/questionnaire/${this.uuid}/${val ? "open" : "close"}`;
+      fetch(url, { method: "POST" });
+    },
   },
   methods: {
     updateIntro(e: InputEvent) {
       this.introduction = (e.target as HTMLInputElement).value;
       this.savedIntro = false;
 
-      this.saveIntro();
+      this.saveQuestionnaire();
     },
-    saveIntro() {
+    saveQuestionnaire() {
       if (!this.loading) {
         fetch(`${API_URL}api/questionnaire/${this.uuid}`, {
           method: "POST",
-          body: JSON.stringify({ uuid: this.uuid, introduction: this.introduction }),
+          body: JSON.stringify({
+            uuid: this.uuid,
+            introduction: this.introduction,
+            opened: this.opened,
+          }),
           headers: { "Content-Type": "application/json" },
         }).then(() => (this.savedIntro = true));
       }
@@ -185,14 +196,14 @@ export default defineComponent({
     },
   },
   mounted() {
-    this.saveIntro = debounce(this.saveIntro, 5000);
+    this.saveQuestionnaire = debounce(this.saveQuestionnaire, 5000);
     this.updateIntro = debounce(this.updateIntro, 300);
     this.saveQuestions = debounce(this.saveQuestions, 1000);
     if (this.uuid) this.getQuestionnaire(this.uuid);
     setTimeout(() => (this.loading = false), 5000);
   },
   unmounted() {
-    if (!this.savedIntro) this.saveIntro();
+    if (!this.savedIntro) this.saveQuestionnaire();
     if (!this.savedQuestions) this.saveQuestions();
   },
 });

+ 1 - 1
src/components/Utils/Footer.vue

@@ -2,7 +2,7 @@
   <footer class="footer">
     <a :href="logout" v-if="connected">Se déconnecter</a>
     <a :href="adminPage" v-if="isAdmin">Admninistration</a>
-    <span>© 2021 - {{ year }} par Clovis Jaquin 1.3.3</span>
+    <span>© 2021 - {{ year }} par Clovis Jaquin 1.3.4</span>
   </footer>
 </template>
 

+ 5 - 2
src/mixins/getQuestionnaire.ts

@@ -6,7 +6,7 @@ const API_URL = process.env.VUE_APP_API_URL;
 
 export default defineComponent({
   data() {
-    return { introduction: "", questions: [] as Array<Question> };
+    return { introduction: "", questions: [] as Array<Question>, opened: false };
   },
   methods: {
     getQuestionnaire(uuid: string) {
@@ -26,7 +26,10 @@ export default defineComponent({
           }
           throw new Error("Failed");
         })
-        .then((t) => (this.introduction = t.introduction ?? ""));
+        .then((t) => {
+          this.introduction = t.introduction ?? "";
+          this.opened = t.opened ?? false;
+        });
       // Get previously saved questions
       fetch(`${API_URL}api/questionnaire/${uuid}/questions`, {
         method: "GET",

+ 1 - 0
src/models/Questionnaire.ts

@@ -17,6 +17,7 @@ export type Question = {
 
 type Questionnaire = {
   introduction: string;
+  opened: boolean;
   questions: Array<Question>;
 };
 export default Questionnaire;

+ 12 - 8
src/views/BenevoleManager.vue

@@ -51,12 +51,16 @@ import DataTable, {
 import { defineComponent } from "vue";
 import { MutationTypes } from "@/store/Mutations";
 import Benevole from "@/models/Benevole";
-import csv from "@/utils/csv";
+import csv, { csvOptions } from "@/utils/csv";
 import dayjs from "dayjs";
 import Toast from "@/utils/Toast";
 import commit from "@/mixins/commit";
 
-const csvDefaultcolumn = "id,prenom,nom,telephone,email,commentaire";
+const csvFrenchOptions: csvOptions = { delimiter: '"', separator: ";" };
+
+const csvDefaultcolumn = "id,prenom,nom,telephone,email,commentaire"
+  .split(",")
+  .join(csvFrenchOptions.separator);
 const navOption = [
   { id: "benevole", title: "Bénévoles" },
   { id: "questionnaire", title: "Gestion du questionnaire" },
@@ -219,9 +223,9 @@ export default defineComponent({
     },
     getImportTemplate() {
       const competences = this.$store.state.competenceList.map((c) => ({ id: c.id, name: c.name }));
-      let csvContent = `${csvDefaultcolumn},${competences
+      let csvContent = `\uFEFF${csvDefaultcolumn}${csvFrenchOptions.separator}${competences
         .map((c) => csv.escapeCsvField(c.name))
-        .join(",")}\r\n`;
+        .join(csvFrenchOptions.separator)}\r\n`;
       this.benevoleList.forEach(
         (b) =>
           (csvContent +=
@@ -231,11 +235,11 @@ export default defineComponent({
               b.surname,
               b.phone,
               b.email,
-              b.comment,
+              b.comment.replaceAll("\n", " ").replaceAll("\r", " "),
               ...competences.map((c) => (b.competenceIdList.includes(c.id) ? "X" : "")),
             ]
-              .map((s) => csv.escapeCsvField(s))
-              .join(",") + "\r\n")
+              .map((s) => csv.escapeCsvField(s, csvFrenchOptions))
+              .join(csvFrenchOptions.separator) + "\r\n")
       );
       const dummy = document.createElement("a");
       dummy.href = "data:text/csv;charset=utf-8," + encodeURI(csvContent);
@@ -250,7 +254,7 @@ export default defineComponent({
         reader.readAsText(fs[0]);
         reader.onload = () => {
           let csvtxt = reader.result as string;
-          const arr = csv.toArray(csvtxt);
+          const arr = csv.toArray(csvtxt, csvFrenchOptions);
           const defaultKey = csvDefaultcolumn.split(",");
           const competencesMap: { [k: string]: Competence } = {};
           for (let key of arr[0]) {