瀏覽代碼

fixed #90

ali 3 年之前
父節點
當前提交
b8b1fb8a7b

+ 1 - 0
src/api/models/Registration.js

@@ -22,6 +22,7 @@ export default class RegistrationAPI extends APIRepository {
       api: this.api,
       request: this.APIAdresses.base,
       data: this.getNormalizedSendData({
+        owner: null, // Number
         per_page: 10, // Number
         page: 1 // Number
       }, data),

+ 270 - 0
src/components/ClassroomItem.vue

@@ -0,0 +1,270 @@
+<template>
+  <q-card flat
+          class="classroom-item"
+          :class="{'isRegistered' : classroom.is_current_user_registered }">
+    <q-card-section class="thumbnail">
+      <router-link :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
+        <div class="RegisteredSign">
+          <svg class="ribbon"
+               xmlns="http://www.w3.org/2000/svg"
+               width="123.945"
+               height="123.422"
+               viewBox="0 0 123.945 123.422">
+            <g id="Group_11524"
+               data-name="Group 11524"
+               transform="translate(-361 -1111)">
+              <g id="Group_7903"
+                 data-name="Group 7903"
+                 transform="translate(361 1111)">
+                <g id="Group_7901"
+                   data-name="Group 7901"
+                   transform="translate(0 0)">
+                  <rect id="Rectangle_1771"
+                        data-name="Rectangle 1771"
+                        width="13.986"
+                        height="39.668"
+                        transform="translate(0 83.754)"
+                        fill="#cfb184" />
+                  <rect id="Rectangle_1772"
+                        data-name="Rectangle 1772"
+                        width="39.668"
+                        height="13.986"
+                        transform="translate(84.277 0)"
+                        fill="#cfb184" />
+                  <path id="Path_18668"
+                        data-name="Path 18668"
+                        d="M1938.931,282.651l123.945-123.406-.016-.016h-44a9.041,9.041,0,0,0-6.379,2.631l-70.907,70.6a8.962,8.962,0,0,0-2.642,6.352Z"
+                        transform="translate(-1938.931 -159.229)"
+                        fill="#eac38a" />
+                </g>
+              </g>
+              <text id="دوره_های_من"
+                    data-name="دوره‌های من"
+                    transform="translate(445.063 1135.174) rotate(-45)"
+                    fill="#fff"
+                    font-size="18"
+                    font-family="SegoeUI-Bold, Segoe UI"
+                    font-weight="700"><tspan x="0"
+                                             y="0">دوره‌های من</tspan></text>
+            </g>
+          </svg>
+        </div>
+        <q-img class="q-ma-xs"
+               :src="classroom.thumbnail" />
+      </router-link>
+    </q-card-section>
+    <q-card-section class="title">
+      <router-link :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
+        {{classroom.title}}
+      </router-link>
+    </q-card-section>
+    <q-card-section class="attribute">
+      <div class="attribute-item">
+        <div class="attribute-logo">
+          <svg id="Profile"
+               xmlns="http://www.w3.org/2000/svg"
+               width="17.058"
+               height="21.399"
+               viewBox="0 0 17.058 21.399">
+            <path id="Combined_Shape"
+                  data-name="Combined Shape"
+                  d="M0,17.418c0-3.55,4.868-3.96,8.53-3.96,2.109,0,8.528,0,8.528,3.982,0,3.548-4.867,3.959-8.528,3.959C6.42,21.4,0,21.4,0,17.418Zm1.616,0c0,1.57,2.326,2.366,6.914,2.366s6.913-.789,6.913-2.345-2.326-2.366-6.913-2.366S1.616,15.862,1.616,17.418ZM8.5,11.436A5.718,5.718,0,0,1,8.53,0a5.718,5.718,0,0,1,0,11.436ZM4.349,5.718A4.171,4.171,0,0,0,8.5,9.9l.031.77V9.9a4.18,4.18,0,1,0-4.181-4.18Z"
+                  transform="translate(0 0)"
+                  fill="#aaa095" />
+          </svg>
+        </div>
+        <div class="attribute-value">
+          {{classroom.professor_info.firstname}}
+          {{classroom.professor_info.lastname}}
+        </div>
+      </div>
+      <div class="attribute-item">
+        <div class="attribute-logo">
+          <q-icon name="cast_for_education"
+                  size="20px"
+                  color="grey" />
+        </div>
+        <div class="attribute-value">
+          {{ getHoldingType(classroom) }}
+        </div>
+      </div>
+      <div class="attribute-item">
+        <div class="attribute-logo">
+          <svg id="Group_11306"
+               data-name="Group 11306"
+               xmlns="http://www.w3.org/2000/svg"
+               width="21.539"
+               height="21.044"
+               viewBox="0 0 21.539 21.044">
+            <g id="Buy"
+               transform="translate(0 0)">
+              <path id="Combined_Shape"
+                    data-name="Combined Shape"
+                    d="M16.3,19.649A1.395,1.395,0,1,1,17.7,21.044,1.4,1.4,0,0,1,16.3,19.649Zm-12.147,0a1.394,1.394,0,1,1,1.394,1.395A1.4,1.4,0,0,1,4.157,19.649ZM17.77,16.139H6.014A2.76,2.76,0,0,1,3.28,13.615L2.294,1.883.671,1.6A.812.812,0,0,1,.012.668.811.811,0,0,1,.815,0a.829.829,0,0,1,.13.011L3.186.4a.808.808,0,0,1,.666.729L4.1,4.143c15.367.007,15.424.014,15.5.022a2.254,2.254,0,0,1,1.912,2.553l-1.023,7.062a2.76,2.76,0,0,1-2.717,2.358ZM4.89,13.483a1.123,1.123,0,0,0,1.127,1.04H17.771a1.139,1.139,0,0,0,1.122-.972l1.024-7.064a.632.632,0,0,0-.121-.472.625.625,0,0,0-.418-.249c-.052,0-.6,0-1.677,0-1.693,0-4.455,0-7.291,0l-6.17,0ZM13.059,9.74a.808.808,0,0,1,0-1.616h2.985a.808.808,0,0,1,0,1.616Z"
+                    transform="translate(0)"
+                    fill="#aaa095" />
+            </g>
+          </svg>
+        </div>
+        <div class="attribute-value">
+          {{classroom.price}}
+          ریال
+        </div>
+      </div>
+    </q-card-section>
+    <q-card-actions class="action-section">
+      <q-btn color="primary"
+             class="btn-show-classroom"
+             :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
+        مشاهده و ثبت نام
+        <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>
+    </q-card-actions>
+  </q-card>
+</template>
+
+<script>
+import { defineComponent } from 'vue'
+import { Classroom } from 'src/models/Classroom.js'
+
+export default defineComponent({
+  name: 'OptionPanel',
+  props: {
+    classroom: {
+      type: Classroom,
+      default: new Classroom()
+    }
+  },
+  data() {
+    return {
+      size: 'xs',
+      sizeOptions: ['xs', 'sm', 'md', 'lg', 'xl'],
+      actionTypes: ['event', 'scroll', 'link'],
+      defaultOptions: {
+        imageSource: null,
+        ratio: null,
+        hasAction: false,
+        useAEEEvent: false,
+        AEEEventBody: {
+          id: '-',
+          name: '-',
+          creative: null,
+          position: null
+        },
+        action: {
+          name: null,
+          route: null,
+          scrollTo: null,
+          eventName: null,
+          eventArgs: null
+        },
+        xs: {
+          height: null,
+          width: null,
+          src: null
+        },
+        sm: {
+          height: null,
+          width: null,
+          src: null
+        },
+        md: {
+          height: null,
+          width: null,
+          src: null
+        },
+        lg: {
+          height: null,
+          width: null,
+          src: null
+        },
+        xl: {
+          height: null,
+          width: null,
+          src: null
+        }
+      }
+    }
+  },
+  methods: {
+    getHoldingType (classroom) {
+      return new Classroom(classroom).holding_type_info.label
+    }
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.classroom-item {
+  width: 100%;
+  background-color: #F6F6F6;
+  border-radius: 8px;
+  &.isRegistered {
+    .thumbnail {
+      position: relative;
+      z-index: 1;
+      .RegisteredSign {
+        position: absolute;
+        right: 5px;
+        top: 7px;
+        z-index: 2;
+        display: block;
+      }
+    }
+  }
+  .thumbnail {
+    padding-top: 17px;
+    padding-left: 22px;
+    padding-right: 22px;
+    padding-bottom: 26px;
+    .RegisteredSign {
+      display: none;
+    }
+    :deep(img) {
+      border-radius: 10px;
+    }
+  }
+  .title {
+    text-align: left;
+    padding-top: 0;
+    padding-left: 46px;
+    padding-right: 46px;
+    padding-bottom: 33px;
+  }
+  .attribute {
+    padding-top: 0;
+    padding-left: 46px;
+    padding-right: 46px;
+    padding-bottom: 44px;
+    .attribute-item {
+      margin-bottom: 21px;
+      display: flex;
+      flex-flow: row;
+      .attribute-logo {
+        margin-right: 15px;
+      }
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+  }
+  .action-section {
+    padding: 0;
+    .btn-show-classroom {
+      width: 100%;
+      height: 60px;
+      border-top-right-radius: 0;
+      border-top-left-radius: 0;
+    }
+  }
+}
+</style>

+ 4 - 200
src/components/Widgets/Other/AllClassrooms/AllClassrooms.vue

@@ -68,138 +68,7 @@
       <div v-for="classroom in classrooms.list"
            :key="classroom.id"
            class="classroom-col col-md-4">
-        <q-card flat
-                class="classroom-item"
-                :class="{'isRegistered' : classroom.is_current_user_registered }">
-          <!--          isClassroomRegistered(classroom.id)-->
-          <q-card-section class="thumbnail">
-            <router-link :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
-              <div class="RegisteredSign">
-                <svg class="ribbon"
-                     xmlns="http://www.w3.org/2000/svg"
-                     width="123.945"
-                     height="123.422"
-                     viewBox="0 0 123.945 123.422">
-                  <g id="Group_11524"
-                     data-name="Group 11524"
-                     transform="translate(-361 -1111)">
-                    <g id="Group_7903"
-                       data-name="Group 7903"
-                       transform="translate(361 1111)">
-                      <g id="Group_7901"
-                         data-name="Group 7901"
-                         transform="translate(0 0)">
-                        <rect id="Rectangle_1771"
-                              data-name="Rectangle 1771"
-                              width="13.986"
-                              height="39.668"
-                              transform="translate(0 83.754)"
-                              fill="#cfb184" />
-                        <rect id="Rectangle_1772"
-                              data-name="Rectangle 1772"
-                              width="39.668"
-                              height="13.986"
-                              transform="translate(84.277 0)"
-                              fill="#cfb184" />
-                        <path id="Path_18668"
-                              data-name="Path 18668"
-                              d="M1938.931,282.651l123.945-123.406-.016-.016h-44a9.041,9.041,0,0,0-6.379,2.631l-70.907,70.6a8.962,8.962,0,0,0-2.642,6.352Z"
-                              transform="translate(-1938.931 -159.229)"
-                              fill="#eac38a" />
-                      </g>
-                    </g>
-                    <text id="دوره_های_من"
-                          data-name="دوره‌های من"
-                          transform="translate(445.063 1135.174) rotate(-45)"
-                          fill="#fff"
-                          font-size="18"
-                          font-family="SegoeUI-Bold, Segoe UI"
-                          font-weight="700"><tspan x="0"
-                                                   y="0">دوره‌های من</tspan></text>
-                  </g>
-                </svg>
-              </div>
-              <q-img class="q-ma-xs"
-                     :src="classroom.thumbnail" />
-            </router-link>
-          </q-card-section>
-          <q-card-section class="title">
-            <router-link :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
-              {{classroom.title}}
-            </router-link>
-          </q-card-section>
-          <q-card-section class="attribute">
-            <div class="attribute-item">
-              <div class="attribute-logo">
-                <svg id="Profile"
-                     xmlns="http://www.w3.org/2000/svg"
-                     width="17.058"
-                     height="21.399"
-                     viewBox="0 0 17.058 21.399">
-                  <path id="Combined_Shape"
-                        data-name="Combined Shape"
-                        d="M0,17.418c0-3.55,4.868-3.96,8.53-3.96,2.109,0,8.528,0,8.528,3.982,0,3.548-4.867,3.959-8.528,3.959C6.42,21.4,0,21.4,0,17.418Zm1.616,0c0,1.57,2.326,2.366,6.914,2.366s6.913-.789,6.913-2.345-2.326-2.366-6.913-2.366S1.616,15.862,1.616,17.418ZM8.5,11.436A5.718,5.718,0,0,1,8.53,0a5.718,5.718,0,0,1,0,11.436ZM4.349,5.718A4.171,4.171,0,0,0,8.5,9.9l.031.77V9.9a4.18,4.18,0,1,0-4.181-4.18Z"
-                        transform="translate(0 0)"
-                        fill="#aaa095" />
-                </svg>
-              </div>
-              <div class="attribute-value">
-                {{classroom.professor_info.firstname}}
-                {{classroom.professor_info.lastname}}
-              </div>
-            </div>
-            <div class="attribute-item">
-              <div class="attribute-logo">
-                <q-icon name="cast_for_education"
-                        size="20px"
-                        color="grey" />
-              </div>
-              <div class="attribute-value">
-                {{ getHoldingType(classroom) }}
-              </div>
-            </div>
-            <div class="attribute-item">
-              <div class="attribute-logo">
-                <svg id="Group_11306"
-                     data-name="Group 11306"
-                     xmlns="http://www.w3.org/2000/svg"
-                     width="21.539"
-                     height="21.044"
-                     viewBox="0 0 21.539 21.044">
-                  <g id="Buy"
-                     transform="translate(0 0)">
-                    <path id="Combined_Shape"
-                          data-name="Combined Shape"
-                          d="M16.3,19.649A1.395,1.395,0,1,1,17.7,21.044,1.4,1.4,0,0,1,16.3,19.649Zm-12.147,0a1.394,1.394,0,1,1,1.394,1.395A1.4,1.4,0,0,1,4.157,19.649ZM17.77,16.139H6.014A2.76,2.76,0,0,1,3.28,13.615L2.294,1.883.671,1.6A.812.812,0,0,1,.012.668.811.811,0,0,1,.815,0a.829.829,0,0,1,.13.011L3.186.4a.808.808,0,0,1,.666.729L4.1,4.143c15.367.007,15.424.014,15.5.022a2.254,2.254,0,0,1,1.912,2.553l-1.023,7.062a2.76,2.76,0,0,1-2.717,2.358ZM4.89,13.483a1.123,1.123,0,0,0,1.127,1.04H17.771a1.139,1.139,0,0,0,1.122-.972l1.024-7.064a.632.632,0,0,0-.121-.472.625.625,0,0,0-.418-.249c-.052,0-.6,0-1.677,0-1.693,0-4.455,0-7.291,0l-6.17,0ZM13.059,9.74a.808.808,0,0,1,0-1.616h2.985a.808.808,0,0,1,0,1.616Z"
-                          transform="translate(0)"
-                          fill="#aaa095" />
-                  </g>
-                </svg>
-              </div>
-              <div class="attribute-value">
-                {{classroom.price}}
-                ریال
-              </div>
-            </div>
-          </q-card-section>
-          <q-card-actions class="action-section">
-            <q-btn color="primary"
-                   class="btn-show-classroom"
-                   :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
-              مشاهده و ثبت نام
-              <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>
-          </q-card-actions>
-        </q-card>
+        <classroom-item :classroom="classroom" />
       </div>
     </div>
     <div v-else-if="!classrooms.loading && classrooms.list.length === 0">
@@ -304,14 +173,15 @@ import Enums from 'src/assets/Enums/Enums.js'
 import API_ADDRESS from 'src/api/Addresses.js'
 import ShamsiDate from 'src/assets/ShamsiDate.js'
 import { APIGateway } from 'src/api/APIGateway.js'
+import { ClassroomList } from 'src/models/Classroom.js'
+import ClassroomItem from 'src/components/ClassroomItem.vue'
 import SelectControl from 'src/components/Control/Select.vue'
 import { UnitCategoryList } from 'src/models/UnitCategory.js'
-import { Classroom, ClassroomList } from 'src/models/Classroom.js'
 import { ClassroomRegistrationList } from 'src/models/ClassroomRegistration.js'
 
 export default {
   name: 'AllClassrooms',
-  components: { SelectControl },
+  components: { SelectControl, ClassroomItem },
   data: () => ({
     loading: false,
     user: new User(),
@@ -414,9 +284,6 @@ export default {
       }
       return ShamsiDate.getTerm(classroom.beginning_registration_period)
     },
-    getHoldingType (classroom) {
-      return new Classroom(classroom).holding_type_info.label
-    },
     getProfessors () {
       this.$axios.get(API_ADDRESS.user.base + '?per_page=9999&role=professor')
         .then(response => {
@@ -548,69 +415,6 @@ export default {
       }
     }
   }
-  .classroom-item {
-    width: 100%;
-    background-color: #F6F6F6;
-    border-radius: 8px;
-    &.isRegistered {
-      .thumbnail {
-        position: relative;
-        z-index: 1;
-        .RegisteredSign {
-          position: absolute;
-          right: 5px;
-          top: 7px;
-          z-index: 2;
-          display: block;
-        }
-      }
-    }
-    .thumbnail {
-      padding-top: 17px;
-      padding-left: 22px;
-      padding-right: 22px;
-      padding-bottom: 26px;
-      .RegisteredSign {
-        display: none;
-      }
-      :deep(img) {
-        border-radius: 10px;
-      }
-    }
-    .title {
-      text-align: left;
-      padding-top: 0;
-      padding-left: 46px;
-      padding-right: 46px;
-      padding-bottom: 33px;
-    }
-    .attribute {
-      padding-top: 0;
-      padding-left: 46px;
-      padding-right: 46px;
-      padding-bottom: 44px;
-      .attribute-item {
-        margin-bottom: 21px;
-        display: flex;
-        flex-flow: row;
-        .attribute-logo {
-          margin-right: 15px;
-        }
-        &:last-child {
-          margin-bottom: 0;
-        }
-      }
-    }
-    .action-section {
-      padding: 0;
-      .btn-show-classroom {
-        width: 100%;
-        height: 60px;
-        border-top-right-radius: 0;
-        border-top-left-radius: 0;
-      }
-    }
-  }
 }
 </style>
 

+ 4 - 133
src/components/Widgets/Other/ClassroomCarousel/ClassroomCarousel.vue

@@ -30,138 +30,7 @@
                 dir="rtl">
         <slide v-for="classroom in classrooms.list"
                :key="classroom.id + classroomsKey">
-          <q-card flat
-                  class="classroomCarousel-item"
-                  :class="{'isRegistered' : classroom.is_current_user_registered }">
-            <!--          isClassroomRegistered(classroom.id)-->
-            <q-card-section class="thumbnail">
-              <router-link :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
-                <div class="RegisteredSign">
-                  <svg class="ribbon"
-                       xmlns="http://www.w3.org/2000/svg"
-                       width="123.945"
-                       height="123.422"
-                       viewBox="0 0 123.945 123.422">
-                    <g id="Group_11524"
-                       data-name="Group 11524"
-                       transform="translate(-361 -1111)">
-                      <g id="Group_7903"
-                         data-name="Group 7903"
-                         transform="translate(361 1111)">
-                        <g id="Group_7901"
-                           data-name="Group 7901"
-                           transform="translate(0 0)">
-                          <rect id="Rectangle_1771"
-                                data-name="Rectangle 1771"
-                                width="13.986"
-                                height="39.668"
-                                transform="translate(0 83.754)"
-                                fill="#cfb184" />
-                          <rect id="Rectangle_1772"
-                                data-name="Rectangle 1772"
-                                width="39.668"
-                                height="13.986"
-                                transform="translate(84.277 0)"
-                                fill="#cfb184" />
-                          <path id="Path_18668"
-                                data-name="Path 18668"
-                                d="M1938.931,282.651l123.945-123.406-.016-.016h-44a9.041,9.041,0,0,0-6.379,2.631l-70.907,70.6a8.962,8.962,0,0,0-2.642,6.352Z"
-                                transform="translate(-1938.931 -159.229)"
-                                fill="#eac38a" />
-                        </g>
-                      </g>
-                      <text id="دوره_های_من"
-                            data-name="دوره‌های من"
-                            transform="translate(445.063 1135.174) rotate(-45)"
-                            fill="#fff"
-                            font-size="18"
-                            font-family="SegoeUI-Bold, Segoe UI"
-                            font-weight="700"><tspan x="0"
-                                                     y="0">دوره‌های من</tspan></text>
-                    </g>
-                  </svg>
-                </div>
-                <q-img class="q-ma-xs"
-                       :src="classroom.thumbnail" />
-              </router-link>
-            </q-card-section>
-            <q-card-section class="title">
-              <router-link :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
-                {{classroom.title}}
-              </router-link>
-            </q-card-section>
-            <q-card-section class="attribute">
-              <div class="attribute-item">
-                <div class="attribute-logo">
-                  <svg id="Profile"
-                       xmlns="http://www.w3.org/2000/svg"
-                       width="17.058"
-                       height="21.399"
-                       viewBox="0 0 17.058 21.399">
-                    <path id="Combined_Shape"
-                          data-name="Combined Shape"
-                          d="M0,17.418c0-3.55,4.868-3.96,8.53-3.96,2.109,0,8.528,0,8.528,3.982,0,3.548-4.867,3.959-8.528,3.959C6.42,21.4,0,21.4,0,17.418Zm1.616,0c0,1.57,2.326,2.366,6.914,2.366s6.913-.789,6.913-2.345-2.326-2.366-6.913-2.366S1.616,15.862,1.616,17.418ZM8.5,11.436A5.718,5.718,0,0,1,8.53,0a5.718,5.718,0,0,1,0,11.436ZM4.349,5.718A4.171,4.171,0,0,0,8.5,9.9l.031.77V9.9a4.18,4.18,0,1,0-4.181-4.18Z"
-                          transform="translate(0 0)"
-                          fill="#aaa095" />
-                  </svg>
-                </div>
-                <div class="attribute-value">
-                  {{classroom.professor_info.firstname}}
-                  {{classroom.professor_info.lastname}}
-                </div>
-              </div>
-              <div class="attribute-item">
-                <div class="attribute-logo">
-                  <q-icon name="cast_for_education"
-                          size="20px"
-                          color="grey" />
-                </div>
-                <div class="attribute-value">
-                  {{ getHoldingType(classroom) }}
-                </div>
-              </div>
-              <div class="attribute-item">
-                <div class="attribute-logo">
-                  <svg id="Group_11306"
-                       data-name="Group 11306"
-                       xmlns="http://www.w3.org/2000/svg"
-                       width="21.539"
-                       height="21.044"
-                       viewBox="0 0 21.539 21.044">
-                    <g id="Buy"
-                       transform="translate(0 0)">
-                      <path id="Combined_Shape"
-                            data-name="Combined Shape"
-                            d="M16.3,19.649A1.395,1.395,0,1,1,17.7,21.044,1.4,1.4,0,0,1,16.3,19.649Zm-12.147,0a1.394,1.394,0,1,1,1.394,1.395A1.4,1.4,0,0,1,4.157,19.649ZM17.77,16.139H6.014A2.76,2.76,0,0,1,3.28,13.615L2.294,1.883.671,1.6A.812.812,0,0,1,.012.668.811.811,0,0,1,.815,0a.829.829,0,0,1,.13.011L3.186.4a.808.808,0,0,1,.666.729L4.1,4.143c15.367.007,15.424.014,15.5.022a2.254,2.254,0,0,1,1.912,2.553l-1.023,7.062a2.76,2.76,0,0,1-2.717,2.358ZM4.89,13.483a1.123,1.123,0,0,0,1.127,1.04H17.771a1.139,1.139,0,0,0,1.122-.972l1.024-7.064a.632.632,0,0,0-.121-.472.625.625,0,0,0-.418-.249c-.052,0-.6,0-1.677,0-1.693,0-4.455,0-7.291,0l-6.17,0ZM13.059,9.74a.808.808,0,0,1,0-1.616h2.985a.808.808,0,0,1,0,1.616Z"
-                            transform="translate(0)"
-                            fill="#aaa095" />
-                    </g>
-                  </svg>
-                </div>
-                <div class="attribute-value">
-                  {{classroom.price}}
-                  ریال
-                </div>
-              </div>
-            </q-card-section>
-            <q-card-actions class="action-section">
-              <q-btn color="primary"
-                     class="btn-show-classroom"
-                     :to="{name: 'Public.ShowClassroomInfo', params: {id: classroom.id}}">
-                جزییات دوره
-                <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>
-            </q-card-actions>
-          </q-card>
+          <classroom-item :classroom="classroom" />
         </slide>
 
         <template #addons="{ slidesCount }">
@@ -184,6 +53,7 @@ import 'vue3-carousel/dist/carousel.css'
 import { User } from 'src/models/User.js'
 import ShamsiDate from 'src/assets/ShamsiDate.js'
 import { APIGateway } from 'src/api/APIGateway.js'
+import ClassroomItem from 'src/components/ClassroomItem.vue'
 import { mixinPrefetchServerData } from 'src/mixin/Mixins.js'
 import { Classroom, ClassroomList } from 'src/models/Classroom.js'
 import { ClassroomRegistrationList } from 'src/models/ClassroomRegistration.js'
@@ -195,7 +65,8 @@ export default {
     Carousel,
     Slide,
     Pagination,
-    Navigation
+    Navigation,
+    ClassroomItem
   },
   mixins: [mixinPrefetchServerData],
   data: () => ({

+ 21 - 0
src/components/Widgets/Registration/RegistrationList/OptionPanel.vue

@@ -0,0 +1,21 @@
+<template>
+  <option-panel-tabs v-model:options="localOptions">
+    <template #main-tab>
+      ...
+    </template>
+  </option-panel-tabs>
+</template>
+
+<script>
+import { defineComponent } from 'vue'
+import { mixinOptionPanel } from 'quasar-ui-q-page-builder'
+import OptionPanelTabs from 'quasar-ui-q-page-builder/src/components/OptionPanelComponents/OptionPanelTabs.vue'
+
+export default defineComponent({
+  name: 'OptionPanel',
+  components: {
+    OptionPanelTabs
+  },
+  mixins: [mixinOptionPanel]
+})
+</script>

+ 81 - 0
src/components/Widgets/Registration/RegistrationList/RegistrationList.vue

@@ -0,0 +1,81 @@
+<template>
+  <div class="RegistrationList"
+       :style="localOptions.style">
+    <template v-if="isUserLogin">
+      <q-banner class="q-mb-md">
+        دوره های شما
+      </q-banner>
+      <q-linear-progress v-if="registrations.loading"
+                         indeterminate />
+      <template v-else>
+        <div class="row q-col-gutter-md">
+          <div v-for="registration in registrations.list"
+               :key="registration.id"
+               class="col-md-4">
+            <classroom-item :classroom="registration.classroom_info" />
+          </div>
+        </div>
+      </template>
+    </template>
+  </div>
+</template>
+
+<script>
+import { APIGateway } from 'src/api/APIGateway.js'
+import { mixinWidget, mixinAuth } from 'src/mixin/Mixins.js'
+import ClassroomItem from 'src/components/ClassroomItem.vue'
+import { RegistrationList } from 'src/models/Registration.js'
+
+export default {
+  name: 'RegistrationList',
+  components: { ClassroomItem },
+  mixins: [mixinWidget, mixinAuth],
+  data: () => {
+    return {
+      registrations: new RegistrationList()
+    }
+  },
+  mounted() {
+    this.getRegistrations()
+  },
+  methods: {
+    getRegistrations () {
+      this.registrations.loading = true
+      APIGateway.registration.index({ per_page: 9999, owner: this.user.id })
+        .then((registrations) => {
+          this.registrations = new RegistrationList(registrations.list)
+          this.registrations.loading = false
+        })
+        .catch(() => {
+          this.registrations.loading = false
+        })
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.RegistrationList {
+  .title {
+    font-style: normal;
+    font-weight: 700;
+    font-size: 24px;
+    line-height: 140%;
+    color: #424242;
+    margin-bottom: 27px;
+  }
+  :deep(.list) {
+    .quasar-crud-index-table {
+      padding: 0;
+      .q-table__container {
+        background-color: transparent;
+        box-shadow: none;
+        border: none;
+        .q-table__top {
+          display: none;
+        }
+      }
+    }
+  }
+}
+</style>

+ 21 - 0
src/components/Widgets/Registration/RegistrationShow/OptionPanel.vue

@@ -0,0 +1,21 @@
+<template>
+  <option-panel-tabs v-model:options="localOptions">
+    <template #main-tab>
+      ...
+    </template>
+  </option-panel-tabs>
+</template>
+
+<script>
+import { defineComponent } from 'vue'
+import { mixinOptionPanel } from 'quasar-ui-q-page-builder'
+import OptionPanelTabs from 'quasar-ui-q-page-builder/src/components/OptionPanelComponents/OptionPanelTabs.vue'
+
+export default defineComponent({
+  name: 'OptionPanel',
+  components: {
+    OptionPanelTabs
+  },
+  mixins: [mixinOptionPanel]
+})
+</script>

+ 273 - 0
src/components/Widgets/Registration/RegistrationShow/RegistrationShow.vue

@@ -0,0 +1,273 @@
+<template>
+  <div class="RegistrationShow"
+       :style="localOptions.style">
+    <div class="title q-pb-lg">
+      <div class="static-title" />
+      <div class="dynamic-title" />
+      <div v-if="localOptions.showBackBtn"
+           class="back-action">
+        <q-btn flat
+               :to="{name: 'UserPanel.Invoice.List'}"
+               color="grey">
+          بازگشت
+          >
+        </q-btn>
+      </div>
+    </div>
+    <q-card v-if="invoice.item_info"
+            class="q-mt-lg">
+      <q-linear-progress v-if="invoice.loading"
+                         indeterminate />
+      <q-card-section>
+        صورتحساب شناسه
+        {{ invoice.id }}
+        <q-btn v-if="!invoice.loading && invoice.status === 'PAYING' && localOptions.showNeedInstallmentBtn"
+               outline
+               color="primary"
+               class="btn-need-installment"
+               :to="{name: 'UserPanel.Invoice.Ticket.Create', query: {source_type: 'INVOICE', source_id: invoice.id}}">
+          درخواست مساعدت
+        </q-btn>
+      </q-card-section>
+      <q-separator />
+      <q-card-section>
+        <div class="row">
+          <div class="col-md-3 col-12">
+            <q-banner>
+              <q-icon name="isax:stickynote" />
+              {{ getDateTime(invoice.creation_time) }}
+            </q-banner>
+          </div>
+          <div class="col-md-3 col-12">
+            <q-banner>
+              {{ (invoice.amount ? invoice.amount.toLocaleString('fa') : 0) }}
+              ریال
+            </q-banner>
+          </div>
+          <div class="col-md-3 col-12">
+            <q-banner>
+              شماره پیگیری
+              {{ invoice.id }}
+            </q-banner>
+          </div>
+          <div class="col-md-3 col-12">
+            <q-banner>
+              وضعیت:
+              {{ invoice.status_info.label }}
+            </q-banner>
+          </div>
+        </div>
+      </q-card-section>
+      <q-separator />
+      <q-card-section>
+        <div class="row q-col-gutter-lg">
+          <div class="col-md-4 col-12 flex items-center justify-start">
+            <q-img :src="invoice.item_info.thumbnail"
+                   width="100px" />
+            {{ invoice.item_info.title }}
+          </div>
+          <div class="col-md-4 col-12 flex items-center justify-start">
+            <q-icon name="isax:user" />
+            استاد:
+            {{ invoice.item_info.professor_info.firstname }}
+            {{ invoice.item_info.professor_info.lastname }}
+          </div>
+          <div class="col-md-4 col-12 flex items-center justify-start">
+            <q-icon name="isax:card" />
+            قیمت:
+            {{ invoice.item_info?.price ? invoice.item_info.price.toLocaleString('fa') : 0 }}
+            ریال
+          </div>
+        </div>
+      </q-card-section>
+    </q-card>
+    <div class="action q-mt-lg">
+      <q-card v-if="!invoice.loading && invoice.status!=='PAYING' && invoice.status!=='PAID_FULL' && invoice.status!=='PAID_IN_INSTALMENT'"
+              class="q-mb-md">
+        <q-card-section>
+          تنها در صورتی که وضعیت سفارش در حال پرداخت باشد امکان پرداخت با کیف پول وجود دارد
+        </q-card-section>
+      </q-card>
+      <q-card v-if="!invoice.loading && (invoice.status==='PAYING' || invoice.status==='PAYING_IN_INSTALMENT')">
+        <q-card-section>
+          پرداخت
+        </q-card-section>
+        <q-separator />
+        <q-card-section>
+          <invoice-payment-card :wallet="wallet"
+                                :invoice="invoice"
+                                class="payment-card"
+                                @onCancel="onCancel"
+                                @onAccept="onAccept"
+                                @onInstalmentPayed="onInstalmentPayed" />
+        </q-card-section>
+      </q-card>
+
+    </div>
+  </div>
+</template>
+
+<script>
+import Assist from 'assets/js/Assist.js'
+import { User } from 'src/models/User.js'
+import { Wallet } from 'src/models/Wallet.js'
+import { Invoice } from 'src/models/Invoice.js'
+import { mixinWidget } from 'src/mixin/Mixins.js'
+import { APIGateway } from 'src/api/APIGateway.js'
+import InvoicePaymentCard from 'src/components/InvoicePaymentCard/InvoicePaymentCard.vue'
+
+export default {
+  name: 'RegistrationShow',
+  components: { InvoicePaymentCard },
+  mixins: [mixinWidget],
+  props: {
+    invoiceId: {
+      type: Number,
+      default: null
+    }
+  },
+  data: () => {
+    return {
+      user: new User(),
+      wallet: new Wallet(),
+      invoice: new Invoice(),
+      defaultOptions: {
+        showBackBtn: true,
+        showNeedInstallmentBtn: true
+      }
+    }
+  },
+  mounted() {
+    this.loadAuthData()
+    this.getMyWallet()
+    this.getInvoice()
+  },
+  methods: {
+    loadAuthData() { // prevent Hydration node mismatch
+      this.user = this.$store.getters['Auth/user']
+    },
+    getDateTime (dateTime) {
+      return Assist.miladiToShamsi(dateTime)
+    },
+    onCancel () {
+      this.invoice.loading = true
+      APIGateway.invoice.cancel(this.invoice.id)
+        .then((message) => {
+          this.invoice.loading = false
+          this.getInvoice()
+          this.$q.notify({
+            message,
+            type: 'positive'
+          })
+        })
+        .catch(() => {
+          this.invoice.loading = false
+        })
+    },
+    onAccept () {
+      this.payInvoice()
+    },
+    onInstalmentPayed () {
+      this.getMyWallet()
+      this.getInvoice()
+    },
+    getMyWallet () {
+      this.wallet.loading = true
+      APIGateway.wallet.getMyWallet(this.user.id)
+        .then((wallet) => {
+          this.wallet = new Wallet(wallet)
+          this.wallet.loading = false
+          this.walletLoaded = true
+        })
+        .catch(() => {
+          this.wallet.loading = false
+        })
+    },
+    amountOfDepositWalletNeeded () {
+      return this.invoice.amount - this.wallet.inventory
+    },
+    payInvoice () {
+      if (this.amountOfDepositWalletNeeded() > 0) {
+        this.payInvoiceByDepositWallet()
+      } else {
+        this.payInvoiceByWallet()
+      }
+    },
+    payInvoiceByWallet () {
+      this.invoice.loading = true
+      APIGateway.invoice.pay(this.invoice.id)
+        .then((message) => {
+          this.invoice.loading = false
+          this.getInvoice()
+          this.$q.notify({
+            message,
+            type: 'positive'
+          })
+        })
+        .catch(() => {
+          this.invoice.loading = false
+        })
+    },
+    payInvoiceByDepositWallet () {
+      this.invoice.loading = true
+      APIGateway.wallet.deposit({
+        amount: this.amountOfDepositWalletNeeded(),
+        invoice: this.invoice.id
+      })
+        .then((url) => {
+          window.location.href = url
+        })
+        .catch(() => {
+          this.depositLoading = false
+        })
+    },
+    getInvoiceId () {
+      return this.localOptions.invoiceId || this.$route.params.id
+    },
+    getInvoice () {
+      this.invoice.loading = true
+      const invoiceId = this.getInvoiceId()
+      APIGateway.invoice.get({ data: { id: invoiceId } })
+        .then((invoice) => {
+          this.invoice = new Invoice(invoice)
+          this.invoice.loading = false
+        })
+        .catch(() => {
+          this.invoice.loading = false
+        })
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.RegistrationShow {
+  .title {
+    font-style: normal;
+    font-weight: 700;
+    font-size: 24px;
+    line-height: 140%;
+    color: #424242;
+    margin-bottom: 27px;
+    display: flex;
+    flex-flow: row;
+    position: relative;
+    .static-title {
+
+    }
+    .dynamic-title {
+
+    }
+    .back-action {
+      position: absolute;
+      right: 0;
+      top: 0;
+    }
+  }
+  .btn-need-installment {
+    position: absolute;
+    right: 18px;
+    top: 8px;
+  }
+}
+</style>

+ 2 - 0
src/models/Registration.js

@@ -8,6 +8,8 @@ class Registration extends Model {
     super(data, [
       { key: 'id' },
       { key: 'product_info' },
+      { key: 'classroom' },
+      { key: 'classroom_info' },
       { key: 'item' },
       { key: 'item_info' },
       { key: 'basket' },

+ 6 - 22
src/pages/Public/classrooms.vue

@@ -6,36 +6,20 @@
 </template>
 
 <script>
+// import { mixinSEO, mixinPageOptions, mixinPrefetchServerData } from 'src/mixin/Mixins.js'
 export default {
   name: 'Public.AllClassrooms',
+  // mixins: [mixinPrefetchServerData, mixinPageOptions, mixinSEO],
   data () {
     return {
       pageConfig: {},
       pageBuilderEditable: false,
       pageBuilderLoading: false,
-      currenSections: [
-        {
-          data: {
-            rows: [
-              {
-                cols: [
-                  {
-                    widgets: [
-                      {
-                        name: 'AllClassrooms'
-                      }
-                    ]
-                  }
-                ],
-                options: {
-                  boxed: true
-                }
-              }
-            ]
-          }
-        }
-      ]
+      currenSections: [{ data: { rows: [{ cols: [{ widgets: [{ name: 'AllClassrooms', options: { imageSource: null, ratio: null, hasAction: false, useAEEEvent: false, AEEEventBody: { id: '-', name: '-', creative: null, position: null }, action: { name: null, route: null, scrollTo: null, eventName: null, eventArgs: null }, xs: { height: null, width: null, src: null }, sm: { height: null, width: null, src: null }, md: { height: null, width: null, src: null }, lg: { height: null, width: null, src: null }, xl: { height: null, width: null, src: null }, style: { marginBottom: '32px' } } }, { name: 'RegistrationList', options: { style: { marginBottom: '32px' } } }] }], options: { boxed: true } }] } }]
     }
   }
+  // mounted() {
+  //   this.currenSections = this.sections
+  // }
 }
 </script>