ClassroomCarousel.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <template>
  2. <div class="classroomCarousel">
  3. <div class="classroomCarousel-title">
  4. <div>
  5. <q-banner class="banner">
  6. دوره های آموزشی
  7. </q-banner>
  8. </div>
  9. <div>
  10. <q-btn flat
  11. :to="{name: 'Public.AllClassrooms'}">
  12. مشاهده همه
  13. <svg xmlns="http://www.w3.org/2000/svg"
  14. width="18.387"
  15. height="11.502"
  16. viewBox="0 0 18.387 11.502"
  17. class="q-ml-sm">
  18. <path id="Combined_Shape"
  19. data-name="Combined Shape"
  20. 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"
  21. transform="translate(18.387)"
  22. fill="#eac38a" />
  23. </svg>
  24. </q-btn>
  25. </div>
  26. </div>
  27. <div class="carousel-section">
  28. <carousel v-if="!classrooms.loading && classrooms.list.length > 0"
  29. :breakpoints="breakpoints"
  30. dir="rtl">
  31. <slide v-for="classroom in classrooms.list"
  32. :key="classroom.id + classroomsKey">
  33. <classroom-item :classroom="classroom" />
  34. </slide>
  35. <template #addons="{ slidesCount }">
  36. <navigation v-if="slidesCount > 1" />
  37. <pagination v-if="slidesCount > 1 && false" />
  38. </template>
  39. </carousel>
  40. <div v-else-if="!classrooms.loading && classrooms.list.length === 0">
  41. دوره ای یافت نشد.
  42. </div>
  43. <div v-else-if="classrooms.loading">
  44. کمی صبر کنید ...
  45. </div>
  46. </div>
  47. </div>
  48. </template>
  49. <script>
  50. import 'vue3-carousel/dist/carousel.css'
  51. import { User } from 'src/models/User.js'
  52. import ShamsiDate from 'src/assets/ShamsiDate.js'
  53. import { APIGateway } from 'src/api/APIGateway.js'
  54. import ClassroomItem from 'src/components/ClassroomItem.vue'
  55. import { mixinPrefetchServerData } from 'src/mixin/Mixins.js'
  56. import { Classroom, ClassroomList } from 'src/models/Classroom.js'
  57. import { ClassroomRegistrationList } from 'src/models/ClassroomRegistration.js'
  58. import { Carousel, Slide, Pagination, Navigation } from 'vue3-carousel/dist/carousel'
  59. export default {
  60. name: 'ClassroomCarousel',
  61. components: {
  62. Carousel,
  63. Slide,
  64. Pagination,
  65. Navigation,
  66. ClassroomItem
  67. },
  68. mixins: [mixinPrefetchServerData],
  69. data: () => ({
  70. loading: false,
  71. user: new User(),
  72. classroomsKey: Date.now(),
  73. userRegistrations: new ClassroomRegistrationList(),
  74. slide: 0,
  75. classrooms: new ClassroomList(),
  76. breakpoints: {
  77. // 1024 and up
  78. 1024: {
  79. itemsToShow: 3,
  80. snapAlign: 'start'
  81. },
  82. // 700px and up
  83. 700: {
  84. itemsToShow: 2.2,
  85. snapAlign: 'center'
  86. },
  87. // 300px and up
  88. 300: {
  89. itemsToShow: 1.1,
  90. snapAlign: 'center'
  91. }
  92. },
  93. maximizedToggle: true,
  94. dialog: false
  95. }),
  96. mounted () {
  97. this.loadAuthData()
  98. if (this.user && this.user.id !== null) {
  99. this.getUserRegistrations()
  100. }
  101. },
  102. methods: {
  103. getHoldingType (classroom) {
  104. return new Classroom(classroom).holding_type_info.label
  105. },
  106. prefetchServerDataPromise () {
  107. return this.getClassrooms()
  108. },
  109. prefetchServerDataPromiseThen (classroomList) {
  110. this.classrooms = new ClassroomList(classroomList.list)
  111. this.classrooms.loading = false
  112. },
  113. prefetchServerDataPromiseCatch () {
  114. this.classrooms.loading = false
  115. },
  116. loadAuthData () {
  117. this.user = this.$store.getters['Auth/user']
  118. },
  119. getTerm (classroom) {
  120. if (!classroom.beginning_registration_period) {
  121. return '-'
  122. }
  123. return ShamsiDate.getTerm(classroom.beginning_registration_period)
  124. },
  125. isClassroomRegistered (classroomId) {
  126. return !!this.userRegistrations.list.find(item => item.classroom === classroomId && (item.status === 'REGISTERED' || item.status === 'ENROLLED'))
  127. },
  128. getUserRegistrations () {
  129. this.userRegistrations.loading = true
  130. APIGateway.classroomRegistration.index()
  131. .then((classroomRegistrationList) => {
  132. this.userRegistrations = new ClassroomRegistrationList(classroomRegistrationList.list)
  133. this.classroomsKey = Date.now()
  134. this.userRegistrations.loading = false
  135. })
  136. .catch(() => {
  137. this.userRegistrations.loading = false
  138. })
  139. },
  140. getClassrooms () {
  141. this.classrooms.loading = true
  142. return APIGateway.classroom.index({
  143. unit__category__type: 'EVENT'
  144. })
  145. }
  146. }
  147. }
  148. </script>
  149. <style scoped lang="scss">
  150. .classroomCarousel {
  151. padding: 60px 0;
  152. .classroomCarousel-title {
  153. display: flex;
  154. flex-flow: row;
  155. justify-content: space-between;
  156. padding-bottom: 33px;
  157. }
  158. .carousel-section {
  159. padding: 0 60px;
  160. :deep(.carousel__prev),
  161. :deep(.carousel__next) {
  162. width: 48px;
  163. height: 48px;
  164. background-color: #475F4A;
  165. border-radius: 8px;
  166. &.carousel__prev--in-active {
  167. background-color: #DEDEDE;
  168. }
  169. &:after {
  170. }
  171. svg {
  172. //display: none;
  173. }
  174. }
  175. :deep(.carousel__prev) {
  176. right: auto;
  177. left: 0;
  178. transform: translate(-100%, -50%);
  179. color: white;
  180. }
  181. :deep(.carousel__next) {
  182. left: auto;
  183. right: 0;
  184. transform: translate(100%, -50%);
  185. color: white;
  186. }
  187. .carousel__slide {
  188. padding: 0 12px;
  189. .classroomCarousel-item {
  190. width: 100%;
  191. &.isRegistered {
  192. .thumbnail {
  193. position: relative;
  194. z-index: 1;
  195. .RegisteredSign {
  196. position: absolute;
  197. right: 5px;
  198. top: 7px;
  199. z-index: 2;
  200. display: block;
  201. }
  202. }
  203. }
  204. .thumbnail {
  205. padding-top: 17px;
  206. padding-left: 22px;
  207. padding-right: 22px;
  208. padding-bottom: 26px;
  209. .RegisteredSign {
  210. display: none;
  211. }
  212. }
  213. .title {
  214. text-align: left;
  215. padding-top: 0;
  216. padding-left: 46px;
  217. padding-right: 46px;
  218. padding-bottom: 33px;
  219. }
  220. .attribute {
  221. padding-top: 0;
  222. padding-left: 46px;
  223. padding-right: 46px;
  224. padding-bottom: 44px;
  225. .attribute-item {
  226. margin-bottom: 21px;
  227. display: flex;
  228. flex-flow: row;
  229. .attribute-logo {
  230. margin-right: 15px;
  231. }
  232. &:last-child {
  233. margin-bottom: 0;
  234. }
  235. }
  236. }
  237. .action-section {
  238. padding: 0;
  239. .btn-show-classroom {
  240. width: 100%;
  241. height: 60px;
  242. border-top-right-radius: 0;
  243. border-top-left-radius: 0;
  244. }
  245. }
  246. }
  247. }
  248. }
  249. }
  250. </style>