@getmicdrop/svelte-components 2.6.0 → 2.6.3

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 (152) hide show
  1. package/dist/__LIB_STORES__.js +2 -30
  2. package/dist/components/Badges/Badge.svelte +17 -268
  3. package/dist/components/Badges/Badge.svelte.d.ts +2 -18
  4. package/dist/components/Badges/Badge.svelte.d.ts.map +1 -1
  5. package/dist/components/Breadcrumb/Breadcrumb.svelte +36 -65
  6. package/dist/components/Breadcrumb/Breadcrumb.svelte.d.ts +2 -16
  7. package/dist/components/Breadcrumb/Breadcrumb.svelte.d.ts.map +1 -1
  8. package/dist/components/Button/Button.svelte +3 -136
  9. package/dist/components/Button/Button.svelte.d.ts +0 -2
  10. package/dist/components/Button/Button.svelte.d.ts.map +1 -1
  11. package/dist/components/Calendar/Calendar.spec.d.ts +2 -0
  12. package/dist/components/Calendar/Calendar.spec.d.ts.map +1 -0
  13. package/dist/components/Calendar/Calendar.spec.js +131 -0
  14. package/dist/components/Calendar/Calendar.svelte +1115 -0
  15. package/dist/components/Calendar/{MiniMonthCalendar.svelte.d.ts → Calendar.svelte.d.ts} +21 -20
  16. package/dist/components/Calendar/Calendar.svelte.d.ts.map +1 -0
  17. package/dist/components/Calendar/QuarterView.spec.d.ts +2 -0
  18. package/dist/components/Calendar/QuarterView.spec.d.ts.map +1 -0
  19. package/dist/components/Calendar/QuarterView.spec.js +394 -0
  20. package/dist/components/Calendar/QuarterView.stories.svelte +134 -0
  21. package/dist/components/{ShowTimeCard/ShowTimeCard.svelte.d.ts → Calendar/QuarterView.stories.svelte.d.ts} +21 -17
  22. package/dist/components/Calendar/QuarterView.stories.svelte.d.ts.map +1 -0
  23. package/dist/components/Calendar/QuarterView.svelte +736 -0
  24. package/dist/components/{FAQs/FAQs.svelte.d.ts → Calendar/QuarterView.svelte.d.ts} +10 -10
  25. package/dist/components/{Skeleton/Skeleton.svelte.d.ts.map → Calendar/QuarterView.svelte.d.ts.map} +1 -1
  26. package/dist/components/Card.svelte +2 -2
  27. package/dist/components/Card.svelte.d.ts +2 -2
  28. package/dist/components/Card.svelte.d.ts.map +1 -1
  29. package/dist/components/DarkModeToggle.svelte +0 -2
  30. package/dist/components/DarkModeToggle.svelte.d.ts.map +1 -1
  31. package/dist/components/ErrorDisplay.svelte.d.ts +2 -2
  32. package/dist/components/Input/Input.svelte +12 -105
  33. package/dist/components/Input/Input.svelte.d.ts +12 -28
  34. package/dist/components/Input/Input.svelte.d.ts.map +1 -1
  35. package/dist/components/Input/MultiSelect.svelte +5 -4
  36. package/dist/components/Input/MultiSelect.svelte.d.ts +8 -8
  37. package/dist/components/Input/MultiSelect.svelte.d.ts.map +1 -1
  38. package/dist/components/Input/OTPInput.svelte +1 -1
  39. package/dist/components/Input/Select.svelte +5 -4
  40. package/dist/components/Input/Select.svelte.d.ts +8 -8
  41. package/dist/components/Input/Select.svelte.d.ts.map +1 -1
  42. package/dist/components/Layout/Header.svelte +4 -14
  43. package/dist/components/Modal/ConfirmationModal.svelte +17 -69
  44. package/dist/components/Modal/ConfirmationModal.svelte.d.ts +0 -22
  45. package/dist/components/Modal/ConfirmationModal.svelte.d.ts.map +1 -1
  46. package/dist/components/Modal/Modal.svelte +8 -34
  47. package/dist/components/Modal/Modal.svelte.d.ts +0 -2
  48. package/dist/components/Modal/Modal.svelte.d.ts.map +1 -1
  49. package/dist/components/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte.d.ts +2 -2
  50. package/dist/components/Spinner/Spinner.svelte +17 -73
  51. package/dist/components/Spinner/Spinner.svelte.d.ts +3 -5
  52. package/dist/components/Spinner/Spinner.svelte.d.ts.map +1 -1
  53. package/dist/components/pages/performers/AvailabilityCalendarModal.svelte +632 -0
  54. package/dist/components/{PublicCard/PublicCard.svelte.d.ts → pages/performers/AvailabilityCalendarModal.svelte.d.ts} +14 -12
  55. package/dist/components/pages/performers/AvailabilityCalendarModal.svelte.d.ts.map +1 -0
  56. package/dist/components/pages/performers/ShowDetails.svelte.d.ts +4 -4
  57. package/dist/components/pages/performers/ShowItemCard.svelte.d.ts +8 -8
  58. package/dist/components/pages/performers/SwitchOption.svelte.d.ts +2 -2
  59. package/dist/components/pages/performers/VenueInfo.svelte.d.ts +2 -2
  60. package/dist/components/pages/performers/VenueItemCard.svelte +2 -2
  61. package/dist/components/pages/performers/VenueItemCard.svelte.d.ts +4 -4
  62. package/dist/components/pages/profile/profile-form.svelte +1 -1
  63. package/dist/components/pages/settings/tabs/CustomImageDropzone.svelte.d.ts +2 -2
  64. package/dist/components/pages/shows/TabNavigation.svelte +8 -7
  65. package/dist/constants/formOptions.d.ts +2 -5
  66. package/dist/constants/formOptions.d.ts.map +1 -1
  67. package/dist/constants/formOptions.js +1 -2
  68. package/dist/index.d.ts +4 -28
  69. package/dist/index.js +29 -33
  70. package/dist/services/EventService.js +75 -75
  71. package/dist/services/EventService.spec.js +217 -217
  72. package/dist/services/ShowService.spec.js +342 -342
  73. package/package.json +160 -160
  74. package/dist/components/AboutShow/AboutShow.svelte +0 -278
  75. package/dist/components/AboutShow/AboutShow.svelte.d.ts +0 -43
  76. package/dist/components/AboutShow/AboutShow.svelte.d.ts.map +0 -1
  77. package/dist/components/Accordion/Accordion.svelte +0 -44
  78. package/dist/components/Accordion/Accordion.svelte.d.ts +0 -42
  79. package/dist/components/Accordion/Accordion.svelte.d.ts.map +0 -1
  80. package/dist/components/Accordion/AccordionItem.svelte +0 -141
  81. package/dist/components/Accordion/AccordionItem.svelte.d.ts +0 -50
  82. package/dist/components/Accordion/AccordionItem.svelte.d.ts.map +0 -1
  83. package/dist/components/Calendar/MiniMonthCalendar.svelte +0 -1446
  84. package/dist/components/Calendar/MiniMonthCalendar.svelte.d.ts.map +0 -1
  85. package/dist/components/Checkbox/Checkbox.svelte +0 -90
  86. package/dist/components/Checkbox/Checkbox.svelte.d.ts +0 -64
  87. package/dist/components/Checkbox/Checkbox.svelte.d.ts.map +0 -1
  88. package/dist/components/Drawer/Drawer.svelte +0 -207
  89. package/dist/components/Drawer/Drawer.svelte.d.ts +0 -74
  90. package/dist/components/Drawer/Drawer.svelte.d.ts.map +0 -1
  91. package/dist/components/Dropdown/Dropdown.svelte +0 -193
  92. package/dist/components/Dropdown/Dropdown.svelte.d.ts +0 -50
  93. package/dist/components/Dropdown/Dropdown.svelte.d.ts.map +0 -1
  94. package/dist/components/Dropdown/DropdownItem.svelte +0 -111
  95. package/dist/components/Dropdown/DropdownItem.svelte.d.ts +0 -48
  96. package/dist/components/Dropdown/DropdownItem.svelte.d.ts.map +0 -1
  97. package/dist/components/Dropdown/SelectDropdown.svelte +0 -301
  98. package/dist/components/Dropdown/SelectDropdown.svelte.d.ts +0 -51
  99. package/dist/components/Dropdown/SelectDropdown.svelte.d.ts.map +0 -1
  100. package/dist/components/EmptyState/EmptyState.svelte +0 -80
  101. package/dist/components/EmptyState/EmptyState.svelte.d.ts +0 -37
  102. package/dist/components/EmptyState/EmptyState.svelte.d.ts.map +0 -1
  103. package/dist/components/FAQs/FAQs.svelte +0 -49
  104. package/dist/components/FAQs/FAQs.svelte.d.ts.map +0 -1
  105. package/dist/components/Input/Search.svelte +0 -173
  106. package/dist/components/Input/Search.svelte.d.ts +0 -68
  107. package/dist/components/Input/Search.svelte.d.ts.map +0 -1
  108. package/dist/components/Input/Textarea.svelte +0 -160
  109. package/dist/components/Input/Textarea.svelte.d.ts +0 -69
  110. package/dist/components/Input/Textarea.svelte.d.ts.map +0 -1
  111. package/dist/components/Label/Label.svelte +0 -60
  112. package/dist/components/Label/Label.svelte.d.ts +0 -48
  113. package/dist/components/Label/Label.svelte.d.ts.map +0 -1
  114. package/dist/components/Layout/PageLayout.svelte +0 -64
  115. package/dist/components/Layout/PageLayout.svelte.d.ts +0 -58
  116. package/dist/components/Layout/PageLayout.svelte.d.ts.map +0 -1
  117. package/dist/components/Modal/InputModal.svelte +0 -180
  118. package/dist/components/Modal/InputModal.svelte.d.ts +0 -77
  119. package/dist/components/Modal/InputModal.svelte.d.ts.map +0 -1
  120. package/dist/components/Modal/StatusModal.svelte +0 -221
  121. package/dist/components/Modal/StatusModal.svelte.d.ts +0 -59
  122. package/dist/components/Modal/StatusModal.svelte.d.ts.map +0 -1
  123. package/dist/components/MonthSwitcher/MonthSwitcher.svelte +0 -206
  124. package/dist/components/MonthSwitcher/MonthSwitcher.svelte.d.ts +0 -37
  125. package/dist/components/MonthSwitcher/MonthSwitcher.svelte.d.ts.map +0 -1
  126. package/dist/components/OrderSummary/OrderSummary.svelte +0 -553
  127. package/dist/components/OrderSummary/OrderSummary.svelte.d.ts +0 -65
  128. package/dist/components/OrderSummary/OrderSummary.svelte.d.ts.map +0 -1
  129. package/dist/components/Pagination/Pagination.svelte +0 -197
  130. package/dist/components/Pagination/Pagination.svelte.d.ts +0 -53
  131. package/dist/components/Pagination/Pagination.svelte.d.ts.map +0 -1
  132. package/dist/components/PublicCard/PublicCard.svelte +0 -267
  133. package/dist/components/PublicCard/PublicCard.svelte.d.ts.map +0 -1
  134. package/dist/components/Radio/Radio.svelte +0 -119
  135. package/dist/components/Radio/Radio.svelte.d.ts +0 -54
  136. package/dist/components/Radio/Radio.svelte.d.ts.map +0 -1
  137. package/dist/components/ShowCard/ShowCard.svelte +0 -240
  138. package/dist/components/ShowCard/ShowCard.svelte.d.ts +0 -39
  139. package/dist/components/ShowCard/ShowCard.svelte.d.ts.map +0 -1
  140. package/dist/components/ShowTimeCard/ShowTimeCard.svelte +0 -92
  141. package/dist/components/ShowTimeCard/ShowTimeCard.svelte.d.ts.map +0 -1
  142. package/dist/components/Skeleton/Skeleton.svelte +0 -68
  143. package/dist/components/Skeleton/Skeleton.svelte.d.ts +0 -37
  144. package/dist/components/Tabs/TabItem.svelte +0 -39
  145. package/dist/components/Tabs/TabItem.svelte.d.ts +0 -52
  146. package/dist/components/Tabs/TabItem.svelte.d.ts.map +0 -1
  147. package/dist/components/Tabs/Tabs.svelte +0 -181
  148. package/dist/components/Tabs/Tabs.svelte.d.ts +0 -46
  149. package/dist/components/Tabs/Tabs.svelte.d.ts.map +0 -1
  150. package/dist/components/Typography/Typography.svelte +0 -50
  151. package/dist/components/Typography/Typography.svelte.d.ts +0 -48
  152. package/dist/components/Typography/Typography.svelte.d.ts.map +0 -1
