@explorer-1/vue 0.2.7 → 0.2.9

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 (79) hide show
  1. package/components.d.ts +6 -1
  2. package/dist/explorer-1-vue.js +6871 -6420
  3. package/dist/explorer-1-vue.umd.cjs +13 -13
  4. package/dist/src/components/{BaseTag/BaseTag.stories.d.ts → BasePill/BasePill.stories.d.ts} +2 -2
  5. package/dist/src/components/{BaseTag/BaseTag.vue.d.ts → BasePill/BasePill.vue.d.ts} +7 -3
  6. package/dist/src/components/BlockLinkCard/BlockLinkCard.stories.d.ts +89 -15
  7. package/dist/src/components/BlockLinkCard/BlockLinkCard.vue.d.ts +66 -7
  8. package/dist/src/components/BlockLinkCarousel/BlockLinkCarousel.stories.d.ts +70 -2
  9. package/dist/src/components/BlockLinkTile/BlockLinkTile.vue.d.ts +4 -4
  10. package/dist/src/components/CalendarButton/CalendarButton.vue.d.ts +2 -2
  11. package/dist/src/components/CalendarChip/CalendarChip.vue.d.ts +36 -0
  12. package/dist/src/components/EventCard/EventCard.vue.d.ts +9 -0
  13. package/dist/src/components/EventDetailHero/EventDetailHero.vue.d.ts +27 -9
  14. package/dist/src/components/HeroListingIndex/HeroListingIndex.stories.d.ts +1 -0
  15. package/dist/src/components/HeroListingIndex/HeroListingIndex.vue.d.ts +6 -4
  16. package/dist/src/components/HeroMedium/HeroMedium.vue.d.ts +28 -2
  17. package/dist/src/components/Icons/IconProfile.vue.d.ts +2 -0
  18. package/dist/src/components/Icons/IconSubject.vue.d.ts +2 -0
  19. package/dist/src/components/Icons/Icons.stories.d.ts +17 -0
  20. package/dist/src/components/MetadataEduResource/MetadataEduResource.stories.d.ts +55 -0
  21. package/dist/src/components/MetadataEduResource/MetadataEduResource.vue.d.ts +38 -0
  22. package/dist/src/components/MetadataEvent/MetadataEvent.stories.d.ts +29 -0
  23. package/dist/src/components/MetadataEvent/MetadataEvent.vue.d.ts +38 -0
  24. package/dist/src/components/NavDesktopEdu/NavDesktopEdu.stories.d.ts +1 -0
  25. package/dist/src/components/SearchResultCard/SearchResultCard.stories.d.ts +23 -4
  26. package/dist/src/components/SearchResultCard/SearchResultCard.vue.d.ts +66 -1
  27. package/dist/src/components/SearchResultGridItem/SearchResultGridItem.stories.d.ts +7 -0
  28. package/dist/src/components/SearchResultGridItem/SearchResultGridItem.vue.d.ts +65 -11
  29. package/dist/src/components/SearchResultsList/SearchResultsList.stories.d.ts +404 -0
  30. package/dist/src/components/TopicDetailMoreItem/TopicDetailMoreItem.vue.d.ts +8 -4
  31. package/dist/src/constants.d.ts +4 -0
  32. package/dist/src/interfaces.d.ts +38 -3
  33. package/dist/src/templates/PageContent/PageContent.stories.d.ts +1 -0
  34. package/dist/src/templates/PageEventDetail/PageEventDetail.stories.d.ts +2 -13
  35. package/dist/src/templates/PageEventDetail/PageEventDetail.vue.d.ts +6 -3
  36. package/dist/src/templates/edu/PageEduEventDetail/PageEduEventDetail.stories.d.ts +153 -31
  37. package/dist/src/utils/mixins.d.ts +1 -1
  38. package/dist/src/utils/rangeifyGrades.d.ts +3 -0
  39. package/dist/style.css +1 -1
  40. package/lib/main.ts +2 -2
  41. package/package.json +2 -2
  42. package/src/components/{BaseTag/BaseTag.stories.js → BasePill/BasePill.stories.js} +3 -3
  43. package/src/components/BasePill/BasePill.vue +54 -0
  44. package/src/components/BlockLinkCard/BlockLinkCard.stories.js +93 -12
  45. package/src/components/BlockLinkCard/BlockLinkCard.vue +180 -39
  46. package/src/components/BlockLinkCarousel/BlockLinkCarousel.stories.js +60 -3
  47. package/src/components/BlockLinkTile/BlockLinkTile.vue +11 -8
  48. package/src/components/CalendarChip/CalendarChip.vue +52 -0
  49. package/src/components/DetailHeadline/DetailHeadline.vue +5 -5
  50. package/src/components/EventCard/EventCard.vue +28 -88
  51. package/src/components/EventDetailHero/EventDetailHero.vue +18 -25
  52. package/src/components/HeroListingIndex/HeroListingIndex.stories.js +1 -0
  53. package/src/components/HeroListingIndex/HeroListingIndex.vue +8 -3
  54. package/src/components/HeroMedium/HeroMedium.vue +24 -12
  55. package/src/components/Icons/IconProfile.vue +30 -0
  56. package/src/components/Icons/IconSubject.vue +38 -0
  57. package/src/components/Icons/Icons.stories.ts +15 -0
  58. package/src/components/MetadataEduResource/MetadataEduResource.stories.js +59 -0
  59. package/src/components/MetadataEduResource/MetadataEduResource.vue +93 -0
  60. package/src/components/MetadataEvent/MetadataEvent.stories.js +31 -0
  61. package/src/components/MetadataEvent/MetadataEvent.vue +164 -0
  62. package/src/components/NavMobile/NavMobile.vue +3 -1
  63. package/src/components/SearchResultCard/SearchResultCard.stories.js +22 -5
  64. package/src/components/SearchResultCard/SearchResultCard.vue +71 -14
  65. package/src/components/SearchResultGridItem/SearchResultGridItem.stories.js +8 -1
  66. package/src/components/SearchResultGridItem/SearchResultGridItem.vue +81 -31
  67. package/src/components/SearchResultsList/SearchResultsList.stories.js +1197 -0
  68. package/src/components/SearchResultsList/SearchResultsList.vue +1 -0
  69. package/src/components/TopicDetailMoreItem/TopicDetailMoreItem.vue +12 -8
  70. package/src/constants.ts +20 -0
  71. package/src/interfaces.ts +41 -3
  72. package/src/templates/PageContent/PageContent.stories.js +1 -0
  73. package/src/templates/PageEventDetail/PageEventDetail.stories.js +1 -1
  74. package/src/templates/PageEventDetail/PageEventDetail.vue +25 -90
  75. package/src/templates/edu/PageEduEventDetail/PageEduEventDetail.stories.js +4 -3
  76. package/src/templates/edu/PageEduEventDetail/PageEduEventDetail.vue +38 -123
  77. package/src/utils/mixins.ts +2 -2
  78. package/src/utils/rangeifyGrades.ts +76 -0
  79. package/src/components/BaseTag/BaseTag.vue +0 -36
