@getmicdrop/svelte-components 2.0.13 → 2.1.0

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 (58) hide show
  1. package/dist/__LIB_STORES__.js +30 -2
  2. package/dist/components/AboutShow/AboutShow.svelte +278 -0
  3. package/dist/components/AboutShow/AboutShow.svelte.d.ts +43 -0
  4. package/dist/components/AboutShow/AboutShow.svelte.d.ts.map +1 -0
  5. package/dist/components/Calendar/MiniMonthCalendar.svelte +1446 -0
  6. package/dist/components/Calendar/{Calendar.svelte.d.ts → MiniMonthCalendar.svelte.d.ts} +20 -21
  7. package/dist/components/Calendar/MiniMonthCalendar.svelte.d.ts.map +1 -0
  8. package/dist/components/DarkModeToggle.svelte +3 -1
  9. package/dist/components/DarkModeToggle.svelte.d.ts.map +1 -1
  10. package/dist/components/FAQs/FAQs.svelte +49 -0
  11. package/dist/components/{Calendar/QuarterView.svelte.d.ts → FAQs/FAQs.svelte.d.ts} +10 -10
  12. package/dist/components/FAQs/FAQs.svelte.d.ts.map +1 -0
  13. package/dist/components/Input/Input.svelte +100 -12
  14. package/dist/components/Input/Input.svelte.d.ts +12 -0
  15. package/dist/components/Input/Input.svelte.d.ts.map +1 -1
  16. package/dist/components/Input/OTPInput.svelte +1 -1
  17. package/dist/components/MonthSwitcher/MonthSwitcher.svelte +206 -0
  18. package/dist/components/MonthSwitcher/MonthSwitcher.svelte.d.ts +37 -0
  19. package/dist/components/MonthSwitcher/MonthSwitcher.svelte.d.ts.map +1 -0
  20. package/dist/components/OrderSummary/OrderSummary.svelte +553 -0
  21. package/dist/components/OrderSummary/OrderSummary.svelte.d.ts +65 -0
  22. package/dist/components/OrderSummary/OrderSummary.svelte.d.ts.map +1 -0
  23. package/dist/components/PublicCard/PublicCard.svelte +267 -0
  24. package/dist/components/{pages/performers/AvailabilityCalendarModal.svelte.d.ts → PublicCard/PublicCard.svelte.d.ts} +12 -14
  25. package/dist/components/PublicCard/PublicCard.svelte.d.ts.map +1 -0
  26. package/dist/components/ShowCard/ShowCard.svelte +240 -0
  27. package/dist/components/ShowCard/ShowCard.svelte.d.ts +39 -0
  28. package/dist/components/ShowCard/ShowCard.svelte.d.ts.map +1 -0
  29. package/dist/components/ShowTimeCard/ShowTimeCard.svelte +92 -0
  30. package/dist/components/{Calendar/QuarterView.stories.svelte.d.ts → ShowTimeCard/ShowTimeCard.svelte.d.ts} +17 -21
  31. package/dist/components/ShowTimeCard/ShowTimeCard.svelte.d.ts.map +1 -0
  32. package/dist/components/Spinner/Spinner.svelte +73 -17
  33. package/dist/components/Spinner/Spinner.svelte.d.ts +5 -3
  34. package/dist/components/Spinner/Spinner.svelte.d.ts.map +1 -1
  35. package/dist/components/pages/performers/ShowDetails.svelte.d.ts +2 -2
  36. package/dist/components/pages/performers/ShowItemCard.svelte.d.ts +6 -6
  37. package/dist/components/pages/performers/VenueItemCard.svelte.d.ts +2 -2
  38. package/dist/components/pages/shows/TabNavigation.svelte +7 -8
  39. package/dist/index.d.ts +8 -3
  40. package/dist/index.js +12 -3
  41. package/dist/services/EventService.js +75 -75
  42. package/dist/services/EventService.spec.js +217 -217
  43. package/dist/services/ShowService.spec.js +342 -342
  44. package/package.json +160 -160
  45. package/dist/components/Calendar/Calendar.spec.d.ts +0 -2
  46. package/dist/components/Calendar/Calendar.spec.d.ts.map +0 -1
  47. package/dist/components/Calendar/Calendar.spec.js +0 -131
  48. package/dist/components/Calendar/Calendar.svelte +0 -1115
  49. package/dist/components/Calendar/Calendar.svelte.d.ts.map +0 -1
  50. package/dist/components/Calendar/QuarterView.spec.d.ts +0 -2
  51. package/dist/components/Calendar/QuarterView.spec.d.ts.map +0 -1
  52. package/dist/components/Calendar/QuarterView.spec.js +0 -394
  53. package/dist/components/Calendar/QuarterView.stories.svelte +0 -134
  54. package/dist/components/Calendar/QuarterView.stories.svelte.d.ts.map +0 -1
  55. package/dist/components/Calendar/QuarterView.svelte +0 -736
  56. package/dist/components/Calendar/QuarterView.svelte.d.ts.map +0 -1
  57. package/dist/components/pages/performers/AvailabilityCalendarModal.svelte +0 -632
  58. package/dist/components/pages/performers/AvailabilityCalendarModal.svelte.d.ts.map +0 -1
