|
1 | 1 | <template>
|
2 | 2 | <div :class="[
|
3 |
| - event?.album ? 'col-span-2' : 'md:col-span-1 col-span-2', |
| 3 | + event?.album ? 'col-span-2 md:col-span-1' : 'md:col-span-1 col-span-2', |
4 | 4 | isNextMeetup ? 'border-green-600 dark:border-green-500' : 'border-verse-50 dark:border-white/10 ',
|
5 |
| - 'group in-card bg-white dark:bg-verse-700/30 dark:backdrop-blur-sm border-2 rounded-xl overflow-hidden hover:border-verse-500 transition-all duration-300', |
6 |
| - ]" :title="hasAlbum() ? 'has album' : 'no album'"> |
| 5 | + 'group group/event in-card bg-white dark:bg-verse-700/30 dark:backdrop-blur-sm border-2 rounded-xl overflow-hidden hover:border-verse-500 transition-all duration-300', |
| 6 | + ]"> |
7 | 7 | <div
|
8 |
| - class="relative flex flex-col md:flex-row justify-between w-full transition-all duration-300 group-hover[.in-card]:shadow-lg group-hover[.in-card]:border-verse-400"> |
| 8 | + class="relative flex overflow-clip h-full flex-col md:flex-row justify-between w-full transition-all duration-300 group-hover[.in-card]:shadow-lg group-hover[.in-card]:border-red-400"> |
| 9 | + |
| 10 | + <div class="absolute inset-0 z-0 "> |
| 11 | + <CardAlbum :currentAlbum="currentAlbum" :source="photoAlbumSource" /> |
| 12 | + </div> |
| 13 | + |
| 14 | + <div |
| 15 | + class="inset-0 absolute z-0 bg-gradient-to-r from-white via-white dark:from-verse-900 dark:via-verse-900 to-transparent" /> |
| 16 | + |
9 | 17 | <NuxtLink class="absolute inset-0 z-10" :href="`/meetup/${event.id}`">
|
10 | 18 | <span class="sr-only">View details for {{ event?.title }}</span>
|
11 | 19 | </NuxtLink>
|
12 |
| - <div class="relative flex flex-col p-4 w-full"> |
13 |
| - <!-- Date --> |
| 20 | + |
| 21 | + <div class="relative z-5 flex flex-col p-4 w-full justify-between gap-4"> |
| 22 | + |
14 | 23 | <template v-if="event.Date">
|
15 | 24 | <div :class="[
|
16 | 25 | !isUpcoming(event.Date) ? 'text-green-600 font-bold' : 'text-verse-900 dark:text-verse-300',
|
17 |
| - 'flex font-mono text-sm font-medium items-center gap-2 w-full justify-between', |
| 26 | + 'flex flex-col font-mono text-sm font-medium gap-2 w-full justify-between', |
18 | 27 | ]">
|
19 |
| - <div> |
20 | 28 |
|
21 |
| - <Icon name="carbon:calendar" class="mr-2 h-6 w-6" /> |
22 |
| - <span>{{ formatDate(new Date(event.Date), 'dd MMM yyyy') }}</span> |
| 29 | + |
| 30 | + <!-- Title --> |
| 31 | + <h3 |
| 32 | + class="leading-2 text-2xl font-semibold text-verse-500 dark:text-white group-hover[.in-card]:text-verse-500"> |
| 33 | + <div class="w-[300px] md:w-96 focus:outline-none" :title="`Meetup ${event?.title}`"> |
| 34 | + {{ event?.title }} |
| 35 | + </div> |
| 36 | + </h3> |
| 37 | + |
| 38 | + <div class="flex items-center gap-2"> |
| 39 | + |
| 40 | + <!-- Date --> |
| 41 | + <div> |
| 42 | + <Icon name="carbon:calendar" class="mr-2 h-4 w-4" /> |
| 43 | + <span>{{ formatDate(new Date(event.Date), 'dd MMM yyyy') }}</span> |
| 44 | + </div> |
| 45 | + |
| 46 | + <div v-if="event.Venue" |
| 47 | + class="flex gap-1 md:gap-0 items-center justify-start text-base font-medium leading-3 md:leading-5 "> |
| 48 | + <Icon name="carbon:location" class="mr-1.5 h-4 w-4 flex-shrink-0 truncate " aria-hidden="true" /> |
| 49 | + <div class="pt-[2px] line-clamp-1 md:line-clamp-0"> |
| 50 | + {{ event.Venue }} |
| 51 | + </div> |
| 52 | + </div> |
| 53 | + |
| 54 | + |
| 55 | + |
23 | 56 | </div>
|
24 | 57 | <template v-if="isNextMeetup">
|
25 | 58 | <span class="bg-green-700 text-sm font-mono justify-end text-white px-3 rounded-md font-bold">
|
|
29 | 62 | </div>
|
30 | 63 | </template>
|
31 | 64 |
|
32 |
| - <!-- Title --> |
33 |
| - <h3 |
34 |
| - class="leading-2 text-2xl font-semibold flex-1 py-2 text-verse-500 dark:text-verse-100 group-hover[.in-card]:text-verse-500"> |
35 |
| - <div class="w-[300px] md:w-96 focus:outline-none" :title="`Meetup ${event?.title}`"> |
36 |
| - <!-- :style="vTransitionName('session-title', event.id)" --> |
37 |
| - <span class="absolute inset-0" aria-hidden="true"></span> |
38 |
| - {{ event?.title }} |
39 |
| - </div> |
40 |
| - </h3> |
41 |
| - |
42 |
| - <div class="flex gap-4 pr-4 border-gray-100"> |
43 |
| - <template v-if="event.Venue"> |
44 |
| - <div |
45 |
| - class="flex gap-1 md:gap-0 items-center justify-start text-base font-medium leading-3 md:leading-5 text-verse-600 dark:text-verse-200"> |
46 |
| - <Icon name="carbon:location" |
47 |
| - class="mr-1.5 h-[15px] w-[15px] flex-shrink-0 truncate text-verse-600 dark:text-verse-200" |
48 |
| - aria-hidden="true" /> |
| 65 | + <div class="flex justify-between items-end"> |
| 66 | + <SpeakerList :event="event" /> |
| 67 | + |
| 68 | + <template v-if="event.Attendees"> |
| 69 | + <div class="flex items-center border-gray-100 bg-white/70 dark:bg-verse-950/60 rounded-full px-2" |
| 70 | + title="Attendees"> |
| 71 | + <Icon name="carbon:group" class="mr-1.5 h-4 w-4 flex-shrink-0 truncate " aria-hidden="true" /> |
49 | 72 | <div class="pt-[2px] line-clamp-1 md:line-clamp-0">
|
50 |
| - {{ event.Venue }} |
| 73 | + {{ event?.Attendees === 0 ? 'No' : event?.Attendees }} |
51 | 74 | </div>
|
52 | 75 | </div>
|
53 | 76 | </template>
|
54 |
| - |
55 |
| - <div |
56 |
| - class="flex gap-1 md:gap-0 items-center justify-start text-base font-medium leading-3 md:leading-5 text-verse-600 dark:text-verse-200"> |
57 |
| - <template v-if="event.Attendees"> |
58 |
| - <div class="flex items-center" title="Attendees"> |
59 |
| - <Icon name="solar:users-group-rounded-bold" |
60 |
| - class="mr-1.5 h-[15px] w-[15px] flex-shrink-0 truncate text-verse-600 dark:text-verse-200" |
61 |
| - aria-hidden="true" /> |
62 |
| - <div class="pt-[2px] line-clamp-1 md:line-clamp-0"> |
63 |
| - {{ event?.Attendees === 0 ? 'No' : event?.Attendees }} |
64 |
| - </div> |
65 |
| - </div> |
66 |
| - </template> |
67 |
| - </div> |
68 | 77 | </div>
|
69 | 78 | </div>
|
70 |
| - <div class="max-w-screen-sm"> |
71 |
| - <CardAlbum :currentAlbum="currentAlbum" :source="photoAlbumSource" /> |
72 |
| - </div> |
| 79 | + |
73 | 80 | </div>
|
74 | 81 | </div>
|
75 | 82 | </template>
|
76 | 83 |
|
77 | 84 | <script setup lang="ts">
|
78 | 85 | import { defineProps } from 'vue';
|
79 | 86 | import { format } from 'date-fns';
|
80 |
| -// import IconLocation from '~icons/carbon/location'; |
81 |
| -// import IconCalendar from '~icons/carbon/calendar'; |
82 |
| -// import IconGroup from '~icons/solar/users-group-rounded-bold'; |
83 | 87 | import photosResponse from '../../../frontendmu-astro/src/data/photos-raw.json';
|
84 | 88 | import CardAlbum from './CardAlbum.vue';
|
85 |
| -// import { vTransitionName } from '@utils/helpers'; |
86 | 89 |
|
87 | 90 | const appConfig = useAppConfig();
|
88 | 91 | const photoAlbumSource = appConfig.photoAlbumSource
|
89 |
| -interface Meetup { |
90 |
| - id: string; |
91 |
| - accepting_rsvp: boolean; |
92 |
| - title: string; |
93 |
| - Date: string; |
94 |
| - Attendees: number; |
95 |
| - Venue: string; |
96 |
| - description: string; |
97 |
| - Location: string; |
98 |
| - Time: string; |
99 |
| - images?: []; |
100 |
| - gallery?: []; |
101 |
| - album?: string; |
102 |
| -} |
| 92 | +
|
103 | 93 |
|
104 | 94 | interface Props {
|
105 | 95 | event: Meetup;
|
@@ -128,11 +118,15 @@ function fetchAlbumDetails() {
|
128 | 118 | const filteredPhotos = albumPhotosParsed.filter((photo) => {
|
129 | 119 | return !photo.endsWith('.mp4');
|
130 | 120 | });
|
131 |
| - return filteredPhotos.slice(0, 4); |
| 121 | + return filteredPhotos.slice(0, 3); |
132 | 122 | }
|
133 | 123 | }
|
134 | 124 | }
|
135 | 125 |
|
| 126 | +function allSpeakersForEvent(event: Meetup) { |
| 127 | + return event.sessions.map((session) => session.Session_id?.speakers); |
| 128 | +} |
| 129 | +
|
136 | 130 | let currentAlbum = fetchAlbumDetails();
|
137 | 131 |
|
138 | 132 | function formatDate(date: Date, formatString: string) {
|
|
0 commit comments