@@ -17,6 +17,7 @@
17
17
  <SearchResultCard
18
18
  :is-events="isEvents"
19
19
  :is-profiles="isProfiles"
20
+ :page-content-type="page.content_type"
20
21
  :url="page.url"
21
22
  :type="page.type"
22
23
  :topic="page.topic"
@@ -40,7 +40,7 @@
40
40
  <div class="text-gray-dark md:px-5 md:py-5 lg:px-10 lg:py-8 w-full px-10 py-8">
41
41
  <!-- label area -->
42
42
  <div
43
- v-if="theData.label || theData.date || theData.startDate"
43
+ v-if="theData.label || theData.date || (theData as EventCardObject).startDate"
44
44
  class="flex flex-wrap items-center justify-between mb-5"
45
45
  >
46
46
  <p class="divide-gray-mid text-subtitle flex divide-x">
@@ -50,7 +50,7 @@
50
50
  >{{ theData.label }}</span
51
51
  >
52
52
  <span
53
- v-if="theData.date || theData.startDate"
53
+ v-if="theData.date || (theData as EventCardObject).startDate"
54
54
  class="text-gray-mid-dark"
55
55
  :class="{ 'pl-2': theData.label }"
56
56
  >
@@ -60,7 +60,7 @@
60
60
  $filters.displayDate(theData.date)
61
61
  }}
62
62
  </template>
63
- <template v-else-if="theData.startDate">
63
+ <template v-else-if="(theData as EventCardObject).startDate">
64
64
  {{ formattedEventDates }}
65
65
  </template>
66
66
  </span>
