Przeglądaj źródła

admin panel fix

ali 3 lat temu
rodzic
commit
a9bf4d82c7
45 zmienionych plików z 729 dodań i 432 usunięć
  1. 1 5
      index.html
  2. BIN
      public/favicon.ico
  3. BIN
      public/icons/apple-icon-120x120.png
  4. BIN
      public/icons/apple-icon-152x152.png
  5. BIN
      public/icons/apple-icon-167x167.png
  6. BIN
      public/icons/apple-icon-180x180.png
  7. BIN
      public/icons/favicon-128x128.png
  8. BIN
      public/icons/favicon-16x16.png
  9. BIN
      public/icons/favicon-32x32.png
  10. BIN
      public/icons/favicon-96x96.png
  11. BIN
      public/icons/icon-128x128.png
  12. BIN
      public/icons/icon-144x144.png
  13. BIN
      public/icons/icon-152x152.png
  14. BIN
      public/icons/icon-192x192.png
  15. BIN
      public/icons/icon-384x384.png
  16. BIN
      public/icons/icon-48x48.png
  17. BIN
      public/icons/icon-512x512.png
  18. BIN
      public/icons/icon-72x72.png
  19. BIN
      public/icons/icon-96x96.png
  20. BIN
      public/icons/logo.png
  21. BIN
      public/icons/ms-icon-144x144.png
  22. BIN
      public/img/QuestionBank/toolbar-back-ground.png
  23. BIN
      public/img/mapMarker.png
  24. 4 46
      quasar.config.js
  25. 4 0
      src/api/APIGateway.js
  26. 68 0
      src/api/models/Session.js
  27. 68 0
      src/api/models/SessionTemplate.js
  28. 20 0
      src/api/models/Unit.js
  29. 35 1
      src/api/models/User.js
  30. 51 48
      src/components/Control/PostRequisites.vue
  31. 7 1
      src/components/Control/btn.vue
  32. 4 4
      src/css/Theme/Widgets/widgets.scss
  33. 32 0
      src/models/SessionTemplate.js
  34. 1 0
      src/models/UnitCategory.js
  35. 8 4
      src/models/User.js
  36. 46 35
      src/pages/Admin/Category/create.vue
  37. 44 31
      src/pages/Admin/Category/index.vue
  38. 76 64
      src/pages/Admin/Category/show.vue
  39. 48 34
      src/pages/Admin/Classroom/create.vue
  40. 60 46
      src/pages/Admin/Classroom/index.vue
  41. 51 36
      src/pages/Admin/Classroom/show.vue
  42. 30 25
      src/pages/Admin/Session/show.vue
  43. 29 25
      src/pages/Admin/Unit/show.vue
  44. 32 21
      src/pages/Admin/User/index.vue
  45. 10 6
      src/pages/Admin/User/show.vue

+ 1 - 5
index.html

@@ -5,11 +5,7 @@
     <meta name="format-detection" content="telephone=no">
     <meta name="msapplication-tap-highlight" content="no">
     <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
-    <link rel="icon" type="image/png" sizes="16x16" href="https://nodes.alaatv.com/upload/alaa-logo-favicon.png">
-    <link rel="icon" type="image/png" sizes="128x128" href="https://nodes.alaatv.com/upload/alaa-logo-favicon.png">
-    <link rel="icon" type="image/png" sizes="96x96" href="https://nodes.alaatv.com/upload/alaa-logo-favicon.png">
-    <link rel="icon" type="image/png" sizes="32x32" href="https://nodes.alaatv.com/upload/alaa-logo-favicon.png">
-    <link rel="icon" type="image/ico" href="https://nodes.alaatv.com/upload/alaa-logo.png">
+    <link rel="icon" type="image/png" sizes="96x96" href="/icons/logo.png">
   </head>
   <body>
     <!-- quasar:entry-point -->

BIN
public/favicon.ico


BIN
public/icons/apple-icon-120x120.png


BIN
public/icons/apple-icon-152x152.png


BIN
public/icons/apple-icon-167x167.png


BIN
public/icons/apple-icon-180x180.png


BIN
public/icons/favicon-128x128.png


BIN
public/icons/favicon-16x16.png


BIN
public/icons/favicon-32x32.png


BIN
public/icons/favicon-96x96.png


BIN
public/icons/icon-128x128.png


BIN
public/icons/icon-144x144.png


BIN
public/icons/icon-152x152.png


BIN
public/icons/icon-192x192.png


BIN
public/icons/icon-384x384.png


BIN
public/icons/icon-48x48.png


BIN
public/icons/icon-512x512.png


BIN
public/icons/icon-72x72.png


BIN
public/icons/icon-96x96.png


BIN
public/icons/logo.png


BIN
public/icons/ms-icon-144x144.png


BIN
public/img/QuestionBank/toolbar-back-ground.png


BIN
public/img/mapMarker.png


+ 4 - 46
quasar.config.js

