Event.vue 10 KB

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