UserClassroomCard.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <template>
  2. <q-card-section class="classroom-card row">
  3. <div class="right-side col-6">
  4. <img class="thumbnail"
  5. :src="registration.classroom_info.thumbnail">
  6. <q-btn color="primary"
  7. :to="{name: showPageRouteName, params: {id: registration.classroom_info.id}}">
  8. مشاهده
  9. </q-btn>
  10. </div>
  11. <div class="left-side col-6">
  12. <div class="title-box">
  13. <q-banner class="banner">{{ convertClassroomTitle(registration.classroom_info.title) }}</q-banner>
  14. <div>
  15. {{ getClassroomTitleCaption(registration.classroom_info.title) }}
  16. </div>
  17. <div>
  18. {{ getHoldingType(registration.classroom_info.holding_type) }}
  19. |
  20. {{ registration.classroom_info.sessions_count }} جلسه
  21. </div>
  22. </div>
  23. <div class="status-box">
  24. <div class="registration-status-box">
  25. <q-icon name="event_note"
  26. class="material-icons-outlined" />
  27. {{ this.getRegistrationStatusTitle(registration) }}
  28. </div>
  29. <div class="financial-status-box">
  30. <q-icon name="credit_card"
  31. class="material-icons-outlined" />
  32. {{ this.getInvoiceStatusTitle(registration.invoice_info.status) }}
  33. </div>
  34. </div>
  35. </div>
  36. </q-card-section>
  37. </template>
  38. <script>
  39. import Enums from 'assets/Enums/Enums.js'
  40. import ShamsiDate from 'assets/ShamsiDate.js'
  41. import { APIGateway } from 'src/api/APIGateway.js'
  42. import { Classroom } from 'src/models/Classroom.js'
  43. import { Registration } from 'src/models/Registration.js'
  44. import { UnitCategory } from 'src/models/UnitCategory'
  45. import { mixinWidget } from 'src/mixin/Mixins.js'
  46. import { TranscriptSheet } from 'src/models/TranscriptSheet'
  47. export default {
  48. name: 'UserClassroomCard',
  49. mixins: [mixinWidget],
  50. props: {
  51. registration: {
  52. type: Registration,
  53. default: new Registration()
  54. },
  55. classroom: {
  56. type: Classroom,
  57. default: new Classroom()
  58. },
  59. classroomId: {
  60. type: Number,
  61. default: null
  62. },
  63. ownerId: {
  64. type: Number,
  65. default: null
  66. },
  67. classroomType: {
  68. type: String,
  69. default: 'TRAINING'
  70. }
  71. },
  72. emits: [],
  73. data: () => ({
  74. defaultOptions: {
  75. profileMode: false,
  76. classroomType: 'TRAINING'
  77. },
  78. acceptClassType: 'register', // accept - enrollment - rules
  79. fetchCodesLoading: false,
  80. dropLoading: false,
  81. rulesAccept: false,
  82. rulesDialog: false,
  83. loading: true
  84. }),
  85. computed: {
  86. listTitle () {
  87. if (this.localOptions.classroomType === 'TRAINING') {
  88. return 'لیست دوره های آموزشی'
  89. }
  90. if (this.localOptions.classroomType === 'EVENT') {
  91. return 'لیست رویدادها'
  92. }
  93. return 'لیست دوره های آموزشی'
  94. },
  95. showPageRouteName () {
  96. if (this.localOptions.classroomType === 'TRAINING') {
  97. return 'UserPanel.Profile.ClassroomInfo'
  98. }
  99. if (this.localOptions.classroomType === 'EVENT') {
  100. return 'UserPanel.Profile.EventInfo'
  101. }
  102. return 'UserPanel.Profile.ClassroomInfo'
  103. },
  104. classroomTypeTitle () {
  105. const unitCategory = new UnitCategory({ type: this.localOptions.classroomType })
  106. return unitCategory.type_info.label
  107. }
  108. },
  109. methods: {
  110. getClassroomTitleCaption(title) {
  111. const match = title.match(/^(.*?)\s*\((.*?)\)$/)
  112. if (match) {
  113. const insideParenthesis = match[2].split('-')[0].trim()
  114. return `${insideParenthesis}`
  115. } else {
  116. return ''
  117. }
  118. },
  119. convertClassroomTitle(title) {
  120. const match = title.match(/^(.*?)\s*\((.*?)\)$/)
  121. if (match) {
  122. const beforeParenthesis = match[1]
  123. return `${beforeParenthesis}`
  124. } else {
  125. return title
  126. }
  127. },
  128. getTitledDateTime (dateTime) {
  129. return ShamsiDate.getTitledDateTime(dateTime)
  130. },
  131. acceptAndContinue () {
  132. this.$store.commit('Shop/updateOnRegisterClassroom', this.classroom)
  133. this.$router.push({ name: 'UserPanel.ShopCompleteInfo', query: { type: this.acceptClassType, source: this.classroomType === 'EVENT' ? 'event' : 'classroom' } })
  134. },
  135. onEnrolment () {
  136. this.acceptClassType = 'enrollment'
  137. this.rulesDialog = true
  138. },
  139. onDropping () {
  140. this.$q.dialog({
  141. title: 'توجه',
  142. message: 'آیا از حذف این دوره اطمینان دارید؟',
  143. cancel: true,
  144. persistent: true
  145. }).onOk(() => {
  146. this.dropLoading = true
  147. APIGateway.classroom.dropByUser(this.classroom.id)
  148. .then(() => {
  149. this.dropLoading = false
  150. this.$emit('onDrop')
  151. })
  152. .catch(() => {
  153. this.dropLoading = false
  154. })
  155. })
  156. },
  157. openRulesDialog () {
  158. this.acceptClassType = 'rules'
  159. this.rulesDialog = true
  160. },
  161. openCodeLink () {
  162. if (!this.classroom.codes) {
  163. return
  164. }
  165. const fileName = (this.classroom.codes.match(/(?<=\/)[^/?#]+(?=[^/]*$)/gm) || [this.classroom.title])[0]
  166. this.fetchCodesLoading = true
  167. fetch(this.classroom.codes)
  168. .then(response => response.blob())
  169. .then(blob => {
  170. const link = document.createElement('a')
  171. link.href = URL.createObjectURL(blob)
  172. link.download = fileName
  173. link.click()
  174. this.fetchCodesLoading = false
  175. })
  176. .catch(() => {
  177. this.fetchCodesLoading = false
  178. })
  179. },
  180. openRegisterDialog () {
  181. this.acceptClassType = 'register'
  182. this.rulesDialog = true
  183. },
  184. getHoldingType (type) {
  185. const target = Enums.classroomHoldingTypes.find(item => item.value === type)
  186. if (target) {
  187. return target.label
  188. }
  189. return '-'
  190. },
  191. getClassroomHoldingTypeTitle (type) {
  192. const target = Enums.classroomHoldingTypes.find(item => item.value === type)
  193. if (!target) {
  194. return '-'
  195. }
  196. return target.label
  197. },
  198. getRegistrationStatusTitle (registration) {
  199. if (registration.status === 'REGISTERED' && registration.transcript_sheet_info) {
  200. return (new TranscriptSheet(registration.transcript_sheet_info)).status_info.label
  201. } else {
  202. return (new Registration(registration)).status_info.label
  203. }
  204. },
  205. getRegistrationStatusTitleClass (registration) {
  206. if (registration.status === 'REGISTERED' && registration.transcript_sheet_info) {
  207. return (new TranscriptSheet(registration.transcript_sheet_info)).status_info.value
  208. }
  209. return null
  210. },
  211. getClassroomStatusTitle (type) {
  212. const target = Enums.classroomStatuses.find(item => item.value === type)
  213. if (!target) {
  214. return '-'
  215. }
  216. return target.label
  217. },
  218. getInvoiceStatusTitle (type) {
  219. const target = Enums.invoiceStatus.find(item => item.value === type)
  220. if (!target) {
  221. return '-'
  222. }
  223. return target.label
  224. },
  225. getAudienceGenderType (type) {
  226. const target = Enums.classroomGenders.find(item => item.value === type)
  227. if (target) {
  228. return target.label
  229. }
  230. return '-'
  231. },
  232. getTime (time) {
  233. return ShamsiDate.getDateTime(time)
  234. },
  235. getTerm (classroom) {
  236. if (!classroom.beginning_registration_period) {
  237. return '-'
  238. }
  239. return ShamsiDate.getTerm(classroom.beginning_registration_period)
  240. }
  241. }
  242. }
  243. </script>
  244. <style scoped lang="scss">
  245. .classroom-card {
  246. display: flex;
  247. justify-content: space-between;
  248. align-items: flex-start;
  249. align-self: stretch;
  250. padding: 0;
  251. :deep(.q-card__section--vert){
  252. padding: 0;
  253. }
  254. .q-card__section.q-card__section--vert.classroom-card.row {
  255. padding: 0;
  256. }
  257. .right-side {
  258. display: flex;
  259. flex-direction: column;
  260. align-items: flex-start;
  261. padding: 0 4px 0 0;
  262. .thumbnail {
  263. max-width: 100%;
  264. height: auto;
  265. display: block;
  266. }
  267. .q-btn {
  268. display: flex;
  269. height: 48px;
  270. justify-content: center;
  271. align-items: center;
  272. align-self: stretch;
  273. border-radius: 0 0 0 4px;
  274. }
  275. }
  276. .left-side {
  277. display: flex;
  278. flex-direction: column;
  279. justify-content: center;
  280. align-items: flex-end;
  281. gap: 16px;
  282. align-self: stretch;
  283. .title-box {
  284. display: flex;
  285. flex-direction: column;
  286. justify-content: center;
  287. align-items: flex-start;
  288. align-self: stretch;
  289. gap: 8px;
  290. :deep(.q-banner) {
  291. padding: 8px 4px;
  292. .q-banner__content {
  293. font-size: 16px;
  294. }
  295. }
  296. }
  297. .status-box {
  298. display: flex;
  299. flex-direction: column;
  300. justify-content: center;
  301. align-items: flex-start;
  302. align-self: stretch;
  303. .registration-status-box {
  304. display: flex;
  305. height: 30px;
  306. align-items: center;
  307. gap: 4px;
  308. align-self: stretch;
  309. }
  310. .financial-status-box {
  311. display: flex;
  312. align-items: center;
  313. gap: 4px;
  314. align-self: stretch;
  315. }
  316. }
  317. }
  318. }
  319. </style>