@@ -347,62 +347,20 @@ module.exports = configure(function (ctx) {
       manifestFilename: 'manifest.json',
       useCredentialsForManifestTag: false,
       manifest: {
-        name: 'مدرسه آنلاین آلاء',
-        short_name: 'آلاء',
+        name: 'پالیزوانی',
+        short_name: 'پالیزوانی',
         start_url: '/',
         background_color: '#FFFFFF',
         theme_color: '#ffc107',
-        description: 'آموزش مجازی آلاء',
+        description: 'پالیزوانی',
         display: 'standalone',
         orientation: 'portrait',
         icons: [
           {
-            src: 'icons/icon-72x72.png',
+            src: 'icons/logo.png',
             sizes: '72x72',
             type: 'image/png',
             purpose: 'maskable any'
-          },
-          {
-            src: 'icons/icon-96x96.png',
-            sizes: '96x96',
-            type: 'image/png',
-            purpose: 'maskable any'
-          },
-          {
-            src: 'icons/icon-128x128.png',
-            sizes: '128x128',
-            type: 'image/png',
-            purpose: 'maskable any'
-          },
-          {
-            src: 'icons/icon-144x144.png',
-            sizes: '144x144',
-            type: 'image/png',
-            purpose: 'maskable any'
-          },
-          {
-            src: 'icons/icon-152x152.png',
-            sizes: '152x152',
-            type: 'image/png',
-            purpose: 'maskable any'
-          },
-          {
-            src: 'icons/icon-192x192.png',
-            sizes: '192x192',
-            type: 'image/png',
-            purpose: 'maskable any'
-          },
-          {
-            src: 'icons/icon-384x384.png',
-            sizes: '384x384',
-            type: 'image/png',
-            purpose: 'maskable any'
-          },
-          {
-            src: 'icons/icon-512x512.png',
-            sizes: '512x512',
-            type: 'image/png',
-            purpose: 'maskable any'
           }
         ]
       },

+ 4 - 0
src/api/APIGateway.js

@@ -2,9 +2,11 @@ import SeoAPI from 'src/api/models/Seo.js'
 import AuthAPI from 'src/api/models/Auth.js'
 import UserAPI from 'src/api/models/User.js'
 import UnitAPI from 'src/api/models/Unit.js'
+import SessionAPI from 'src/api/models/Session.js'
 import ClassroomAPI from 'src/api/models/Classroom.js'
 import PageSettingAPI from 'src/api/models/PageSetting.js'
 import UnitCategoryAPI from 'src/api/models/UnitCategory.js'
+import SessionTemplateAPI from 'src/api/models/SessionTemplate.js'
 import ClassroomRegistrationAPI from 'src/api/models/ClassroomRegistration.js'
 
 /* Exporting the APIGateway object. */
@@ -13,8 +15,10 @@ export const APIGateway = {
   auth: new AuthAPI(),
   user: new UserAPI(),
   unit: new UnitAPI(),
+  session: new SessionAPI(),
   classroom: new ClassroomAPI(),
   pageSetting: new PageSettingAPI(),
   unitCategory: new UnitCategoryAPI(),
+  sessionTemplate: new SessionTemplateAPI(),
   classroomRegistration: new ClassroomRegistrationAPI()
 }

+ 68 - 0
src/api/models/Session.js

@@ -0,0 +1,68 @@
+import { appApi } from 'src/boot/axios.js'
+import APIRepository from '../classes/APIRepository.js'
+import { Session, SessionList } from 'src/models/Session.js'
+
+export default class SessionAPI extends APIRepository {
+  constructor() {
+    super('Session', appApi, '/lma/categories', Session)
+    this.APIAdresses = {
+      base: '/lma/sessions',
+      byId: (id) => '/lma/sessions/' + id
+    }
+    this.CacheList = {
+      base: this.name + this.APIAdresses.base,
+      byId: (id) => this.name + this.APIAdresses.byId(id)
+    }
+  }
+
+  index(data) {
+    return this.sendRequest({
+      apiMethod: 'get',
+      api: this.api,
+      request: this.APIAdresses.base,
+      data: this.getNormalizedSendData({
+        category: null, // Number
+        per_page: 10, // Number
+        page: 1 // Number
+      }, data),
+      resolveCallback: (response) => {
+        const paginate = response.data
+        const results = response.data.results
+        delete paginate.results
+        return {
+          list: new SessionList(results),
+          paginate
+          // {
+          //   "count": 1,
+          //   "num_pages": 1,
+          //   "per_page": 10,
+          //   "current": 1,
+          //   "next": null,
+          //   "previous": null,
+          // }
+        }
+      },
+      rejectCallback: (error) => {
+        return error
+      }
+    })
+  }
+
+  create (data) {
+    return this.sendRequest({
+      apiMethod: 'post',
+      api: this.api,
+      request: this.APIAdresses.base,
+      data: this.getNormalizedSendData({
+        title: null, // String
+        unit: null // Number
+      }, data),
+      resolveCallback: (response) => {
+        return new Session(response.data)
+      },
+      rejectCallback: (error) => {
+        return error
+      }
+    })
+  }
+}

+ 68 - 0
src/api/models/SessionTemplate.js

@@ -0,0 +1,68 @@
+import { appApi } from 'src/boot/axios.js'
+import APIRepository from '../classes/APIRepository.js'
+import { SessionTemplate, SessionTemplateList } from 'src/models/SessionTemplate.js'
+
+export default class SessionTemplateAPI extends APIRepository {
+  constructor() {
+    super('SessionTemplate', appApi, '/lma/categories', SessionTemplate)
+    this.APIAdresses = {
+      base: '/lma/session_templates',
+      byId: (id) => '/lma/session_templates/' + id
+    }
+    this.CacheList = {
+      base: this.name + this.APIAdresses.base,
+      byId: (id) => this.name + this.APIAdresses.byId(id)
+    }
+  }
+
+  index(data) {
+    return this.sendRequest({
+      apiMethod: 'get',
+      api: this.api,
+      request: this.APIAdresses.base,
+      data: this.getNormalizedSendData({
+        category: null, // Number
+        per_page: 10, // Number
+        page: 1 // Number
+      }, data),
+      resolveCallback: (response) => {
+        const paginate = response.data
+        const results = response.data.results
+        delete paginate.results
+        return {
+          list: new SessionTemplateList(results),
+          paginate
+          // {
+          //   "count": 1,
+          //   "num_pages": 1,
+          //   "per_page": 10,
+          //   "current": 1,
+          //   "next": null,
+          //   "previous": null,
+          // }
+        }
+      },
+      rejectCallback: (error) => {
+        return error
+      }
+    })
+  }
+
+  create (data) {
+    return this.sendRequest({
+      apiMethod: 'post',
+      api: this.api,
+      request: this.APIAdresses.base,
+      data: this.getNormalizedSendData({
+        title: null, // String
+        unit: null // Number
+      }, data),
+      resolveCallback: (response) => {
+        return new SessionTemplate(response.data)
+      },
+      rejectCallback: (error) => {
+        return error
+      }
+    })
+  }
+}

+ 20 - 0
src/api/models/Unit.js

@@ -47,4 +47,24 @@ export default class UnitAPI extends APIRepository {
       }
     })
   }
+
+  create (data) {
+    return this.sendRequest({
+      apiMethod: 'post',
+      api: this.api,
+      request: this.APIAdresses.base,
+      data: this.getNormalizedSendData({
+        title: null, // String
+        category: null, // Number
+        default_session_count: null, // Number
+        prerequisites: [] // Array
+      }, data),
+      resolveCallback: (response) => {
+        return new Unit(response.data)
+      },
+      rejectCallback: (error) => {
+        return error
+      }
+    })
+  }
 }

+ 35 - 1
src/api/models/User.js

@@ -1,5 +1,5 @@
-import { User } from 'src/models/User.js'
 import { appApi } from 'src/boot/axios.js'
+import { User, UserList } from 'src/models/User.js'
 import APIRepository from '../classes/APIRepository.js'
 
 export default class UserAPI extends APIRepository {
@@ -21,6 +21,39 @@ export default class UserAPI extends APIRepository {
     }
   }
 