@@ -80,7 +80,7 @@
80
80
  <script lang="ts">
81
81
  import { defineComponent } from 'vue'
82
82
  import type { PropType } from 'vue'
83
- import type { Card } from '../../interfaces'
83
+ import type { Card, EventCardObject } from '../../interfaces'
84
84
  import { mixinFormatEventDates } from '../../utils/mixins'
85
85
  import BaseLink from './../BaseLink/BaseLink.vue'
86
86
  import BaseImage from './../BaseImage/BaseImage.vue'
@@ -99,8 +99,9 @@ export default defineComponent({
99
99
  },
100
100
  props: {
101
101
  data: {
102
- type: Object as PropType<Card>,
103
- required: false
102
+ type: Object as PropType<Card | EventCardObject>,
103
+ required: false,
104
+ default: undefined
104
105
  }
105
106
  },
106
107
  computed: {
@@ -113,8 +114,11 @@ export default defineComponent({
113
114
  return undefined
114
115
  },
115
116
  formattedEventDates() {
116
- if (this.theData?.startDate) {
117
- return mixinFormatEventDates(this.theData.startDate, this.theData.endDate)
117
+ if ((this.theData as EventCardObject)?.startDate) {
118
+ return mixinFormatEventDates(
119
+ (this.theData as EventCardObject).startDate,
120
+ (this.theData as EventCardObject).endDate
121
+ )
118
122
  }
119
123
  return undefined
120
124
  }
@@ -0,0 +1,20 @@
1
+ import type { DictionaryInterface, PillDictionaryInterface } from './interfaces'
2
+
3
+ export const eduMetadataDictionary: PillDictionaryInterface = {
4
+ EDUExplainerArticlePage: {
5
+ label: 'Explainer Article',
6
+ variant: 'secondary'
7
+ },
8
+ EDUEventPage: {
9
+ variant: 'primary'
10
+ }
11
+ }
12
+
13
+ // TODO: finish this
14
+ export const searchContentTypeToPageType: DictionaryInterface = {
15
+ news_news: 'News',
16
+ events_eventpage: 'EventPage',
17
+ missions_mission: 'Mission',
18
+ eduevents_edueventpage: 'EDUEventPage',
19
+ eduresources_eduexplainerarticlepage: 'EDUExplainerArticlePage'
20
+ }
package/src/interfaces.ts CHANGED
@@ -79,13 +79,38 @@ export interface Card {
79
79
  type?: string
80
80
  url?: string
81
81
  externalLink?: string
82
- page?: Card
82
+ page?: Card | EventCardObject | EduResourceCardObject
83
83
  title?: string
84
84
  date?: string
85
- startDate?: string
86
- endDate?: string
87
85
  label?: string
88
86
  thumbnailImage?: Partial<ImageObject>
87
+ summary?: string
88
+ }
89
+ export interface EventCardObject extends Card {
90
+ startDate?: string
91
+ endDate?: string
92
+ startDatetime?: string
93
+ endDatetime?: string
94
+ startTime?: string
95
+ endTime?: string
96
+ customDate?: string
97
+ eventType?: string
98
+ ongoing?: boolean
99
+ isVirtualEvent?: boolean
100
+ locationName?: string
101
+ location?: string
102
+ locationLink?: string
103
+ }
104
+
105
+ export interface PrimarySubjectObject {
106
+ subject: string
107
+ }
108
+ export interface GradeLevelsObject {
109
+ gradeLevel: string
110
+ }
111
+ export interface EduResourceCardObject extends Card {
112
+ primarySubject: PrimarySubjectObject
113
+ gradeLevels: GradeLevelsObject[]
89
114
  }
90
115
 
91
116
  export interface LinkObject {
@@ -138,3 +163,16 @@ export interface Topic {
138
163
  title: string
139
164
  url: string
140
165
  }
166
+
167
+ export type MetadataType = 'event' | 'resource'
168
+
169
+ export interface LabelObject {
170
+ label?: string
171
+ variant: string
172
+ }
173
+ export interface PillDictionaryInterface {
174
+ [EDUExplainerArticlePage: string]: LabelObject
175
+ }
176
+ export interface DictionaryInterface {
177
+ [key: string]: string
178
+ }
@@ -62,6 +62,7 @@ export const ContentPageData = {
62
62
  // via page chooser
63
63
  {
64
64
  page: {
65
+ __typename: 'EDUExplainerArticlePage',
65
66
  label: 'Mission',
66
67
  thumbnailImage: {
67
68
  src: {
@@ -51,7 +51,7 @@ export const BaseStory = {
51
51
  '<p>Lorem ipsum <a href="/missions/test-mission/">dolor</a> sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.</p><p>Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.</p>\n'
52
52
  }
53
53
  ],
54
- moreEvents: [...EventsBlockLinkCarouselData],
54
+ moreEvents: EventsBlockLinkCarouselData,
55
55
  speakers: [
56
56
  {
57
57
  host: 'host',
@@ -63,7 +63,8 @@
63
63
  <LayoutHelper indent="col-2">
64
64
  <EventDetailHero
65
65
  :image="data.eventImage"
66
- :start-date-split="formattedSplitEventDates"
66
+ :start-date="data.startDate"
67
+ :end-date="data.endDate"
67
68
  />
68
69
 
69
70
  <!-- Event details -->
@@ -72,62 +73,7 @@
72
73
  class="py-1 mb-10 text-xl lg:mb-0 lg:flex"
73
74
  :class="data.registerLink && data.registerLink.length > 0 ? '' : 'lg:mb-10'"
74
75
  >
75
- <div class="PageEventDetail__Metadata text-primary">
76
- <IconCalendar class="relative mr-3 text-[1.2rem]" />
77
- <span>{{ formattedEventDates }}</span>
78
- </div>
79
- <div
80
- v-show="displayTime"
81
- class="PageEventDetail__Metadata text-primary"
82
- >
83
- <IconTime class="relative mr-3" />
84
- <span>{{ displayTime }}</span>
85
- </div>
86
- <!--Virtual location -->
87
- <div
88
- v-if="data.isVirtualEvent && data.locationLink"
89
- itemprop="location"
90
- itemscope
91
- itemtype="https://schema.org/VirtualLocation"
92
- class="PageEventDetail__Metadata text-primary"
93
- >
94
- <link
95
- itemprop="url"
96
- :href="data.locationLink"
97
- />
98
- <meta
99
- itemprop="name"
100
- :content="data.location"
101
- />
102
- <IconLocation class="relative mr-3" />
103
- <BaseLink
104
- variant="none"
105
- :href="data.locationLink"
106
- external-target-blank
107
- >
108
- {{ data.location }}
109
- </BaseLink>
110
- </div>
111
- <!-- Normal location -->
112
- <div
113
- v-else-if="data.location"
114
- class="PageEventDetail__Metadata text-primary"
115
- >
116
- <meta
117
- itemprop="location"
118
- :content="data.location"
119
- />
120
- <IconLocation class="relative mr-3" />
121
- <BaseLink
122
- v-if="data.locationLink"
123
- variant="none"
124
- :href="data.locationLink"
125
- external-target-blank
126
- >
127
- {{ data.location }}
128
- </BaseLink>
129
- <span v-else>{{ data.location }}</span>
130
- </div>
76
+ <MetadataEvent :event="data" />
131
77
  <div class="PageEventDetail__Buttons">
132
78
  <BaseButton
133
79
  v-if="
@@ -267,34 +213,26 @@
267
213
  </LayoutHelper>
268
214
 
269
215
  <!-- Related Events -->
270
- <LayoutHelper
271
- v-if="data.moreEvents && data.moreEvents.length > 0"
272
- indent="col-1"
216
+ <div
217
+ v-if="moreEvents?.length > 0"
273
218
  class="my-12 lg:my-16 print:!px-4"
274
219
  >
275
220
  <BlockLinkCarousel
276
221
  item-type="cards"
277
222
  class="print:!px-4"
278
223
  heading="MORE EVENTS"
279
- :items="data.moreEvents"
224
+ :items="moreEvents"
280
225
  />
281
- </LayoutHelper>
226
+ </div>
282
227
  </div>
283
228
  </template>
284
229
  <script lang="ts">
285
230
  import { defineComponent } from 'vue'
286
- import {
287
- mixinFormatEventDates,
288
- mixinFormatEventTimeInHoursAndMinutes,
289
- mixinFormatSplitEventDates
290
- } from '../../utils/mixins'
231
+ import type { EventCardObject } from './../../interfaces'
291
232
  import LayoutHelper from './../../components/LayoutHelper/LayoutHelper.vue'
292
233
  import BaseHeading from './../../components/BaseHeading/BaseHeading.vue'
293
234
  import ShareButtons from './../../components/ShareButtons/ShareButtons.vue'
294
235
  import EventDetailHero from './../../components/EventDetailHero/EventDetailHero.vue'
295
- import IconCalendar from './../../components/Icons/IconCalendar.vue'
296
- import IconLocation from './../../components/Icons/IconLocation.vue'
297
- import IconTime from './../../components/Icons/IconTime.vue'
298
236
  import BaseLink from './../../components/BaseLink/BaseLink.vue'
299
237
  import BaseButton from './../../components/BaseButton/BaseButton.vue'
300
238
  import CalendarButton from './../../components/CalendarButton/CalendarButton.vue'
@@ -303,6 +241,7 @@ import BaseImagePlaceholder from './../../components/BaseImagePlaceholder/BaseIm
303
241
  import BaseImage from './../../components/BaseImage/BaseImage.vue'
304
242
  import BlockRelatedLinks from './../../components/BlockRelatedLinks/BlockRelatedLinks.vue'
305
243
  import BlockLinkCarousel from './../../components/BlockLinkCarousel/BlockLinkCarousel.vue'
244
+ import MetadataEvent from './../../components/MetadataEvent/MetadataEvent.vue'
306
245
  // @ts-ignore
307
246
  import PlaceholderPortrait from '@explorer-1/common/src/images/svg/placeholder-portrait.svg'
308
247
 
@@ -313,9 +252,6 @@ export default defineComponent({
313
252
  BaseHeading,
314
253
  ShareButtons,
315
254
  EventDetailHero,
316
- IconCalendar,
317
- IconLocation,
318
- IconTime,
319
255
  BaseLink,
320
256
  BaseButton,
321
257
  CalendarButton,
@@ -323,12 +259,14 @@ export default defineComponent({
323
259
  BaseImagePlaceholder,
324
260
  BaseImage,
325
261
  BlockRelatedLinks,
326
- BlockLinkCarousel
262
+ BlockLinkCarousel,
263
+ MetadataEvent
327
264
  },
328
265
  props: {
329
266
  data: {
330
267
  type: Object,
331
- required: false
268
+ required: false,
269
+ default: undefined
332
270
  }
333
271
  },
334
272
  data() {
@@ -337,22 +275,19 @@ export default defineComponent({
337
275
  }
338
276
  },
339
277
  computed: {
340
- displayTime(): string {
341
- return this.data
342
- ? mixinFormatEventTimeInHoursAndMinutes(
343
- this.data.startDatetime,
344
- this.data.endDatetime,
345
- this.data.endTime
346
- )
347
- : ''
348
- },
349
- formattedEventDates(): string {
350
- return this.data ? mixinFormatEventDates(this.data.startDatetime, this.data.endDatetime) : ''
351
- },
352
- formattedSplitEventDates() {
353
- return this.data
354
- ? mixinFormatSplitEventDates(this.data.startDatetime, this.data.endDatetime)
278
+ moreEvents(): EventCardObject[] {
279
+ // mimic the data shape of a PageChooserBlock array
280
+ const mapped = this.data?.moreEvents
281
+ ? this.data.moreEvents.map((event: EventCardObject) => {
282
+ return {
283
+ page: {
284
+ __typename: 'EventPage',
285
+ ...event
286
+ }
287
+ }
288
+ })
355
289
  : undefined
290
+ return mapped
356
291
  }
357
292
  }
358
293
  })
@@ -34,6 +34,7 @@ const PageEduEventDetailData = {
34
34
  summary:
35
35
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus et luctus nisi. Maecenas vel turpis sem. Nullam ultricies nulla quis nisi faucibus eleifend. In turpis ante, blandit nec dapibus tempor, posuere at erat. In justo quam, imperdiet at hendrerit eget, imperdiet ut orci. ',
36
36
  locationName: 'Webcast',
37
+ locationLink: 'https://www.nasa.gov',
37
38
  registerLink: [
38
39
  {
39
40
  document: null,
@@ -76,7 +77,7 @@ const PageEduEventDetailData = {
76
77
  '<p>Lorem ipsum <a href="/missions/test-mission/">dolor</a> sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.</p><p>Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.</p>\n'
77
78
  }
78
79
  ],
79
- relatedEvents: [...EventsBlockLinkCarouselData],
80
+ relatedEvents: EventsBlockLinkCarouselData,
80
81
  speakers: [
81
82
  {
82
83
  speaker: {
@@ -125,7 +126,7 @@ const PageEduEventDetailData = {
125
126
  ]
126
127
  }
127
128
  ],
128
- relatedContent: BlockLinkCardCarouselData
129
+ relatedContent: [...BlockLinkCardCarouselData, ...EventsBlockLinkCarouselData]
129
130
  }
130
131
  // stories
131
132
  export const BaseStory = {
@@ -155,7 +156,7 @@ export const MultiDayEvent = {
155
156
  ...PageEduEventDetailData,
156
157
  startDate: '2024-08-08',
157
158
  endDate: '2024-08-12',
158
- startDatetime: '2024-08-08T14:00:00-07:00',
159
+ startDatetime: '2024-08-08T11:00:00-07:00',
159
160
  startTime: '15:00:00',
160
161
  endDatetime: '2024-08-12T22:00:00-07:00'
161
162
  }
@@ -38,17 +38,12 @@
38
38
  :image="data.eventImage"
39
39
  :constrain="data.heroConstrain"
40
40
  />
41
- <div
42
- v-if="formattedSplitEventDates"
43
- class="ThemeVariantLight absolute top-0 left-0 z-10 px-4 py-4 text-center text-white bg-primary print:hidden"
44
- >
45
- <div class="font-extrabold text-6xl leading-tight tracking-wider">
46
- {{ formattedSplitEventDates.month }}
47
- </div>
48
- <div class="text-subtitle">
49
- {{ formattedSplitEventDates.year }}
50
- </div>
51
- </div>
41
+ <CalendarChip
42
+ v-if="startDatetimeForFormatting"
43
+ :start-date="startDatetimeForFormatting"
44
+ :end-date="data.endDatetime"
45
+ :ongoing="data.ongoing"
46
+ />
52
47
  </div>
53
48
  <LayoutHelper
54
49
  indent="col-2"
@@ -58,12 +53,12 @@
58
53
  v-if="data.eventType"
59
54
  class="flex flex-wrap items-start mb-4"
60
55
  >
61
- <BaseTag
56
+ <BasePill
62
57
  variant="primary"
63
58
  size="lg"
64
59
  >
65
60
  {{ data.eventType }}
66
- </BaseTag>
61
+ </BasePill>
67
62
  </div>
68
63
  <BaseHeading
69
64
  level="h1"
@@ -90,7 +85,8 @@
90
85
  <EventDetailHero
91
86
  v-if="heroIsInline"
92
87
  :image="data.eventImage"
93
- :start-date-split="formattedSplitEventDates"
88
+ :start-date="startDatetimeForFormatting"
89
+ :end-date="data.endDate"
94
90
  :constrain="data.heroConstrain"
95
91
  :ongoing="data.ongoing"
96
92
  />
@@ -98,73 +94,12 @@
98
94
  <!-- Event details -->
99
95
  <div>
100
96
  <div
101
- class="py-1 mb-10 text-xl lg:mb-0 lg:flex"
97
+ class="py-1 mb-10 lg:mb-0 lg:flex"
102
98
  :class="data.registerLink && data.registerLink.length > 0 ? '' : 'lg:mb-10'"
103
99
  >
104
- <div
105
- v-if="data.ongoing || data.customDate || formattedEventDates"
106
- class="PageEduEventDetail__Metadata text-primary"
107
- :class="{ 'flex-2': data.customDate }"
108
- >
109
- <IconCalendar class="relative mr-3 lg:mr-2 xl:mr-3 text-[1.2rem]" />
110
- <span>{{ data.ongoing ? 'Ongoing' : data.customDate || formattedEventDates }}</span>
111
- </div>
112
- <div
113
- v-show="displayTime"
114
- class="PageEduEventDetail__Metadata text-primary"
115
- >
116
- <IconTime class="relative mr-3 lg:mr-2 xl:mr-3" />
117
- <span>{{ displayTime }}</span>
118
- </div>
119
- <!--Virtual location -->
120
- <div
121
- v-if="data.isVirtualEvent && data.locationLink"
122
- itemprop="location"
123
- itemscope
124
- itemtype="https://schema.org/VirtualLocation"
125
- class="PageEduEventDetail__Metadata text-primary"
126
- >
127
- <link
128
- itemprop="url"
129
- :href="data.locationLink"
130
- />
131
- <meta
132
- itemprop="name"
133
- :content="data.locationName"
134
- />
135
- <IconLocation class="relative mr-3 lg:mr-2 xl:mr-3" />
136
- <BaseLink
137
- variant="none"
138
- class="text-action"
139
- :href="data.locationLink"
140
- external-target-blank
141
- >
142
- {{ data.locationName }}
143
- </BaseLink>
144
- </div>
145
- <!-- Normal location -->
146
- <div
147
- v-else-if="data.locationName"
148
- min-
149
- class="PageEduEventDetail__Metadata text-primary"
150
- >
151
- <meta
152
- itemprop="location"
153
- :content="data.locationName"
154
- />
155
- <IconLocation class="relative mr-3 lg:mr-2 xl:mr-3" />
156
- <BaseLink
157
- v-if="data.locationLink"
158
- variant="none"
159
- :href="data.locationLink"
160
- external-target-blank
161
- >
162
- {{ data.locationName }}
163
- </BaseLink>
164
- <span v-else>{{ data.locationName }}</span>
165
- </div>
100
+ <MetadataEvent :event="data" />
166
101
 
167
- <div class="PageEduEventDetail__Buttons">
102
+ <div class="PageEduEventDetail__Buttons max-w-[17rem]">
168
103
  <BaseButton
169
104
  v-if="
170
105
  data.registerLink &&
@@ -313,18 +248,17 @@
313
248
  </LayoutHelper>
314
249
 
315
250
  <!-- Related Events -->
316
- <LayoutHelper
317
- v-if="data.relatedEvents?.length"
318
- indent="col-1"
251
+ <div
252
+ v-if="relatedEvents?.length"
319
253
  class="my-12 lg:my-16 px-0"
320
254
  >
321
255
  <BlockLinkCarousel
322
256
  item-type="cards"
323
257
  size="h3"
324
258
  heading="Related Events"
325
- :items="data.relatedEvents"
259
+ :items="relatedEvents"
326
260
  />
327
- </LayoutHelper>
261
+ </div>
328
262
  <!-- Related Content -->
329
263
  <div
330
264
  v-if="data.relatedContent?.length"
@@ -341,20 +275,13 @@
341
275
  </template>
342
276
  <script lang="ts">
343
277
  import { defineComponent } from 'vue'
344
- import {
345
- mixinFormatEventDates,
346
- mixinFormatEventTimeInHoursAndMinutes,
347
- mixinFormatSplitEventDates
348
- } from '../../../utils/mixins'
278
+ import type { EventCardObject } from './../../../interfaces'
349
279
  import LayoutHelper from './../../../components/LayoutHelper/LayoutHelper.vue'
350
280
  import BaseHeading from './../../../components/BaseHeading/BaseHeading.vue'
351
- import BaseTag from './../../../components/BaseTag/BaseTag.vue'
281
+ import BasePill from './../../../components/BasePill/BasePill.vue'
352
282
  import ShareButtonsEdu from './../../../components/ShareButtonsEdu/ShareButtonsEdu.vue'
353
283
  import EventDetailHero from './../../../components/EventDetailHero/EventDetailHero.vue'
354
284
  import HeroMedia from './../../../components/HeroMedia/HeroMedia.vue'
355
- import IconCalendar from './../../../components/Icons/IconCalendar.vue'
356
- import IconLocation from './../../../components/Icons/IconLocation.vue'
357
- import IconTime from './../../../components/Icons/IconTime.vue'
358
285
  import BaseLink from './../../../components/BaseLink/BaseLink.vue'
359
286
  import BaseButton from './../../../components/BaseButton/BaseButton.vue'
360
287
  import CalendarButton from './../../../components/CalendarButton/CalendarButton.vue'
@@ -364,6 +291,8 @@ import BaseImage from './../../../components/BaseImage/BaseImage.vue'
364
291
  import BlockRelatedLinks from './../../../components/BlockRelatedLinks/BlockRelatedLinks.vue'
365
292
  import BlockLinkCarousel from './../../../components/BlockLinkCarousel/BlockLinkCarousel.vue'
366
293
  import BlockText from './../../../components/BlockText/BlockText.vue'
294
+ import CalendarChip from './../../../components/CalendarChip/CalendarChip.vue'
295
+ import MetadataEvent from './../../../components/MetadataEvent/MetadataEvent.vue'
367
296
 
368
297
  // @ts-ignore
369
298
  import PlaceholderPortrait from '@explorer-1/common/src/images/svg/placeholder-portrait.svg'
@@ -373,13 +302,10 @@ export default defineComponent({
373
302
  components: {
374
303
  LayoutHelper,
375
304
  BaseHeading,
376
- BaseTag,
305
+ BasePill,
377
306
  ShareButtonsEdu,
378
307
  EventDetailHero,
379
308
  HeroMedia,
380
- IconCalendar,
381
- IconLocation,
382
- IconTime,
383
309
  BaseLink,
384
310
  BaseButton,
385
311
  CalendarButton,
@@ -388,7 +314,9 @@ export default defineComponent({
388
314
  BaseImage,
389
315
  BlockRelatedLinks,
390
316
  BlockLinkCarousel,
391
- BlockText
317
+ BlockText,
318
+ CalendarChip,
319
+ MetadataEvent
392
320
  },
393
321
  props: {
394
322
  data: {
@@ -403,35 +331,23 @@ export default defineComponent({
403
331
  }
404
332
  },
405
333
  computed: {
406
- startDateTimeForFormatting(): string {
334
+ startDatetimeForFormatting(): string {
407
335
  return this.data?.startDatetime || this.data?.startDate
408
336
  },
409
- displayTime(): string {
410
- if (!this.data?.customDate) {
411
- const time =
412
- this.data && this.startDateTimeForFormatting
413
- ? mixinFormatEventTimeInHoursAndMinutes(
414
- this.startDateTimeForFormatting,
415
- this.data.endDatetime,
416
- this.data.endTime
417
- )
418
- : undefined
419
- return time ? time.replaceAll(':00', '') : ''
420
- }
421
- return ''
422
- },
423
- formattedEventDates(): string | undefined {
424
- return this.data && this.startDateTimeForFormatting
425
- ? mixinFormatEventDates(this.startDateTimeForFormatting, this.data.endDatetime)
426
- : undefined
427
- },
428
- formattedSplitEventDates() {
429
- return this.data && this.startDateTimeForFormatting
430
- ? mixinFormatSplitEventDates(this.startDateTimeForFormatting, this.data.endDatetime)
431
- : undefined
432
- },
433
337
  heroIsInline(): boolean {
434
338
  return this.data?.heroPosition === 'inline'
339
+ },
340
+ relatedEvents(): EventCardObject[] {
341
+ // mimic the data shape of a PageChooserBlock array
342
+ const mapped = this.data?.relatedEvents
343
+ ? this.data.relatedEvents.map((event: EventCardObject) => {
344
+ return {
345
+ __typename: 'EDUEventPage',
346
+ page: event
347
+ }
348
+ })
349
+ : undefined
350
+ return mapped
435
351
  }
436
352
  }
437
353
  })
@@ -461,7 +377,6 @@ export default defineComponent({
461
377
  @apply mt-10;
462
378
  @apply lg:mt-0;
463
379
  @apply text-center;
464
- @apply max-w-[17rem];
465
380
  }
466
381
  .bg-stars .MixinCarousel__Heading {
467
382
  @apply text-white;
@@ -307,7 +307,7 @@ export const mixinFormatSplitEventDates = (
307
307
  }
308
308
 
309
309
  // return event dates formatted for listing cards
310
- export const mixinFormatEventDates = (startDatetime: string, endDatetime?: string): string => {
310
+ export const mixinFormatEventDates = (startDatetime?: string, endDatetime?: string): string => {
311
311
  const startDateDayjs = dayjs(startDatetime)
312
312
 
313
313
  let eventDate = startDateDayjs.format('ll')
@@ -352,7 +352,7 @@ export const mixinFormatEventTimeInHoursAndMinutes = (
352
352
  // Event is less than 24 hours and spans 1 day
353
353
  if (endTime) {
354
354
  if (startDateDayjs.format('a') === endDateDayjs.format('a')) {
355
- time = `${startDateDayjs.format('h:mm')} - ${endDateDayjs.format('h:mm a z')}`
355
+ time = `${startDateDayjs.format('h:mm')}-${endDateDayjs.format('h:mm a z')}`
356
356
  } else {
357
357
  time = `${startDateDayjs.format('h:mm a')} - ${endDateDayjs.format('h:mm a z')}`
358
358
  }