@getmicdrop/svelte-components 2.4.0 → 2.6.1

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 (132) hide show
  1. package/dist/__LIB_STORES__.js +2 -30
  2. package/dist/components/Badges/Badge.svelte +3 -129
  3. package/dist/components/Badges/Badge.svelte.d.ts +2 -8
  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 +0 -1
  9. package/dist/components/Calendar/Calendar.spec.d.ts +2 -0
  10. package/dist/components/Calendar/Calendar.spec.d.ts.map +1 -0
  11. package/dist/components/Calendar/Calendar.spec.js +131 -0
  12. package/dist/components/Calendar/Calendar.svelte +1115 -0
  13. package/dist/components/Calendar/{MiniMonthCalendar.svelte.d.ts → Calendar.svelte.d.ts} +21 -20
  14. package/dist/components/{Checkbox/Checkbox.svelte.d.ts.map → Calendar/Calendar.svelte.d.ts.map} +1 -1
  15. package/dist/components/Calendar/QuarterView.spec.d.ts +2 -0
  16. package/dist/components/Calendar/QuarterView.spec.d.ts.map +1 -0
  17. package/dist/components/Calendar/QuarterView.spec.js +394 -0
  18. package/dist/components/Calendar/QuarterView.stories.svelte +134 -0
  19. package/dist/components/{PublicCard/PublicCard.svelte.d.ts → Calendar/QuarterView.stories.svelte.d.ts} +21 -15
  20. package/dist/components/Calendar/QuarterView.stories.svelte.d.ts.map +1 -0
  21. package/dist/components/Calendar/QuarterView.svelte +736 -0
  22. package/dist/components/{FAQs/FAQs.svelte.d.ts → Calendar/QuarterView.svelte.d.ts} +10 -10
  23. package/dist/components/{Skeleton/Skeleton.svelte.d.ts.map → Calendar/QuarterView.svelte.d.ts.map} +1 -1
  24. package/dist/components/DarkModeToggle.svelte +0 -2
  25. package/dist/components/DarkModeToggle.svelte.d.ts.map +1 -1
  26. package/dist/components/Input/Input.svelte +12 -100
  27. package/dist/components/Input/Input.svelte.d.ts +6 -18
  28. package/dist/components/Input/Input.svelte.d.ts.map +1 -1
  29. package/dist/components/Input/MultiSelect.svelte +5 -4
  30. package/dist/components/Input/MultiSelect.svelte.d.ts +6 -6
  31. package/dist/components/Input/MultiSelect.svelte.d.ts.map +1 -1
  32. package/dist/components/Input/OTPInput.svelte +1 -1
  33. package/dist/components/Input/Select.svelte +5 -4
  34. package/dist/components/Input/Select.svelte.d.ts +6 -6
  35. package/dist/components/Input/Select.svelte.d.ts.map +1 -1
  36. package/dist/components/Layout/Header.svelte +4 -14
  37. package/dist/components/Modal/ConfirmationModal.svelte +17 -69
  38. package/dist/components/Modal/ConfirmationModal.svelte.d.ts +0 -22
  39. package/dist/components/Modal/ConfirmationModal.svelte.d.ts.map +1 -1
  40. package/dist/components/Modal/Modal.svelte +8 -34
  41. package/dist/components/Modal/Modal.svelte.d.ts +0 -2
  42. package/dist/components/Modal/Modal.svelte.d.ts.map +1 -1
  43. package/dist/components/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte.d.ts +2 -2
  44. package/dist/components/Spinner/Spinner.svelte +17 -73
  45. package/dist/components/Spinner/Spinner.svelte.d.ts +3 -5
  46. package/dist/components/Spinner/Spinner.svelte.d.ts.map +1 -1
  47. package/dist/components/pages/performers/AvailabilityCalendarModal.svelte +632 -0
  48. package/dist/components/{ShowTimeCard/ShowTimeCard.svelte.d.ts → pages/performers/AvailabilityCalendarModal.svelte.d.ts} +14 -14
  49. package/dist/components/pages/performers/AvailabilityCalendarModal.svelte.d.ts.map +1 -0
  50. package/dist/components/pages/performers/ShowDetails.svelte.d.ts +2 -2
  51. package/dist/components/pages/performers/ShowItemCard.svelte.d.ts +8 -8
  52. package/dist/components/pages/performers/SwitchOption.svelte.d.ts +2 -2
  53. package/dist/components/pages/performers/VenueInfo.svelte.d.ts +2 -2
  54. package/dist/components/pages/performers/VenueItemCard.svelte +2 -2
  55. package/dist/components/pages/performers/VenueItemCard.svelte.d.ts +4 -4
  56. package/dist/components/pages/profile/profile-form.svelte +1 -1
  57. package/dist/components/pages/shows/TabNavigation.svelte +8 -7
  58. package/dist/constants/formOptions.d.ts +2 -5
  59. package/dist/constants/formOptions.d.ts.map +1 -1
  60. package/dist/constants/formOptions.js +1 -2
  61. package/dist/index.d.ts +4 -24
  62. package/dist/index.js +4 -30
  63. package/dist/services/EventService.js +75 -75
  64. package/dist/services/EventService.spec.js +217 -217
  65. package/dist/services/ShowService.spec.js +342 -342
  66. package/package.json +160 -160
  67. package/dist/components/AboutShow/AboutShow.svelte +0 -278
  68. package/dist/components/AboutShow/AboutShow.svelte.d.ts +0 -43
  69. package/dist/components/AboutShow/AboutShow.svelte.d.ts.map +0 -1
  70. package/dist/components/Accordion/Accordion.svelte +0 -44
  71. package/dist/components/Accordion/Accordion.svelte.d.ts +0 -42
  72. package/dist/components/Accordion/Accordion.svelte.d.ts.map +0 -1
  73. package/dist/components/Accordion/AccordionItem.svelte +0 -141
  74. package/dist/components/Accordion/AccordionItem.svelte.d.ts +0 -50
  75. package/dist/components/Accordion/AccordionItem.svelte.d.ts.map +0 -1
  76. package/dist/components/Calendar/MiniMonthCalendar.svelte +0 -1446
  77. package/dist/components/Calendar/MiniMonthCalendar.svelte.d.ts.map +0 -1
  78. package/dist/components/Checkbox/Checkbox.svelte +0 -116
  79. package/dist/components/Checkbox/Checkbox.svelte.d.ts +0 -52
  80. package/dist/components/Drawer/Drawer.svelte +0 -207
  81. package/dist/components/Drawer/Drawer.svelte.d.ts +0 -74
  82. package/dist/components/Drawer/Drawer.svelte.d.ts.map +0 -1
  83. package/dist/components/Dropdown/Dropdown.svelte +0 -129
  84. package/dist/components/Dropdown/Dropdown.svelte.d.ts +0 -48
  85. package/dist/components/Dropdown/Dropdown.svelte.d.ts.map +0 -1
  86. package/dist/components/Dropdown/DropdownItem.svelte +0 -111
  87. package/dist/components/Dropdown/DropdownItem.svelte.d.ts +0 -48
  88. package/dist/components/Dropdown/DropdownItem.svelte.d.ts.map +0 -1
  89. package/dist/components/FAQs/FAQs.svelte +0 -49
  90. package/dist/components/FAQs/FAQs.svelte.d.ts.map +0 -1
  91. package/dist/components/Input/Search.svelte +0 -173
  92. package/dist/components/Input/Search.svelte.d.ts +0 -68
  93. package/dist/components/Input/Search.svelte.d.ts.map +0 -1
  94. package/dist/components/Input/Textarea.svelte +0 -160
  95. package/dist/components/Input/Textarea.svelte.d.ts +0 -69
  96. package/dist/components/Input/Textarea.svelte.d.ts.map +0 -1
  97. package/dist/components/Label/Label.svelte +0 -60
  98. package/dist/components/Label/Label.svelte.d.ts +0 -48
  99. package/dist/components/Label/Label.svelte.d.ts.map +0 -1
  100. package/dist/components/Modal/InputModal.svelte +0 -180
  101. package/dist/components/Modal/InputModal.svelte.d.ts +0 -77
  102. package/dist/components/Modal/InputModal.svelte.d.ts.map +0 -1
  103. package/dist/components/Modal/StatusModal.svelte +0 -221
  104. package/dist/components/Modal/StatusModal.svelte.d.ts +0 -59
  105. package/dist/components/Modal/StatusModal.svelte.d.ts.map +0 -1
  106. package/dist/components/MonthSwitcher/MonthSwitcher.svelte +0 -206
  107. package/dist/components/MonthSwitcher/MonthSwitcher.svelte.d.ts +0 -37
  108. package/dist/components/MonthSwitcher/MonthSwitcher.svelte.d.ts.map +0 -1
  109. package/dist/components/OrderSummary/OrderSummary.svelte +0 -553
  110. package/dist/components/OrderSummary/OrderSummary.svelte.d.ts +0 -65
  111. package/dist/components/OrderSummary/OrderSummary.svelte.d.ts.map +0 -1
  112. package/dist/components/Pagination/Pagination.svelte +0 -197
  113. package/dist/components/Pagination/Pagination.svelte.d.ts +0 -53
  114. package/dist/components/Pagination/Pagination.svelte.d.ts.map +0 -1
  115. package/dist/components/PublicCard/PublicCard.svelte +0 -267
  116. package/dist/components/PublicCard/PublicCard.svelte.d.ts.map +0 -1
  117. package/dist/components/Radio/Radio.svelte +0 -119
  118. package/dist/components/Radio/Radio.svelte.d.ts +0 -54
  119. package/dist/components/Radio/Radio.svelte.d.ts.map +0 -1
  120. package/dist/components/ShowCard/ShowCard.svelte +0 -240
  121. package/dist/components/ShowCard/ShowCard.svelte.d.ts +0 -39
  122. package/dist/components/ShowCard/ShowCard.svelte.d.ts.map +0 -1
  123. package/dist/components/ShowTimeCard/ShowTimeCard.svelte +0 -92
  124. package/dist/components/ShowTimeCard/ShowTimeCard.svelte.d.ts.map +0 -1
  125. package/dist/components/Skeleton/Skeleton.svelte +0 -68
  126. package/dist/components/Skeleton/Skeleton.svelte.d.ts +0 -37
  127. package/dist/components/Tabs/TabItem.svelte +0 -39
  128. package/dist/components/Tabs/TabItem.svelte.d.ts +0 -52
  129. package/dist/components/Tabs/TabItem.svelte.d.ts.map +0 -1
  130. package/dist/components/Tabs/Tabs.svelte +0 -181
  131. package/dist/components/Tabs/Tabs.svelte.d.ts +0 -46
  132. package/dist/components/Tabs/Tabs.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,23 +1,23 @@
