@getmicdrop/svelte-components 2.0.4 → 2.0.6

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 (107) hide show
  1. package/dist/components/Alert/Alert.spec.js +170 -170
  2. package/dist/components/Badges/Badge.spec.js +103 -103
  3. package/dist/components/BottomSheet/BottomSheet.spec.js +127 -127
  4. package/dist/components/Breadcrumb/Breadcrumb.spec.js +120 -120
  5. package/dist/components/Button/Button.spec.js +211 -211
  6. package/dist/components/Button/ButtonSaveDemo.spec.js +48 -48
  7. package/dist/components/Calendar/Calendar.spec.js +131 -131
  8. package/dist/components/Calendar/QuarterView.spec.js +394 -394
  9. package/dist/components/Card.spec.js +47 -47
  10. package/dist/components/CropImage/CropImage.spec.js +216 -216
  11. package/dist/components/DarkModeToggle.spec.js +357 -357
  12. package/dist/components/ErrorDisplay.spec.js +69 -69
  13. package/dist/components/FormActions.spec.js +88 -88
  14. package/dist/components/FormValidationSummary.spec.js +203 -203
  15. package/dist/components/Icons/Icon.spec.js +175 -175
  16. package/dist/components/Icons/MoreHori.spec.js +67 -67
  17. package/dist/components/Icons/WarningIcon.spec.js +30 -30
  18. package/dist/components/Input/Input.spec.js +573 -573
  19. package/dist/components/Input/MultiSelect.spec.js +257 -257
  20. package/dist/components/Input/OTPInput.spec.js +238 -238
  21. package/dist/components/Input/Select.spec.js +218 -218
  22. package/dist/components/Layout/BottomNav.spec.js +130 -130
  23. package/dist/components/Layout/Header.spec.js +203 -203
  24. package/dist/components/Modal/ConfirmationModal.spec.js +191 -191
  25. package/dist/components/Modal/Modal.spec.js +95 -95
  26. package/dist/components/Modal/ModalStateManager.spec.js +100 -100
  27. package/dist/components/PageLoader.spec.js +54 -54
  28. package/dist/components/PasswordStrengthIndicator/PasswordStrengthIndicator.spec.js +173 -173
  29. package/dist/components/PlaceAutocomplete/PlaceAutocomplete.spec.js +300 -300
  30. package/dist/components/Spinner/Spinner.spec.js +75 -75
  31. package/dist/components/StatusIndicator/StatusIndicator.spec.js +129 -129
  32. package/dist/components/Toaster/Toaster.stories.svelte +1 -1
  33. package/dist/components/Toggle.spec.js +158 -158
  34. package/dist/components/ValidationError.spec.js +79 -79
  35. package/dist/components/pages/performers/AvailabilityCalendarModal.spec.js +606 -606
  36. package/dist/components/pages/performers/AvailabilityCalendarModal.svelte +4 -4
  37. package/dist/components/pages/performers/ModalShowInfo.spec.js +124 -124
  38. package/dist/components/pages/performers/ModalShowInfo.svelte +1 -1
  39. package/dist/components/pages/performers/PageBackButton.spec.js +89 -89
  40. package/dist/components/pages/performers/SectionHeader.spec.js +75 -75
  41. package/dist/components/pages/performers/ShowDetails.spec.js +166 -166
  42. package/dist/components/pages/performers/ShowItemCard.spec.js +793 -793
  43. package/dist/components/pages/performers/ShowItemCard.svelte +4 -4
  44. package/dist/components/pages/performers/SwitchOption.spec.js +127 -127
  45. package/dist/components/pages/performers/VenueInfo.spec.js +167 -167
  46. package/dist/components/pages/performers/VenueInfo.svelte +1 -1
  47. package/dist/components/pages/performers/VenueItemCard.spec.js +763 -763
  48. package/dist/components/pages/performers/VenueItemCard.svelte +4 -4
  49. package/dist/components/pages/profile/profile-form.spec.js +9 -9
  50. package/dist/components/pages/settings/tabs/CustomImageDropzone.svelte +3 -3
  51. package/dist/components/pages/shows/ShowList.spec.js +33 -33
  52. package/dist/components/pages/shows/TabContent.spec.js +90 -90
  53. package/dist/components/pages/shows/TabNavigation.spec.js +143 -143
  54. package/dist/config.js +5 -5
  55. package/dist/config.spec.js +29 -29
  56. package/dist/constants/formOptions.js +25 -25
  57. package/dist/constants/formOptions.spec.js +88 -88
  58. package/dist/index.js +111 -111
  59. package/dist/stores/auth.d.ts +9 -0
  60. package/dist/stores/auth.d.ts.map +1 -0
  61. package/dist/stores/auth.js +36 -0
  62. package/dist/stores/auth.spec.d.ts +2 -0
  63. package/dist/stores/auth.spec.d.ts.map +1 -0
  64. package/dist/stores/auth.spec.js +139 -0
  65. package/dist/stores/formDataStore.d.ts +17 -0
  66. package/dist/stores/formDataStore.d.ts.map +1 -0
  67. package/dist/stores/formDataStore.js +25 -0
  68. package/dist/stores/formDataStore.spec.d.ts +2 -0
  69. package/dist/stores/formDataStore.spec.d.ts.map +1 -0
  70. package/dist/stores/formDataStore.spec.js +257 -0
  71. package/dist/stores/formSave.d.ts +24 -0
  72. package/dist/stores/formSave.d.ts.map +1 -0
  73. package/dist/stores/formSave.js +132 -0
  74. package/dist/stores/formSave.spec.d.ts +2 -0
  75. package/dist/stores/formSave.spec.d.ts.map +1 -0
  76. package/dist/stores/formSave.spec.js +296 -0
  77. package/dist/stores/index.d.ts +1 -0
  78. package/dist/stores/index.d.ts.map +1 -0
  79. package/dist/stores/index.js +0 -0
  80. package/dist/stores/navigation.d.ts +5 -0
  81. package/dist/stores/navigation.d.ts.map +1 -0
  82. package/dist/stores/navigation.js +12 -0
  83. package/dist/stores/navigation.spec.d.ts +2 -0
  84. package/dist/stores/navigation.spec.d.ts.map +1 -0
  85. package/dist/stores/navigation.spec.js +136 -0
  86. package/dist/stores/toaster.d.ts +4 -0
  87. package/dist/stores/toaster.d.ts.map +1 -0
  88. package/dist/stores/toaster.js +13 -0
  89. package/dist/stores/toaster.spec.d.ts +2 -0
  90. package/dist/stores/toaster.spec.d.ts.map +1 -0
  91. package/dist/stores/toaster.spec.js +59 -0
  92. package/dist/telemetry.js +357 -357
  93. package/dist/telemetry.server.js +211 -211
  94. package/dist/telemetry.server.spec.js +434 -434
  95. package/dist/telemetry.spec.js +660 -660
  96. package/dist/utils/apiConfig.js +49 -49
  97. package/dist/utils/apiConfig.spec.js +118 -118
  98. package/dist/utils/greetings.js +187 -187
  99. package/dist/utils/greetings.spec.js +337 -337
  100. package/dist/utils/imageValidation.js +121 -121
  101. package/dist/utils/imageValidation.spec.js +220 -220
  102. package/dist/utils/portal.js +25 -25
  103. package/dist/utils/portal.spec.js +143 -143
  104. package/dist/utils/utils/utils.js +323 -323
  105. package/dist/utils/utils/utils.spec.js +698 -698
  106. package/dist/utils/utils.spec.js +643 -643
  107. package/package.json +1 -1