+  index(data) {
+    return this.sendRequest({
+      apiMethod: 'get',
+      api: this.api,
+      request: this.APIAdresses.base,
+      data: this.getNormalizedSendData({
+        role: null, // String
+        per_page: 10, // Number
+        page: 1 // Number
+      }, data),
+      resolveCallback: (response) => {
+        const paginate = response.data
+        const results = response.data.results
+        delete paginate.results
+        return {
+          list: new UserList(results),
+          paginate
+          // {
+          //   "count": 1,
+          //   "num_pages": 1,
+          //   "per_page": 10,
+          //   "current": 1,
+          //   "next": null,
+          //   "previous": null,
+          // }
+        }
+      },
+      rejectCallback: (error) => {
+        return error
+      }
+    })
+  }
+
   updateCurrent(data = {}) {
     return this.sendRequest({
       apiMethod: 'put',
@@ -75,6 +108,7 @@ export default class UserAPI extends APIRepository {
         marital_status: 'UNKNOWN', // String
         birthdate: null, // String
         national_code: '', // String
+        is_active: false, // Boolean
         has_seminary_education: false, // Boolean
         last_academic_degree: 'UNDER_DIPLOMA', // String
         last_academic_degree_field: null, // String

+ 51 - 48
src/components/Control/PostRequisites.vue

@@ -7,21 +7,21 @@
       <div class="row q-col-gutter-md">
         <div class="col-md-3">
           <select-control v-model:value="prerequisite.category"
-                          :options="categories"
-                          :disable="categoriesLoading"
-                          :loading="categoriesLoading"
-                          optionValue="id"
-                          optionLabel="title"
+                          :options="categories.list"
+                          :disable="categories.loading"
+                          :loading="categories.loading"
+                          :option-value="'id'"
+                          :option-label="'title'"
                           label="دسته بندی"
                           @update:model-value="getUnits" />
         </div>
         <div class="col-md-3">
           <select-control v-model:value="prerequisite.unit"
-                          :options="units"
-                          :disable="unitsLoading"
-                          :loading="unitsLoading"
-                          optionValue="id"
-                          optionLabel="title"
+                          :options="units.list"
+                          :disable="units.loading"
+                          :loading="units.loading"
+                          :option-value="'id'"
+                          :option-label="'title'"
                           label="درس" />
         </div>
         <div class="col-md-3">
@@ -38,17 +38,19 @@
            class="col-md-3">
         <div class="preItem">
           <div class="preItem-title">
-            {{ prerequisite.category.title }},
-            {{ prerequisite.unit.title }}
+            {{ prerequisite.category?.title }},
+            {{ prerequisite.unit?.title }}
           </div>
           <div class="preItem-actions">
-            <div class="view">
+            <q-btn v-if="prerequisite.unit?.id"
+                   flat
+                   class="view"
+                   :to="{ name: 'Admin.Unit.Show', params: { id: prerequisite.unit.id } }">
               <svg data-name="Component 14 – 2"
                    xmlns="http://www.w3.org/2000/svg"
                    width="42"
                    height="42"
-                   viewBox="0 0 42 42"
-                   @click="showUnit(prerequisite.unit.id)">
+                   viewBox="0 0 42 42">
                 <g data-name="Rectangle 3232"
                    fill="#fff"
                    stroke="#475f4a"
@@ -71,14 +73,14 @@
                         fill="#475f4a" />
                 </g>
               </svg>
-            </div>
-            <div class="remove">
+            </q-btn>
+            <div class="remove"
+                 @click="removeUnit(prerequisite.unit.id)">
               <svg data-name="Component 13 – 43"
                    xmlns="http://www.w3.org/2000/svg"
                    width="42"
                    height="42"
-                   viewBox="0 0 42 42"
-                   @click="removeUnit(prerequisite.unit.id)">
+                   viewBox="0 0 42 42">
                 <g data-name="Rectangle 3219"
                    fill="#fff"
                    stroke="#f83a3a"
@@ -115,8 +117,10 @@
 </template>
 
 <script>
-import API_ADDRESS from 'src/api/Addresses'
-import SelectControl from 'components/Control/Select'
+import { UnitList } from 'src/models/Unit.js'
+import { APIGateway } from 'src/api/APIGateway.js'
+import SelectControl from 'src/components/Control/Select.vue'
+import { UnitCategoryList } from 'src/models/UnitCategory.js'
 
 export default {
   name: 'PostRequisites',
@@ -174,11 +178,10 @@ export default {
         category: null,
         unit: null
       },
-      categoriesLoading: false,
-      categories: [],
+      categories: new UnitCategoryList(),
       unitsLoading: false,
-      allUnits: [],
-      units: []
+      allUnits: new UnitList(),
+      units: new UnitList()
     }
   },
   watch: {
@@ -219,13 +222,13 @@ export default {
       this.change()
     },
     getCategoryObject (categoryId) {
-      return this.categories.find(cat => cat.id === categoryId)
+      return this.categories.list.find(cat => cat.id === categoryId)
     },
     getUnitObjectByCategoryId (categoryId) {
-      return this.allUnits.find(unit => unit.category_info.id === categoryId)
+      return this.allUnits.list.find(unit => unit.category_info.id === categoryId)
     },
     getCategoryObjectByUnitId (unitId) {
-      const target = this.allUnits.find(unit => unit.id === unitId)
+      const target = this.allUnits.list.find(unit => unit.id === unitId)
       if (!target) {
         return null
       }
@@ -233,7 +236,7 @@ export default {
       return target.category_info
     },
     getUnitObject (unitId) {
-      return this.allUnits.find(unit => unit.id === unitId)
+      return this.allUnits.list.find(unit => unit.id === unitId)
     },
     addPostRequisites () {
       if (!this.prerequisite.category || !this.prerequisite.unit) {
@@ -249,39 +252,39 @@ export default {
       this.change()
     },
     getCategories () {
-      this.categoriesLoading = true
-      this.$axios.get(API_ADDRESS.category.base)
-        .then(response => {
-          this.categoriesLoading = false
-          this.categories = response.data.results
+      this.categories.loading = true
+      APIGateway.unitCategory.index()
+        .then(categories => {
+          this.categories.loading = false
+          this.categories = new UnitCategoryList(categories.list)
         })
         .catch(() => {
-          this.categoriesLoading = false
+          this.categories.loading = false
         })
     },
     getAllUnits () {
-      this.unitsLoading = true
-      this.$axios.get(API_ADDRESS.unit.base)
-        .then(response => {
-          this.unitsLoading = false
-          this.allUnits = response.data.results
+      this.allUnits.loading = true
+      APIGateway.unit.index({ per_page: 9999 })
+        .then(units => {
+          this.allUnits.loading = false
+          this.allUnits = new UnitList(units.list)
           this.loadPrerequisitesFromInputData()
         })
         .catch(() => {
-          this.unitsLoading = false
+          this.allUnits.loading = false
         })
     },
     getUnits () {
-      this.unitsLoading = true
-      this.units = []
+      this.units.loading = true
+      this.units = new UnitList()
       this.prerequisite.unit = null
-      this.$axios.get(API_ADDRESS.unit.base + '?category=' + this.prerequisite.category)
-        .then(response => {
-          this.unitsLoading = false
-          this.units = response.data.results
+      APIGateway.unit.index({ category: this.prerequisite.category })
+        .then(units => {
+          this.units.loading = false
+          this.units = new UnitList(units.list)
         })
         .catch(() => {
-          this.unitsLoading = false
+          this.units.loading = false
         })
     },
     change () {

+ 7 - 1
src/components/Control/btn.vue

@@ -4,7 +4,7 @@
          :class="btnClass"
          :disable="disable"
          :loading="loading"
-         @click="atClick" />
+         @click="onClick" />
 </template>
 
 <script>
@@ -47,6 +47,12 @@ export default {
   },
   created () {
     this.inputData = this.value
+  },
+  methods: {
+    onClick (event) {
+      this.atClick()
+      this.$emit('onClick', event)
+    }
   }
 }
 </script>

+ 4 - 4
src/css/Theme/Widgets/widgets.scss

@@ -1,5 +1,5 @@
-@import 'chip';
-@import "pagination";
-@import 'src/css/Theme/Widgets/card';
-@import 'src/css/Theme/Widgets/scrollBar.scss';
+//@import 'src/css/Theme/Widgets/card';
+//@import 'src/css/Theme/Widgets/scrollBar.scss';
+//@import './chip';
+@import './banner.scss';
 

+ 32 - 0
src/models/SessionTemplate.js

@@ -0,0 +1,32 @@
+import { Unit } from 'src/models/Unit.js'
+import { Model, Collection } from 'js-abstract-model'
+
+class SessionTemplate extends Model {
+  constructor (data) {
+    super(data, [
+      { key: 'id' },
+      { key: 'unit' },
+      {
+        key: 'unit_info',
+        relatedModel: Unit
+      },
+      { key: 'title' },
+      { key: 'syllabus' },
+      { key: 'description' },
+      { key: 'starting_time' },
+      { key: 'ending_time' },
+      { key: 'question' },
+      { key: 'answer' },
+      { key: 'question_info' },
+      { key: 'creation_time' },
+      { key: 'last_modification_time' }
+    ])
+  }
+}
+
+class SessionTemplateList extends Collection {
+  model () {
+    return SessionTemplate
+  }
+}
+export { SessionTemplate, SessionTemplateList }

+ 1 - 0
src/models/UnitCategory.js

@@ -6,6 +6,7 @@ class UnitCategory extends Model {
   constructor (data) {
     super(data, [
       { key: 'id' },
+      { key: 'title' },
       { key: 'creator' },
       {
         key: 'creator_info',

+ 8 - 4
src/models/User.js

@@ -1,6 +1,4 @@
-/* eslint-disable camelcase,prefer-const */
-import { Model } from 'js-abstract-model'
-// import API_ADDRESS from '../api/Addresses'
+import { Collection, Model } from 'js-abstract-model'
 
 class User extends Model {
   constructor (data) {
@@ -162,4 +160,10 @@ class User extends Model {
   }
 }
 
-export { User }
+class UserList extends Collection {
+  model () {
+    return User
+  }
+}
+
+export { User, UserList }

+ 46 - 35
src/pages/Admin/Category/create.vue

@@ -1,43 +1,47 @@
 <template>
-  <entity-create ref="classroomEntityCreate"
-                 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">
-    <template #after-form-builder>
-      <div class="row q-col-gutter-md q-mb-md">
-        <div class="col-md-3">
-          <q-input v-model="newUnitName"
-                   label="درس ها"
+  <div class="ddd">
+    <entity-create v-if="mounted"
+                   ref="classroomEntityCreate"
+                   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"
+                   @onInputClick="onInputClick">
+      <template #after-form-builder>
+        <div class="row q-col-gutter-md q-mb-md">
+          <div class="col-md-3">
+            <q-input v-model="newUnitName"
+                     label="درس ها"
+                     :disable="true" />
+          </div>
+          <div class="col-md-3">
+            <q-input v-model="newUnitSessionCount"
+                     label="تعداد جلسات"
+                     type="number"
+                     :disable="true" />
+          </div>
+          <div class="col-md-3">
+            <q-btn color="primary"
+                   label="افزودن"
                    :disable="true" />
+          </div>
         </div>
-        <div class="col-md-3">
-          <q-input v-model="newUnitSessionCount"
-                   label="تعداد جلسات"
-                   type="number"
-                   :disable="true" />
-        </div>
-        <div class="col-md-3">
-          <q-btn color="primary"
-                 label="افزودن"
-                 :disable="true" />
-        </div>
-      </div>
-    </template>
-  </entity-create>
+      </template>
+    </entity-create>
+  </div>
 </template>
 
 <script>
 import { shallowRef } from 'vue'
 import { EntityCreate } from 'quasar-crud'
-import API_ADDRESS from 'src/api/Addresses.jS'
+import { APIGateway } from 'src/api/APIGateway.js'
 import BtnControl from 'src/components/Control/btn.vue'
 
 const BtnControlComp = shallowRef(BtnControl)
@@ -49,21 +53,28 @@ export default {
   },
   data () {
     return {
+      mounted: false,
       newUnitLoading: false,
       newUnitName: null,
       newUnitSessionCount: null,
-      api: API_ADDRESS.category.base,
+      api: APIGateway.unitCategory.APIAdresses.base,
       entityIdKey: 'id',
       entityParamKey: 'id',
       showRouteName: 'Admin.Category.Show',
       inputs: [
         { type: 'input', name: 'title', responseKey: 'title', label: 'نام دسته بندی', col: 'col-md-6' },
-        { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'تایید', props: { atClick: this.createClassroom }, col: 'col-md-6' }
+        { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'تایید', col: 'col-md-6' }
       ]
     }
   },
+  mounted() {
+    this.mounted = true
+  },
   methods: {
-    createClassroom () {
+    onInputClick (data) {
+      if (data.input.name !== 'btn') {
+        return
+      }
       this.$refs.classroomEntityCreate.createEntity()
     }
   }

+ 44 - 31
src/pages/Admin/Category/index.vue

@@ -1,42 +1,44 @@
 <template>
-  <div class="add-new-action-row">
-    <q-btn color="primary"
-           label="ایجاد دسته بندی جدید"
-           :to="{name: 'Admin.Category.Create'}" />
-  </div>
-  <entity-index ref="entityIndex"
-                v-model:value="inputs"
-                title="لیست دسته بندی ها"
-                :api="api"
-                :table="table"
-                :table-keys="tableKeys"
-                :show-search-button="false"
-                :show-reload-button="false"
-                :show-expand-button="false">
-    <template #table-cell="{inputData, showConfirmRemoveDialog}">
-      <q-td :props="inputData.props">
-        <template v-if="inputData.props.col.name === 'actions'">
+  <div class="AdminCategoryIndex">
+    <div class="add-new-action-row">
+      <q-btn color="primary"
+             label="ایجاد دسته بندی جدید"
+             :to="{name: 'Admin.Category.Create'}" />
+    </div>
+    <entity-index v-if="mounted"
+                  ref="entityIndex"
+                  v-model:value="inputs"
+                  title="لیست دسته بندی ها"
+                  :api="api"
+                  :table="table"
+                  :table-keys="tableKeys"
+                  :show-search-button="false"
+                  :show-reload-button="false"
+                  :show-expand-button="false">
+      <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
+        <template v-if="inputData.col.name === 'actions'">
           <div class="action-column-entity-index">
             <q-btn size="md"
                    color="primary"
                    label="جزییات"
-                   :to="{name: 'Admin.Category.Show', params: {id: inputData.props.row.id}}" />
+                   :to="{name: 'Admin.Category.Show', params: {id: inputData.props.row.id}}"
+                   class="q-mr-md" />
             <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
           </div>
         </template>
         <template v-else>
-          {{ inputData.props.value }}
+          {{ inputData.col.value }}
         </template>
-      </q-td>
-    </template>
-  </entity-index>
+      </template>
+    </entity-index>
+  </div>
 </template>
 
 <script>
 import { shallowRef } from 'vue'
 import { EntityIndex } from 'quasar-crud'
-import API_ADDRESS from 'src/api/Addresses.js'
 import ShamsiDate from 'src/assets/ShamsiDate.js'
+import { APIGateway } from 'src/api/APIGateway.js'
 import BtnControl from 'src/components/Control/btn.vue'
 import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
 
@@ -50,11 +52,12 @@ export default {
   },
   data () {
     return {
+      mounted: false,
       inputs: [
         { type: 'input', name: 'title', value: null, label: 'نام', col: 'col-md-2' },
         { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'جستجو', props: { atClick: this.search }, col: 'col-md-2' }
       ],
-      api: API_ADDRESS.category.base,
+      api: APIGateway.unitCategory.APIAdresses.base,
       table: {
         columns: [
           {
@@ -111,6 +114,9 @@ export default {
       }
     }
   },
+  mounted() {
+    this.mounted = true
+  },
   methods: {
     search () {
       this.$refs.entityIndex.search()
@@ -122,12 +128,19 @@ export default {
 }
 </script>
 
-<style>
-.add-new-action-row {
-  display: flex;
-  flex-flow: row;
-  align-items: center;
-  justify-content: flex-end;
-  margin-bottom: 22px;
+<style lang="scss" scoped>
+.AdminCategoryIndex {
+  .add-new-action-row {
+    display: flex;
+    flex-flow: row;
+    align-items: center;
+    justify-content: flex-end;
+    margin-bottom: 22px;
+  }
+  .action-column-entity-index {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+  }
 }
 </style>

+ 76 - 64
src/pages/Admin/Category/show.vue

@@ -1,75 +1,78 @@
 <template>
-  <entity-edit ref="categoryEntityEdit"
-               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">
-    <template #after-form-builder>
-      <div class="row q-col-gutter-md q-mb-md">
-        <div class="col-md-3">
-          <q-input v-model="newUnitName"
-                   label="درس ها"
-                   :disable="newUnitLoading"
-                   :loading="newUnitLoading" />
+  <div class="AdminCategoryIndex">
+    <entity-edit v-if="mounted"
+                 ref="categoryEntityEdit"
+                 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">
+      <template #after-form-builder>
+        <div class="row q-col-gutter-md q-mb-md">
+          <div class="col-md-3">
+            <q-input v-model="newUnitName"
+                     label="درس ها"
+                     :disable="newUnitLoading"
+                     :loading="newUnitLoading" />
+          </div>
+          <div class="col-md-3">
+            <q-input v-model="newUnitSessionCount"
+                     label="تعداد جلسات"
+                     type="number"
+                     :disable="newUnitLoading"
+                     :loading="newUnitLoading" />
+          </div>
+          <div class="col-md-3">
+            <q-btn color="primary"
+                   label="افزودن"
+                   @click="createUnit" />
+          </div>
         </div>
-        <div class="col-md-3">
-          <q-input v-model="newUnitSessionCount"
-                   label="تعداد جلسات"
-                   type="number"
-                   :disable="newUnitLoading"
-                   :loading="newUnitLoading" />
-        </div>
-        <div class="col-md-3">
-          <q-btn color="primary"
-                 label="افزودن"
-                 @click="createUnit" />
-        </div>
-      </div>
-      <div class="row ">
-        <div class="col">
-          <entity-index ref="unitEntityIndex"
-                        v-model:value="unitFilterInputs"
-                        title="لیست درس ها"
-                        :api="unitApi"
-                        :table="unitTable"
-                        :table-keys="unitTableKeys"
-                        :show-reload-button="false"
-                        :show-search-button="false"
-                        :show-expand-button="false">
-            <template #table-cell="{inputData, showConfirmRemoveDialog}">
-              <q-td :props="inputData.props">
-                <template v-if="inputData.props.col.name === 'actions'">
+        <div class="row ">
+          <div class="col">
+            <entity-index ref="unitEntityIndex"
+                          v-model:value="unitFilterInputs"
+                          title="لیست درس ها"
+                          :api="unitApi"
+                          :table="unitTable"
+                          :table-keys="unitTableKeys"
+                          :show-reload-button="false"
+                          :show-search-button="false"
+                          :show-expand-button="false"
+                          :default-layout="false">
+              <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
+                <template v-if="inputData.col.name === 'actions'">
                   <div class="action-column-entity-index">
                     <q-btn size="md"
                            color="primary"
                            label="تعیین جزییات"
-                           :to="{name: 'Admin.Unit.Show', params: {id: inputData.props.row.id}}" />
+                           :to="{name: 'Admin.Unit.Show', params: {id: inputData.props.row.id}}"
+                           class="q-mr-md" />
                     <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
                   </div>
                 </template>
                 <template v-else>
-                  {{ inputData.props.value }}
+                  {{ inputData.col.value }}
                 </template>
-              </q-td>
-            </template>
-          </entity-index>
+              </template>
+            </entity-index>
+          </div>
         </div>
-      </div>
-    </template>
-  </entity-edit>
+      </template>
+    </entity-edit>
+  </div>
 </template>
 
 <script>
 import { shallowRef } from 'vue'
-import API_ADDRESS from 'src/api/Addresses.js'
 import ShamsiDate from 'src/assets/ShamsiDate.js'
+import { APIGateway } from 'src/api/APIGateway.js'
 import { EntityEdit, EntityIndex } from 'quasar-crud'
 import BtnControl from 'src/components/Control/btn.vue'
 import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
@@ -85,10 +88,11 @@ export default {
   },
   data () {
     return {
+      mounted: false,
       newUnitLoading: false,
       newUnitName: null,
       newUnitSessionCount: null,
-      api: API_ADDRESS.category.base,
+      api: null,
       entityIdKey: 'id',
       entityParamKey: 'id',
       showRouteName: 'Admin.Category.Show',
@@ -98,9 +102,11 @@ export default {
         { type: 'hidden', name: 'id', responseKey: 'id', label: 'id' }
       ],
 
-      unitFilterInputs: [],
+      unitFilterInputs: [
+        // { type: 'hidden', name: 'category', value: null }
+      ],
 
-      unitApi: API_ADDRESS.unit.base + '?category=' + this.$route.params.id,
+      unitApi: APIGateway.unit.APIAdresses.base + '?category=' + this.$route.params.id,
       unitTable: {
         columns: [
           {
@@ -158,8 +164,10 @@ export default {
 
     }
   },
-  created () {
-    this.api += '/' + this.$route.params.id
+  mounted () {
+    // this.unitFilterInputs[0].value = this.$route.params.id
+    this.api = APIGateway.unitCategory.APIAdresses.byId(this.$route.params.id)
+    this.mounted = true
   },
   methods: {
     updateCategory () {
@@ -176,7 +184,7 @@ export default {
     },
     createUnit () {
       this.newUnitLoading = true
-      this.$axios.post(API_ADDRESS.unit.base, {
+      APIGateway.unit.create({
         title: this.newUnitName,
         category: this.$route.params.id,
         default_session_count: this.newUnitSessionCount
@@ -193,8 +201,12 @@ export default {
 }
 </script>
 
-<style>
-.fit-to-card {
-  margin: -16px;
+<style lang="scss" scoped>
+.AdminCategoryIndex {
+  .action-column-entity-index {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+  }
 }
 </style>

+ 48 - 34
src/pages/Admin/Classroom/create.vue

@@ -1,30 +1,33 @@
 <template>
-  <entity-create ref="classroomEntityCreate"
-                 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">
-    <template #after-form-builder>
-      <div class="flex justify-end">
-        <q-btn color="primary"
-               label="ایجاد دوره آموزشی جدید"
-               @click="createClassroom" />
-      </div>
-    </template>
-  </entity-create>
+  <div class="AdminClassroomCreate">
+    <entity-create v-if="mounted"
+                   ref="classroomEntityCreate"
+                   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">
+      <template #after-form-builder>
+        <div class="flex justify-end">
+          <q-btn color="primary"
+                 label="ایجاد دوره آموزشی جدید"
+                 @click="createClassroom" />
+        </div>
+      </template>
+    </entity-create>
+  </div>
 </template>
 
 <script>
 import { EntityCreate } from 'quasar-crud'
 import Enums from 'src/assets/Enums/Enums.js'
-import API_ADDRESS from 'src/api/Addresses.js'
+import { APIGateway } from 'src/api/APIGateway'
 
 export default {
   name: 'Admin.Classroom.Create',
@@ -33,10 +36,11 @@ export default {
   },
   data () {
     return {
+      mounted: false,
       newUnitLoading: false,
       newUnitName: null,
       newUnitSessionCount: null,
-      api: API_ADDRESS.classroom.base,
+      api: APIGateway.classroom.APIAdresses.base,
       entityIdKey: 'id',
       entityParamKey: 'id',
       showRouteName: 'Admin.Classroom.Show',
@@ -136,7 +140,8 @@ export default {
       this.getUnits(this.selectedCategoryId)
     }
   },
-  created () {
+  mounted () {
+    this.mounted = true
     this.beforeLoadInputData()
   },
   methods: {
@@ -150,24 +155,33 @@ export default {
       })
     },
     async getProfessors (setNewInputData) {
-      const response = await this.$axios.get(API_ADDRESS.user.base + '?per_page=9999&role=professor')
-      this.loadSelectOptions('professor', response.data.results.map(item => {
-        return {
-          value: item.id,
-          label: this.getUserFullname(item)
-        }
-      }), setNewInputData)
+      APIGateway.user.index({ per_page: 9999, role: 'professor' })
+        .then((users) => {
+          this.loadSelectOptions('professor', users.list.list.map(item => {
+            return {
+              value: item.id,
+              label: this.getUserFullname(item)
+            }
+          }), setNewInputData)
+        })
+        .catch(() => {})
     },
     getUserFullname (user) {
       return user.firstname + ' ' + user.lastname
     },
     async getCategories (setNewInputData) {
-      const response = await this.$axios.get(API_ADDRESS.category.base)
-      this.loadSelectOptions('category', this.getSelectOptions(response.data.results, 'id', 'title'), setNewInputData)
+      APIGateway.unitCategory.index({ per_page: 9999 })
+        .then((categories) => {
+          this.loadSelectOptions('category', this.getSelectOptions(categories.list.list, 'id', 'title'), setNewInputData)
+        })
+        .catch(() => {})
     },
     async getUnits (selectedcategoryId, setNewInputData) {
-      const response = await this.$axios.get(API_ADDRESS.unit.base + '?category=' + selectedcategoryId)
-      this.loadSelectOptions('unit', this.getSelectOptions(response.data.results, 'id', 'title'), setNewInputData)
+      APIGateway.unit.index({ per_page: 9999, category: selectedcategoryId })
+        .then((units) => {
+          this.loadSelectOptions('unit', this.getSelectOptions(units.list.list, 'id', 'title'), setNewInputData)
+        })
+        .catch(() => {})
     },
     getSelectOptions (result, value, label) {
       return result.map(item => {

+ 60 - 46
src/pages/Admin/Classroom/index.vue

@@ -1,54 +1,56 @@
 <template>
-  <div class="add-new-action-row">
-    <q-btn color="primary"
-           :to="{name: 'Admin.Classroom.Create'}">
-      <svg data-name="Close Square"
-           xmlns="http://www.w3.org/2000/svg"
-           width="20"
-           height="20"
-           viewBox="0 0 20 20"
-           class="q-mr-md">
-        <path id="Combined_Shape"
-              data-name="Combined Shape"
-              d="M5.665,20C2.276,20,0,17.623,0,14.084V5.916C0,2.377,2.276,0,5.665,0h8.67C17.723,0,20,2.377,20,5.916v8.168C20,17.623,17.723,20,14.333,20ZM1.5,5.916v8.168c0,2.683,1.634,4.416,4.164,4.416h8.669c2.532,0,4.167-1.733,4.167-4.416V5.916c0-2.682-1.635-4.415-4.166-4.415H5.665C3.135,1.5,1.5,3.234,1.5,5.916Zm7.968,8a.747.747,0,0,1-.22-.53V10.741H6.611a.75.75,0,0,1-.75-.75.749.749,0,0,1,.75-.75H9.249V6.6a.75.75,0,1,1,1.5,0V9.241h2.639a.75.75,0,0,1,0,1.5H10.748v2.642a.75.75,0,0,1-1.28.53Z"
-              fill="#fff" />
-      </svg>
-      ایجاد دوره آموزشی جدید
-    </q-btn>
-  </div>
-  <entity-index v-model:value="inputs"
-                title="لیست دسته بندی ها"
-                :api="api"
-                :table="table"
-                :table-keys="tableKeys"
-                :show-expand-button="false"
-                :show-reload-button="false"
-                :show-search-button="false">
-    <template #table-cell="{inputData, showConfirmRemoveDialog}">
-      <q-td :props="inputData.props">
-        <template v-if="inputData.props.col.name === 'actions'">
+  <div class="AdminClassroomIndex">
+    <div class="add-new-action-row">
+      <q-btn color="primary"
+             :to="{name: 'Admin.Classroom.Create'}">
+        <svg data-name="Close Square"
+             xmlns="http://www.w3.org/2000/svg"
+             width="20"
+             height="20"
+             viewBox="0 0 20 20"
+             class="q-mr-md">
+          <path id="Combined_Shape"
+                data-name="Combined Shape"
+                d="M5.665,20C2.276,20,0,17.623,0,14.084V5.916C0,2.377,2.276,0,5.665,0h8.67C17.723,0,20,2.377,20,5.916v8.168C20,17.623,17.723,20,14.333,20ZM1.5,5.916v8.168c0,2.683,1.634,4.416,4.164,4.416h8.669c2.532,0,4.167-1.733,4.167-4.416V5.916c0-2.682-1.635-4.415-4.166-4.415H5.665C3.135,1.5,1.5,3.234,1.5,5.916Zm7.968,8a.747.747,0,0,1-.22-.53V10.741H6.611a.75.75,0,0,1-.75-.75.749.749,0,0,1,.75-.75H9.249V6.6a.75.75,0,1,1,1.5,0V9.241h2.639a.75.75,0,0,1,0,1.5H10.748v2.642a.75.75,0,0,1-1.28.53Z"
+                fill="#fff" />
+        </svg>
+        ایجاد دوره آموزشی جدید
+      </q-btn>
+    </div>
+    <entity-index v-if="mounted"
+                  v-model:value="inputs"
+                  title="لیست دسته بندی ها"
+                  :api="api"
+                  :table="table"
+                  :table-keys="tableKeys"
+                  :show-expand-button="false"
+                  :show-reload-button="false"
+                  :show-search-button="false">
+      <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
+        <template v-if="inputData.col.name === 'actions'">
           <div class="action-column-entity-index">
             <q-btn size="md"
                    color="primary"
                    label="جزییات"
-                   :to="{name: 'Admin.Classroom.Show', params: {id: inputData.props.row.id}}" />
+                   :to="{name: 'Admin.Classroom.Show', params: {id: inputData.props.row.id}}"
+                   class="q-mr-md" />
             <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
           </div>
         </template>
         <template v-else>
-          {{ inputData.props.value }}
+          {{ inputData.col.value }}
         </template>
-      </q-td>
-    </template>
-  </entity-index>
+      </template>
+    </entity-index>
+  </div>
 </template>
 
 <script>
 import { shallowRef } from 'vue'
 import { EntityIndex } from 'quasar-crud'
 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 BtnControl from 'src/components/Control/btn.vue'
 import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
 
@@ -62,6 +64,7 @@ export default {
   },
   data () {
     return {
+      mounted: false,
       inputs: [
         {
           type: 'select',
@@ -81,7 +84,7 @@ export default {
         },
         { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'جستجو', props: { atClick: this.search }, col: 'col-md-2' }
       ],
-      api: API_ADDRESS.classroom.base,
+      api: APIGateway.classroom.APIAdresses.base,
       table: {
         columns: [
           {
@@ -166,14 +169,18 @@ export default {
       }
     }
   },
-  created () {
+  mounted () {
+    this.mounted = true
     this.getUnits()
   },
   methods: {
     getUnits () {
-      this.$axios.get(API_ADDRESS.unit.base)
-        .then((response) => {
-          this.loadSelectOptions('unit', this.getSelectOptions(response.data.results, 'id', 'title'))
+      APIGateway.unit.index({ per_page: 9999 })
+        .then((units) => {
+          this.loadSelectOptions('unit', this.getSelectOptions(units.list.list, 'id', 'title'))
+        })
+        .catch(() => {
+
         })
     },
     loadSelectOptions (name, value) {
@@ -211,12 +218,19 @@ export default {
 }
 </script>
 
-<style>
-.add-new-action-row {
-  display: flex;
-  flex-flow: row;
-  align-items: center;
-  justify-content: flex-end;
-  margin-bottom: 22px;
+<style lang="scss" scoped>
+.AdminClassroomIndex {
+  .add-new-action-row {
+    display: flex;
+    flex-flow: row;
+    align-items: center;
+    justify-content: flex-end;
+    margin-bottom: 22px;
+  }
+  .action-column-entity-index {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+  }
 }
 </style>

+ 51 - 36
src/pages/Admin/Classroom/show.vue

@@ -1,5 +1,5 @@
 <template>
-  <q-card>
+  <q-card class="AdminClassroomShow">
     <q-tabs v-model="tab"
             dense
             class="text-grey"
@@ -21,7 +21,8 @@
 
     <q-separator />
 
-    <q-tab-panels v-model="tab"
+    <q-tab-panels v-if="mounted"
+                  v-model="tab"
                   animated>
       <q-tab-panel name="classroomInfo">
         <entity-edit ref="categoryEntityEdit"
@@ -55,21 +56,20 @@
                       :show-search-button="false"
                       :show-reload-button="false"
                       :show-expand-button="false">
-          <template #table-cell="{inputData, showConfirmRemoveDialog}">
-            <q-td :props="inputData.props">
-              <template v-if="inputData.props.col.name === 'actions'">
-                <div class="action-column-entity-index">
-                  <q-btn size="md"
-                         color="primary"
-                         label="جزییات"
-                         :to="{name: 'Admin.Session.Show', params: {id: inputData.props.row.id}}" />
-                  <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
-                </div>
-              </template>
-              <template v-else>
-                {{ inputData.props.value }}
-              </template>
-            </q-td>
+          <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
+            <template v-if="inputData.col.name === 'actions'">
+              <div class="action-column-entity-index">
+                <q-btn size="md"
+                       color="primary"
+                       label="جزییات"
+                       :to="{name: 'Admin.Session.Show', params: {id: inputData.props.row.id}}"
+                       class="q-mr-md" />
+                <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
+              </div>
+            </template>
+            <template v-else>
+              {{ inputData.col.value }}
+            </template>
           </template>
         </entity-index>
       </q-tab-panel>
@@ -89,7 +89,7 @@
 
 <script>
 import Enums from 'src/assets/Enums/Enums.js'
-import API_ADDRESS from 'src/api/Addresses.js'
+import { APIGateway } from 'src/api/APIGateway.js'
 import ShamsiDate from 'src/assets/ShamsiDate.js'
 import { EntityEdit, EntityIndex } from 'quasar-crud'
 import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
@@ -103,8 +103,9 @@ export default {
   },
   data () {
     return {
+      mounted: false,
       tab: 'classroomInfo',
-      api: API_ADDRESS.classroom.base,
+      api: null,
       entityIdKey: 'id',
       entityParamKey: 'id',
       showRouteName: 'Admin.Classroom.Show',
@@ -197,7 +198,7 @@ export default {
       sessionListInputs: [
         { type: 'hidden', name: 'classroom', value: this.$route.params.id, label: 'نام دوره', col: 'col-md-12' }
       ],
-      sessionListApi: API_ADDRESS.session.base,
+      sessionListApi: APIGateway.session.APIAdresses.base,
       sessionListTable: {
         columns: [
           {
@@ -258,8 +259,9 @@ export default {
       this.getUnits(this.selectedCategoryId)
     }
   },
-  created () {
-    this.api += '/' + this.$route.params.id
+  mounted () {
+    this.api = APIGateway.classroom.APIAdresses.byId(this.$route.params.id)
+    this.mounted = true
   },
   methods: {
     async beforeLoadInputData (responseData, setNewInputData) {
@@ -272,24 +274,33 @@ export default {
       })
     },
     async getProfessors (setNewInputData) {
-      const response = await this.$axios.get(API_ADDRESS.user.base + '?per_page=9999&role=professor')
-      this.loadSelectOptions('professor', response.data.results.map(item => {
-        return {
-          value: item.id,
-          label: this.getUserFullname(item)
-        }
-      }), setNewInputData)
+      APIGateway.user.index({ per_page: 9999, role: 'professor' })
+        .then((users) => {
+          this.loadSelectOptions('professor', users.list.list.map(item => {
+            return {
+              value: item.id,
+              label: this.getUserFullname(item)
+            }
+          }), setNewInputData)
+        })
+        .catch(() => {})
     },
     getUserFullname (user) {
       return user.firstname + ' ' + user.lastname
     },
     async getCategories (setNewInputData) {
-      const response = await this.$axios.get(API_ADDRESS.category.base)
-      this.loadSelectOptions('category', this.getSelectOptions(response.data.results, 'id', 'title'), setNewInputData)
+      APIGateway.unitCategory.index({ per_page: 9999 })
+        .then((categories) => {
+          this.loadSelectOptions('category', this.getSelectOptions(categories.list.list, 'id', 'title'), setNewInputData)
+        })
+        .catch(() => {})
     },
     async getUnits (selectedcategoryId, setNewInputData) {
-      const response = await this.$axios.get(API_ADDRESS.unit.base + '?category=' + selectedcategoryId)
-      this.loadSelectOptions('unit', this.getSelectOptions(response.data.results, 'id', 'title'), setNewInputData)
+      APIGateway.unit.index({ per_page: 9999, category: selectedcategoryId })
+        .then((units) => {
+          this.loadSelectOptions('unit', this.getSelectOptions(units.list.list, 'id', 'title'), setNewInputData)
+        })
+        .catch(() => {})
     },
     getSelectOptions (result, value, label) {
       return result.map(item => {
@@ -324,8 +335,12 @@ export default {
 }
 </script>
 
-<style>
-.fit-to-card {
-  margin: -16px;
+<style lang="scss" scoped>
+.AdminClassroomShow {
+  .action-column-entity-index {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+  }
 }
 </style>

+ 30 - 25
src/pages/Admin/Session/show.vue

@@ -1,41 +1,45 @@
 <template>
-  <entity-edit ref="sessionEntityEdit"
-               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">
-    <template #after-form-builder>
-      <div class="flex justify-end">
-        <q-btn color="primary"
-               label="ذخیره جزییات"
-               @click="updateSessionTemplates" />
-      </div>
-    </template>
-  </entity-edit>
+  <div class="AdminSessionShow">
+    <entity-edit v-if="mounted"
+                 ref="sessionEntityEdit"
+                 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">
+      <template #after-form-builder>
+        <div class="flex justify-end">
+          <q-btn color="primary"
+                 label="ذخیره جزییات"
+                 @click="updateSessionTemplates" />
+        </div>
+      </template>
+    </entity-edit>
+  </div>
 </template>
 
 <script>
 import { EntityEdit } from 'quasar-crud'
-import API_ADDRESS from 'src/api/Addresses.js'
+import { APIGateway } from 'src/api/APIGateway.js'
 
 export default {
-  name: 'Admin.SessionTemplates.Index',
+  name: 'Admin.Session.Show',
   components: {
     EntityEdit
   },
   data () {
     return {
+      mounted: false,
       newUnitLoading: false,
       newUnitName: null,
       newUnitSessionCount: null,
-      api: API_ADDRESS.session.base,
+      api: null,
       entityIdKey: 'id',
       entityParamKey: 'id',
       showRouteName: 'Admin.SessionTemplate.Show',
@@ -51,8 +55,9 @@ export default {
       ]
     }
   },
-  created () {
-    this.api += '/' + this.$route.params.id
+  mounted () {
+    this.api = APIGateway.session.APIAdresses.byId(this.$route.params.id)
+    this.mounted = true
   },
   methods: {
     updateSessionTemplates () {

+ 29 - 25
src/pages/Admin/Unit/show.vue

@@ -1,7 +1,8 @@
 <template>
   <div>
     <div>
-      <entity-edit ref="categoryEntityEdit"
+      <entity-edit v-if="mounted"
+                   ref="categoryEntityEdit"
                    v-model:value="inputs"
                    title="مشخصات دسته بندی"
                    :api="api"
@@ -23,7 +24,8 @@
       </entity-edit>
     </div>
     <div class="q-mt-md">
-      <entity-index ref="sessionEntityIndex"
+      <entity-index v-if="mounted"
+                    ref="sessionEntityIndex"
                     v-model:value="sessionFilterInputs"
                     title="لیست جلسات"
                     :api="sessionApi"
@@ -72,10 +74,11 @@
 
 <script>
 import { shallowRef } from 'vue'
-import API_ADDRESS from 'src/api/Addresses.js'
 import ShamsiDate from 'src/assets/ShamsiDate.js'
+import { APIGateway } from 'src/api/APIGateway.js'
 import { EntityEdit, EntityIndex } from 'quasar-crud'
 import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
+import { UnitCategoryList } from 'src/models/UnitCategory.js'
 import PostRequisites from 'src/components/Control/PostRequisites.vue'
 
 const PostRequisitesComp = shallowRef(PostRequisites)
@@ -89,10 +92,11 @@ export default {
   },
   data () {
     return {
+      mounted: false,
       newSessionLoading: false,
       newSessionName: '-',
       newSessionSessionCount: null,
-      api: API_ADDRESS.unit.base,
+      api: null,
       entityIdKey: 'id',
       entityParamKey: 'id',
       showRouteName: 'Admin.Unit.Show',
@@ -105,10 +109,8 @@ export default {
         { type: 'hidden', name: 'category', responseKey: 'category_info.id', label: 'id', col: 'col-md-3' }
       ],
 
-      categoriesLoading: false,
-      categories: [],
-      unitsLoading: false,
-      units: [],
+      categories: new UnitCategoryList(),
+      units: new UnitCategoryList(),
       prerequisite: {
         category: null,
         unit: null
@@ -116,7 +118,7 @@ export default {
 
       sessionFilterInputs: [],
 
-      sessionApi: API_ADDRESS.sessionTemplates.base + '?unit=' + this.$route.params.id,
+      sessionApi: null,
       sessionTable: {
         columns: [
           {
@@ -173,31 +175,33 @@ export default {
       }
     }
   },
-  created () {
-    this.api += '/' + this.$route.params.id
-    this.getCategories()
+  mounted () {
+    this.api = APIGateway.unit.APIAdresses.byId(this.$route.params.id)
+    this.sessionApi = APIGateway.sessionTemplate.APIAdresses.base + '?unit=' + this.$route.params.id
+    // this.getCategories()
+    this.mounted = true
   },
   methods: {
     getCategories () {
-      this.categoriesLoading = true
-      this.$axios.get(API_ADDRESS.category.base)
-        .then(response => {
-          this.categoriesLoading = false
-          this.categories = response.data.results
+      this.categories.loading = true
+      APIGateway.unitCategory.index()
+        .then(categories => {
+          this.categories.loading = false
+          this.categories = new UnitCategoryList(categories.list)
         })
         .catch(() => {
-          this.categoriesLoading = false
+          this.categories.loading = false
         })
     },
     getUnits () {
-      this.unitsLoading = true
-      this.$axios.get(API_ADDRESS.unit.base + '?category=' + this.prerequisite.category)
-        .then(response => {
-          this.unitsLoading = false
-          this.units = response.data.results
+      this.units.loading = true
+      APIGateway.unit.index({ category: this.prerequisite.category })
+        .then(units => {
+          this.units.loading = false
+          this.units = new UnitCategoryList(units.list)
         })
         .catch(() => {
-          this.unitsLoading = false
+          this.units.loading = false
         })
     },
     updateCategory () {
@@ -211,7 +215,7 @@ export default {
     },
     createSession () {
       this.newSessionLoading = true
-      this.$axios.post(API_ADDRESS.sessionTemplates.base, {
+      APIGateway.sessionTemplate.create({
         title: this.newSessionName,
         unit: this.$route.params.id
       })

+ 32 - 21
src/pages/Admin/User/index.vue

@@ -1,21 +1,22 @@
 <template>
-  <entity-index ref="entityIndex"
-                v-model:value="inputs"
-                title="لیست کاربران"
-                :api="api"
-                :table="table"
-                :table-keys="tableKeys"
-                :show-expand-button="false"
-                :show-reload-button="false"
-                :show-search-button="false">
-    <template #table-cell="{inputData, showConfirmRemoveDialog}">
-      <q-td :props="inputData.props">
-        <template v-if="inputData.props.col.name === 'actions'">
+  <div class="AdminUserIndex">
+    <entity-index ref="entityIndex"
+                  v-model:value="inputs"
+                  title="لیست کاربران"
+                  :api="api"
+                  :table="table"
+                  :table-keys="tableKeys"
+                  :show-expand-button="false"
+                  :show-reload-button="false"
+                  :show-search-button="false">
+      <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
+        <template v-if="inputData.col.name === 'actions'">
           <div class="action-column-entity-index">
             <q-btn size="md"
                    color="primary"
                    label="جزییات"
-                   :to="{name: 'Admin.User.Show', params: {id: inputData.props.row.id}}" />
+                   :to="{name: 'Admin.User.Show', params: {id: inputData.props.row.id}}"
+                   class="q-mr-md" />
             <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))">
               <q-tooltip>
                 حذف
@@ -23,7 +24,7 @@
             </delete-btn>
           </div>
         </template>
-        <template v-else-if="inputData.props.col.name === 'status'">
+        <template v-else-if="inputData.col.name === 'status'">
           <div class="action-column-entity-index">
             <q-toggle v-model="inputData.props.row.is_active"
                       label="فعال/غیر فعال"
@@ -31,17 +32,17 @@
           </div>
         </template>
         <template v-else>
-          {{ inputData.props.value }}
+          {{ inputData.col.value }}
         </template>
-      </q-td>
-    </template>
-  </entity-index>
+      </template>
+    </entity-index>
+  </div>
 </template>
 
 <script>
 import { shallowRef } from 'vue'
 import { EntityIndex } from 'quasar-crud'
-import API_ADDRESS from 'src/api/Addresses.js'
+import { APIGateway } from 'src/api/APIGateway.js'
 import BtnControl from 'src/components/Control/btn.vue'
 import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
 
@@ -62,7 +63,7 @@ export default {
         { type: 'input', name: 'national_code', value: null, label: 'کد ملی', col: 'col-md-2' },
         { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'جستجو', props: { atClick: this.search }, col: 'col-md-2' }
       ],
-      api: API_ADDRESS.user.base,
+      api: APIGateway.user.APIAdresses.base,
       table: {
         columns: [
           {
@@ -131,7 +132,7 @@ export default {
       this.$refs.entityIndex.search()
     },
     changeUserActiveStatus (user) {
-      this.$axios.put(API_ADDRESS.user.base + '/' + user.id, user)
+      APIGateway.user.updateByAdmin(user)
         .then(() => {
           this.search()
         })
@@ -145,3 +146,13 @@ export default {
   }
 }
 </script>
+
+<style lang="scss">
+.AdminUserIndex {
+  .action-column-entity-index {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+  }
+}
+</style>

+ 10 - 6
src/pages/Admin/User/show.vue

@@ -28,7 +28,8 @@
     <q-tab-panels v-model="tab"
                   animated>
       <q-tab-panel name="userInfo">
-        <entity-edit ref="entityEdit"
+        <entity-edit v-if="mounted"
+                     ref="entityEdit"
                      v-model:value="inputs"
                      title="اطلاعات کاربری"
                      :api="api"
@@ -36,6 +37,7 @@
                      :entity-id-key="entityIdKey"
                      :entity-param-key="entityParamKey"
                      :show-route-name="showRouteName"
+                     :default-layout="false"
                      :show-close-button="false"
                      :show-edit-button="false"
                      :show-expand-button="false"
@@ -77,7 +79,7 @@
 <script>
 import { EntityEdit } from 'quasar-crud'
 import Enums from 'src/assets/Enums/Enums.js'
-import API_ADDRESS from 'src/api/Addresses.js'
+import { APIGateway } from 'src/api/APIGateway.js'
 
 export default {
   name: 'Admin.User.Show',
@@ -85,7 +87,8 @@ export default {
   data () {
     return {
       tab: 'userInfo',
-      api: API_ADDRESS.user.base,
+      api: null,
+      mounted: false,
       entityIdKey: 'id',
       entityParamKey: 'id',
       showRouteName: 'Admin.User.Show',
@@ -105,7 +108,7 @@ export default {
         { type: 'input', name: 'on_call_mobile_number', label: 'تلفن همراه', responseKey: 'on_call_mobile_number', col: 'col-md-3' },
         { type: 'input', name: 'national_code', label: 'کدملی/کد اتباع غیر ایرانی', responseKey: 'national_code', col: 'col-md-3' },
         { type: 'separator', name: 'space', label: 'اطلاعات پروفایل', col: 'col-md-12' },
-        { type: 'file', name: 'picture', label: 'عکس پروفایل', responseKey: 'data.picture', col: 'col-md-3' },
+        { type: 'file', name: 'picture', label: 'عکس پروفایل', responseKey: 'picture', col: 'col-md-3' },
         { type: 'separator', name: 'space', size: '0', col: 'col-md-12' },
         { type: 'input', name: 'firstname', label: 'نام', responseKey: 'firstname', col: 'col-md-3' },
         { type: 'input', name: 'lastname', label: 'نام خانوادگی', responseKey: 'lastname', col: 'col-md-3' },
@@ -164,8 +167,9 @@ export default {
       ]
     }
   },
-  created () {
-    this.api += '/' + this.$route.params.id
+  mounted () {
+    this.api = APIGateway.user.APIAdresses.byId(this.$route.params.id)
+    this.mounted = true
   },
   methods: {
     afterLoadInputData (responseData, setNewInputData) {