@@ -0,0 +1,632 @@
1
+ <script>
2
+ import { fade, fly } from "svelte/transition";
3
+ import { writable } from "svelte/store";
4
+ import { jwtDecode } from "jwt-decode";
5
+ import QuarterView from "../../Calendar/QuarterView.svelte";
6
+ import { timeAgo } from "../../../utils/utils/utils";
7
+ import { buildApiUrl, API_ENDPOINTS } from "../../../utils/apiConfig.js";
8
+ import { auth, initializeAuthState } from "../../../stores/auth.js";
9
+ import microphonePlaceholder from "../../../assets/images/microphone.png";
10
+
11
+ export let show = false;
12
+ export let venue = null;
13
+ export let onClose = () => {};
14
+ export let onUpdate = (updatedTimestamp) => {};
15
+
16
+ let isLoading = false;
17
+ let currentEvents = [];
18
+ const selectedDates = writable([]);
19
+ const message = writable("");
20
+ let localLastUpdated = venue?.lastUpdated || new Date().toISOString();
21
+ let saveTimeout = null;
22
+ let lastSavedDatesJson = "[]";
23
+ let isInitialLoad = true;
24
+
25
+ // Parse location into street address and city/state/zip
26
+ function parseLocation(locationString) {
27
+ if (!locationString) return { street: '', cityStateZip: '' };
28
+
29
+ // Split by comma to separate components
30
+ const parts = locationString.split(',').map(part => part.trim());
31
+
32
+ if (parts.length >= 3) {
33
+ // Format: "3400 Warner Blvd, Burbank, CA 91505"
34
+ const street = parts[0];
35
+ const cityStateZip = parts.slice(1).join(', ');
36
+ return { street, cityStateZip };
37
+ } else if (parts.length === 2) {
38
+ // Format: "Street, City State Zip"
39
+ return { street: parts[0], cityStateZip: parts[1] };
40
+ } else {
41
+ // Single part or unexpected format
42
+ return { street: locationString, cityStateZip: '' };
43
+ }
44
+ }
45
+
46
+ $: parsedLocation = parseLocation(venue?.location);
47
+
48
+ // Generate currentEvents up to 360 days in advance
49
+ function generateCurrentEvents() {
50
+ currentEvents = [];
51
+ const today = new Date();
52
+ for (let i = 0; i <= 360; i++) {
53
+ const date = new Date(today);
54
+ date.setDate(today.getDate() + i);
55
+ currentEvents.push({ date: normalizeDate(date) });
56
+ }
57
+ }
58
+
59
+ function normalizeDate(date) {
60
+ const d = new Date(date);
61
+ const year = d.getFullYear();
62
+ const month = String(d.getMonth() + 1).padStart(2, "0");
63
+ const day = String(d.getDate()).padStart(2, "0");
64
+ return `${year}-${month}-${day}`;
65
+ }
66
+
67
+ async function loadAvailabilityData() {
68
+ if (!venue) return;
69
+
70
+ isLoading = true;
71
+ initializeAuthState();
72
+ generateCurrentEvents();
73
+
74
+ try {
75
+ const getCookie = (name) => {
76
+ const value = `; ${document.cookie}`;
77
+ const parts = value.split(`; ${name}=`);
78
+ if (parts.length === 2) return parts.pop().split(";").shift();
79
+ };
80
+ const token = getCookie("performer_token");
81
+
82
+ let userId;
83
+ if (token) {
84
+ try {
85
+ const decoded = jwtDecode(token);
86
+ userId = decoded?.id || decoded?.userId;
87
+ } catch (err) {
88
+ console.error("Failed to decode token:", err);
89
+ }
90
+ }
91
+
92
+ const res = await fetch(
93
+ buildApiUrl(`${API_ENDPOINTS.PERFORMER_AVAILABILITIES}/${userId}`),
94
+ {
95
+ credentials: "include",
96
+ headers: {
97
+ Authorization: token ? `Bearer ${token}` : "",
98
+ },
99
+ },
100
+ );
101
+
102
+ if (res.ok) {
103
+ const events = await res.json();
104
+ const eventDetails = events.filter(
105
+ (event) => event.VenueID === Number(venue.venueId),
106
+ );
107
+
108
+ selectedDates.set([]);
109
+ eventDetails.forEach((event) => {
110
+ if (event.Date) {
111
+ const normalizedDate = normalizeDate(event.Date);
112
+ selectedDates.update((dates) => [...dates, normalizedDate]);
113
+ }
114
+ });
115
+
116
+ // Initialize lastSavedDatesJson with loaded dates
117
+ selectedDates.subscribe(dates => {
118
+ if (isInitialLoad) {
119
+ lastSavedDatesJson = JSON.stringify([...dates].sort());
120
+ }
121
+ });
122
+ }
123
+ } catch (err) {
124
+ console.error("Error loading availabilities:", err);
125
+ } finally {
126
+ setTimeout(() => {
127
+ isInitialLoad = false;
128
+ }, 100);
129
+ isLoading = false;
130
+ }
131
+ }
132
+
133
+ async function saveSelectedDates() {
134
+ if (!venue || venue.venueId === 0) return;
135
+
136
+ if (!$auth.token) {
137
+ initializeAuthState();
138
+ }
139
+
140
+ const dates = $selectedDates.map((dateObj) => dateObj);
141
+ const url = `/api/performer/performerAvailabilities/${venue.venueId}`;
142
+
143
+ const response = await fetch(url, {
144
+ method: "POST",
145
+ headers: {
146
+ "Content-Type": "application/json",
147
+ },
148
+ credentials: "include",
149
+ body: JSON.stringify(dates),
150
+ });
151
+
152
+ if (response.ok) {
153
+ lastSavedDatesJson = JSON.stringify([...$selectedDates].sort());
154
+ localLastUpdated = new Date().toISOString();
155
+ onUpdate(localLastUpdated);
156
+ }
157
+ }
158
+
159
+ // Reactive statement to save selected dates with debouncing
160
+ $: {
161
+ const currentDatesJson = JSON.stringify([...$selectedDates].sort());
162
+ const hasChanged = currentDatesJson !== lastSavedDatesJson;
163
+
164
+ if ($selectedDates.length > 0 && !isInitialLoad && hasChanged) {
165
+ // ALWAYS show "saving" on ANY change - this is key for consistent feedback
166
+ message.set("saving");
167
+
168
+ // Clear existing timeout to reset the debounce
169
+ if (saveTimeout) {
170
+ clearTimeout(saveTimeout);
171
+ }
172
+
173
+ localLastUpdated = new Date().toISOString();
174
+
175
+ // Start new debounce timer - wait for user to stop making changes
176
+ saveTimeout = setTimeout(async () => {
177
+ await saveSelectedDates();
178
+ message.set("saved");
179
+
180
+ // Success haptic feedback - notification style for iOS, pattern for Android
181
+ if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.haptic) {
182
+ window.webkit.messageHandlers.haptic.postMessage('success');
183
+ } else if (window.TapticEngine) {
184
+ window.TapticEngine.notification({ type: 'success' });
185
+ } else if (navigator.vibrate) {
186
+ navigator.vibrate([10, 50, 10]);
187
+ }
188
+
189
+ // Clear the "saved" message after 2 seconds (Google Docs style)
190
+ setTimeout(() => {
191
+ message.set("");
192
+ }, 2000);
193
+
194
+ saveTimeout = null;
195
+ }, 1000);
196
+ }
197
+ }
198
+
199
+ // Reset message when venue changes
200
+ $: if (venue) {
201
+ message.set("");
202
+ }
203
+
204
+ // Load data when modal opens
205
+ $: if (show && venue) {
206
+ loadAvailabilityData();
207
+ }
208
+
209
+ // Handle ESC key
210
+ function handleKeydown(event) {
211
+ if (event.key === "Escape" && show) {
212
+ onClose();
213
+ }
214
+ }
215
+
216
+ // Handle backdrop click
217
+ function handleBackdropClick(event) {
218
+ if (event.target === event.currentTarget) {
219
+ onClose();
220
+ }
221
+ }
222
+ </script>
223
+
224
+ <svelte:window on:keydown={handleKeydown} />
225
+
226
+ {#if show && venue}
227
+ <!-- Mobile: Full-screen modal (shown on mobile via CSS) -->
228
+ <div
229
+ class="fullscreen-modal modal-mobile-only"
230
+ transition:fade={{ duration: 200 }}
231
+ role="dialog"
232
+ aria-modal="true"
233
+ >
234
+ <!-- Header with safe area padding -->
235
+ <header class="fullscreen-modal__header">
236
+ <button
237
+ on:click={onClose}
238
+ class="modal-back-btn"
239
+ aria-label="Back to venues"
240
+ >
241
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
242
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
243
+ </svg>
244
+ </button>
245
+ <div class="modal-venue-info">
246
+ <div class="modal-venue-image">
247
+ <img
248
+ src={venue.image?.trim()
249
+ ? (venue.image.startsWith("http")
250
+ ? venue.image
251
+ : `https://moxy.sfo3.digitaloceanspaces.com${venue.image}`)
252
+ : microphonePlaceholder}
253
+ alt={venue.name}
254
+ />
255
+ </div>
256
+ <div class="modal-venue-text">
257
+ <h2 class="modal-venue-name">{venue.name}</h2>
258
+ <p class="modal-save-status">
259
+ {#if $message === "saving"}
260
+ <span class="text-green-500">Saving...</span>
261
+ {:else if $message === "saved"}
262
+ <span class="text-green-500">✓ Saved</span>
263
+ {/if}
264
+ </p>
265
+ </div>
266
+ </div>
267
+ </header>
268
+
269
+ <!-- Calendar Content - uses fullscreen-modal__body for proper scrolling -->
270
+ <div class="fullscreen-modal__body">
271
+ <div class="calendar-content">
272
+ {#if isLoading}
273
+ <!-- Loading Skeleton -->
274
+ <div class="loading-skeleton">
275
+ <div class="skeleton-nav">
276
+ <div class="skeleton-btn"></div>
277
+ <div class="skeleton-title"></div>
278
+ <div class="skeleton-btn"></div>
279
+ </div>
280
+ <div class="skeleton-grid">
281
+ {#each Array(35) as _}
282
+ <div class="skeleton-day"></div>
283
+ {/each}
284
+ </div>
285
+ </div>
286
+ {:else}
287
+ <QuarterView
288
+ currentevents={currentEvents}
289
+ {selectedDates}
290
+ saveStatus={$message}
291
+ />
292
+ {/if}
293
+ </div>
294
+ </div>
295
+ </div>
296
+
297
+ <!-- Desktop: Side panel (shown on desktop via CSS) -->
298
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
299
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
300
+ <div
301
+ class="desktop-panel-backdrop modal-desktop-only"
302
+ transition:fade={{ duration: 200 }}
303
+ on:click={handleBackdropClick}
304
+ role="dialog"
305
+ aria-modal="true"
306
+ >
307
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
308
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
309
+ <div
310
+ class="desktop-panel"
311
+ transition:fly={{ x: "100%", duration: 300 }}
312
+ on:click|stopPropagation
313
+ >
314
+ <!-- Header -->
315
+ <header class="desktop-panel-header">
316
+ <div class="desktop-venue-image">
317
+ <img
318
+ src={venue.image?.trim()
319
+ ? (venue.image.startsWith("http")
320
+ ? venue.image
321
+ : `https://moxy.sfo3.digitaloceanspaces.com${venue.image}`)
322
+ : microphonePlaceholder}
323
+ alt={venue.name}
324
+ />
325
+ </div>
326
+ <div class="desktop-venue-text">
327
+ <h2 class="desktop-venue-name">{venue.name}</h2>
328
+ <p class="modal-save-status">
329
+ {#if $message === "saving"}
330
+ <span class="text-green-500">Saving...</span>
331
+ {:else if $message === "saved"}
332
+ <span class="text-green-500">✓ Saved</span>
333
+ {/if}
334
+ </p>
335
+ </div>
336
+ <button
337
+ on:click={onClose}
338
+ class="desktop-close-btn"
339
+ aria-label="Close"
340
+ >
341
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
342
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
343
+ </svg>
344
+ </button>
345
+ </header>
346
+
347
+ <!-- Calendar Content -->
348
+ <div class="desktop-panel-body">
349
+ <div class="calendar-content">
350
+ {#if isLoading}
351
+ <!-- Loading Skeleton -->
352
+ <div class="loading-skeleton">
353
+ <div class="skeleton-nav">
354
+ <div class="skeleton-btn"></div>
355
+ <div class="skeleton-title"></div>
356
+ <div class="skeleton-btn"></div>
357
+ </div>
358
+ <div class="skeleton-grid">
359
+ {#each Array(35) as _}
360
+ <div class="skeleton-day"></div>
361
+ {/each}
362
+ </div>
363
+ </div>
364
+ {:else}
365
+ <QuarterView
366
+ currentevents={currentEvents}
367
+ {selectedDates}
368
+ saveStatus={$message}
369
+ />
370
+ {/if}
371
+ </div>
372
+ </div>
373
+ </div>
374
+ </div>
375
+ {/if}
376
+
377
+ <style>
378
+ /* Responsive show/hide - mobile shows fullscreen, desktop shows side panel */
379
+ .modal-mobile-only {
380
+ display: flex !important;
381
+ }
382
+
383
+ .modal-desktop-only {
384
+ display: none !important;
385
+ }
386
+
387
+ @media (min-width: 768px) {
388
+ .modal-mobile-only {
389
+ display: none !important;
390
+ }
391
+
392
+ .modal-desktop-only {
393
+ display: flex !important;
394
+ }
395
+ }
396
+
397
+ /*
398
+ Mobile fullscreen modal uses .fullscreen-modal class from app.css
399
+ which handles:
400
+ - position: fixed with inset: 0
401
+ - z-index: var(--z-critical) to be above everything
402
+ - flex column layout
403
+
404
+ .fullscreen-modal__header handles:
405
+ - Safe area padding (notch)
406
+ - Fixed height matching app header
407
+ - Border bottom
408
+
409
+ .fullscreen-modal__body handles:
410
+ - flex: 1 to fill remaining space
411
+ - overflow-y: auto with proper scrolling
412
+ - overscroll-behavior: contain (no iOS bounce)
413
+ - padding-bottom for safe area
414
+ */
415
+
416
+ /* Back button */
417
+ .modal-back-btn {
418
+ width: 2.5rem;
419
+ height: 2.5rem;
420
+ display: flex;
421
+ align-items: center;
422
+ justify-content: center;
423
+ border-radius: 0.5rem;
424
+ background: transparent;
425
+ border: none;
426
+ cursor: pointer;
427
+ color: hsl(var(--Text-Primary));
428
+ transition: background-color 0.15s;
429
+ flex-shrink: 0;
430
+ }
431
+
432
+ .modal-back-btn:hover {
433
+ background-color: hsl(var(--BG-Tertiary));
434
+ }
435
+
436
+ /* Venue info in header */
437
+ .modal-venue-info {
438
+ display: flex;
439
+ align-items: center;
440
+ gap: 0.75rem;
441
+ flex: 1;
442
+ min-width: 0;
443
+ }
444
+
445
+ .modal-venue-image {
446
+ width: 2.5rem;
447
+ height: 2.5rem;
448
+ background-color: hsl(var(--BG-Secondary));
449
+ border-radius: 0.375rem;
450
+ overflow: hidden;
451
+ flex-shrink: 0;
452
+ }
453
+
454
+ .modal-venue-image img {
455
+ width: 100%;
456
+ height: 100%;
457
+ -o-object-fit: contain;
458
+ object-fit: contain;
459
+ }
460
+
461
+ .modal-venue-text {
462
+ flex: 1;
463
+ min-width: 0;
464
+ }
465
+
466
+ .modal-venue-name {
467
+ font-size: 1rem;
468
+ font-weight: 500;
469
+ color: hsl(var(--Text-Primary));
470
+ display: -webkit-box;
471
+ -webkit-line-clamp: 2;
472
+ -webkit-box-orient: vertical;
473
+ overflow: hidden;
474
+ line-height: 1.25;
475
+ margin: 0;
476
+ }
477
+
478
+ .modal-save-status {
479
+ font-size: 0.75rem;
480
+ margin-top: 0.125rem;
481
+ min-height: 1rem;
482
+ margin-bottom: 0;
483
+ }
484
+
485
+ /* Calendar content area */
486
+ .calendar-content {
487
+ padding: 1rem;
488
+ }
489
+
490
+ /* Loading skeleton */
491
+ .loading-skeleton {
492
+ width: 100%;
493
+ max-width: 28rem;
494
+ margin: 0 auto;
495
+ }
496
+
497
+ .skeleton-nav {
498
+ display: flex;
499
+ justify-content: space-between;
500
+ align-items: center;
501
+ margin-bottom: 1.5rem;
502
+ }
503
+
504
+ .skeleton-btn {
505
+ width: 2.5rem;
506
+ height: 2.5rem;
507
+ background-color: hsl(var(--BG-Secondary));
508
+ border-radius: 0.5rem;
509
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
510
+ }
511
+
512
+ .skeleton-title {
513
+ width: 8rem;
514
+ height: 1.5rem;
515
+ background-color: hsl(var(--BG-Secondary));
516
+ border-radius: 0.25rem;
517
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
518
+ }
519
+
520
+ .skeleton-grid {
521
+ display: grid;
522
+ grid-template-columns: repeat(7, 1fr);
523
+ gap: 0.5rem;
524
+ }
525
+
526
+ .skeleton-day {
527
+ width: 100%;
528
+ aspect-ratio: 1;
529
+ background-color: hsl(var(--BG-Secondary));
530
+ border-radius: 0.25rem;
531
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
532
+ }
533
+
534
+ @keyframes pulse {
535
+ 0%, 100% {
536
+ opacity: 1;
537
+ }
538
+ 50% {
539
+ opacity: 0.5;
540
+ }
541
+ }
542
+
543
+ /* Desktop side panel */
544
+ .desktop-panel-backdrop {
545
+ position: fixed;
546
+ inset: 0;
547
+ background-color: rgba(0, 0, 0, 0.3);
548
+ z-index: var(--z-modal, 50);
549
+ }
550
+
551
+ .desktop-panel {
552
+ position: absolute;
553
+ top: 0;
554
+ right: 0;
555
+ bottom: 0;
556
+ width: 100%;
557
+ max-width: 28rem;
558
+ background-color: hsl(var(--BG-Primary));
559
+ box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);
560
+ display: flex;
561
+ flex-direction: column;
562
+ }
563
+
564
+ .desktop-panel-header {
565
+ flex-shrink: 0;
566
+ display: flex;
567
+ align-items: center;
568
+ gap: 0.75rem;
569
+ padding: 1rem;
570
+ border-bottom: 1px solid hsl(var(--Stroke-Primary));
571
+ background-color: hsl(var(--BG-Primary));
572
+ }
573
+
574
+ .desktop-venue-image {
575
+ width: 3rem;
576
+ height: 3rem;
577
+ background-color: hsl(var(--BG-Secondary));
578
+ border-radius: 0.375rem;
579
+ overflow: hidden;
580
+ flex-shrink: 0;
581
+ }
582
+
583
+ .desktop-venue-image img {
584
+ width: 100%;
585
+ height: 100%;
586
+ -o-object-fit: contain;
587
+ object-fit: contain;
588
+ }
589
+
590
+ .desktop-venue-text {
591
+ flex: 1;
592
+ min-width: 0;
593
+ }
594
+
595
+ .desktop-venue-name {
596
+ font-size: 1.125rem;
597
+ font-weight: 500;
598
+ color: hsl(var(--Text-Primary));
599
+ display: -webkit-box;
600
+ -webkit-line-clamp: 2;
601
+ -webkit-box-orient: vertical;
602
+ overflow: hidden;
603
+ line-height: 1.25;
604
+ margin: 0;
605
+ }
606
+
607
+ .desktop-close-btn {
608
+ width: 2rem;
609
+ height: 2rem;
610
+ display: flex;
611
+ align-items: center;
612
+ justify-content: center;
613
+ border-radius: 0.375rem;
614
+ background: transparent;
615
+ border: none;
616
+ cursor: pointer;
617
+ color: hsl(var(--Text-Primary));
618
+ transition: background-color 0.15s;
619
+ flex-shrink: 0;
620
+ }
621
+
622
+ .desktop-close-btn:hover {
623
+ background-color: hsl(var(--BG-Tertiary));
624
+ }
625
+
626
+ .desktop-panel-body {
627
+ flex: 1;
628
+ overflow-y: auto;
629
+ overscroll-behavior: contain;
630
+ -webkit-overflow-scrolling: touch;
631
+ }
632
+ </style>
@@ -1,21 +1,23 @@
1
- export default PublicCard;
2
- type PublicCard = SvelteComponent<{
3
- view?: string | undefined;
4
- events?: any[] | undefined;
5
- placeholderImage?: null | undefined;
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;
6
7
  }, {
7
- eventClick: CustomEvent<any>;
8
+ click: PointerEvent;
8
9
  } & {
9
10
  [evt: string]: CustomEvent<any>;
10
11
  }, {}> & {
11
12
  $$bindings?: string | undefined;
12
13
  };
13
- declare const PublicCard: $$__sveltets_2_IsomorphicComponent<{
14
- view?: string | undefined;
15
- events?: any[] | undefined;
16
- placeholderImage?: null | undefined;
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;
17
19
  }, {
18
- eventClick: CustomEvent<any>;
20
+ click: PointerEvent;
19
21
  } & {
20
22
  [evt: string]: CustomEvent<any>;
21
23
  }, {}, {}, string>;
@@ -32,4 +34,4 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
32
34
  };
33
35
  z_$$bindings?: Bindings;
34
36
  }
35
- //# sourceMappingURL=PublicCard.svelte.d.ts.map
37
+ //# sourceMappingURL=AvailabilityCalendarModal.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvailabilityCalendarModal.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/pages/performers/AvailabilityCalendarModal.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;AA4WA;;;;;;;;;mBAA4K;6CAT/H,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"}
@@ -1,31 +1,31 @@
1
1
  export default ShowDetails;
2
2
  type ShowDetails = SvelteComponent<{
3
- venue: any;
4
3
  status: any;
4
+ venue: any;
5
5
  formattedStartTime: any;
6
6
  showFullDate: any;
7
7
  formattedDoorsOpenTime: any;
8
8
  setLength: any;
9
9
  eventDetails: any;
10
10
  onToggleModal: any;
11
- role?: string | undefined;
12
11
  stageName?: string | undefined;
12
+ role?: string | undefined;
13
13
  }, {
14
14
  [evt: string]: CustomEvent<any>;
15
15
  }, {}> & {
16
16
  $$bindings?: string | undefined;
17
17
  };
18
18
  declare const ShowDetails: $$__sveltets_2_IsomorphicComponent<{
19
- venue: any;
20
19
  status: any;
20
+ venue: any;
21
21
  formattedStartTime: any;
22
22
  showFullDate: any;
23
23
  formattedDoorsOpenTime: any;
24
24
  setLength: any;
25
25
  eventDetails: any;
26
26
  onToggleModal: any;
27
- role?: string | undefined;
28
27
  stageName?: string | undefined;
28
+ role?: string | undefined;
29
29
  }, {
30
30
  [evt: string]: CustomEvent<any>;
31
31
  }, {}, {}, string>;