@@ -0,0 +1,139 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { get } from 'svelte/store';
3
+ import { auth, setAuthState, clearAuthState, initializeAuthState } from './auth';
4
+
5
+ describe('auth store', () => {
6
+ beforeEach(() => {
7
+ // Reset auth state before each test
8
+ clearAuthState();
9
+ // Clear cookies
10
+ Object.defineProperty(document, 'cookie', {
11
+ writable: true,
12
+ value: '',
13
+ });
14
+ });
15
+
16
+ describe('initial state', () => {
17
+ it('starts with isAuthenticated as false', () => {
18
+ expect(get(auth).isAuthenticated).toBe(false);
19
+ });
20
+
21
+ it('starts with token as null', () => {
22
+ expect(get(auth).token).toBe(null);
23
+ });
24
+
25
+ it('starts with userDetails as null', () => {
26
+ expect(get(auth).userDetails).toBe(null);
27
+ });
28
+ });
29
+
30
+ describe('setAuthState', () => {
31
+ it('sets authentication state', () => {
32
+ setAuthState({
33
+ isAuthenticated: true,
34
+ token: 'test-token',
35
+ userDetails: { email: 'test@test.com' },
36
+ });
37
+
38
+ const state = get(auth);
39
+ expect(state.isAuthenticated).toBe(true);
40
+ expect(state.token).toBe('test-token');
41
+ expect(state.userDetails).toEqual({ email: 'test@test.com' });
42
+ });
43
+
44
+ it('can update partial state', () => {
45
+ setAuthState({ isAuthenticated: true, token: 'token1', userDetails: null });
46
+ setAuthState({ isAuthenticated: true, token: 'token2', userDetails: { name: 'User' } });
47
+
48
+ const state = get(auth);
49
+ expect(state.token).toBe('token2');
50
+ expect(state.userDetails).toEqual({ name: 'User' });
51
+ });
52
+ });
53
+
54
+ describe('clearAuthState', () => {
55
+ it('clears authentication state', () => {
56
+ setAuthState({
57
+ isAuthenticated: true,
58
+ token: 'test-token',
59
+ userDetails: { email: 'test@test.com' },
60
+ });
61
+
62
+ clearAuthState();
63
+
64
+ const state = get(auth);
65
+ expect(state.isAuthenticated).toBe(false);
66
+ expect(state.token).toBe(null);
67
+ expect(state.userDetails).toBe(null);
68
+ });
69
+ });
70
+
71
+ describe('initializeAuthState', () => {
72
+ it('does nothing when no performer_token cookie exists', () => {
73
+ Object.defineProperty(document, 'cookie', {
74
+ writable: true,
75
+ value: '',
76
+ });
77
+
78
+ initializeAuthState();
79
+
80
+ const state = get(auth);
81
+ expect(state.isAuthenticated).toBe(false);
82
+ });
83
+
84
+ it('sets auth state from performer_token cookie', () => {
85
+ Object.defineProperty(document, 'cookie', {
86
+ writable: true,
87
+ value: 'performer_token=my-token',
88
+ });
89
+
90
+ initializeAuthState();
91
+
92
+ const state = get(auth);
93
+ expect(state.isAuthenticated).toBe(true);
94
+ expect(state.token).toBe('my-token');
95
+ });
96
+
97
+ it('parses userDetails cookie when present', () => {
98
+ const userDetails = JSON.stringify({ email: 'test@test.com', firstName: 'Test' });
99
+ Object.defineProperty(document, 'cookie', {
100
+ writable: true,
101
+ value: `performer_token=my-token; userDetails=${encodeURIComponent(userDetails)}`,
102
+ });
103
+
104
+ initializeAuthState();
105
+
106
+ const state = get(auth);
107
+ expect(state.userDetails).toEqual({ email: 'test@test.com', firstName: 'Test' });
108
+ });
109
+
110
+ it('handles missing userDetails cookie', () => {
111
+ Object.defineProperty(document, 'cookie', {
112
+ writable: true,
113
+ value: 'performer_token=my-token',
114
+ });
115
+
116
+ initializeAuthState();
117
+
118
+ const state = get(auth);
119
+ expect(state.isAuthenticated).toBe(true);
120
+ expect(state.userDetails).toBe(null);
121
+ });
122
+ });
123
+
124
+ describe('store subscription', () => {
125
+ it('can subscribe to auth changes', () => {
126
+ const values = [];
127
+ const unsubscribe = auth.subscribe((value) => {
128
+ values.push(value.isAuthenticated);
129
+ });
130
+
131
+ setAuthState({ isAuthenticated: true, token: 'token', userDetails: null });
132
+ clearAuthState();
133
+
134
+ unsubscribe();
135
+
136
+ expect(values).toEqual([false, true, false]);
137
+ });
138
+ });
139
+ });
@@ -0,0 +1,17 @@
1
+ export const profileFormData: import("svelte/store").Writable<{
2
+ basicInfo: {
3
+ firstName: string;
4
+ lastName: string;
5
+ email: string;
6
+ phone: string;
7
+ stageName: string;
8
+ location: string;
9
+ };
10
+ socialMedia: {
11
+ videoLink: string;
12
+ };
13
+ extraDetails: {};
14
+ }>;
15
+ export const initialFormData: import("svelte/store").Writable<null>;
16
+ export const hasChanges: import("svelte/store").Readable<boolean>;
17
+ //# sourceMappingURL=formDataStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formDataStore.d.ts","sourceRoot":"","sources":["../../src/lib/stores/formDataStore.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,oEAA8C;AAE9C,kEAKE"}
@@ -0,0 +1,25 @@
1
+ import { writable, derived } from "svelte/store";
2
+
3
+ export const profileFormData = writable({
4
+ basicInfo: {
5
+ firstName: "",
6
+ lastName: "",
7
+ email: "",
8
+ phone: "",
9
+ stageName: "",
10
+ location: "",
11
+ },
12
+ socialMedia: {
13
+ videoLink: "",
14
+ },
15
+ extraDetails: {},
16
+ });
17
+
18
+ export const initialFormData = writable(null);
19
+
20
+ export const hasChanges = derived(
21
+ [profileFormData, initialFormData],
22
+ ([$profileFormData, $initialFormData]) => {
23
+ return JSON.stringify($profileFormData) !== JSON.stringify($initialFormData);
24
+ }
25
+ );
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=formDataStore.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formDataStore.spec.d.ts","sourceRoot":"","sources":["../../src/lib/stores/formDataStore.spec.js"],"names":[],"mappings":""}
@@ -0,0 +1,257 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { get } from 'svelte/store';
3
+ import { profileFormData, initialFormData, hasChanges } from './formDataStore';
4
+
5
+ describe('formDataStore', () => {
6
+ beforeEach(() => {
7
+ // Reset stores to initial state
8
+ profileFormData.set({
9
+ basicInfo: {
10
+ firstName: '',
11
+ lastName: '',
12
+ email: '',
13
+ phone: '',
14
+ stageName: '',
15
+ location: '',
16
+ },
17
+ socialMedia: {
18
+ videoLink: '',
19
+ },
20
+ extraDetails: {},
21
+ });
22
+ initialFormData.set(null);
23
+ });
24
+
25
+ describe('profileFormData', () => {
26
+ it('has initial structure with basicInfo', () => {
27
+ const data = get(profileFormData);
28
+ expect(data.basicInfo).toBeDefined();
29
+ expect(data.basicInfo.firstName).toBe('');
30
+ expect(data.basicInfo.lastName).toBe('');
31
+ expect(data.basicInfo.email).toBe('');
32
+ });
33
+
34
+ it('has initial structure with socialMedia', () => {
35
+ const data = get(profileFormData);
36
+ expect(data.socialMedia).toBeDefined();
37
+ expect(data.socialMedia.videoLink).toBe('');
38
+ });
39
+
40
+ it('has initial structure with extraDetails', () => {
41
+ const data = get(profileFormData);
42
+ expect(data.extraDetails).toBeDefined();
43
+ });
44
+
45
+ it('can be updated', () => {
46
+ profileFormData.update((data) => ({
47
+ ...data,
48
+ basicInfo: {
49
+ ...data.basicInfo,
50
+ firstName: 'John',
51
+ lastName: 'Doe',
52
+ },
53
+ }));
54
+
55
+ const data = get(profileFormData);
56
+ expect(data.basicInfo.firstName).toBe('John');
57
+ expect(data.basicInfo.lastName).toBe('Doe');
58
+ });
59
+
60
+ it('can be set completely', () => {
61
+ profileFormData.set({
62
+ basicInfo: {
63
+ firstName: 'Jane',
64
+ lastName: 'Smith',
65
+ email: 'jane@example.com',
66
+ phone: '555-1234',
67
+ stageName: 'JSmith',
68
+ location: 'LA',
69
+ },
70
+ socialMedia: {
71
+ videoLink: 'https://youtube.com/watch',
72
+ },
73
+ extraDetails: { bio: 'Test bio' },
74
+ });
75
+
76
+ const data = get(profileFormData);
77
+ expect(data.basicInfo.firstName).toBe('Jane');
78
+ expect(data.socialMedia.videoLink).toBe('https://youtube.com/watch');
79
+ expect(data.extraDetails.bio).toBe('Test bio');
80
+ });
81
+ });
82
+
83
+ describe('initialFormData', () => {
84
+ it('starts as null', () => {
85
+ expect(get(initialFormData)).toBe(null);
86
+ });
87
+
88
+ it('can store form data snapshot', () => {
89
+ const snapshot = {
90
+ basicInfo: {
91
+ firstName: 'Original',
92
+ lastName: 'Name',
93
+ email: '',
94
+ phone: '',
95
+ stageName: '',
96
+ location: '',
97
+ },
98
+ socialMedia: { videoLink: '' },
99
+ extraDetails: {},
100
+ };
101
+ initialFormData.set(snapshot);
102
+
103
+ expect(get(initialFormData)).toEqual(snapshot);
104
+ });
105
+ });
106
+
107
+ describe('hasChanges (derived store)', () => {
108
+ it('is false when both are null/empty', () => {
109
+ profileFormData.set({
110
+ basicInfo: {
111
+ firstName: '',
112
+ lastName: '',
113
+ email: '',
114
+ phone: '',
115
+ stageName: '',
116
+ location: '',
117
+ },
118
+ socialMedia: { videoLink: '' },
119
+ extraDetails: {},
120
+ });
121
+ initialFormData.set(null);
122
+
123
+ // The comparison will be false because null !== stringified object
124
+ expect(get(hasChanges)).toBe(true);
125
+ });
126
+
127
+ it('is false when form data matches initial', () => {
128
+ const data = {
129
+ basicInfo: {
130
+ firstName: 'John',
131
+ lastName: 'Doe',
132
+ email: 'john@example.com',
133
+ phone: '',
134
+ stageName: '',
135
+ location: '',
136
+ },
137
+ socialMedia: { videoLink: '' },
138
+ extraDetails: {},
139
+ };
140
+
141
+ profileFormData.set(data);
142
+ initialFormData.set(data);
143
+
144
+ expect(get(hasChanges)).toBe(false);
145
+ });
146
+
147
+ it('is true when form data differs from initial', () => {
148
+ const initial = {
149
+ basicInfo: {
150
+ firstName: 'John',
151
+ lastName: 'Doe',
152
+ email: 'john@example.com',
153
+ phone: '',
154
+ stageName: '',
155
+ location: '',
156
+ },
157
+ socialMedia: { videoLink: '' },
158
+ extraDetails: {},
159
+ };
160
+
161
+ const changed = {
162
+ ...initial,
163
+ basicInfo: { ...initial.basicInfo, firstName: 'Jane' },
164
+ };
165
+
166
+ initialFormData.set(initial);
167
+ profileFormData.set(changed);
168
+
169
+ expect(get(hasChanges)).toBe(true);
170
+ });
171
+
172
+ it('detects changes in socialMedia', () => {
173
+ const initial = {
174
+ basicInfo: {
175
+ firstName: '',
176
+ lastName: '',
177
+ email: '',
178
+ phone: '',
179
+ stageName: '',
180
+ location: '',
181
+ },
182
+ socialMedia: { videoLink: '' },
183
+ extraDetails: {},
184
+ };
185
+
186
+ initialFormData.set(initial);
187
+ profileFormData.set({
188
+ ...initial,
189
+ socialMedia: { videoLink: 'https://youtube.com/new' },
190
+ });
191
+
192
+ expect(get(hasChanges)).toBe(true);
193
+ });
194
+
195
+ it('detects changes in extraDetails', () => {
196
+ const initial = {
197
+ basicInfo: {
198
+ firstName: '',
199
+ lastName: '',
200
+ email: '',
201
+ phone: '',
202
+ stageName: '',
203
+ location: '',
204
+ },
205
+ socialMedia: { videoLink: '' },
206
+ extraDetails: {},
207
+ };
208
+
209
+ initialFormData.set(initial);
210
+ profileFormData.set({
211
+ ...initial,
212
+ extraDetails: { bio: 'New bio' },
213
+ });
214
+
215
+ expect(get(hasChanges)).toBe(true);
216
+ });
217
+
218
+ it('updates reactively when form changes', () => {
219
+ const initial = {
220
+ basicInfo: {
221
+ firstName: 'John',
222
+ lastName: 'Doe',
223
+ email: '',
224
+ phone: '',
225
+ stageName: '',
226
+ location: '',
227
+ },
228
+ socialMedia: { videoLink: '' },
229
+ extraDetails: {},
230
+ };
231
+
232
+ profileFormData.set(initial);
233
+ initialFormData.set(initial);
234
+
235
+ // No changes initially
236
+ expect(get(hasChanges)).toBe(false);
237
+
238
+ // Make a change
239
+ profileFormData.update((data) => ({
240
+ ...data,
241
+ basicInfo: { ...data.basicInfo, firstName: 'Jane' },
242
+ }));
243
+
244
+ // Now has changes
245
+ expect(get(hasChanges)).toBe(true);
246
+
247
+ // Revert the change
248
+ profileFormData.update((data) => ({
249
+ ...data,
250
+ basicInfo: { ...data.basicInfo, firstName: 'John' },
251
+ }));
252
+
253
+ // Back to no changes
254
+ expect(get(hasChanges)).toBe(false);
255
+ });
256
+ });
257
+ });
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Creates a form save handler with loading and success states
3
+ * @param {Object} options - Configuration options
4
+ * @param {string} options.endpoint - API endpoint for saving
5
+ * @param {string} options.successMessage - Message to show on success
6
+ * @param {string} options.errorMessage - Message to show on error
7
+ * @param {Function} options.onSuccess - Callback after successful save
8
+ * @param {Function} options.onError - Callback after error
9
+ * @returns {Object} Form save store and handlers
10
+ */
11
+ export function createFormSave(options?: {
12
+ endpoint: string;
13
+ successMessage: string;
14
+ errorMessage: string;
15
+ onSuccess: Function;
16
+ onError: Function;
17
+ }): Object;
18
+ /**
19
+ * Creates a simple dirty state tracker for forms
20
+ * @param {Object} initialData - Initial form data
21
+ * @returns {Object} Dirty state tracker
22
+ */
23
+ export function createDirtyTracker(initialData: Object): Object;
24
+ //# sourceMappingURL=formSave.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formSave.d.ts","sourceRoot":"","sources":["../../src/lib/stores/formSave.js"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,yCAPG;IAAwB,QAAQ,EAAxB,MAAM;IACU,cAAc,EAA9B,MAAM;IACU,YAAY,EAA5B,MAAM;IACY,SAAS;IACT,OAAO;CACjC,GAAU,MAAM,CA6FlB;AAED;;;;GAIG;AACH,gDAHW,MAAM,GACJ,MAAM,CAsBlB"}
@@ -0,0 +1,132 @@
1
+ import { writable, get } from "svelte/store";
2
+ import { showToast } from "./toaster";
3
+
4
+ /**
5
+ * Creates a form save handler with loading and success states
6
+ * @param {Object} options - Configuration options
7
+ * @param {string} options.endpoint - API endpoint for saving
8
+ * @param {string} options.successMessage - Message to show on success
9
+ * @param {string} options.errorMessage - Message to show on error
10
+ * @param {Function} options.onSuccess - Callback after successful save
11
+ * @param {Function} options.onError - Callback after error
12
+ * @returns {Object} Form save store and handlers
13
+ */
14
+ export function createFormSave(options = {}) {
15
+ const {
16
+ endpoint = "",
17
+ successMessage = "Changes saved successfully",
18
+ errorMessage = "Failed to save changes",
19
+ onSuccess,
20
+ onError,
21
+ } = options;
22
+
23
+ const isLoading = writable(false);
24
+ const isSuccess = writable(false);
25
+ const error = writable(null);
26
+
27
+ /**
28
+ * Reset success state (call when form becomes dirty)
29
+ */
30
+ function resetSuccess() {
31
+ isSuccess.set(false);
32
+ }
33
+
34
+ /**
35
+ * Save form data to the endpoint
36
+ * @param {Object} data - Data to save
37
+ * @param {string} customEndpoint - Override the default endpoint
38
+ * @returns {Promise<boolean>} Success status
39
+ */
40
+ async function save(data, customEndpoint = null) {
41
+ const targetEndpoint = customEndpoint || endpoint;
42
+
43
+ if (!targetEndpoint) {
44
+ console.error("No endpoint specified for form save");
45
+ return false;
46
+ }
47
+
48
+ isLoading.set(true);
49
+ isSuccess.set(false);
50
+ error.set(null);
51
+
52
+ try {
53
+ const res = await fetch(targetEndpoint, {
54
+ method: "POST",
55
+ headers: { "Content-Type": "application/json" },
56
+ body: JSON.stringify(data),
57
+ });
58
+
59
+ if (res.ok) {
60
+ isSuccess.set(true);
61
+ if (successMessage) {
62
+ showToast(successMessage, "success");
63
+ }
64
+ onSuccess?.();
65
+ return true;
66
+ } else {
67
+ const errorData = await res.json().catch(() => ({}));
68
+ const errorMsg = errorData.message || errorMessage;
69
+ error.set(errorMsg);
70
+ showToast(errorMsg, "error");
71
+ onError?.(errorMsg);
72
+ return false;
73
+ }
74
+ } catch (err) {
75
+ const errorMsg = err.message || "Something went wrong";
76
+ error.set(errorMsg);
77
+ showToast(errorMsg, "error");
78
+ onError?.(errorMsg);
79
+ return false;
80
+ } finally {
81
+ isLoading.set(false);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Reset all states
87
+ */
88
+ function reset() {
89
+ isLoading.set(false);
90
+ isSuccess.set(false);
91
+ error.set(null);
92
+ }
93
+
94
+ return {
95
+ isLoading,
96
+ isSuccess,
97
+ error,
98
+ save,
99
+ resetSuccess,
100
+ reset,
101
+ // Convenience getters
102
+ get loading() { return get(isLoading); },
103
+ get success() { return get(isSuccess); },
104
+ };
105
+ }
106
+
107
+ /**
108
+ * Creates a simple dirty state tracker for forms
109
+ * @param {Object} initialData - Initial form data
110
+ * @returns {Object} Dirty state tracker
111
+ */
112
+ export function createDirtyTracker(initialData) {
113
+ const isDirty = writable(false);
114
+ let initial = JSON.stringify(initialData);
115
+
116
+ function check(currentData) {
117
+ const dirty = JSON.stringify(currentData) !== initial;
118
+ isDirty.set(dirty);
119
+ return dirty;
120
+ }
121
+
122
+ function reset(newInitialData) {
123
+ initial = JSON.stringify(newInitialData);
124
+ isDirty.set(false);
125
+ }
126
+
127
+ return {
128
+ isDirty,
129
+ check,
130
+ reset,
131
+ };
132
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=formSave.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formSave.spec.d.ts","sourceRoot":"","sources":["../../src/lib/stores/formSave.spec.js"],"names":[],"mappings":""}