@@ -0,0 +1,267 @@
1
+ <script>
2
+ import { createEventDispatcher, onMount, onDestroy } from "svelte";
3
+
4
+ export let events = [];
5
+ export let view = "row"; // 'row' for list view, 'col' for gallery view
6
+ export let placeholderImage = null; // Allow custom placeholder
7
+
8
+ const dispatch = createEventDispatcher();
9
+ let isSmallScreen = false;
10
+
11
+ // Default placeholder image for events without images
12
+ const DEFAULT_PLACEHOLDER = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect fill='%23e5e7eb' width='100' height='100'/%3E%3Cpath d='M50 25c-8.3 0-15 6.7-15 15v5c0 8.3 6.7 15 15 15s15-6.7 15-15v-5c0-8.3-6.7-15-15-15zm0 45c-13.8 0-25 5.6-25 12.5V90h50v-7.5c0-6.9-11.2-12.5-25-12.5z' fill='%239ca3af'/%3E%3C/svg%3E";
13
+
14
+ $: placeholder = placeholderImage || DEFAULT_PLACEHOLDER;
15
+
16
+ let options = {
17
+ weekday: "short",
18
+ month: "short",
19
+ day: "numeric",
20
+ };
21
+
22
+ onMount(() => {
23
+ isSmallScreen = window.innerWidth < 768;
24
+ window.addEventListener("resize", handleResize);
25
+ });
26
+
27
+ onDestroy(() => {
28
+ if (typeof window !== 'undefined') {
29
+ window.removeEventListener("resize", handleResize);
30
+ }
31
+ });
32
+
33
+ function handleResize() {
34
+ isSmallScreen = window.innerWidth < 768;
35
+ }
36
+
37
+ function handleEventClick(event) {
38
+ dispatch("eventClick", event);
39
+ }
40
+
41
+ function handleKeydown(e, event) {
42
+ if (e.key === 'Enter' || e.key === ' ') {
43
+ e.preventDefault();
44
+ handleEventClick(event);
45
+ }
46
+ }
47
+
48
+ function getStatusBadgeClass(status) {
49
+ switch (status) {
50
+ case 'Sold out':
51
+ return 'badge-sold-out';
52
+ case 'Selling fast':
53
+ return 'badge-selling-fast';
54
+ case 'Almost sold out':
55
+ return 'badge-almost-sold-out';
56
+ default:
57
+ return '';
58
+ }
59
+ }
60
+
61
+ // Only show badges for urgency statuses (not "On Sale" which is the default state)
62
+ function shouldShowBadge(status) {
63
+ return status === 'Sold out' || status === 'Selling fast' || status === 'Almost sold out';
64
+ }
65
+
66
+ function formatEventDate(dateStr) {
67
+ if (!dateStr) return '';
68
+ // Parse as local date (not UTC)
69
+ const [year, month, day] = dateStr.split('-').map(Number);
70
+ const date = new Date(year, month - 1, day);
71
+ return date.toLocaleDateString("en-US", options);
72
+ }
73
+ </script>
74
+
75
+ {#each events as event}
76
+ <article
77
+ class={`event-card rounded-lg cursor-pointer overflow-hidden bg-bg-primary border border-stroke-secondary transition-all duration-200 hover:shadow-lg hover:border-stroke-primary focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 relative ${
78
+ view === "col"
79
+ ? "flex flex-col"
80
+ : "grid grid-cols-[100px_1fr] sm:grid-cols-[160px_1fr] gap-3 sm:gap-4 p-3 sm:p-4"
81
+ }`}
82
+ on:click={() => handleEventClick(event)}
83
+ on:keydown={(e) => handleKeydown(e, event)}
84
+ tabindex="0"
85
+ role="button"
86
+ aria-label={`${event.name}, ${event.status || 'On Sale'}, ${formatEventDate(event.date)}. Press Enter to view details.`}
87
+ >
88
+ <!-- Event Image -->
89
+ <div
90
+ class={`bg-bg-secondary flex items-center justify-center overflow-hidden ${
91
+ view === "col"
92
+ ? "w-full aspect-[4/3] rounded-t-lg"
93
+ : "w-[100px] h-[100px] sm:w-[160px] sm:h-[120px] rounded-lg flex-shrink-0"
94
+ }`}
95
+ >
96
+ <img
97
+ src={event.image || placeholder}
98
+ alt={event.name}
99
+ class="object-contain w-full h-full"
100
+ loading="lazy"
101
+ />
102
+ </div>
103
+
104
+ <!-- Event Details -->
105
+ <div
106
+ class={`flex flex-col ${
107
+ view === "col" ? "p-3 gap-1" : "gap-1.5 sm:gap-2 justify-center"
108
+ }`}
109
+ >
110
+ <!-- Status Badge for gallery view - positioned over image -->
111
+ {#if view === "col" && event.status && shouldShowBadge(event.status)}
112
+ <span
113
+ class={`status-badge ${getStatusBadgeClass(event.status)} absolute top-2 left-2`}
114
+ >
115
+ {event.status}
116
+ </span>
117
+ {/if}
118
+
119
+ <!-- Status Badge for list view - inline -->
120
+ {#if view === "row" && event.status && shouldShowBadge(event.status)}
121
+ <span
122
+ class={`status-badge ${getStatusBadgeClass(event.status)}`}
123
+ >
124
+ {event.status}
125
+ </span>
126
+ {/if}
127
+
128
+ <!-- Event Name -->
129
+ <h3
130
+ class={`font-semibold text-text-primary leading-tight ${
131
+ view === "col"
132
+ ? "text-sm sm:text-base line-clamp-2"
133
+ : "text-sm sm:text-lg line-clamp-2"
134
+ }`}
135
+ >
136
+ {event.name}
137
+ </h3>
138
+
139
+ <!-- Date & Time -->
140
+ <div
141
+ class={`text-text-secondary ${
142
+ view === "col" ? "text-xs" : "text-xs sm:text-sm"
143
+ }`}
144
+ >
145
+ <span class="font-medium">
146
+ {formatEventDate(event.date)}
147
+ {#if event.timeline}
148
+ <span class="text-text-tertiary">•</span>
149
+ {event.timeline.split("-")[0].trim()}
150
+ {/if}
151
+ </span>
152
+ </div>
153
+
154
+ <!-- Description (list view only) -->
155
+ {#if view === "row" && event.description}
156
+ <p class="text-text-tertiary text-xs sm:text-sm line-clamp-2 mt-1">
157
+ {event.description}
158
+ </p>
159
+ {/if}
160
+
161
+ <!-- Doors time (if available) -->
162
+ {#if event.doorsTimeline && view === "row"}
163
+ <div class="text-[10px] sm:text-xs text-text-tertiary">
164
+ {event.doorsTimeline}
165
+ </div>
166
+ {/if}
167
+ </div>
168
+ </article>
169
+ {/each}
170
+
171
+ <style>
172
+ /* Event card base styles */
173
+ .event-card {
174
+ background-color: hsl(var(--BG-Primary));
175
+ border-color: hsl(var(--Stroke-Secondary));
176
+ transition: all 0.2s ease-in-out;
177
+ }
178
+
179
+ .event-card:hover {
180
+ transform: translateY(-2px);
181
+ border-color: hsl(var(--Stroke-Primary));
182
+ }
183
+
184
+ .event-card:active {
185
+ transform: translateY(0);
186
+ }
187
+
188
+ /* Text colors using CSS variables */
189
+ .text-text-primary {
190
+ color: hsl(var(--Text-Primary));
191
+ }
192
+
193
+ .text-text-secondary {
194
+ color: hsl(var(--Text-Secondary));
195
+ }
196
+
197
+ .text-text-tertiary {
198
+ color: hsl(var(--Text-Tartiary));
199
+ }
200
+
201
+ .bg-bg-secondary {
202
+ background-color: hsl(var(--BG-Secondary));
203
+ }
204
+
205
+ /* Status badge base styles - compact inline pill */
206
+ .status-badge {
207
+ display: inline-flex;
208
+ align-items: center;
209
+ width: -moz-fit-content;
210
+ width: fit-content;
211
+ padding: 2px 8px;
212
+ font-size: 11px;
213
+ font-weight: 600;
214
+ line-height: 1.4;
215
+ border-radius: 4px;
216
+ }
217
+
218
+ @media (min-width: 640px) {
219
+ .status-badge {
220
+ font-size: 12px;
221
+ padding: 3px 10px;
222
+ }
223
+ }
224
+
225
+ /* Status badge variants using CSS variables */
226
+ .badge-selling-fast {
227
+ background-color: hsl(var(--Status-SellingFast) / 0.15);
228
+ color: hsl(var(--Status-SellingFast));
229
+ }
230
+
231
+ .badge-sold-out {
232
+ background-color: hsl(var(--Status-SoldOut) / 0.15);
233
+ color: hsl(var(--Status-SoldOut));
234
+ }
235
+
236
+ .badge-almost-sold-out {
237
+ background-color: hsl(var(--Status-SoldOut) / 0.15);
238
+ color: hsl(var(--Status-SoldOut));
239
+ }
240
+
241
+ /* Line clamping for text truncation */
242
+ .line-clamp-2 {
243
+ display: -webkit-box;
244
+ -webkit-line-clamp: 2;
245
+ line-clamp: 2;
246
+ -webkit-box-orient: vertical;
247
+ overflow: hidden;
248
+ }
249
+
250
+ /* Reduced motion support */
251
+ @media (prefers-reduced-motion: reduce) {
252
+ .event-card {
253
+ transition: none;
254
+ }
255
+
256
+ .event-card:hover {
257
+ transform: none;
258
+ }
259
+ }
260
+
261
+ /* Mobile optimizations */
262
+ @media (max-width: 640px) {
263
+ .event-card {
264
+ -webkit-tap-highlight-color: transparent;
265
+ }
266
+ }
267
+ </style>
@@ -1,23 +1,21 @@
1
- export default AvailabilityCalendarModal;
2
- type AvailabilityCalendarModal = SvelteComponent<{
3
- onClose?: (() => void) | undefined;
4
- show?: boolean | undefined;
5
- venue?: null | undefined;
6
- onUpdate?: ((updatedTimestamp: any) => void) | undefined;
1
+ export default PublicCard;
2
+ type PublicCard = SvelteComponent<{
3
+ view?: string | undefined;
4
+ events?: any[] | undefined;
5
+ placeholderImage?: null | undefined;
7
6
  }, {
8
- click: PointerEvent;
7
+ eventClick: CustomEvent<any>;
9
8
  } & {
10
9
  [evt: string]: CustomEvent<any>;
11
10
  }, {}> & {
12
11
  $$bindings?: string | undefined;
13
12
  };
14
- declare const AvailabilityCalendarModal: $$__sveltets_2_IsomorphicComponent<{
15
- onClose?: (() => void) | undefined;
16
- show?: boolean | undefined;
17
- venue?: null | undefined;
18
- onUpdate?: ((updatedTimestamp: any) => void) | undefined;
13
+ declare const PublicCard: $$__sveltets_2_IsomorphicComponent<{
14
+ view?: string | undefined;
15
+ events?: any[] | undefined;
16
+ placeholderImage?: null | undefined;
19
17
  }, {
20
- click: PointerEvent;
18
+ eventClick: CustomEvent<any>;
21
19
  } & {
22
20
  [evt: string]: CustomEvent<any>;
23
21
  }, {}, {}, string>;
@@ -34,4 +32,4 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
34
32
  };
35
33
  z_$$bindings?: Bindings;
36
34
  }
37
- //# sourceMappingURL=AvailabilityCalendarModal.svelte.d.ts.map
35
+ //# sourceMappingURL=PublicCard.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PublicCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/PublicCard/PublicCard.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;AAoKA;;;;;;;;mBAA4J;6CAT/G,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,OAAO,OAAO,QAAQ;IAC3L,cAAc,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,WAAW,OAAO,SAAS,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,240 @@
1
+ <script>
2
+ import { createEventDispatcher } from 'svelte';
3
+ import Share from 'carbon-icons-svelte/lib/Share.svelte';
4
+ import Checkmark from 'carbon-icons-svelte/lib/Checkmark.svelte';
5
+ import ShowTimeCard from '../ShowTimeCard/ShowTimeCard.svelte';
6
+
7
+ export let event = {};
8
+ export let showtimes = [];
9
+ export let showTitle = true;
10
+
11
+ // Formatting functions - can be overridden via props
12
+ export let formatDateTime = (dateStr) => {
13
+ if (!dateStr) return '';
14
+ const date = new Date(dateStr);
15
+ if (isNaN(date.getTime())) return dateStr;
16
+ return date.toLocaleDateString('en-US', {
17
+ weekday: 'long',
18
+ year: 'numeric',
19
+ month: 'long',
20
+ day: 'numeric',
21
+ hour: 'numeric',
22
+ minute: '2-digit'
23
+ });
24
+ };
25
+
26
+ export let formatTimeline = (timeStr) => {
27
+ if (!timeStr) return '';
28
+ // Handle ISO datetime or time string
29
+ const date = new Date(timeStr);
30
+ if (!isNaN(date.getTime())) {
31
+ return date.toLocaleTimeString('en-US', {
32
+ hour: 'numeric',
33
+ minute: '2-digit',
34
+ hour12: true
35
+ });
36
+ }
37
+ return timeStr;
38
+ };
39
+
40
+ const dispatch = createEventDispatcher();
41
+
42
+ let selectedDate = null;
43
+ let shareSuccess = false;
44
+
45
+ function handleSelect(e) {
46
+ selectedDate = e.detail.date;
47
+ dispatch('showtimeSelect', e.detail);
48
+ }
49
+
50
+ async function handleShare() {
51
+ const shareData = {
52
+ title: event.name,
53
+ text: `Check out ${event.name} at ${event.venue?.name || 'this venue'}!`,
54
+ url: typeof window !== 'undefined' ? window.location.href : ''
55
+ };
56
+
57
+ try {
58
+ // Use Web Share API if available (mobile devices, some desktop browsers)
59
+ if (typeof navigator !== 'undefined' && navigator.share && navigator.canShare && navigator.canShare(shareData)) {
60
+ await navigator.share(shareData);
61
+ } else if (typeof navigator !== 'undefined' && navigator.clipboard) {
62
+ // Fallback: copy URL to clipboard
63
+ await navigator.clipboard.writeText(shareData.url);
64
+ shareSuccess = true;
65
+ setTimeout(() => {
66
+ shareSuccess = false;
67
+ }, 2000);
68
+ }
69
+ } catch (err) {
70
+ // User cancelled share or error occurred - try clipboard as last resort
71
+ if (err.name !== 'AbortError' && typeof navigator !== 'undefined' && navigator.clipboard) {
72
+ try {
73
+ await navigator.clipboard.writeText(shareData.url);
74
+ shareSuccess = true;
75
+ setTimeout(() => {
76
+ shareSuccess = false;
77
+ }, 2000);
78
+ } catch {
79
+ console.error('Share failed:', err);
80
+ }
81
+ }
82
+ }
83
+ }
84
+ </script>
85
+
86
+ <div class="show-card h-fit rounded-[8px] sm:px-5 py-4 md:border">
87
+ <!-- Event Title -->
88
+ {#if showTitle}
89
+ <div class="flex justify-between items-start gap-2 mb-4">
90
+ <h1 class="event-title flex-1 text-left font-semibold text-[22px] leading-tight">
91
+ {event.name || ''}
92
+ </h1>
93
+ <button
94
+ class="share-btn flex-shrink-0 p-2 rounded-lg transition-colors relative"
95
+ aria-label="Share event"
96
+ on:click={handleShare}
97
+ >
98
+ {#if shareSuccess}
99
+ <Checkmark size={20} class="success-icon" />
100
+ {:else}
101
+ <Share size={20} class="share-icon cursor-pointer" />
102
+ {/if}
103
+ </button>
104
+ </div>
105
+ {/if}
106
+
107
+ <!-- Date & Time -->
108
+ <div class="space-y-1 text-[15px]">
109
+ <p class="date-primary font-medium">{formatDateTime(event.startDateTime)}</p>
110
+ {#if event.displayStartTime && event.doorsOpenTime}
111
+ <p class="date-secondary">Doors open {formatTimeline(event.doorsOpenTime)}</p>
112
+ {/if}
113
+ {#if event.displayEndTime && event.endDateTime}
114
+ <p class="date-secondary">Ends {formatTimeline(event.endDateTime)}</p>
115
+ {/if}
116
+ </div>
117
+
118
+ {#if showtimes && showtimes.length > 1}
119
+ <div class="showtimes-section mt-4 pt-4">
120
+ <p class="showtimes-label text-sm mb-2">More showtimes</p>
121
+ <div class="flex flex-wrap gap-2">
122
+ {#each showtimes as showtime}
123
+ <div class="w-[91px]">
124
+ <ShowTimeCard
125
+ day={showtime.day}
126
+ date={showtime.date}
127
+ time={showtime.time}
128
+ isSelected={selectedDate === showtime.date}
129
+ on:select={handleSelect}
130
+ />
131
+ </div>
132
+ {/each}
133
+ </div>
134
+ </div>
135
+ {/if}
136
+
137
+ <!-- Location -->
138
+ {#if event.venue}
139
+ <div class="location-section mt-4 pt-4">
140
+ <a
141
+ href="https://www.google.com/maps/search/?api=1&query={encodeURIComponent(event.venue.googleLocationNameCache || event.venue.address || event.venue.name)}"
142
+ target="_blank"
143
+ rel="noopener noreferrer"
144
+ class="group block"
145
+ >
146
+ <p class="venue-name text-[15px] font-medium transition-colors">
147
+ {event.venue.name}
148
+ </p>
149
+ <p class="venue-address text-[14px] transition-colors">
150
+ {event.venue.address || ''}
151
+ </p>
152
+ </a>
153
+
154
+ {#if event.hasAgeRestriction || event.ageRequirement || event.minimumAge}
155
+ <p class="age-text text-[14px] mt-2">
156
+ {#if event.ageRequirement != null}
157
+ {event.ageRequirement <= 1 ? 'All ages' : `${event.ageRequirement}+`}
158
+ {:else if event.minimumAge != null}
159
+ {event.minimumAge <= 1 ? 'All ages' : `${event.minimumAge}+`}
160
+ {:else if event.ageRestriction != null}
161
+ {event.ageRestriction <= 1 ? 'All ages' : `${event.ageRestriction}+`}
162
+ {/if}
163
+ </p>
164
+ {/if}
165
+ </div>
166
+ {/if}
167
+ </div>
168
+
169
+ <style>
170
+ /* Theme-responsive colors using CSS variables */
171
+ .show-card {
172
+ background-color: hsl(var(--BG-Primary));
173
+ }
174
+
175
+ @media (min-width: 768px) {
176
+ .show-card {
177
+ border-color: hsl(var(--Stroke-Secondary));
178
+ }
179
+ }
180
+
181
+ .event-title {
182
+ color: hsl(var(--Text-Primary));
183
+ }
184
+
185
+ .share-btn:hover {
186
+ background-color: hsl(var(--BG-Secondary));
187
+ }
188
+
189
+ :global(.share-icon) {
190
+ color: hsl(var(--Text-Tartiary));
191
+ }
192
+
193
+ :global(.share-icon:hover) {
194
+ color: hsl(var(--Text-Secondary));
195
+ }
196
+
197
+ :global(.success-icon) {
198
+ color: hsl(var(--Status-OnSale));
199
+ }
200
+
201
+ .date-primary {
202
+ color: hsl(var(--Text-Primary));
203
+ }
204
+
205
+ .date-secondary {
206
+ color: hsl(var(--Text-Secondary));
207
+ }
208
+
209
+ .showtimes-section {
210
+ border-top: 1px solid hsl(var(--Stroke-Secondary));
211
+ }
212
+
213
+ .showtimes-label {
214
+ color: hsl(var(--Text-Tartiary));
215
+ }
216
+
217
+ .location-section {
218
+ border-top: 1px solid hsl(var(--Stroke-Secondary));
219
+ }
220
+
221
+ .venue-name {
222
+ color: hsl(var(--Text-Primary));
223
+ }
224
+
225
+ .group:hover .venue-name {
226
+ color: hsl(var(--Brand-Primary));
227
+ }
228
+
229
+ .venue-address {
230
+ color: hsl(var(--Text-Tartiary));
231
+ }
232
+
233
+ .group:hover .venue-address {
234
+ color: hsl(var(--Brand-Primary));
235
+ }
236
+
237
+ .age-text {
238
+ color: hsl(var(--Text-Tartiary));
239
+ }
240
+ </style>
@@ -0,0 +1,39 @@
1
+ export default ShowCard;
2
+ type ShowCard = SvelteComponent<{
3
+ event?: {} | undefined;
4
+ showtimes?: any[] | undefined;
5
+ showTitle?: boolean | undefined;
6
+ formatDateTime?: ((dateStr: any) => any) | undefined;
7
+ formatTimeline?: ((timeStr: any) => any) | undefined;
8
+ }, {
9
+ showtimeSelect: CustomEvent<any>;
10
+ } & {
11
+ [evt: string]: CustomEvent<any>;
12
+ }, {}> & {
13
+ $$bindings?: string | undefined;
14
+ };
15
+ declare const ShowCard: $$__sveltets_2_IsomorphicComponent<{
16
+ event?: {} | undefined;
17
+ showtimes?: any[] | undefined;
18
+ showTitle?: boolean | undefined;
19
+ formatDateTime?: ((dateStr: any) => any) | undefined;
20
+ formatTimeline?: ((timeStr: any) => any) | undefined;
21
+ }, {
22
+ showtimeSelect: CustomEvent<any>;
23
+ } & {
24
+ [evt: string]: CustomEvent<any>;
25
+ }, {}, {}, string>;
26
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
27
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
28
+ $$bindings?: Bindings;
29
+ } & Exports;
30
+ (internal: unknown, props: Props & {
31
+ $$events?: Events;
32
+ $$slots?: Slots;
33
+ }): Exports & {
34
+ $set?: any;
35
+ $on?: any;
36
+ };
37
+ z_$$bindings?: Bindings;
38
+ }
39
+ //# sourceMappingURL=ShowCard.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShowCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/ShowCard/ShowCard.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;AA8KA;;;;;;;;;;mBAAyL;6CAT5I,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,OAAO,OAAO,QAAQ;IAC3L,cAAc,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,WAAW,OAAO,SAAS,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,92 @@
1
+ <script>
2
+ import { createEventDispatcher } from 'svelte';
3
+
4
+ export let day = '';
5
+ export let date = '';
6
+ export let time = '';
7
+ export let isSelected = false;
8
+
9
+ const dispatch = createEventDispatcher();
10
+
11
+ function handleCardClick() {
12
+ dispatch('select', { date });
13
+ }
14
+
15
+ function handleKeydown(e) {
16
+ if (e.key === 'Enter' || e.key === ' ') {
17
+ e.preventDefault();
18
+ handleCardClick();
19
+ }
20
+ }
21
+
22
+ function formatHour(timeStr) {
23
+ if (!timeStr) return '';
24
+ // Handle various time formats
25
+ const date = new Date(`1970-01-01T${timeStr}`);
26
+ if (isNaN(date.getTime())) return timeStr;
27
+ return date.toLocaleTimeString('en-US', {
28
+ hour: 'numeric',
29
+ minute: '2-digit',
30
+ hour12: true
31
+ });
32
+ }
33
+
34
+ function formatDate(dateStr) {
35
+ if (!dateStr) return '';
36
+ const d = new Date(dateStr);
37
+ if (isNaN(d.getTime())) return dateStr;
38
+ return d.toLocaleDateString('en-US', {
39
+ month: 'short',
40
+ day: 'numeric',
41
+ });
42
+ }
43
+ </script>
44
+
45
+ <div
46
+ class="showtime-card w-full h-[106px] rounded-lg flex flex-col justify-center items-center gap-1.5 cursor-pointer border-2 px-1 transition-colors"
47
+ class:selected={isSelected}
48
+ on:click={handleCardClick}
49
+ on:keydown={handleKeydown}
50
+ tabindex="0"
51
+ role="button"
52
+ aria-label={`${day} ${formatDate(date)} at ${formatHour(time)}${isSelected ? ', selected' : ''}`}
53
+ aria-pressed={isSelected}
54
+ >
55
+ <span class="day-text font-medium text-sm">{day}</span>
56
+ <span class="date-text font-medium text-[16px]" class:selected-text={isSelected}>
57
+ {formatDate(date)}
58
+ </span>
59
+ <span class="time-text font-medium text-sm">{formatHour(time)}</span>
60
+ </div>
61
+
62
+ <style>
63
+ /* Theme-responsive colors using CSS variables */
64
+ .showtime-card {
65
+ background-color: hsl(var(--BG-Primary));
66
+ border-color: hsl(var(--Stroke-Secondary));
67
+ }
68
+
69
+ .showtime-card:hover {
70
+ border-color: hsl(var(--Brand-Primary));
71
+ }
72
+
73
+ .showtime-card.selected {
74
+ border-color: hsl(var(--Brand-Primary));
75
+ }
76
+
77
+ .day-text {
78
+ color: hsl(var(--Text-Tartiary));
79
+ }
80
+
81
+ .date-text {
82
+ color: hsl(var(--Text-Primary));
83
+ }
84
+
85
+ .date-text.selected-text {
86
+ color: hsl(var(--Brand-Primary));
87
+ }
88
+
89
+ .time-text {
90
+ color: hsl(var(--Text-Tartiary));
91
+ }
92
+ </style>