1
- export default ShowTimeCard;
2
- type ShowTimeCard = SvelteComponent<{
3
- time?: string | undefined;
4
- day?: string | undefined;
5
- date?: string | undefined;
6
- isSelected?: boolean | 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;
7
7
  }, {
8
- select: CustomEvent<any>;
8
+ click: PointerEvent;
9
9
  } & {
10
10
  [evt: string]: CustomEvent<any>;
11
11
  }, {}> & {
12
12
  $$bindings?: string | undefined;
13
13
  };
14
- declare const ShowTimeCard: $$__sveltets_2_IsomorphicComponent<{
15
- time?: string | undefined;
16
- day?: string | undefined;
17
- date?: string | undefined;
18
- isSelected?: boolean | 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;
19
19
  }, {
20
- select: CustomEvent<any>;
20
+ click: PointerEvent;
21
21
  } & {
22
22
  [evt: string]: CustomEvent<any>;
23
23
  }, {}, {}, string>;
@@ -34,4 +34,4 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
34
34
  };
35
35
  z_$$bindings?: Bindings;
36
36
  }
37
- //# sourceMappingURL=ShowTimeCard.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"}
@@ -8,8 +8,8 @@ type ShowDetails = SvelteComponent<{
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
  }, {}> & {
@@ -24,8 +24,8 @@ declare const ShowDetails: $$__sveltets_2_IsomorphicComponent<{
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>;