@icvdeveloper/common-module 0.0.113 → 0.0.114

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +6 -6
  2. package/dist/module.json +1 -1
  3. package/dist/runtime/@types/components.d.ts +2 -0
  4. package/dist/runtime/assets/svg/answer.svg +14 -14
  5. package/dist/runtime/assets/svg/avatar.svg +1 -1
  6. package/dist/runtime/assets/svg/bell-icon.svg +3 -3
  7. package/dist/runtime/assets/svg/checkmark-icon.svg +1 -1
  8. package/dist/runtime/assets/svg/close-icon.svg +1 -1
  9. package/dist/runtime/assets/svg/icon-avatar.svg +1 -1
  10. package/dist/runtime/assets/svg/icon-chevron.svg +4 -4
  11. package/dist/runtime/assets/svg/icon-circle-plus.svg +1 -1
  12. package/dist/runtime/assets/svg/icon-close.svg +1 -1
  13. package/dist/runtime/assets/svg/icon-info.svg +2 -2
  14. package/dist/runtime/assets/svg/icon-new-window.svg +11 -11
  15. package/dist/runtime/assets/svg/icon-offline.svg +3 -3
  16. package/dist/runtime/assets/svg/icon-online.svg +3 -3
  17. package/dist/runtime/assets/svg/icon-person.svg +2 -2
  18. package/dist/runtime/assets/svg/icon-play.svg +2 -2
  19. package/dist/runtime/assets/svg/icon-star-filled.svg +29 -29
  20. package/dist/runtime/assets/svg/icon-star.svg +24 -24
  21. package/dist/runtime/assets/svg/icon-video-chat.svg +14 -14
  22. package/dist/runtime/assets/svg/icon-website.svg +2 -2
  23. package/dist/runtime/assets/svg/icon-zoom.svg +10 -10
  24. package/dist/runtime/assets/svg/notification-icon.svg +32 -32
  25. package/dist/runtime/assets/svg/offline-icon.svg +1 -1
  26. package/dist/runtime/assets/svg/online-icon.svg +3 -3
  27. package/dist/runtime/assets/svg/peer2peer.svg +3 -3
  28. package/dist/runtime/assets/svg/phone.svg +1 -1
  29. package/dist/runtime/assets/svg/plus-icon.svg +1 -1
  30. package/dist/runtime/assets/svg/red-icon.svg +3 -3
  31. package/dist/runtime/assets/svg/reject.svg +14 -14
  32. package/dist/runtime/assets/svg/search-icon.svg +3 -3
  33. package/dist/runtime/components/affiliates/AffiliatePage.vue +17 -17
  34. package/dist/runtime/components/agenda/AgendaList.vue +271 -271
  35. package/dist/runtime/components/agenda/AgendaTabbed.vue +309 -309
  36. package/dist/runtime/components/agenda/components/AgendaListAccordion.vue +67 -67
  37. package/dist/runtime/components/agenda/components/Calendar.vue +81 -81
  38. package/dist/runtime/components/agenda/components/InfoLink.vue +56 -56
  39. package/dist/runtime/components/agenda/components/PlayIcon.vue +49 -49
  40. package/dist/runtime/components/agenda/components/PresentationLink.vue +137 -137
  41. package/dist/runtime/components/agenda/components/Sponsor.vue +132 -132
  42. package/dist/runtime/components/auth/LoginFullWidth.vue +78 -78
  43. package/dist/runtime/components/auth/PasswordReset.vue +60 -60
  44. package/dist/runtime/components/auth/Registration.vue +27 -27
  45. package/dist/runtime/components/auth/Ucc.vue +132 -132
  46. package/dist/runtime/components/core/Accordion.vue +97 -97
  47. package/dist/runtime/components/core/CountdownTimer.vue +357 -357
  48. package/dist/runtime/components/core/DynamicHtml.vue +1 -1
  49. package/dist/runtime/components/core/Modal.vue +111 -111
  50. package/dist/runtime/components/core/Navbar.vue +154 -154
  51. package/dist/runtime/components/core/SvgIcon.vue +157 -157
  52. package/dist/runtime/components/core/ZoomModal.vue +37 -37
  53. package/dist/runtime/components/events/EventHeader.vue +133 -133
  54. package/dist/runtime/components/events/ListEvents.vue +567 -551
  55. package/dist/runtime/components/forms/AlertBox.vue +21 -21
  56. package/dist/runtime/components/forms/ErrorField.vue +17 -17
  57. package/dist/runtime/components/forms/Message.vue +27 -27
  58. package/dist/runtime/components/forms/SearchInput.vue +38 -38
  59. package/dist/runtime/components/forms/SupportForm.vue +112 -112
  60. package/dist/runtime/components/forms/SwitchInput.vue +42 -42
  61. package/dist/runtime/components/forms/TextArea.vue +26 -26
  62. package/dist/runtime/components/forms/TextInput.vue +28 -28
  63. package/dist/runtime/components/layouts/Accordion.vue +78 -78
  64. package/dist/runtime/components/media/ArchivePlayerAndContentContainer.vue +160 -157
  65. package/dist/runtime/components/media/ArchiveVideoPlayer.vue +186 -186
  66. package/dist/runtime/components/media/PlayerAndContentContainer.vue +178 -175
  67. package/dist/runtime/components/media/WebcastVideoPlayer.vue +167 -167
  68. package/dist/runtime/components/media/components/AgendaPanel.vue +43 -43
  69. package/dist/runtime/components/media/components/ArchiveMediaContainer.vue +91 -91
  70. package/dist/runtime/components/media/components/CeCreditNotification.vue +95 -95
  71. package/dist/runtime/components/media/components/ContentAccordion.vue +63 -63
  72. package/dist/runtime/components/media/components/ContentArea.vue +158 -158
  73. package/dist/runtime/components/media/components/ContentTabs.vue +231 -231
  74. package/dist/runtime/components/media/components/DocumentsPanel.vue +31 -31
  75. package/dist/runtime/components/media/components/JsonApi.vue +31 -31
  76. package/dist/runtime/components/media/components/MediaContainer.vue +63 -63
  77. package/dist/runtime/components/media/components/OverviewPanel.vue +52 -52
  78. package/dist/runtime/components/media/components/PresentersPanel.vue +52 -52
  79. package/dist/runtime/components/media/components/SessionReporting.vue +93 -93
  80. package/dist/runtime/components/media/components/SponsorsPanel.vue +71 -71
  81. package/dist/runtime/components/media/components/WindowContent.vue +92 -92
  82. package/dist/runtime/components/media/components/WindowSlide.vue +72 -72
  83. package/dist/runtime/components/presenters/PresenterListing.vue +164 -164
  84. package/dist/runtime/components/presenters/PresenterModal.vue +223 -223
  85. package/dist/runtime/components/profile/Profile.vue +149 -149
  86. package/dist/runtime/components/profile/components/Sidebar.vue +27 -27
  87. package/dist/runtime/components/profile/components/SidebarNavItem.vue +39 -39
  88. package/dist/runtime/components/profile/tabs/Favorites.vue +21 -21
  89. package/dist/runtime/components/profile/tabs/GeneralInformation.vue +122 -122
  90. package/dist/runtime/components/profile/tabs/ProfileImage.vue +75 -75
  91. package/dist/runtime/components/support/FAQAccordion.vue +140 -140
  92. package/dist/runtime/composables/useEvents.d.ts +4 -0
  93. package/dist/runtime/composables/useEvents.mjs +11 -1
  94. package/package.json +1 -1
