Event.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. <template>
  2. <LayoutCommonSection>
  3. <v-row>
  4. <v-col cols="12" sm="12">
  5. <h4 class="mb-8">{{ $t('general_informations') }}</h4>
  6. <UiInputText
  7. v-model="entity.name"
  8. field="name"
  9. :rules="getAsserts('name')"
  10. />
  11. <span class="label">{{ $t('datetimeStart') }}</span>
  12. <UiInputDateTimePicker
  13. :model-value="entity.datetimeStart"
  14. field="datetimeStart"
  15. label="datetimeStart"
  16. :with-time-picker="true"
  17. class="my-2"
  18. :rules="getAsserts('datetimeStart')"
  19. validate-on-blur
  20. @update:model-value="onUpdateDateTimeStart(entity, $event)"
  21. />
  22. <span class="label">{{ $t('datetimeEnd') }}</span>
  23. <UiInputDateTimePicker
  24. :model-value="entity.datetimeEnd"
  25. field="datetimeEnd"
  26. label="datetimeEnd"
  27. :with-time-picker="true"
  28. class="my-2"
  29. :rules="getAsserts('datetimeEnd')"
  30. @update:model-value="onUpdateDateTimeEnd(entity, $event)"
  31. />
  32. <span class="label">{{ $t('description') }}</span>
  33. <UiInputTextArea v-model="entity.description" class="mt-3" />
  34. <UiInputTreeSelectEventCategories
  35. v-model="entity.categories"
  36. label="event_categories_choices"
  37. />
  38. <UiInputImage
  39. v-model="entity.image"
  40. field="image"
  41. :width="240"
  42. :cropping-enabled="true"
  43. />
  44. </v-col>
  45. </v-row>
  46. </LayoutCommonSection>
  47. <LayoutCommonSection>
  48. <v-row>
  49. <v-col cols="12">
  50. <h4 class="mb-8">{{ $t('place_event') }}</h4>
  51. <UiInputAutocompleteApiResources
  52. v-if="!newPlace"
  53. :model-value="entity.place"
  54. field="place"
  55. :model="PlaceSearchItem"
  56. list-value="id"
  57. list-label="name"
  58. @update:model-value="getPlace(entity)"
  59. />
  60. <v-row v-if="!newPlace" class="mb-6 justify-center">
  61. <v-col
  62. v-if="entity.place && !editPlace"
  63. cols="12"
  64. sm="6"
  65. class="d-flex justify-center mb-2"
  66. >
  67. <v-btn
  68. prepend-icon="fa-solid fa-pencil"
  69. @click="onEditPlaceClick(entity)"
  70. >
  71. {{ $t('edit_place') }}
  72. </v-btn>
  73. </v-col>
  74. <v-col cols="12" sm="6" class="d-flex justify-center mb-2">
  75. <v-btn
  76. prepend-icon="fa-solid fa-plus"
  77. @click="onAddPlaceClick(entity)"
  78. >
  79. {{ $t('add_place') }}
  80. </v-btn>
  81. </v-col>
  82. </v-row>
  83. <UiInputText
  84. v-model="entity.placeName"
  85. :readonly="!newPlace && !editPlace"
  86. field="placeName"
  87. />
  88. <UiInputText
  89. v-model="entity.streetAddress"
  90. :readonly="!newPlace && !editPlace"
  91. field="streetAddress"
  92. />
  93. <UiInputText
  94. v-model="entity.streetAddressSecond"
  95. :readonly="!newPlace && !editPlace"
  96. field="streetAddressSecond"
  97. />
  98. <UiInputText
  99. v-model="entity.streetAddressThird"
  100. :readonly="!newPlace && !editPlace"
  101. field="streetAddressThird"
  102. />
  103. <UiInputText
  104. v-model="entity.postalCode"
  105. :readonly="!newPlace && !editPlace"
  106. field="postalCode"
  107. />
  108. <UiInputText
  109. v-model="entity.addressCity"
  110. :readonly="!newPlace && !editPlace"
  111. field="addressCity"
  112. />
  113. <UiInputAutocompleteApiResources
  114. v-model="entity.addressCountry"
  115. :readonly="!newPlace && !editPlace"
  116. field="addressCountry"
  117. :model="Country"
  118. list-value="id"
  119. list-label="name"
  120. />
  121. <client-only>
  122. <UiMapLeaflet
  123. v-model:latitude="entity.latitude"
  124. v-model:longitude="entity.longitude"
  125. :readonly="!newPlace && !editPlace"
  126. :street-address="entity.streetAddress"
  127. :street-address-second="entity.streetAddressSecond"
  128. :street-address-third="entity.streetAddressThird"
  129. :postal-code="entity.postalCode"
  130. :address-city="entity.addressCity"
  131. :address-country-id="entity.addressCountry"
  132. :search-button="true"
  133. ></UiMapLeaflet>
  134. </client-only>
  135. </v-col>
  136. </v-row>
  137. </LayoutCommonSection>
  138. <LayoutCommonSection>
  139. <v-row>
  140. <v-col cols="12">
  141. <h4 class="mb-8">{{ $t('communication_params') }}</h4>
  142. <UiInputText v-model="entity.url" field="url" />
  143. <UiInputAutocompleteEnum
  144. v-model="entity.pricing"
  145. enum-name="pricing_event"
  146. field="pricing"
  147. />
  148. <UiInputText
  149. v-if="entity.pricing === 'PAID'"
  150. v-model="entity.urlTicket"
  151. field="urlTicket"
  152. />
  153. <UiInputNumber
  154. v-if="entity.pricing === 'PAID'"
  155. v-model="entity.priceMini"
  156. field="priceMini"
  157. />
  158. <UiInputNumber
  159. v-if="entity.pricing === 'PAID'"
  160. v-model="entity.priceMaxi"
  161. field="priceMaxi"
  162. />
  163. </v-col>
  164. </v-row>
  165. </LayoutCommonSection>
  166. <LazyLayoutDialog :show="showAlert" theme="warning">
  167. <template #dialogType>{{ $t('important') }}</template>
  168. <template #dialogTitle>{{ $t('place_change_everywhere') }}</template>
  169. <template #dialogText>
  170. <v-card-text class="text">
  171. <p>
  172. {{ $t('warning_edit_place') }}
  173. </p>
  174. </v-card-text>
  175. </template>
  176. <template #dialogBtn>
  177. <v-btn class="mr-4 submitBtn theme-neutral-strong" @click="closeDialog">
  178. {{ $t('cancel') }}
  179. </v-btn>
  180. <v-btn class="mr-4 submitBtn theme-warning" @click="onEditPlaceConfirm">
  181. {{ $t('i_understand') }}
  182. </v-btn>
  183. </template>
  184. </LazyLayoutDialog>
  185. </template>
  186. <script setup lang="ts">
  187. import Event from '~/models/Freemium/Event'
  188. import Place from '~/models/Freemium/Place'
  189. import { getAssertUtils } from '~/services/asserts/getAssertUtils'
  190. import DateUtils from '~/services/utils/dateUtils'
  191. import Country from '~/models/Core/Country'
  192. import PlaceSearchItem from '~/models/Custom/Search/PlaceSearchItem'
  193. import { useEntityManager } from '~/composables/data/useEntityManager'
  194. const props = defineProps<{
  195. modelValue: Event
  196. }>()
  197. const { em } = useEntityManager()
  198. const getAsserts = (key) => getAssertUtils(Event.getAsserts(), key)
  199. const emit = defineEmits(['update:modelValue'])
  200. // Pour éviter l'erreur eslint "Unexpected mutation of "modelValue" prop"
  201. const entity = computed({
  202. get: () => props.modelValue,
  203. set: (value) => emit('update:modelValue', value),
  204. })
  205. /**
  206. * Si la date de début est mise à jour, on s'assure que la date de fin est
  207. * après elle, sinon elle devient égale
  208. * @param entity
  209. * @param dateTime
  210. */
  211. const onUpdateDateTimeStart = (entity, dateTime) => {
  212. if (DateUtils.isBefore(props.entity.datetimeEnd, dateTime, false)) {
  213. entity.datetimeEnd = dateTime
  214. }
  215. entity.datetimeStart = dateTime
  216. emit('update:modelValue', entity)
  217. }
  218. /**
  219. * Si la date de fin est mise à jour, on s'assure que la date de début est
  220. * avant elle, sinon elle devient égale
  221. * @param entity
  222. * @param dateTime
  223. */
  224. const onUpdateDateTimeEnd = (entity, dateTime) => {
  225. if (DateUtils.isBefore(dateTime, props.entity.datetimeStart, false)) {
  226. entity.datetimeStart = dateTime
  227. }
  228. entity.datetimeEnd = dateTime
  229. emit('update:modelValue', entity)
  230. }
  231. const showAlert: Ref<boolean> = ref(false)
  232. const newPlace: Ref<boolean> = ref(false)
  233. const editPlace: Ref<boolean> = ref(false)
  234. /**
  235. * Si on clic sur le bouton "Ajouter un lieu", le choix dans la liste déroulante
  236. * est mise à nulle, et les champs input de l'adresse sont vidées
  237. * @param entity
  238. */
  239. const onAddPlaceClick = function (entity: Event) {
  240. newPlace.value = true
  241. entity.place = null
  242. resetPlace(entity)
  243. }
  244. /**
  245. * Quand on clic sur le bouton "Editer le lieu", une alerte s'affiche
  246. */
  247. const onEditPlaceClick = function () {
  248. showAlert.value = true
  249. }
  250. /**
  251. * Quand on ferme la boite de dialogue
  252. */
  253. const closeDialog = function () {
  254. showAlert.value = false
  255. }
  256. /**
  257. * Si on décide d'éditer le lieu
  258. */
  259. const onEditPlaceConfirm = function () {
  260. showAlert.value = false
  261. editPlace.value = true
  262. }
  263. /**
  264. * Lorsque l'on choisit un lieu dans la liste déroulante, on mets a jour les champs
  265. * input de l'adresse
  266. * @param entity
  267. */
  268. const getPlace = async (entity: Event) => {
  269. if (entity.place) {
  270. const placeInstance = await em.fetch(Place, entity.place as number)
  271. entity.placeName = placeInstance.name
  272. entity.streetAddress = placeInstance.streetAddress
  273. entity.streetAddressSecond = placeInstance.streetAddressSecond
  274. entity.streetAddressThird = placeInstance.streetAddressThird
  275. entity.addressCity = placeInstance.addressCity
  276. entity.postalCode = placeInstance.postalCode
  277. entity.addressCountry = placeInstance.addressCountry
  278. entity.latitude = placeInstance.latitude
  279. entity.longitude = placeInstance.longitude
  280. editPlace.value = false
  281. } else {
  282. //Dans le cas où l'on ne récupère aucune place on remet a null le formulaire de l'adresse
  283. resetPlace(entity)
  284. }
  285. emit('update:modelValue', entity)
  286. }
  287. /**
  288. * fonction permettant de remettre à vide tous les champs input de l'adresse
  289. * @param entity
  290. */
  291. const resetPlace = (entity: Event) => {
  292. entity.placeName = null
  293. entity.streetAddress = null
  294. entity.streetAddressSecond = null
  295. entity.streetAddressThird = null
  296. entity.addressCity = null
  297. entity.postalCode = null
  298. entity.addressCountry = null
  299. entity.latitude = null
  300. entity.longitude = null
  301. }
  302. // Nettoyer les données lors du démontage du composant
  303. onBeforeUnmount(() => {
  304. // Nettoyer les références du store si nécessaire
  305. if (import.meta.client) {
  306. clearNuxtData('/^' + Place.entity + '_/')
  307. useRepo(Place).flush()
  308. }
  309. })
  310. </script>
  311. <style scoped lang="scss">
  312. .label {
  313. font-size: 16px;
  314. color: rgb(var(--v-theme-on-primary-alt));
  315. }
  316. </style>