dashboard.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <template>
  2. <v-container fluid class="inner-container">
  3. <v-row>
  4. <!-- Bloc événements -->
  5. <v-col cols="12" md="7">
  6. <v-card>
  7. <v-tabs v-model="tab" class="tabs-title">
  8. <v-tab value="future">{{$t('futur_event')}}</v-tab>
  9. <v-tab value="past">{{$t('past_event')}}</v-tab>
  10. </v-tabs>
  11. <v-btn color="primary" to="events/new" class="ml-5 mt-5">{{$t('add_event')}}</v-btn>
  12. <v-tabs-window v-model="tab">
  13. <v-tabs-window-item value="future">
  14. <UiLoadingPanel v-if="statusUpcomingEvents == FETCHING_STATUS.PENDING" />
  15. <UiEventList
  16. v-if="statusUpcomingEvents == FETCHING_STATUS.SUCCESS && upcomingEvents?.items"
  17. :events="upcomingEvents.items"
  18. :pagination="upcomingEvents.pagination"
  19. @load="loadUpcomingEvents"
  20. @edit="editEvent"
  21. />
  22. <span v-if="upcomingEvents.items.length == 0" class="no_event">
  23. {{$t('no_future_event')}}
  24. </span>
  25. </v-tabs-window-item>
  26. <v-tabs-window-item value="past">
  27. <UiLoadingPanel v-if="statusPastEvents == FETCHING_STATUS.PENDING" />
  28. <UiEventList
  29. v-if="statusPastEvents == FETCHING_STATUS.SUCCESS && pastEvents?.items"
  30. :events="pastEvents.items"
  31. :pagination="pastEvents.pagination"
  32. @load="loadPastEvents"
  33. @edit="editEvent"
  34. />
  35. <span v-if="pastEvents.items.length == 0" class="no_event">
  36. {{$t('no_past_event')}}
  37. </span>
  38. </v-tabs-window-item>
  39. </v-tabs-window>
  40. </v-card>
  41. </v-col>
  42. <!-- Bloc structure -->
  43. <v-col cols="12" md="5">
  44. <v-card v-if="statusOrganization == FETCHING_STATUS.SUCCESS" class="pa-5">
  45. <v-card-title class="text-h6" >
  46. <v-icon icon="fa fa-hotel" class="text-button icon-hotel" />
  47. <span class="organization_title">{{$t('my_organization')}}</span>
  48. </v-card-title>
  49. <v-card-text>
  50. <div><strong>{{$t('name')}} :</strong> {{ organization?.name }}</div>
  51. <div><strong>{{$t('email')}} :</strong> {{ organization?.email }}</div>
  52. </v-card-text>
  53. </v-card>
  54. <v-btn block class="mb-2 btn btn_edit_orga" to="organization">
  55. <i class="fa fa-pen mr-2" />{{$t('edit_organization')}}
  56. </v-btn>
  57. <v-btn block class="text-black btn btn_trial" @click="startTrial">
  58. <span><v-icon icon="fa fa-ticket" /> {{$t('try_premium_light')}}<br /> {{$t('30_days_free')}}</span>
  59. </v-btn>
  60. </v-col>
  61. </v-row>
  62. </v-container>
  63. <LayoutDialogTrialAlreadyDid
  64. :show="showDialogTrialAllReadyDid"
  65. @close-dialog="showDialogTrialAllReadyDid = false"
  66. />
  67. </template>
  68. <script setup lang="ts">
  69. import Query from "~/services/data/Query";
  70. definePageMeta({
  71. name: 'freemium_dashboard_page',
  72. })
  73. import {type Ref, ref} from 'vue'
  74. import {useEntityFetch} from "~/composables/data/useEntityFetch";
  75. import Organization from "~/models/Freemium/Organization";
  76. import Event from "~/models/Freemium/Event";
  77. import type {AsyncData} from "#app";
  78. import OrderBy from "~/services/data/Filters/OrderBy";
  79. import {FETCHING_STATUS, ORDER_BY_DIRECTION, TIME_STRATEGY} from "~/types/enum/data";
  80. import PageFilter from "~/services/data/Filters/PageFilter";
  81. import TimeFilter from "~/services/data/Filters/TimeFilter";
  82. import Country from "~/models/Core/Country";
  83. import DateUtils from "~/services/utils/dateUtils";
  84. import UrlUtils from "~/services/utils/urlUtils";
  85. import {useApiLegacyRequestService} from "~/composables/data/useApiLegacyRequestService";
  86. //Ref Définition
  87. const runtimeConfig = useRuntimeConfig()
  88. const { fetch, fetchCollection } = useEntityFetch()
  89. const { apiRequestService } = useApiLegacyRequestService()
  90. const tab = ref(null)
  91. const upcomingPage = ref(1)
  92. const pastPage = ref(1)
  93. const showDialogTrialAllReadyDid: Ref<boolean> = ref(false)
  94. //Fetch
  95. const { data: organization, status:statusOrganization } = fetch(Organization)
  96. const { data: upcomingEvents, status: statusUpcomingEvents, refresh: refreshUpcomingEvents } = fetchEvents()
  97. const { data: pastEvents, status: statusPastEvents, refresh: refreshPastEvents } = fetchEvents(true)
  98. /**
  99. * Charge une page des événements à venir
  100. * @param pageNumber
  101. */
  102. function loadUpcomingEvents(pageNumber: number) {
  103. upcomingPage.value = pageNumber
  104. refreshPastEvents()
  105. }
  106. /**
  107. * Cahrge une page des événements passées
  108. * @param pageNumber
  109. */
  110. function loadPastEvents(pageNumber: number) {
  111. pastPage.value = pageNumber
  112. refreshPastEvents()
  113. }
  114. /**
  115. * Redirige vers la page d'édition d'un événement
  116. * @param eventId
  117. */
  118. function editEvent(eventId: number) {
  119. navigateTo(UrlUtils.join('events', eventId))
  120. }
  121. /**
  122. * Récupère la liste des événements
  123. * @param past
  124. */
  125. function fetchEvents(past:boolean = false){
  126. const today = computed(() => DateUtils.formatIsoShortDate(new Date()))
  127. const query =
  128. new Query(
  129. new OrderBy('datetimeStart', past ? ORDER_BY_DIRECTION.DESC : ORDER_BY_DIRECTION.ASC),
  130. new PageFilter(past ? pastPage : upcomingPage, ref(5)),
  131. new TimeFilter('datetimeStart', today, past ? TIME_STRATEGY.BEFORE : TIME_STRATEGY.AFTER)
  132. )
  133. return fetchCollection(Event, null, query)
  134. }
  135. /**
  136. * Action lorsque l'on souhaite démarrer l'essai
  137. */
  138. async function startTrial() {
  139. try {
  140. await apiRequestService.get('/trial/is_available')
  141. const v1BaseURL =
  142. runtimeConfig.baseUrlAdminLegacy ||
  143. runtimeConfig.public.baseUrlAdminLegacy
  144. await navigateTo(UrlUtils.join(v1BaseURL, '#', 'trial'), {
  145. external: true,
  146. })
  147. } catch (error) {
  148. console.log(error)
  149. showDialogTrialAllReadyDid.value = true
  150. }
  151. }
  152. /**
  153. * Nettoyage du store
  154. */
  155. onUnmounted(() => {
  156. useRepo(Organization).flush()
  157. useRepo(Event).flush()
  158. useRepo(Country).flush()
  159. })
  160. </script>
  161. <style scoped>
  162. .tabs-title{
  163. margin-top: 20px;
  164. padding-left: 20px;
  165. background-color: rgb(var(--v-theme-neutral));
  166. .v-tab--selected{
  167. color: rgb(var(--v-theme-on-neutral--clickable));
  168. }
  169. }
  170. .v-card {
  171. margin-bottom: 16px;
  172. color: rgb(var(--v-theme-on-primary-alt));
  173. }
  174. .v-card-text{
  175. div{
  176. line-height: 2;
  177. }
  178. }
  179. .organization_title{
  180. font-weight: 500;
  181. }
  182. .icon-hotel{
  183. margin: 0 5px 4px 0;
  184. }
  185. .btn {
  186. border: 1px solid;
  187. cursor: pointer;
  188. }
  189. .inner-container {
  190. margin: 0 auto;
  191. padding: 30px;
  192. }
  193. .btn_trial {
  194. height: 55px;
  195. background-color: rgb(var(--v-theme-x-create-btn));
  196. color: #000;
  197. span {
  198. text-align: center;
  199. line-height: 1.2; /* optionnel : pour resserrer ou espacer */
  200. }
  201. .v-icon {
  202. transform: rotate(135deg); /* angle en degrés */
  203. font-size: 16px;
  204. padding-right: 5px;
  205. margin: 0 5px 4px 0;
  206. }
  207. }
  208. .btn_edit_orga{
  209. color: rgb(var(--v-theme-on-primary-alt)) !important;
  210. }
  211. .no_event{
  212. padding: 25px;
  213. font-size: 16px;
  214. }
  215. </style>