@@ -1,553 +1,569 @@
1
- <script lang="ts" setup>
2
- import { ref, toRefs, computed } from "vue";
3
- import { storeToRefs } from "pinia";
4
- import { useConferencesStore } from "../../store/conferences";
5
- import { useTemplateConfigsStore } from "../../store/templateConfigs";
6
- import { useDateFormat } from "../../composables/useDateFormat";
7
- import { useConferenceHelpers } from "../../composables/useConferenceHelpers";
8
- import { useEvents } from "../../composables/useEvents";
9
- import { useClassBinding } from "../../composables/useClassBinding";
10
- import CommonSponsor from "../agenda/components/Sponsor.vue";
11
- import { Conference, ConferenceState } from "../../models/conference";
12
- import { Position } from "../../enums/general";
13
- import {
14
- listEventsClassObj,
15
- listEventsCompObj,
16
- countdownTimerClassObj,
17
- sponsorClassObj,
18
- } from "../../@types/components";
19
-
20
- interface Props {
21
- showSponsors?: boolean;
22
- showBrand?: boolean;
23
- showCountdown?: boolean;
24
- liveButton?: boolean;
25
- mediaButton?: boolean;
26
- registerButton?: boolean;
27
- loginButton?: boolean;
28
- viewInfoButton?: boolean;
29
- registerPathPrefix?: string;
30
- eventPathPrefix?: string;
31
- liveButtonOpensStream?: boolean;
32
- isUpcoming?: boolean;
33
- showEventImage?: boolean;
34
- sponsorPosition?: Position;
35
- borderPosition?: Position;
36
- countdownPosition?: Position;
37
- classObject?: listEventsClassObj;
38
- }
39
-
40
- const props = withDefaults(defineProps<Props>(), {
41
- showSponsors: true,
42
- showBrand: true,
43
- showCountdown: true,
44
- liveButton: false,
45
- mediaButton: true,
46
- registerButton: true,
47
- loginButton: true,
48
- viewInfoButton: true,
49
- registerPathPrefix: "",
50
- eventPathPrefix: "",
51
- liveButtonOpensStream: true,
52
- isUpcoming: true,
53
- showEventImage: true,
54
- sponsorPosition: Position.RIGHT,
55
- borderPosition: Position.MIDDLE,
56
- countdownPosition: Position.BOTTOM,
57
- classObject: () => {
58
- return {
59
- components: ref<listEventsCompObj>({
60
- countdownTimer: ref<countdownTimerClassObj>({}),
61
- sponsor: ref<sponsorClassObj>({}),
62
- }),
63
- };
64
- },
65
- });
66
-
67
- const {
68
- showSponsors,
69
- showBrand,
70
- showCountdown,
71
- liveButton,
72
- mediaButton,
73
- registerButton,
74
- registerPathPrefix,
75
- loginButton,
76
- viewInfoButton,
77
- isUpcoming,
78
- showEventImage,
79
- sponsorPosition,
80
- borderPosition,
81
- countdownPosition,
82
- classObject,
83
- } = toRefs(props);
84
-
85
- // data
86
- const { pastEvents, upcomingEvents } = storeToRefs(useConferencesStore());
87
-
88
- // methods
89
- const { globalConfigValue, pagesConfigValue } = storeToRefs(
90
- useTemplateConfigsStore()
91
- );
92
- const { formatDate } = useDateFormat();
93
- const {
94
- isSingleDayEvent,
95
- showConferenceViewButton,
96
- getConferenceWebcastUrl,
97
- getConferenceWebcastButtonText,
98
- showViewArchiveButton,
99
- getViewArchiveUrl,
100
- getViewArchiveButtonText,
101
- getConferenceRegUrl,
102
- getConferenceRegText,
103
- showConferenceRegButton,
104
- } = useConferenceHelpers();
105
-
106
- const {
107
- isLoggedIn,
108
- loginModalVisible,
109
- conferenceToLoginTo,
110
- goEventPage,
111
- setConferenceToLoginTo,
112
- buttonClass,
113
- orderAffiliates,
114
- getBrand,
115
- isHomePage,
116
- } = useEvents();
117
-
118
- const { classBinding } = useClassBinding();
119
-
120
- const showViewButton = (_conference: Conference): boolean => {
121
- return isUpcoming.value
122
- ? showConferenceViewButton(_conference)
123
- : showViewArchiveButton(_conference);
124
- };
125
-
126
- const getVideoUrl = (_conference: Conference): string => {
127
- return isUpcoming.value
128
- ? getConferenceWebcastUrl(_conference)
129
- : getViewArchiveUrl(_conference);
130
- };
131
-
132
- const getVideoButtonText = (_conference: Conference): string => {
133
- return isUpcoming.value
134
- ? getConferenceWebcastButtonText(_conference)
135
- : getViewArchiveButtonText(_conference);
136
- };
137
-
138
- // computed
139
- const eventType = computed((): Conference[] => {
140
- return isUpcoming.value ? upcomingEvents.value : pastEvents.value;
141
- });
142
-
143
- const showLoginButton = computed((): boolean => {
144
- const archivedHomepage: boolean =
145
- isUpcoming.value || (!isUpcoming.value && isHomePage.value);
146
- return (
147
- archivedHomepage &&
148
- loginButton.value &&
149
- !isLoggedIn.value &&
150
- !globalConfigValue.value("townhall_registration_enabled")
151
- );
152
- });
153
- </script>
154
-
155
- <template>
156
- <!-- list container -->
157
- <div class="flex w-full flex-col">
158
- <!-- list container -->
159
- <div
160
- :class="
161
- classBinding(classObject, 'listContainer', 'container flex-1 mx-auto')
162
- "
163
- >
164
- <!-- individual event container -->
165
- <div
166
- v-for="conference in eventType"
167
- :key="conference.id"
168
- :class="[
169
- {
170
- 'border-1 border-t border-color-accent-2':
171
- borderPosition === Position.TOP,
172
- },
173
- classBinding(
174
- classObject,
175
- 'eventContainer',
176
- 'flex flex-col items-center md:flex-row py-4'
177
- ),
178
- ]"
179
- >
180
- <!-- event image -->
181
- <div
182
- v-if="showEventImage"
183
- :class="
184
- classBinding(
185
- classObject,
186
- 'eventImageContainer',
187
- 'flex w-full md:w-1/3 pb-3 px-3 md:px-6 overflow-hidden'
188
- )
189
- "
190
- >
191
- <img
192
- :class="
193
- classBinding(
194
- classObject,
195
- 'eventImage',
196
- 'flex-1 self-center mx-auto w-full'
197
- )
198
- "
199
- :src="conference.photo"
200
- />
201
- </div>
202
- <!-- event details container -->
203
- <div
204
- :class="[
205
- { 'md:w-2/3': showEventImage },
206
- classBinding(
207
- classObject,
208
- 'eventContentContainer',
209
- 'flex flex-col justify-center text-center w-full md:pr-6 md:text-left md:justify-start md:items-start'
210
- ),
211
- ]"
212
- >
213
- <!-- event brand, name, date and countdown container -->
214
- <div
215
- :class="[
216
- {
217
- 'border-1 border-b border-color-accent-2 mb-6':
218
- borderPosition === Position.MIDDLE,
219
- },
220
- classBinding(
221
- classObject,
222
- 'eventDetailsContainer',
223
- 'w-full flex flex-col lg:flex-row'
224
- ),
225
- ]"
226
- >
227
- <!-- event details -->
228
- <div
229
- :class="classBinding(classObject, 'eventDetails', 'flex-grow')"
230
- >
231
- <template v-if="showBrand && getBrand(conference.affiliates)">
232
- <a
233
- v-if="getBrand(conference.affiliates).website"
234
- :class="classBinding(classObject, 'eventBrandLink', '')"
235
- :href="getBrand(conference.affiliates).website"
236
- target="_blank"
237
- >
238
- <h3
239
- :class="
240
- classBinding(
241
- classObject,
242
- 'eventBrand',
243
- 'text-base font-bold leading-tight tracking-wide mb-3'
244
- )
245
- "
246
- >
247
- {{ getBrand(conference.affiliates).name }}
248
- </h3>
249
- </a>
250
- <h3
251
- v-else
252
- :class="
253
- classBinding(
254
- classObject,
255
- 'eventBrand',
256
- 'text-base font-bold leading-tight tracking-wide mb-3'
257
- )
258
- "
259
- >
260
- {{ getBrand(conference.affiliates).name }}
261
- </h3>
262
- </template>
263
- <nuxt-link
264
- :to="
265
- eventPathPrefix
266
- ? eventPathPrefix + conference.id
267
- : `/${isUpcoming ? 'upcoming-events' : 'past-events'}/${
268
- conference.id
269
- }`
270
- "
271
- class="no-underline"
272
- >
273
- <h2
274
- :class="
275
- classBinding(
276
- classObject,
277
- 'eventName',
278
- 'text-2xl lg:text-3xl font-medium mb-2 conf-name-alignment'
279
- )
280
- "
281
- >
282
- {{ conference.name }}
283
- </h2>
284
- </nuxt-link>
285
- <p
286
- :class="
287
- classBinding(
288
- classObject,
289
- 'eventDate',
290
- 'text-base leading-normal tracking-wide font-light uppercase md:text-md lg:text-lg'
291
- )
292
- "
293
- >
294
- {{ formatDate(conference.start_date) }}
295
- <span v-if="!isSingleDayEvent(conference)">
296
- - {{ formatDate(conference.end_date) }}</span
297
- >
298
- </p>
299
- </div>
300
- <!-- countdown timer - top-aligned -->
301
- <div
302
- v-if="
303
- isUpcoming &&
304
- showCountdown &&
305
- countdownPosition === Position.TOP &&
306
- pagesConfigValue('main.countdown_timer')
307
- "
308
- :class="
309
- classBinding(
310
- classObject,
311
- 'countdownContainerTop',
312
- 'flex-auto flex items-center self-center mb-4 lg:mb-0'
313
- )
314
- "
315
- >
316
- <CommonCountdownTimer
317
- :date="conference.start_date"
318
- :is-compact="true"
319
- :class-object="classObject.components.countdownTimer"
320
- ></CommonCountdownTimer>
321
- </div>
322
- </div>
323
- <!-- event button, countdown timer, and sponsors container -->
324
- <div
325
- :class="
326
- classBinding(
327
- classObject,
328
- 'buttonCountdownSponsorsContainer',
329
- 'flex flex-col w-full'
330
- )
331
- "
332
- >
333
- <div
334
- :class="
335
- classBinding(
336
- classObject,
337
- 'buttonCountdownContainer',
338
- 'flex-1 flex flex-col justify-between xl:flex-row w-full'
339
- )
340
- "
341
- >
342
- <div
343
- :class="
344
- classBinding(
345
- classObject,
346
- 'buttonContainer',
347
- 'flex-auto mr-0 xl:mr-4'
348
- )
349
- "
350
- >
351
- <!-- live event button - if enabled, hide all other buttons if event is live -->
352
- <template
353
- v-if="liveButton && conference.state === ConferenceState.LIVE"
354
- >
355
- <!-- go to video -->
356
- <a
357
- v-if="liveButtonOpensStream"
358
- :href="getVideoUrl(conference)"
359
- :target="
360
- /^http/.test(!isUpcoming && getVideoUrl(conference))
361
- ? '_blank'
362
- : '_self'
363
- "
364
- >
365
- <button
366
- :class="
367
- classBinding(classObject, 'liveButtonItem', buttonClass)
368
- "
369
- >
370
- {{ getVideoButtonText(conference) }}
371
- </button>
372
- </a>
373
- <!-- go to event page -->
374
- <button
375
- v-else
376
- :class="
377
- classBinding(classObject, 'liveButtonItem', buttonClass)
378
- "
379
- @click="goEventPage(conference, eventPathPrefix)"
380
- >
381
- {{ getVideoButtonText(conference) }}
382
- </button>
383
- </template>
384
-
385
- <template v-else>
386
- <!-- view info button -->
387
- <button
388
- v-if="viewInfoButton"
389
- :class="
390
- classBinding(classObject, 'buttonItem', buttonClass)
391
- "
392
- @click="goEventPage(conference, eventPathPrefix)"
393
- >
394
- More Info
395
- </button>
396
- <!-- view live/preview archive button -->
397
- <a
398
- v-if="mediaButton && showViewButton(conference)"
399
- :href="getVideoUrl(conference)"
400
- :target="
401
- /^http/.test(!isUpcoming && getVideoUrl(conference))
402
- ? '_blank'
403
- : '_self'
404
- "
405
- >
406
- <button
407
- :class="
408
- classBinding(classObject, 'buttonItem', buttonClass)
409
- "
410
- >
411
- {{ getVideoButtonText(conference) }}
412
- </button>
413
- </a>
414
-
415
- <!-- login button -->
416
- <button
417
- v-if="showLoginButton"
418
- :class="
419
- classBinding(classObject, 'buttonItem', buttonClass)
420
- "
421
- @click="setConferenceToLoginTo(conference)"
422
- >
423
- Log In
424
- </button>
425
-
426
- <!-- register button -->
427
- <a
428
- v-if="registerButton && showConferenceRegButton(conference)"
429
- :href="getConferenceRegUrl(conference, registerPathPrefix)"
430
- :target="
431
- /^http/.test(getConferenceRegUrl(conference))
432
- ? '_blank'
433
- : '_self'
434
- "
435
- >
436
- <button
437
- :class="
438
- classBinding(classObject, 'buttonItem', buttonClass)
439
- "
440
- >
441
- {{ getConferenceRegText(conference) }}
442
- </button>
443
- </a>
444
- </template>
445
- </div>
446
- <!-- countdown timer - right-aligned -->
447
- <div
448
- v-if="
449
- isUpcoming &&
450
- showCountdown &&
451
- countdownPosition === Position.RIGHT &&
452
- pagesConfigValue('main.countdown_timer')
453
- "
454
- class="flex-auto md:flex mt-3 md:mt-2"
455
- :class="
456
- classBinding(
457
- classObject,
458
- 'countdownContainerRight',
459
- 'flex-auto flex items-center self-center mb-4 lg:mb-0'
460
- )
461
- "
462
- >
463
- <CommonCountdownTimer
464
- :date="conference.start_date"
465
- :is-compact="true"
466
- :class-object="classObject.components.countdownTimer"
467
- ></CommonCountdownTimer>
468
- </div>
469
- </div>
470
- <!-- countdown timer - bottom-aligned -->
471
- <div
472
- v-if="
473
- isUpcoming &&
474
- showCountdown &&
475
- countdownPosition === Position.BOTTOM &&
476
- pagesConfigValue('main.countdown_timer')
477
- "
478
- :class="
479
- classBinding(
480
- classObject,
481
- 'countdownContainerBottom',
482
- 'flex-auto md:flex my-3 md:my-2'
483
- )
484
- "
485
- >
486
- <CommonCountdownTimer
487
- :date="conference.start_date"
488
- :is-compact="true"
489
- :class-object="classObject.components.countdownTimer"
490
- ></CommonCountdownTimer>
491
- </div>
492
- <!-- sponsors container - bottom-aligned -->
493
- <div
494
- v-if="showSponsors && sponsorPosition === Position.BOTTOM"
495
- class=""
496
- :class="
497
- classBinding(
498
- classObject,
499
- 'sponsorsContainer',
500
- 'grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-y-1.5 gap-x-3'
501
- )
502
- "
503
- >
504
- <!-- individual sponsor -->
505
- <template
506
- v-for="affiliate in orderAffiliates(conference.affiliates)"
507
- >
508
- <CommonSponsor
509
- v-if="affiliate.role == 'sponsor'"
510
- :key="affiliate.id"
511
- :sponsor="affiliate"
512
- :class-object="classObject.components.sponsor"
513
- ></CommonSponsor>
514
- </template>
515
- </div>
516
- </div>
517
- </div>
518
- <!-- sponsors container - right-aligned -->
519
- <div
520
- v-if="showSponsors && sponsorPosition === Position.RIGHT"
521
- class="flex flex-col"
522
- >
523
- <!-- individual sponsor -->
524
- <template v-for="affiliate in orderAffiliates(conference.affiliates)">
525
- <CommonSponsor
526
- v-if="affiliate.role == 'sponsor'"
527
- :key="affiliate.id"
528
- :sponsor="affiliate"
529
- :class-object="classObject.components.sponsor"
530
- ></CommonSponsor>
531
- </template>
532
- </div>
533
- </div>
534
- </div>
535
- <!-- login modal -->
536
- <CommonModal
537
- :visible="loginModalVisible"
538
- :class="classObject.components.modal"
539
- @trigger="loginModalVisible = false"
540
- >
541
- <template #modal-body>
542
- <CommonLoginFullWidth
543
- :conference="conferenceToLoginTo"
544
- :class="classObject.components.login"
545
- />
546
- </template>
547
- </CommonModal>
548
- </div>
549
- </template>
550
-
1
+ <script lang="ts" setup>
2
+ import { ref, toRefs, computed } from "vue";
3
+ import { storeToRefs } from "pinia";
4
+ import { useConferencesStore } from "../../store/conferences";
5
+ import { useTemplateConfigsStore } from "../../store/templateConfigs";
6
+ import { useDateFormat } from "../../composables/useDateFormat";
7
+ import { useConferenceHelpers } from "../../composables/useConferenceHelpers";
8
+ import { useEvents } from "../../composables/useEvents";
9
+ import { useClassBinding } from "../../composables/useClassBinding";
10
+ import CommonSponsor from "../agenda/components/Sponsor.vue";
11
+ import { Conference, ConferenceState } from "../../models/conference";
12
+ import { Position } from "../../enums/general";
13
+ import {
14
+ listEventsClassObj,
15
+ listEventsCompObj,
16
+ countdownTimerClassObj,
17
+ sponsorClassObj,
18
+ } from "../../@types/components";
19
+
20
+ interface Props {
21
+ showSponsors?: boolean;
22
+ showBrand?: boolean;
23
+ showCountdown?: boolean;
24
+ liveButton?: boolean;
25
+ mediaButton?: boolean;
26
+ registerButton?: boolean;
27
+ loginButton?: boolean;
28
+ viewInfoButton?: boolean;
29
+ registerPathPrefix?: string;
30
+ eventPathPrefix?: string;
31
+ liveButtonOpensStream?: boolean;
32
+ isUpcoming?: boolean;
33
+ showEventImage?: boolean;
34
+ sponsorPosition?: Position;
35
+ borderPosition?: Position;
36
+ countdownPosition?: Position;
37
+ classObject?: listEventsClassObj;
38
+ }
39
+
40
+ const props = withDefaults(defineProps<Props>(), {
41
+ showSponsors: true,
42
+ showBrand: true,
43
+ showCountdown: true,
44
+ liveButton: false,
45
+ mediaButton: true,
46
+ registerButton: true,
47
+ loginButton: true,
48
+ viewInfoButton: true,
49
+ registerPathPrefix: "",
50
+ eventPathPrefix: "",
51
+ liveButtonOpensStream: true,
52
+ isUpcoming: true,
53
+ showEventImage: true,
54
+ sponsorPosition: Position.RIGHT,
55
+ borderPosition: Position.MIDDLE,
56
+ countdownPosition: Position.BOTTOM,
57
+ classObject: () => {
58
+ return {
59
+ components: ref<listEventsCompObj>({
60
+ countdownTimer: ref<countdownTimerClassObj>({}),
61
+ sponsor: ref<sponsorClassObj>({}),
62
+ }),
63
+ };
64
+ },
65
+ });
66
+
67
+ const {
68
+ showSponsors,
69
+ showBrand,
70
+ showCountdown,
71
+ liveButton,
72
+ mediaButton,
73
+ registerButton,
74
+ registerPathPrefix,
75
+ loginButton,
76
+ viewInfoButton,
77
+ isUpcoming,
78
+ showEventImage,
79
+ sponsorPosition,
80
+ borderPosition,
81
+ countdownPosition,
82
+ classObject,
83
+ } = toRefs(props);
84
+
85
+ // data
86
+ const { pastEvents, upcomingEvents } = storeToRefs(useConferencesStore());
87
+
88
+ // methods
89
+ const { globalConfigValue, pagesConfigValue } = storeToRefs(
90
+ useTemplateConfigsStore()
91
+ );
92
+ const { formatDate } = useDateFormat();
93
+ const {
94
+ isSingleDayEvent,
95
+ showConferenceViewButton,
96
+ getConferenceWebcastUrl,
97
+ getConferenceWebcastButtonText,
98
+ showViewArchiveButton,
99
+ getViewArchiveUrl,
100
+ getViewArchiveButtonText,
101
+ getConferenceRegUrl,
102
+ getConferenceRegText,
103
+ showConferenceRegButton,
104
+ } = useConferenceHelpers();
105
+
106
+ const {
107
+ isLoggedIn,
108
+ loginModalVisible,
109
+ conferenceToLoginTo,
110
+ goEventPage,
111
+ setConferenceToLoginTo,
112
+ buttonClass,
113
+ getSponsors,
114
+ getBrand,
115
+ isHomePage,
116
+ } = useEvents();
117
+
118
+ const { classBinding } = useClassBinding();
119
+
120
+ const showViewButton = (_conference: Conference): boolean => {
121
+ return isUpcoming.value
122
+ ? showConferenceViewButton(_conference)
123
+ : showViewArchiveButton(_conference);
124
+ };
125
+
126
+ const getVideoUrl = (_conference: Conference): string => {
127
+ return isUpcoming.value
128
+ ? getConferenceWebcastUrl(_conference)
129
+ : getViewArchiveUrl(_conference);
130
+ };
131
+
132
+ const getVideoButtonText = (_conference: Conference): string => {
133
+ return isUpcoming.value
134
+ ? getConferenceWebcastButtonText(_conference)
135
+ : getViewArchiveButtonText(_conference);
136
+ };
137
+
138
+ // computed
139
+ const eventType = computed((): Conference[] => {
140
+ return isUpcoming.value ? upcomingEvents.value : pastEvents.value;
141
+ });
142
+
143
+ const showLoginButton = computed((): boolean => {
144
+ const archivedHomepage: boolean =
145
+ isUpcoming.value || (!isUpcoming.value && isHomePage.value);
146
+ return (
147
+ archivedHomepage &&
148
+ loginButton.value &&
149
+ !isLoggedIn.value &&
150
+ !globalConfigValue.value("townhall_registration_enabled")
151
+ );
152
+ });
153
+ </script>
154
+
155
+ <template>
156
+ <!-- list container -->
157
+ <div class="flex w-full flex-col">
158
+ <!-- list container -->
159
+ <div
160
+ :class="
161
+ classBinding(classObject, 'listContainer', 'container flex-1 mx-auto')
162
+ "
163
+ >
164
+ <!-- individual event container -->
165
+ <div
166
+ v-for="conference in eventType"
167
+ :key="conference.id"
168
+ :class="[
169
+ {
170
+ 'border-1 border-t border-color-accent-2':
171
+ borderPosition === Position.TOP,
172
+ },
173
+ classBinding(
174
+ classObject,
175
+ 'eventContainer',
176
+ 'flex flex-col items-center md:flex-row py-4'
177
+ ),
178
+ ]"
179
+ >
180
+ <!-- event image -->
181
+ <div
182
+ v-if="showEventImage"
183
+ :class="
184
+ classBinding(
185
+ classObject,
186
+ 'eventImageContainer',
187
+ 'flex w-full md:w-1/3 pb-3 px-3 md:px-6 overflow-hidden'
188
+ )
189
+ "
190
+ >
191
+ <img
192
+ :class="
193
+ classBinding(
194
+ classObject,
195
+ 'eventImage',
196
+ 'flex-1 self-center mx-auto w-full'
197
+ )
198
+ "
199
+ :src="conference.photo"
200
+ />
201
+ </div>
202
+ <!-- event details container -->
203
+ <div
204
+ :class="[
205
+ { 'md:w-2/3': showEventImage },
206
+ classBinding(
207
+ classObject,
208
+ 'eventContentContainer',
209
+ 'flex flex-col justify-center text-center w-full md:pr-6 md:text-left md:justify-start md:items-start'
210
+ ),
211
+ ]"
212
+ >
213
+ <!-- event brand, name, date and countdown container -->
214
+ <div
215
+ :class="[
216
+ {
217
+ 'border-1 border-b border-color-accent-2 mb-6':
218
+ borderPosition === Position.MIDDLE,
219
+ },
220
+ classBinding(
221
+ classObject,
222
+ 'eventDetailsContainer',
223
+ 'w-full flex flex-col lg:flex-row'
224
+ ),
225
+ ]"
226
+ >
227
+ <!-- event details -->
228
+ <div
229
+ :class="classBinding(classObject, 'eventDetails', 'flex-grow')"
230
+ >
231
+ <template v-if="showBrand && getBrand(conference.affiliates)">
232
+ <a
233
+ v-if="getBrand(conference.affiliates).website"
234
+ :class="classBinding(classObject, 'eventBrandLink', '')"
235
+ :href="getBrand(conference.affiliates).website"
236
+ target="_blank"
237
+ >
238
+ <h3
239
+ :class="
240
+ classBinding(
241
+ classObject,
242
+ 'eventBrand',
243
+ 'text-base font-bold leading-tight tracking-wide mb-3'
244
+ )
245
+ "
246
+ >
247
+ {{ getBrand(conference.affiliates).name }}
248
+ </h3>
249
+ </a>
250
+ <h3
251
+ v-else
252
+ :class="
253
+ classBinding(
254
+ classObject,
255
+ 'eventBrand',
256
+ 'text-base font-bold leading-tight tracking-wide mb-3'
257
+ )
258
+ "
259
+ >
260
+ {{ getBrand(conference.affiliates).name }}
261
+ </h3>
262
+ </template>
263
+ <nuxt-link
264
+ :to="
265
+ eventPathPrefix
266
+ ? eventPathPrefix + conference.id
267
+ : `/${isUpcoming ? 'upcoming-events' : 'past-events'}/${
268
+ conference.id
269
+ }`
270
+ "
271
+ class="no-underline"
272
+ >
273
+ <h2
274
+ :class="
275
+ classBinding(
276
+ classObject,
277
+ 'eventName',
278
+ 'text-2xl lg:text-3xl font-medium mb-2 conf-name-alignment'
279
+ )
280
+ "
281
+ >
282
+ {{ conference.name }}
283
+ </h2>
284
+ </nuxt-link>
285
+ <p
286
+ :class="
287
+ classBinding(
288
+ classObject,
289
+ 'eventDate',
290
+ 'text-base leading-normal tracking-wide font-light uppercase md:text-md lg:text-lg'
291
+ )
292
+ "
293
+ >
294
+ {{ formatDate(conference.start_date) }}
295
+ <span v-if="!isSingleDayEvent(conference)">
296
+ - {{ formatDate(conference.end_date) }}</span
297
+ >
298
+ </p>
299
+ </div>
300
+ <!-- countdown timer - top-aligned -->
301
+ <div
302
+ v-if="
303
+ isUpcoming &&
304
+ showCountdown &&
305
+ countdownPosition === Position.TOP &&
306
+ pagesConfigValue('main.countdown_timer')
307
+ "
308
+ :class="
309
+ classBinding(
310
+ classObject,
311
+ 'countdownContainerTop',
312
+ 'flex-auto flex items-center self-center mb-4 lg:mb-0'
313
+ )
314
+ "
315
+ >
316
+ <CommonCountdownTimer
317
+ :date="conference.start_date"
318
+ :is-compact="true"
319
+ :class-object="classObject.components.countdownTimer"
320
+ ></CommonCountdownTimer>
321
+ </div>
322
+ </div>
323
+ <!-- event button, countdown timer, and sponsors container -->
324
+ <div
325
+ :class="
326
+ classBinding(
327
+ classObject,
328
+ 'buttonCountdownSponsorsContainer',
329
+ 'flex flex-col w-full'
330
+ )
331
+ "
332
+ >
333
+ <div
334
+ :class="
335
+ classBinding(
336
+ classObject,
337
+ 'buttonCountdownContainer',
338
+ 'flex-1 flex flex-col justify-between xl:flex-row w-full'
339
+ )
340
+ "
341
+ >
342
+ <div
343
+ :class="
344
+ classBinding(
345
+ classObject,
346
+ 'buttonContainer',
347
+ 'flex-auto mr-0 xl:mr-4'
348
+ )
349
+ "
350
+ >
351
+ <!-- live event button - if enabled, hide all other buttons if event is live -->
352
+ <template
353
+ v-if="liveButton && conference.state === ConferenceState.LIVE"
354
+ >
355
+ <!-- go to video -->
356
+ <a
357
+ v-if="liveButtonOpensStream"
358
+ :href="getVideoUrl(conference)"
359
+ :target="
360
+ /^http/.test(!isUpcoming && getVideoUrl(conference))
361
+ ? '_blank'
362
+ : '_self'
363
+ "
364
+ >
365
+ <button
366
+ :class="
367
+ classBinding(classObject, 'liveButtonItem', buttonClass)
368
+ "
369
+ >
370
+ {{ getVideoButtonText(conference) }}
371
+ </button>
372
+ </a>
373
+ <!-- go to event page -->
374
+ <button
375
+ v-else
376
+ :class="
377
+ classBinding(classObject, 'liveButtonItem', buttonClass)
378
+ "
379
+ @click="goEventPage(conference, eventPathPrefix)"
380
+ >
381
+ {{ getVideoButtonText(conference) }}
382
+ </button>
383
+ </template>
384
+
385
+ <template v-else>
386
+ <!-- view info button -->
387
+ <button
388
+ v-if="viewInfoButton"
389
+ :class="
390
+ classBinding(classObject, 'buttonItem', buttonClass)
391
+ "
392
+ @click="goEventPage(conference, eventPathPrefix)"
393
+ >
394
+ More Info
395
+ </button>
396
+ <!-- view live/preview archive button -->
397
+ <a
398
+ v-if="mediaButton && showViewButton(conference)"
399
+ :href="getVideoUrl(conference)"
400
+ :target="
401
+ /^http/.test(!isUpcoming && getVideoUrl(conference))
402
+ ? '_blank'
403
+ : '_self'
404
+ "
405
+ >
406
+ <button
407
+ :class="
408
+ classBinding(classObject, 'buttonItem', buttonClass)
409
+ "
410
+ >
411
+ {{ getVideoButtonText(conference) }}
412
+ </button>
413
+ </a>
414
+
415
+ <!-- login button -->
416
+ <button
417
+ v-if="showLoginButton"
418
+ :class="
419
+ classBinding(classObject, 'buttonItem', buttonClass)
420
+ "
421
+ @click="setConferenceToLoginTo(conference)"
422
+ >
423
+ Log In
424
+ </button>
425
+
426
+ <!-- register button -->
427
+ <a
428
+ v-if="registerButton && showConferenceRegButton(conference)"
429
+ :href="getConferenceRegUrl(conference, registerPathPrefix)"
430
+ :target="
431
+ /^http/.test(getConferenceRegUrl(conference))
432
+ ? '_blank'
433
+ : '_self'
434
+ "
435
+ >
436
+ <button
437
+ :class="
438
+ classBinding(classObject, 'buttonItem', buttonClass)
439
+ "
440
+ >
441
+ {{ getConferenceRegText(conference) }}
442
+ </button>
443
+ </a>
444
+ </template>
445
+ </div>
446
+ <!-- countdown timer - right-aligned -->
447
+ <div
448
+ v-if="
449
+ isUpcoming &&
450
+ showCountdown &&
451
+ countdownPosition === Position.RIGHT &&
452
+ pagesConfigValue('main.countdown_timer')
453
+ "
454
+ class="flex-auto md:flex mt-3 md:mt-2"
455
+ :class="
456
+ classBinding(
457
+ classObject,
458
+ 'countdownContainerRight',
459
+ 'flex-auto flex items-center self-center mb-4 lg:mb-0'
460
+ )
461
+ "
462
+ >
463
+ <CommonCountdownTimer
464
+ :date="conference.start_date"
465
+ :is-compact="true"
466
+ :class-object="classObject.components.countdownTimer"
467
+ ></CommonCountdownTimer>
468
+ </div>
469
+ </div>
470
+ <!-- countdown timer - bottom-aligned -->
471
+ <div
472
+ v-if="
473
+ isUpcoming &&
474
+ showCountdown &&
475
+ countdownPosition === Position.BOTTOM &&
476
+ pagesConfigValue('main.countdown_timer')
477
+ "
478
+ :class="
479
+ classBinding(
480
+ classObject,
481
+ 'countdownContainerBottom',
482
+ 'flex-auto md:flex my-3 md:my-2'
483
+ )
484
+ "
485
+ >
486
+ <CommonCountdownTimer
487
+ :date="conference.start_date"
488
+ :is-compact="true"
489
+ :class-object="classObject.components.countdownTimer"
490
+ ></CommonCountdownTimer>
491
+ </div>
492
+ <!-- sponsors container - bottom-aligned -->
493
+ <div
494
+ v-if="showSponsors && sponsorPosition === Position.BOTTOM"
495
+ class=""
496
+ :class="
497
+ classBinding(
498
+ classObject,
499
+ 'sponsorsContainer',
500
+ 'grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-y-1.5 gap-x-3'
501
+ )
502
+ "
503
+ >
504
+ <!-- individual sponsor -->
505
+ <template
506
+ v-for="(affiliate, index) in getSponsors(conference.affiliates)"
507
+ :key="index"
508
+ >
509
+ <h3
510
+ v-if="index === 0"
511
+ :class="
512
+ classBinding(classObject, 'sponsoredByText', 'hidden')
513
+ "
514
+ >
515
+ Sponsored by:
516
+ </h3>
517
+ <CommonSponsor
518
+ v-if="affiliate.photo"
519
+ :sponsor="affiliate"
520
+ :class-object="classObject.components.sponsor"
521
+ ></CommonSponsor>
522
+ </template>
523
+ </div>
524
+ </div>
525
+ </div>
526
+ <!-- sponsors container - right-aligned -->
527
+ <div
528
+ v-if="showSponsors && sponsorPosition === Position.RIGHT"
529
+ class="flex flex-col"
530
+ >
531
+ <!-- individual sponsor -->
532
+ <template
533
+ v-for="(affiliate, index) in getSponsors(conference.affiliates)"
534
+ :key="index"
535
+ >
536
+ <h3
537
+ v-if="index === 0"
538
+ :class="classBinding(classObject, 'sponsoredByText', 'hidden')"
539
+ >
540
+ Sponsored by:
541
+ </h3>
542
+ <CommonSponsor
543
+ v-if="affiliate.photo"
544
+ :sponsor="affiliate"
545
+ :class-object="classObject.components.sponsor"
546
+ ></CommonSponsor>
547
+ </template>
548
+ </div>
549
+ </div>
550
+ </div>
551
+ <!-- login modal -->
552
+ <CommonModal
553
+ :visible="loginModalVisible"
554
+ :class="classObject.components.modal"
555
+ @trigger="loginModalVisible = false"
556
+ >
557
+ <template #modal-body>
558
+ <CommonLoginFullWidth
559
+ :conference="conferenceToLoginTo"
560
+ :class="classObject.components.login"
561
+ />
562
+ </template>
563
+ </CommonModal>
564
+ </div>
565
+ </template>
566
+
551
567
  <style scoped>
552
568
  .leading-tight {
553
569
  line-height: 1.25rem;
@@ -556,4 +572,4 @@ const showLoginButton = computed((): boolean => {
556
572
  .mr-4 {
557
573
  margin-right: 1rem;
558
574
  }
559
- </style>
575
+ </style>