Explorar o código

event test user side

ali %!s(int64=2) %!d(string=hai) anos
pai
achega
453b648037

+ 19 - 0
src/api/models/AnswerBook.js

@@ -7,6 +7,7 @@ export default class AnswerBookAPI extends APIRepository {
     super('answer_books', appApi)
     this.APIAdresses = {
       base: '/lma/answer_books',
+      getOrCreate: '/lma/answer_books/get_or_create',
       byId: (id) => '/lma/answer_books/' + id,
       confirmAnswers: (id) => '/lma/answer_books/' + id + '/confirm_answers',
       setGraderToMe: (id) => '/lma/answer_books/' + id + '/set_grader_to_me',
@@ -78,6 +79,24 @@ export default class AnswerBookAPI extends APIRepository {
     })
   }
 
+  getOrCreate (userId, testId) {
+    return this.sendRequest({
+      apiMethod: 'post',
+      api: this.api,
+      request: this.APIAdresses.getOrCreate,
+      data: {
+        owner: userId,
+        test: testId
+      },
+      resolveCallback: (response) => {
+        return new AnswerBook(response.data)
+      },
+      rejectCallback: (error) => {
+        return error
+      }
+    })
+  }
+
   getTestQuestions (id) {
     return this.sendRequest({
       apiMethod: 'get',

+ 1 - 1
src/api/models/Test.js

@@ -28,7 +28,7 @@ export default class TestAPI extends APIRepository {
       api: this.api,
       request: this.APIAdresses.base,
       data: this.getNormalizedSendData({
-        category: null, // Number
+        event: null, // Number
         per_page: 10, // Number
         page: 1 // Number
       }, data),

+ 101 - 37
src/components/Widgets/Other/Shop/ShopCompleteInfo/ShopCompleteInfo.vue

@@ -80,67 +80,94 @@
       </div>
     </q-card>
 
-    <q-banner class="banner complete-info-form-banner">
-      تکمیل اطلاعات
-    </q-banner>
-    <q-card class="complete-info-form-card">
-      <entity-edit v-if="mounted"
-                   ref="entityEdit"
-                   v-model:value="inputs"
-                   title="اطلاعات کاربری"
-                   :api="api"
-                   :entity-id-key="entityIdKey"
-                   :entity-param-key="entityParamKey"
-                   :show-route-name="showRouteName"
-                   :show-close-button="false"
-                   :show-edit-button="false"
-                   :show-expand-button="false"
-                   :show-save-button="false"
-                   :show-reload-button="false"
-                   :redirect-after-edit="false"
-                   :after-load-input-data="afterLoadInputData" />
-    </q-card>
+    <q-tab-panels v-model="panel"
+                  animated
+                  class="panels">
+      <q-tab-panel name="userInfo">
+        <q-banner class="banner complete-info-form-banner">
+          تکمیل اطلاعات
+        </q-banner>
+        <q-card class="complete-info-form-card">
+          <entity-edit v-if="mounted"
+                       ref="entityEdit"
+                       v-model:value="inputs"
+                       title="اطلاعات کاربری"
+                       :api="api"
+                       :entity-id-key="entityIdKey"
+                       :entity-param-key="entityParamKey"
+                       :show-route-name="showRouteName"
+                       :show-close-button="false"
+                       :show-edit-button="false"
+                       :show-expand-button="false"
+                       :show-save-button="false"
+                       :show-reload-button="false"
+                       :redirect-after-edit="false"
+                       :after-load-input-data="afterLoadInputData" />
+        </q-card>
 
-    <div class="flex justify-end section-edit-btn">
-      <q-btn color="primary"
-             @click="editEntity">
-        تایید و ادامه
-        <svg xmlns="http://www.w3.org/2000/svg"
-             width="18.387"
-             height="11.502"
-             viewBox="0 0 18.387 11.502">
-          <path id="Combined_Shape"
-                data-name="Combined Shape"
-                d="M-9.338,11.408a.748.748,0,0,0,.388-.656V6.5h8.2A.751.751,0,0,0,0,5.75.75.75,0,0,0-.75,5h-8.2V.75A.751.751,0,0,0-9.338.093.769.769,0,0,0-9.7,0a.735.735,0,0,0-.4.115l-7.938,5a.747.747,0,0,0-.35.635.742.742,0,0,0,.35.634l7.938,5a.751.751,0,0,0,.4.116A.746.746,0,0,0-9.338,11.408ZM-10.45,9.392l-5.78-3.641,5.78-3.642Z"
-                transform="translate(18.387)"
-                fill="#fff" />
-        </svg>
-      </q-btn>
-    </div>
+        <div class="flex justify-end section-edit-btn">
+          <q-btn color="primary"
+                 @click="editEntity">
+            تایید و ادامه
+            <svg xmlns="http://www.w3.org/2000/svg"
+                 width="18.387"
+                 height="11.502"
+                 viewBox="0 0 18.387 11.502">
+              <path id="Combined_Shape"
+                    data-name="Combined Shape"
+                    d="M-9.338,11.408a.748.748,0,0,0,.388-.656V6.5h8.2A.751.751,0,0,0,0,5.75.75.75,0,0,0-.75,5h-8.2V.75A.751.751,0,0,0-9.338.093.769.769,0,0,0-9.7,0a.735.735,0,0,0-.4.115l-7.938,5a.747.747,0,0,0-.35.635.742.742,0,0,0,.35.634l7.938,5a.751.751,0,0,0,.4.116A.746.746,0,0,0-9.338,11.408ZM-10.45,9.392l-5.78-3.641,5.78-3.642Z"
+                    transform="translate(18.387)"
+                    fill="#fff" />
+            </svg>
+          </q-btn>
+        </div>
+      </q-tab-panel>
+
+      <q-tab-panel name="eventTest">
+        <q-banner class="banner complete-info-form-banner">
+          پرسشنامه
+        </q-banner>
+        <show-event-test v-if="!eventTestAnswerBook.loading"
+                         :answer-book="eventTestAnswerBook"
+                         @sentsuccess="editEntity" />
+        <div v-else>
+          کمی صبر کنید...
+        </div>
+      </q-tab-panel>
+
+    </q-tab-panels>
 
   </div>
 </template>
 
 <script>
 import { EntityEdit } from 'quasar-crud'
+import { Test } from 'src/models/Test.js'
 import Enums from 'src/assets/Enums/Enums.js'
 import { Invoice } from 'src/models/Invoice.js'
+import { mixinAuth } from 'src/mixin/Mixins.js'
 import ShamsiDate from 'src/assets/ShamsiDate.js'
 import { APIGateway } from 'src/api/APIGateway.js'
 import { Classroom } from 'src/models/Classroom.js'
+import { AnswerBook } from 'src/models/AnswerBook.js'
 import { FormBuilderAssist } from 'quasar-form-builder'
+import ShowEventTest from './components/ShowEventTest.vue'
 
 export default {
   name: 'ShopCompleteInfo',
-  components: { EntityEdit },
+  components: { EntityEdit, ShowEventTest },
+  mixins: [mixinAuth],
   data: () => ({
     mounted: false,
+    panel: 'userInfo',
     step: false,
     rulesAccept: false,
     rulesDialog: false,
     loading: true,
     classroom: new Classroom(),
     invoice: new Invoice(),
+    eventTest: new Test(),
+    eventTestAnswerBook: new AnswerBook(),
 
     api: APIGateway.user.APIAdresses.current,
     entityIdKey: 'id',
@@ -238,13 +265,47 @@ export default {
   },
   mounted () {
     this.loadClassroomFromStore()
+    if (this.$route.query.source === 'event') {
+      this.getEventTest()
+    }
     this.mounted = true
   },
   methods: {
+    getEventTest () {
+      this.eventTest.loading = true
+      APIGateway.test.index({ event: this.classroom.id })
+        .then(({ list }) => {
+          this.eventTest = new Test(list.list[0])
+          this.eventTest.loading = false
+          this.getEventTestAnswerBook()
+        })
+        .catch(() => {
+          this.eventTest.loading = false
+        })
+    },
+    getEventTestAnswerBook () {
+      if (!this.eventTest.id) {
+        return
+      }
+
+      this.eventTestAnswerBook.loading = true
+      APIGateway.answerBook.getOrCreate({ owner: this.user.id, test: this.eventTest.id })
+        .then((answerBook) => {
+          this.eventTestAnswerBook = new AnswerBook(answerBook)
+          this.eventTestAnswerBook.loading = false
+        })
+        .catch(() => {
+          this.eventTestAnswerBook.loading = false
+        })
+    },
     loadClassroomFromStore () {
       this.classroom = this.$store.getters['Shop/onRegisterClassroom']
     },
     editEntity () {
+      if (this.eventTestAnswerBook.id && this.panel !== 'eventTest') {
+        this.panel = 'eventTest'
+        return
+      }
       this.$refs.entityEdit.editEntity(false)
         .then(() => {
           if (this.$route.query.type === 'register') {
@@ -421,6 +482,9 @@ export default {
       }
     }
   }
+  :deep(.panels) {
+    background: transparent;
+  }
   .section-edit-btn {
     margin-top: 50px;
     margin-bottom: 77px;

+ 119 - 0
src/components/Widgets/Other/Shop/ShopCompleteInfo/components/AllQuestions.vue

@@ -0,0 +1,119 @@
+<template>
+  <div class="AllQuestions">
+    <q-list separator>
+      <!--      <q-item v-for="(question, questionIndex) in answerBook.test_info.test_set_info.test_set_questions"-->
+      <q-item v-for="(answerSheet, answerSheetIndex) in answerBook.answer_sheet_info.list"
+              :key="answerSheetIndex"
+              clickable>
+        <q-item-section v-html="'<span>' + (answerSheetIndex + 1) + ' - </span>' + answerSheet.test_set_question_info.question_info.text" />
+      </q-item>
+    </q-list>
+    <q-separator class="q-my-lg" />
+    <q-card-actions class="flex justify-end AllQuestionsForm">
+      <entity-create v-if="mounted"
+                     ref="entityCreate"
+                     v-model:value="inputs"
+                     :api="api"
+                     :default-layout="false"
+                     :show-close-button="false"
+                     :show-edit-button="false"
+                     :show-expand-button="false"
+                     :show-save-button="false"
+                     :show-reload-button="false" />
+    </q-card-actions>
+  </div>
+</template>
+
+<script>
+import { shallowRef } from 'vue'
+import { EntityCreate } from 'quasar-crud'
+import { APIGateway } from 'src/api/APIGateway.js'
+import { AnswerBook } from 'src/models/AnswerBook.js'
+import BtnControl from 'src/components/Control/btn.vue'
+import { FormBuilderAssist } from 'quasar-form-builder'
+
+const BtnControlComp = shallowRef(BtnControl)
+
+export default {
+  name: 'AllQuestions',
+  components: { EntityCreate },
+  props: {
+    answerBook: {
+      type: AnswerBook,
+      default: new AnswerBook()
+    }
+  },
+  emits: ['sending', 'sentsuccess', 'sentfailed'],
+  data () {
+    return {
+      mounted: false,
+      api: APIGateway.answerBook.APIAdresses.submitOverallAnswer(this.$route.params.answer_book_id),
+      inputs: [
+        // { type: 'inputEditor', name: 'answer_text', label: 'متن پاسخ', placeholder: ' ', col: 'col-12' },
+        { type: 'input', name: 'answer_text', label: 'متن پاسخ', placeholder: ' ', inputType: 'textarea', col: 'col-12' },
+        { type: 'file', name: 'answer_attachment', label: 'فایل جامع پاسخ سوالات', placeholder: ' ', col: 'col-12' },
+        { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'ارسال پرسشنامه', placeholder: ' ', atClick: () => {}, col: 'col-12' }
+      ]
+    }
+  },
+  mounted () {
+    this.setInputs()
+    this.mounted = true
+  },
+  methods: {
+    setInputs () {
+      FormBuilderAssist.setAttributeByName(this.inputs, 'btn', 'atClick', this.sendAnswers)
+      FormBuilderAssist.setAttributeByName(this.inputs, 'answer_text', 'value', this.answerBook.overall_answer_text)
+      FormBuilderAssist.setAttributeByName(this.inputs, 'answer_attachment', 'value', this.answerBook.overall_answer_attachment)
+    },
+    sendAnswers () {
+      const answerText = FormBuilderAssist.getInputsByName(this.inputs, 'answer_text').value
+      if (!answerText) {
+        this.$q.notify({
+          type: 'negative',
+          message: 'لطفا متن پاسخ را کامل کنید.'
+        })
+        return
+      }
+
+      this.$emit('sending')
+      this.$refs.entityCreate.createEntity(false)
+        .then(() => {
+          APIGateway.answerBook.confirmAnswers(this.answerBook.id)
+            .then(() => {
+              this.$emit('sentsuccess')
+            })
+            .catch(() => {
+              this.$emit('sentfailed')
+            })
+        })
+        .catch(() => {
+          this.$emit('sentfailed')
+        })
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.AllQuestions {
+  :deep(.q-list) {
+    .q-item {
+      .q-item__section {
+        display: inline-block;
+      }
+      .q-badge {
+        background: #ACBCAE 0 0 no-repeat padding-box;
+        border-radius: 18px;
+        height: 32px;
+        padding: 4px 16px;
+      }
+    }
+  }
+  .AllQuestionsForm {
+    & > div {
+      width: 100%;
+    }
+  }
+}
+</style>

+ 116 - 0
src/components/Widgets/Other/Shop/ShopCompleteInfo/components/ShowEventTest.vue

@@ -0,0 +1,116 @@
+<template>
+  <div class="ShowEventTest"
+       :style="localOptions.style">
+    <q-card v-if="!localAnswerBook.loading && localAnswerBook.id">
+      <q-card-section class="flex justify-between">
+        <div>{{ localAnswerBook.test_info.title }}</div>
+      </q-card-section>
+      <q-separator />
+      <template v-if="mounted">
+        <all-questions :answer-book="localAnswerBook"
+                       @sentsuccess="onAllQuestionsSentSuccess"
+                       @sending="onAllQuestionsSending"
+                       @sentfailed="onAllQuestionsSentFailed" />
+      </template>
+    </q-card>
+    <div v-else>
+      کمی صبر کنید...
+    </div>
+  </div>
+</template>
+
+<script>
+import AllQuestions from './AllQuestions.vue'
+import { APIGateway } from 'src/api/APIGateway.js'
+import { AnswerBook } from 'src/models/AnswerBook.js'
+
+export default {
+  name: 'ShowEventTest',
+  components: { AllQuestions },
+  props: {
+    answerBook: {
+      type: AnswerBook,
+      default: new AnswerBook()
+    }
+  },
+  emits: ['sending', 'sentsuccess', 'sentfailed'],
+  data () {
+    return {
+      mounted: false,
+      participateType: null,
+      participateTypeDialog: false,
+      storeAnswerBook: null,
+      remainingTime: 0,
+      timerInterval: null
+    }
+  },
+  mounted () {
+    this.localAnswerBook = this.answerBook
+    this.getTestQuestions()
+    this.mounted = true
+  },
+  methods: {
+    onAllQuestionsSending () {
+      this.$emit('sending')
+      this.localAnswerBook.loading = true
+    },
+    onAllQuestionsSentSuccess () {
+      this.$emit('sentsuccess')
+      this.localAnswerBook.loading = false
+    },
+    onAllQuestionsSentFailed () {
+      this.$emit('sentfailed')
+      this.localAnswerBook.loading = false
+    },
+    backToClassList () {
+    },
+    getAnswerBook () {
+      this.localAnswerBook.loading = true
+      APIGateway.answerBook.get(this.$route.params.answer_book_id)
+        .then((answerBook) => {
+          this.localAnswerBook = new AnswerBook(answerBook)
+          if (this.localAnswerBook.test_info.test_set_questions_length === 0) {
+            this.$q.notify({
+              type: 'negative',
+              message: 'لیست سوالات پرسشنامه خالی است.'
+            })
+            this.backToClassList()
+          }
+          this.localAnswerBook.loading = false
+        })
+        .catch(() => {
+          this.localAnswerBook.loading = false
+          this.backToClassList()
+        })
+    },
+    initPageFromAnswerBook (answerBook, setRemainingTime = true) {
+      this.localAnswerBook = new AnswerBook(answerBook)
+      this.localAnswerBook.loading = false
+    },
+    getTestQuestions () {
+      this.localAnswerBook.loading = true
+      APIGateway.answerBook.getTestQuestions(this.$route.params.answer_book_id)
+        .then((answerBook) => {
+          this.initPageFromAnswerBook(answerBook)
+        })
+        .catch(() => {
+          this.localAnswerBook.loading = false
+          this.backToClassList()
+        })
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.ShowEventTest {
+  :deep(.q-banner) {
+    background: #FCF9F4 0 0 no-repeat padding-box;
+    padding: 20px;
+    .q-banner__content {
+      font-size: 16px;
+      font-weight: normal;
+    }
+  }
+}
+</style>