@getmicdrop/svelte-components 5.18.2 → 5.20.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.
- package/dist/base.css +18 -0
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte +10 -8
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte.d.ts.map +1 -1
- package/dist/components/Heading.svelte +8 -2
- package/dist/components/Heading.svelte.d.ts +1 -0
- package/dist/components/Heading.svelte.d.ts.map +1 -1
- package/dist/components/Text.svelte +13 -2
- package/dist/components/Text.svelte.d.ts +2 -1
- package/dist/components/Text.svelte.d.ts.map +1 -1
- package/dist/constants/formOptions.d.ts +2 -5
- package/dist/constants/formOptions.d.ts.map +1 -1
- package/dist/constants/formOptions.js +6 -6
- package/dist/constants/formOptions.spec.js +2 -7
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -2
- package/dist/patterns/forms/FormSection.svelte +2 -1
- package/dist/patterns/forms/FormSection.svelte.d.ts +2 -0
- package/dist/patterns/forms/FormSection.svelte.d.ts.map +1 -1
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts +1 -1
- package/dist/patterns/navigation/Header.svelte +3 -3
- package/dist/primitives/Input/Select.svelte +1 -1
- package/dist/primitives/Pagination/DotIndicator.svelte +66 -0
- package/dist/primitives/Pagination/DotIndicator.svelte.d.ts +18 -0
- package/dist/primitives/Pagination/DotIndicator.svelte.d.ts.map +1 -0
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.js +1 -0
- package/dist/recipes/inputs/phoneInput/CountrySelector.svelte +1 -1
- package/dist/recipes/modals/FeedbackModal.svelte +205 -0
- package/dist/recipes/modals/FeedbackModal.svelte.d.ts +24 -0
- package/dist/recipes/modals/FeedbackModal.svelte.d.ts.map +1 -0
- package/dist/recipes/modals/index.d.ts +1 -0
- package/dist/recipes/modals/index.js +1 -0
- package/dist/schemas/event.d.ts +4 -4
- package/dist/schemas/order.d.ts +2 -2
- package/dist/schemas/promo.d.ts +4 -4
- package/dist/services/event.service.d.ts +11 -0
- package/dist/services/event.service.d.ts.map +1 -0
- package/dist/services/event.service.js +64 -0
- package/dist/services/event.service.spec.d.ts +2 -0
- package/dist/services/event.service.spec.d.ts.map +1 -0
- package/dist/services/event.service.spec.js +168 -0
- package/dist/services/{ShowService.d.ts → show.service.d.ts} +1 -1
- package/dist/services/show.service.d.ts.map +1 -0
- package/dist/services/show.service.js +115 -0
- package/dist/services/show.service.spec.d.ts +2 -0
- package/dist/services/show.service.spec.d.ts.map +1 -0
- package/dist/services/show.service.spec.js +242 -0
- package/dist/tailwind/preset.cjs +5 -0
- package/dist/tailwind/preset.d.cts +2 -0
- package/dist/tailwind/preset.d.cts.map +1 -1
- package/dist/tokens/__tests__/spacing.test.js +2 -2
- package/dist/tokens/base-resets.css +124 -0
- package/dist/tokens/spacing.d.ts +2 -0
- package/dist/tokens/spacing.d.ts.map +1 -1
- package/dist/tokens/spacing.js +1 -0
- package/dist/tokens/tokens.css +1 -1
- package/dist/tokens/utilities.css +79 -2
- package/dist/utils/apiConfig.js +1 -1
- package/dist/utils/apiConfig.spec.js +34 -27
- package/dist/utils/assets.d.ts +3 -0
- package/dist/utils/assets.d.ts.map +1 -0
- package/dist/utils/assets.js +3 -0
- package/dist/utils/classNames.d.ts +10 -0
- package/dist/utils/classNames.d.ts.map +1 -0
- package/dist/utils/classNames.js +15 -0
- package/dist/utils/clickOutside.d.ts +4 -0
- package/dist/utils/clickOutside.d.ts.map +1 -0
- package/dist/utils/clickOutside.js +13 -0
- package/dist/utils/cookieHelpers.d.ts +40 -0
- package/dist/utils/cookieHelpers.d.ts.map +1 -0
- package/dist/utils/cookieHelpers.js +102 -0
- package/dist/utils/dateHelpers.d.ts +71 -0
- package/dist/utils/dateHelpers.d.ts.map +1 -0
- package/dist/utils/dateHelpers.js +253 -0
- package/dist/utils/eventFormatters.d.ts +9 -0
- package/dist/utils/eventFormatters.d.ts.map +1 -0
- package/dist/utils/eventFormatters.js +96 -0
- package/dist/utils/feedbackContext.d.ts +24 -0
- package/dist/utils/feedbackContext.d.ts.map +1 -0
- package/dist/utils/feedbackContext.js +19 -0
- package/dist/utils/fetchHelpers.d.ts +17 -0
- package/dist/utils/fetchHelpers.d.ts.map +1 -0
- package/dist/utils/fetchHelpers.js +45 -0
- package/dist/utils/focusTrap.d.ts +20 -0
- package/dist/utils/focusTrap.d.ts.map +1 -0
- package/dist/utils/focusTrap.js +130 -0
- package/dist/utils/formatters.d.ts +56 -0
- package/dist/utils/formatters.d.ts.map +1 -1
- package/dist/utils/formatters.js +121 -1
- package/dist/utils/formatters.spec.js +128 -1
- package/dist/utils/logger.d.ts +25 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +59 -1
- package/dist/utils/logger.spec.js +99 -1
- package/dist/utils/permissions.d.ts +9 -0
- package/dist/utils/permissions.d.ts.map +1 -0
- package/dist/utils/permissions.js +93 -0
- package/dist/utils/stringHelpers.d.ts +17 -0
- package/dist/utils/stringHelpers.d.ts.map +1 -0
- package/dist/utils/stringHelpers.js +38 -0
- package/dist/utils/transitions.d.ts +99 -1
- package/dist/utils/transitions.d.ts.map +1 -1
- package/dist/utils/transitions.js +144 -2
- package/dist/utils/utils/utils.d.ts +2 -73
- package/dist/utils/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils/utils.js +2 -2
- package/dist/utils/utils.d.ts +41 -98
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +58 -701
- package/package.json +16 -3
- package/dist/services/EventService.d.ts +0 -5
- package/dist/services/EventService.d.ts.map +0 -1
- package/dist/services/EventService.js +0 -79
- package/dist/services/EventService.spec.d.ts +0 -2
- package/dist/services/EventService.spec.d.ts.map +0 -1
- package/dist/services/EventService.spec.js +0 -217
- package/dist/services/ShowService.d.ts.map +0 -1
- package/dist/services/ShowService.js +0 -144
- package/dist/services/ShowService.spec.d.ts +0 -2
- package/dist/services/ShowService.spec.d.ts.map +0 -1
- package/dist/services/ShowService.spec.js +0 -345
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import Button from "../../primitives/Button/Button.svelte";
|
|
3
|
+
import Cancel from "../../assets/svg/cancel.svg";
|
|
4
|
+
import Modal from "../../primitives/Modal/Modal.svelte";
|
|
5
|
+
import { typography } from '../../tokens/typography';
|
|
6
|
+
|
|
7
|
+
const defaultLabels = {
|
|
8
|
+
title: 'Send Feedback',
|
|
9
|
+
bugLabel: 'Report a Bug',
|
|
10
|
+
featureLabel: 'Request a Feature',
|
|
11
|
+
otherLabel: 'Other',
|
|
12
|
+
bugPlaceholder: 'What happened? What were you trying to do?',
|
|
13
|
+
featurePlaceholder: 'What would you like to be able to do?',
|
|
14
|
+
otherPlaceholder: 'How can we help?',
|
|
15
|
+
emailLabel: 'Email',
|
|
16
|
+
descriptionLabel: 'Description',
|
|
17
|
+
submit: 'Submit',
|
|
18
|
+
cancel: 'Cancel',
|
|
19
|
+
close: 'Close',
|
|
20
|
+
sending: 'Sending...',
|
|
21
|
+
successTitle: 'Thanks for your feedback!',
|
|
22
|
+
successMessage: 'We\'ve received your feedback and will review it shortly.',
|
|
23
|
+
successReference: 'Reference',
|
|
24
|
+
done: 'Done',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
let {
|
|
28
|
+
open = $bindable(false),
|
|
29
|
+
email = "",
|
|
30
|
+
loading = false,
|
|
31
|
+
successReferenceId = "",
|
|
32
|
+
labels: userLabels = {},
|
|
33
|
+
|
|
34
|
+
// Callbacks
|
|
35
|
+
onsubmit,
|
|
36
|
+
onclose,
|
|
37
|
+
} = $props();
|
|
38
|
+
|
|
39
|
+
let labels = $derived({ ...defaultLabels, ...userLabels });
|
|
40
|
+
|
|
41
|
+
// Form state
|
|
42
|
+
let feedbackType = $state("bug");
|
|
43
|
+
let description = $state("");
|
|
44
|
+
let contactEmail = $state("");
|
|
45
|
+
let showSuccess = $state(false);
|
|
46
|
+
|
|
47
|
+
// Sync email prop
|
|
48
|
+
$effect(() => {
|
|
49
|
+
if (email && !contactEmail) {
|
|
50
|
+
contactEmail = email;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Show success state when referenceId comes in
|
|
55
|
+
$effect(() => {
|
|
56
|
+
if (successReferenceId) {
|
|
57
|
+
showSuccess = true;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
let placeholder = $derived(
|
|
62
|
+
feedbackType === "bug" ? labels.bugPlaceholder
|
|
63
|
+
: feedbackType === "feature" ? labels.featurePlaceholder
|
|
64
|
+
: labels.otherPlaceholder
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
let isDisabled = $derived(loading || !description.trim());
|
|
68
|
+
|
|
69
|
+
const typeOptions = $derived([
|
|
70
|
+
{ value: "bug", label: labels.bugLabel },
|
|
71
|
+
{ value: "feature", label: labels.featureLabel },
|
|
72
|
+
{ value: "other", label: labels.otherLabel },
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const handleSubmit = () => {
|
|
76
|
+
if (isDisabled) return;
|
|
77
|
+
onsubmit?.({
|
|
78
|
+
type: feedbackType,
|
|
79
|
+
description: description.trim(),
|
|
80
|
+
email: contactEmail,
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const handleClose = () => {
|
|
85
|
+
if (loading) return;
|
|
86
|
+
resetForm();
|
|
87
|
+
open = false;
|
|
88
|
+
onclose?.();
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const resetForm = () => {
|
|
92
|
+
feedbackType = "bug";
|
|
93
|
+
description = "";
|
|
94
|
+
showSuccess = false;
|
|
95
|
+
};
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<Modal bind:open size="md" persistent={loading}>
|
|
99
|
+
{#snippet header()}
|
|
100
|
+
<div class="text-left">
|
|
101
|
+
<div class="flex justify-between items-start -mt-2 -mr-2 mb-2">
|
|
102
|
+
<h3 class={typography.h2}>
|
|
103
|
+
{showSuccess ? labels.successTitle : labels.title}
|
|
104
|
+
</h3>
|
|
105
|
+
<Button variant="icon" size="xs" onclick={handleClose} disabled={loading}>
|
|
106
|
+
<img src={Cancel} alt={labels.close} class="w-5 h-5" />
|
|
107
|
+
</Button>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
{/snippet}
|
|
111
|
+
|
|
112
|
+
{#snippet body()}
|
|
113
|
+
{#if showSuccess}
|
|
114
|
+
<!-- Success state -->
|
|
115
|
+
<div class="text-left mt-4 space-y-4">
|
|
116
|
+
<p class={`${typography.smMuted} leading-relaxed`}>
|
|
117
|
+
{labels.successMessage}
|
|
118
|
+
</p>
|
|
119
|
+
{#if successReferenceId}
|
|
120
|
+
<div class="bg-gray-50 dark:bg-gray-700 rounded-lg px-4 py-3">
|
|
121
|
+
<p class="text-sm text-gray-500 dark:text-gray-400">{labels.successReference}</p>
|
|
122
|
+
<p class="text-lg font-mono font-semibold text-gray-900 dark:text-white">{successReferenceId}</p>
|
|
123
|
+
</div>
|
|
124
|
+
{/if}
|
|
125
|
+
</div>
|
|
126
|
+
{:else}
|
|
127
|
+
<!-- Form -->
|
|
128
|
+
<div class="text-left mt-4 space-y-4">
|
|
129
|
+
<!-- Type selector -->
|
|
130
|
+
<div class="flex gap-2">
|
|
131
|
+
{#each typeOptions as option}
|
|
132
|
+
<button
|
|
133
|
+
type="button"
|
|
134
|
+
class="px-3 py-1.5 text-sm rounded-full border transition-colors
|
|
135
|
+
{feedbackType === option.value
|
|
136
|
+
? 'bg-blue-50 dark:bg-blue-900/30 border-blue-300 dark:border-blue-600 text-blue-700 dark:text-blue-300 font-medium'
|
|
137
|
+
: 'border-gray-300 dark:border-gray-600 text-gray-600 dark:text-gray-400 hover:border-gray-400 dark:hover:border-gray-500'}"
|
|
138
|
+
onclick={() => feedbackType = option.value}
|
|
139
|
+
disabled={loading}
|
|
140
|
+
>
|
|
141
|
+
{option.label}
|
|
142
|
+
</button>
|
|
143
|
+
{/each}
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
<!-- Description -->
|
|
147
|
+
<div>
|
|
148
|
+
<label for="feedback-description" class={`${typography.label} block mb-2`}>
|
|
149
|
+
{labels.descriptionLabel}
|
|
150
|
+
</label>
|
|
151
|
+
<textarea
|
|
152
|
+
id="feedback-description"
|
|
153
|
+
bind:value={description}
|
|
154
|
+
placeholder={placeholder}
|
|
155
|
+
rows={4}
|
|
156
|
+
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 {typography.body} rounded-lg focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
|
|
157
|
+
disabled={loading}
|
|
158
|
+
></textarea>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<!-- Email -->
|
|
162
|
+
<div>
|
|
163
|
+
<label for="feedback-email" class={`${typography.label} block mb-2`}>
|
|
164
|
+
{labels.emailLabel}
|
|
165
|
+
</label>
|
|
166
|
+
<input
|
|
167
|
+
id="feedback-email"
|
|
168
|
+
type="email"
|
|
169
|
+
bind:value={contactEmail}
|
|
170
|
+
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg {typography.body} bg-white dark:bg-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50"
|
|
171
|
+
disabled={loading}
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
{/if}
|
|
176
|
+
{/snippet}
|
|
177
|
+
|
|
178
|
+
{#snippet footer()}
|
|
179
|
+
{#if showSuccess}
|
|
180
|
+
<Button size="full" variant="blue-solid" onclick={handleClose}>
|
|
181
|
+
{labels.done}
|
|
182
|
+
</Button>
|
|
183
|
+
{:else}
|
|
184
|
+
<div class="flex gap-3">
|
|
185
|
+
<Button
|
|
186
|
+
size="full"
|
|
187
|
+
variant="alternative"
|
|
188
|
+
onclick={handleClose}
|
|
189
|
+
disabled={loading}
|
|
190
|
+
>
|
|
191
|
+
{labels.cancel}
|
|
192
|
+
</Button>
|
|
193
|
+
<Button
|
|
194
|
+
size="full"
|
|
195
|
+
variant="blue-solid"
|
|
196
|
+
onclick={handleSubmit}
|
|
197
|
+
disabled={isDisabled}
|
|
198
|
+
{loading}
|
|
199
|
+
>
|
|
200
|
+
{loading ? labels.sending : labels.submit}
|
|
201
|
+
</Button>
|
|
202
|
+
</div>
|
|
203
|
+
{/if}
|
|
204
|
+
{/snippet}
|
|
205
|
+
</Modal>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export default FeedbackModal;
|
|
2
|
+
type FeedbackModal = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const FeedbackModal: import("svelte").Component<{
|
|
7
|
+
open?: boolean;
|
|
8
|
+
email?: string;
|
|
9
|
+
loading?: boolean;
|
|
10
|
+
successReferenceId?: string;
|
|
11
|
+
labels?: Record<string, any>;
|
|
12
|
+
onsubmit: any;
|
|
13
|
+
onclose: any;
|
|
14
|
+
}, {}, "open">;
|
|
15
|
+
type $$ComponentProps = {
|
|
16
|
+
open?: boolean;
|
|
17
|
+
email?: string;
|
|
18
|
+
loading?: boolean;
|
|
19
|
+
successReferenceId?: string;
|
|
20
|
+
labels?: Record<string, any>;
|
|
21
|
+
onsubmit: any;
|
|
22
|
+
onclose: any;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=FeedbackModal.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackModal.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/recipes/modals/FeedbackModal.svelte.js"],"names":[],"mappings":";;;;;AA2LA;WAzJ4B,OAAO;YAAU,MAAM;cAAY,OAAO;yBAAuB,MAAM;aAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;cAAY,GAAG;aAAW,GAAG;eAyJlG;wBAzJzC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as AlertModal } from "./AlertModal.svelte";
|
|
2
2
|
export { default as ConfirmationModal } from "./ConfirmationModal.svelte";
|
|
3
|
+
export { default as FeedbackModal } from "./FeedbackModal.svelte";
|
|
3
4
|
export { default as InputModal } from "./InputModal.svelte";
|
|
4
5
|
export { default as ModalStateManager } from "./ModalStateManager.svelte";
|
|
5
6
|
export { default as ModalTestWrapper } from "./ModalTestWrapper.svelte";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Composite modal components - built on Modal primitive
|
|
2
2
|
export { default as AlertModal } from './AlertModal.svelte';
|
|
3
3
|
export { default as ConfirmationModal } from './ConfirmationModal.svelte';
|
|
4
|
+
export { default as FeedbackModal } from './FeedbackModal.svelte';
|
|
4
5
|
export { default as InputModal } from './InputModal.svelte';
|
|
5
6
|
export { default as ModalStateManager } from './ModalStateManager.svelte';
|
|
6
7
|
export { default as ModalTestWrapper } from './ModalTestWrapper.svelte';
|
package/dist/schemas/event.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const eventStatusSchema: z.ZodEnum<{
|
|
3
|
+
cancelled: "cancelled";
|
|
3
4
|
draft: "draft";
|
|
4
5
|
published: "published";
|
|
5
|
-
cancelled: "cancelled";
|
|
6
6
|
completed: "completed";
|
|
7
7
|
}>;
|
|
8
8
|
export type EventStatus = z.infer<typeof eventStatusSchema>;
|
|
@@ -17,9 +17,9 @@ export declare const eventSchema: z.ZodObject<{
|
|
|
17
17
|
capacity: z.ZodOptional<z.ZodNumber>;
|
|
18
18
|
imageUrl: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodCustom<File, File>, z.ZodNull]>>;
|
|
19
19
|
status: z.ZodDefault<z.ZodEnum<{
|
|
20
|
+
cancelled: "cancelled";
|
|
20
21
|
draft: "draft";
|
|
21
22
|
published: "published";
|
|
22
|
-
cancelled: "cancelled";
|
|
23
23
|
completed: "completed";
|
|
24
24
|
}>>;
|
|
25
25
|
isPrivate: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -39,9 +39,9 @@ export declare const eventUpdateSchema: z.ZodObject<{
|
|
|
39
39
|
capacity: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
40
40
|
imageUrl: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodCustom<File, File>, z.ZodNull]>>>;
|
|
41
41
|
status: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
42
|
+
cancelled: "cancelled";
|
|
42
43
|
draft: "draft";
|
|
43
44
|
published: "published";
|
|
44
|
-
cancelled: "cancelled";
|
|
45
45
|
completed: "completed";
|
|
46
46
|
}>>>;
|
|
47
47
|
isPrivate: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
@@ -52,9 +52,9 @@ export declare const eventUpdateSchema: z.ZodObject<{
|
|
|
52
52
|
export type EventUpdateInput = z.infer<typeof eventUpdateSchema>;
|
|
53
53
|
export declare const eventFilterSchema: z.ZodObject<{
|
|
54
54
|
status: z.ZodOptional<z.ZodEnum<{
|
|
55
|
+
cancelled: "cancelled";
|
|
55
56
|
draft: "draft";
|
|
56
57
|
published: "published";
|
|
57
|
-
cancelled: "cancelled";
|
|
58
58
|
completed: "completed";
|
|
59
59
|
}>>;
|
|
60
60
|
venueId: z.ZodOptional<z.ZodString>;
|
package/dist/schemas/order.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const orderStatusSchema: z.ZodEnum<{
|
|
3
|
-
pending: "pending";
|
|
4
3
|
cancelled: "cancelled";
|
|
4
|
+
pending: "pending";
|
|
5
5
|
completed: "completed";
|
|
6
6
|
processing: "processing";
|
|
7
7
|
refunded: "refunded";
|
|
@@ -86,8 +86,8 @@ export declare const orderNoteSchema: z.ZodObject<{
|
|
|
86
86
|
export type OrderNoteInput = z.infer<typeof orderNoteSchema>;
|
|
87
87
|
export declare const orderFilterSchema: z.ZodObject<{
|
|
88
88
|
status: z.ZodOptional<z.ZodEnum<{
|
|
89
|
-
pending: "pending";
|
|
90
89
|
cancelled: "cancelled";
|
|
90
|
+
pending: "pending";
|
|
91
91
|
completed: "completed";
|
|
92
92
|
processing: "processing";
|
|
93
93
|
refunded: "refunded";
|
package/dist/schemas/promo.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const promoCodeTypeSchema: z.ZodEnum<{
|
|
3
|
-
dollar: "dollar";
|
|
4
3
|
percent: "percent";
|
|
4
|
+
dollar: "dollar";
|
|
5
5
|
}>;
|
|
6
6
|
export type PromoCodeType = z.infer<typeof promoCodeTypeSchema>;
|
|
7
7
|
export declare const promoCodeLimitTypeSchema: z.ZodEnum<{
|
|
@@ -13,8 +13,8 @@ export declare const promoCodeNameSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.Zod
|
|
|
13
13
|
export declare const promoCodeSchema: z.ZodObject<{
|
|
14
14
|
code: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
|
|
15
15
|
discountType: z.ZodEnum<{
|
|
16
|
-
dollar: "dollar";
|
|
17
16
|
percent: "percent";
|
|
17
|
+
dollar: "dollar";
|
|
18
18
|
}>;
|
|
19
19
|
dollarAmount: z.ZodNullable<z.ZodOptional<z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>>>;
|
|
20
20
|
percentAmount: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -32,8 +32,8 @@ export declare const promoCodeSchema: z.ZodObject<{
|
|
|
32
32
|
export type PromoCodeInput = z.infer<typeof promoCodeSchema>;
|
|
33
33
|
export declare const promoCodeUpdateSchema: z.ZodObject<{
|
|
34
34
|
discountType: z.ZodOptional<z.ZodEnum<{
|
|
35
|
-
dollar: "dollar";
|
|
36
35
|
percent: "percent";
|
|
36
|
+
dollar: "dollar";
|
|
37
37
|
}>>;
|
|
38
38
|
dollarAmount: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>>>>;
|
|
39
39
|
percentAmount: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodNumber>>>;
|
|
@@ -53,8 +53,8 @@ export type PromoCodeUpdateInput = z.infer<typeof promoCodeUpdateSchema>;
|
|
|
53
53
|
export declare const globalPromoCodeSchema: z.ZodObject<{
|
|
54
54
|
code: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
|
|
55
55
|
discountType: z.ZodEnum<{
|
|
56
|
-
dollar: "dollar";
|
|
57
56
|
percent: "percent";
|
|
57
|
+
dollar: "dollar";
|
|
58
58
|
}>;
|
|
59
59
|
dollarAmount: z.ZodNullable<z.ZodOptional<z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>>>;
|
|
60
60
|
percentAmount: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface CalendarEvent {
|
|
2
|
+
id: number;
|
|
3
|
+
date: string;
|
|
4
|
+
title: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function fetchEventsFromAPI(venueId?: string | number): Promise<CalendarEvent[]>;
|
|
7
|
+
export declare function fetchEventsForMonth(year: number, month: number): Promise<CalendarEvent[]>;
|
|
8
|
+
export declare function fetchEventsForWeek(date: Date): Promise<CalendarEvent[]>;
|
|
9
|
+
export declare function fetchEventsForDay(date: Date): Promise<CalendarEvent[]>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=event.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.service.d.ts","sourceRoot":"","sources":["../../src/lib/services/event.service.ts"],"names":[],"mappings":"AAGA,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAID,wBAAsB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAqB5F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAY/F;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAkB7E;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAgB5E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { addDays, startOfWeek } from "date-fns";
|
|
2
|
+
import { buildApiUrl } from "../utils/apiConfig";
|
|
3
|
+
let mockEvents = [];
|
|
4
|
+
export async function fetchEventsFromAPI(venueId) {
|
|
5
|
+
try {
|
|
6
|
+
const url = venueId
|
|
7
|
+
? buildApiUrl(`/api/v2/public/events/venue/${venueId}`)
|
|
8
|
+
: buildApiUrl("/api/v2/public/events/venue");
|
|
9
|
+
const response = await fetch(url);
|
|
10
|
+
if (response.ok) {
|
|
11
|
+
const events = await response.json();
|
|
12
|
+
return events.map((event) => ({
|
|
13
|
+
id: event.ID,
|
|
14
|
+
date: event.startDateTime,
|
|
15
|
+
title: event.title,
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.error("Failed to load events:", response.status);
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.error("Error fetching events:", error);
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function fetchEventsForMonth(year, month) {
|
|
29
|
+
mockEvents = await fetchEventsFromAPI();
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
resolve(mockEvents.filter((event) => event.date.startsWith(`${year}-${String(month).padStart(2, "0")}`)));
|
|
33
|
+
}, 500);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export async function fetchEventsForWeek(date) {
|
|
37
|
+
mockEvents = await fetchEventsFromAPI();
|
|
38
|
+
const startOfWeekDate = startOfWeek(date, { weekStartsOn: 1 });
|
|
39
|
+
const endOfWeekDate = addDays(startOfWeekDate, 6);
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
const filteredEvents = mockEvents.filter((event) => {
|
|
43
|
+
const eventDate = new Date(event.date).getTime();
|
|
44
|
+
return (eventDate >= startOfWeekDate.getTime() &&
|
|
45
|
+
eventDate <= endOfWeekDate.getTime());
|
|
46
|
+
});
|
|
47
|
+
resolve(filteredEvents);
|
|
48
|
+
}, 500);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export async function fetchEventsForDay(date) {
|
|
52
|
+
mockEvents = await fetchEventsFromAPI();
|
|
53
|
+
return new Promise((resolve) => {
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
const filteredEvents = mockEvents.filter((event) => {
|
|
56
|
+
const eventDate = new Date(event.date);
|
|
57
|
+
return (eventDate.getUTCDate() === date.getUTCDate() &&
|
|
58
|
+
eventDate.getUTCMonth() === date.getUTCMonth() &&
|
|
59
|
+
eventDate.getUTCFullYear() === date.getUTCFullYear());
|
|
60
|
+
});
|
|
61
|
+
resolve(filteredEvents);
|
|
62
|
+
}, 500);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.service.spec.d.ts","sourceRoot":"","sources":["../../src/lib/services/event.service.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
// Create mock functions we'll spy on
|
|
3
|
+
const mockEvents = [
|
|
4
|
+
{ ID: 1, startDateTime: '2025-01-15T20:00:00', title: 'Comedy Night' },
|
|
5
|
+
{ ID: 2, startDateTime: '2025-01-15T21:00:00', title: 'Open Mic' },
|
|
6
|
+
{ ID: 3, startDateTime: '2025-02-10T19:00:00', title: 'Improv Show' },
|
|
7
|
+
];
|
|
8
|
+
import { fetchEventsFromAPI, fetchEventsForMonth, fetchEventsForWeek, fetchEventsForDay, } from './event.service';
|
|
9
|
+
describe('EventService', () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
vi.clearAllMocks();
|
|
12
|
+
global.fetch = vi.fn();
|
|
13
|
+
});
|
|
14
|
+
describe('fetchEventsFromAPI', () => {
|
|
15
|
+
it('fetches events from the API', async () => {
|
|
16
|
+
global.fetch.mockResolvedValue({
|
|
17
|
+
ok: true,
|
|
18
|
+
json: () => Promise.resolve(mockEvents),
|
|
19
|
+
});
|
|
20
|
+
const events = await fetchEventsFromAPI();
|
|
21
|
+
expect(global.fetch).toHaveBeenCalledWith('https://get-micdrop.com/api/v2/public/events/venue');
|
|
22
|
+
expect(events).toHaveLength(3);
|
|
23
|
+
});
|
|
24
|
+
it('transforms event data correctly', async () => {
|
|
25
|
+
global.fetch.mockResolvedValue({
|
|
26
|
+
ok: true,
|
|
27
|
+
json: () => Promise.resolve([mockEvents[0]]),
|
|
28
|
+
});
|
|
29
|
+
const events = await fetchEventsFromAPI();
|
|
30
|
+
expect(events[0]).toEqual({
|
|
31
|
+
id: 1,
|
|
32
|
+
date: '2025-01-15T20:00:00',
|
|
33
|
+
title: 'Comedy Night',
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
it('returns empty array on failed response', async () => {
|
|
37
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
38
|
+
global.fetch.mockResolvedValue({
|
|
39
|
+
ok: false,
|
|
40
|
+
status: 500,
|
|
41
|
+
});
|
|
42
|
+
const events = await fetchEventsFromAPI();
|
|
43
|
+
expect(events).toEqual([]);
|
|
44
|
+
consoleSpy.mockRestore();
|
|
45
|
+
});
|
|
46
|
+
it('returns empty array on network error', async () => {
|
|
47
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
48
|
+
global.fetch.mockRejectedValue(new Error('Network error'));
|
|
49
|
+
const events = await fetchEventsFromAPI();
|
|
50
|
+
expect(events).toEqual([]);
|
|
51
|
+
consoleSpy.mockRestore();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('fetchEventsForMonth', () => {
|
|
55
|
+
it('filters events by year and month', async () => {
|
|
56
|
+
global.fetch.mockResolvedValue({
|
|
57
|
+
ok: true,
|
|
58
|
+
json: () => Promise.resolve(mockEvents),
|
|
59
|
+
});
|
|
60
|
+
const events = await fetchEventsForMonth(2025, 1);
|
|
61
|
+
expect(events.length).toBe(2);
|
|
62
|
+
expect(events[0].title).toBe('Comedy Night');
|
|
63
|
+
expect(events[1].title).toBe('Open Mic');
|
|
64
|
+
}, 10000);
|
|
65
|
+
it('returns empty for month with no events', async () => {
|
|
66
|
+
global.fetch.mockResolvedValue({
|
|
67
|
+
ok: true,
|
|
68
|
+
json: () => Promise.resolve(mockEvents),
|
|
69
|
+
});
|
|
70
|
+
const events = await fetchEventsForMonth(2025, 3);
|
|
71
|
+
expect(events).toEqual([]);
|
|
72
|
+
}, 10000);
|
|
73
|
+
it('pads single digit months correctly', async () => {
|
|
74
|
+
global.fetch.mockResolvedValue({
|
|
75
|
+
ok: true,
|
|
76
|
+
json: () => Promise.resolve(mockEvents),
|
|
77
|
+
});
|
|
78
|
+
const events = await fetchEventsForMonth(2025, 2);
|
|
79
|
+
expect(events.length).toBe(1);
|
|
80
|
+
expect(events[0].title).toBe('Improv Show');
|
|
81
|
+
}, 10000);
|
|
82
|
+
it('handles double digit months', async () => {
|
|
83
|
+
const decemberEvents = [
|
|
84
|
+
{ ID: 4, startDateTime: '2025-12-25T20:00:00', title: 'Holiday Show' },
|
|
85
|
+
];
|
|
86
|
+
global.fetch.mockResolvedValue({
|
|
87
|
+
ok: true,
|
|
88
|
+
json: () => Promise.resolve(decemberEvents),
|
|
89
|
+
});
|
|
90
|
+
const events = await fetchEventsForMonth(2025, 12);
|
|
91
|
+
expect(events.length).toBe(1);
|
|
92
|
+
}, 10000);
|
|
93
|
+
});
|
|
94
|
+
describe('fetchEventsForWeek', () => {
|
|
95
|
+
it('filters events within the week', async () => {
|
|
96
|
+
// Events on Jan 13-14, 2025 (Monday-Tuesday of that week)
|
|
97
|
+
const weekEvents = [
|
|
98
|
+
{ ID: 1, startDateTime: '2025-01-13T20:00:00', title: 'Monday Show' },
|
|
99
|
+
{ ID: 2, startDateTime: '2025-01-14T19:00:00', title: 'Tuesday Show' },
|
|
100
|
+
{ ID: 3, startDateTime: '2025-01-20T20:00:00', title: 'Next Week Show' },
|
|
101
|
+
];
|
|
102
|
+
global.fetch.mockResolvedValue({
|
|
103
|
+
ok: true,
|
|
104
|
+
json: () => Promise.resolve(weekEvents),
|
|
105
|
+
});
|
|
106
|
+
// Jan 15, 2025 is a Wednesday
|
|
107
|
+
const date = new Date('2025-01-15');
|
|
108
|
+
const events = await fetchEventsForWeek(date);
|
|
109
|
+
// Should include Monday and Tuesday shows (same week)
|
|
110
|
+
expect(events.length).toBe(2);
|
|
111
|
+
}, 10000);
|
|
112
|
+
it('uses Monday as week start', async () => {
|
|
113
|
+
const events = [
|
|
114
|
+
{ ID: 1, startDateTime: '2025-01-12T20:00:00', title: 'Sunday Show' },
|
|
115
|
+
{ ID: 2, startDateTime: '2025-01-13T20:00:00', title: 'Monday Show' },
|
|
116
|
+
];
|
|
117
|
+
global.fetch.mockResolvedValue({
|
|
118
|
+
ok: true,
|
|
119
|
+
json: () => Promise.resolve(events),
|
|
120
|
+
});
|
|
121
|
+
// Pass a date in the week starting Jan 13
|
|
122
|
+
const date = new Date('2025-01-15');
|
|
123
|
+
const result = await fetchEventsForWeek(date);
|
|
124
|
+
// Sunday should be excluded, Monday included
|
|
125
|
+
expect(result.some((e) => e.title === 'Monday Show')).toBe(true);
|
|
126
|
+
}, 10000);
|
|
127
|
+
});
|
|
128
|
+
describe('fetchEventsForDay', () => {
|
|
129
|
+
it('filters events for specific day', async () => {
|
|
130
|
+
// Use Z suffix for UTC dates to avoid timezone issues
|
|
131
|
+
const dayEvents = [
|
|
132
|
+
{ ID: 1, startDateTime: '2025-01-15T14:00:00Z', title: 'Afternoon Show' },
|
|
133
|
+
{ ID: 2, startDateTime: '2025-01-15T20:00:00Z', title: 'Evening Show' },
|
|
134
|
+
{ ID: 3, startDateTime: '2025-01-16T20:00:00Z', title: 'Next Day Show' },
|
|
135
|
+
];
|
|
136
|
+
global.fetch.mockResolvedValue({
|
|
137
|
+
ok: true,
|
|
138
|
+
json: () => Promise.resolve(dayEvents),
|
|
139
|
+
});
|
|
140
|
+
const date = new Date(Date.UTC(2025, 0, 15)); // Jan 15, 2025 UTC
|
|
141
|
+
const events = await fetchEventsForDay(date);
|
|
142
|
+
expect(events.length).toBe(2);
|
|
143
|
+
expect(events[0].title).toBe('Afternoon Show');
|
|
144
|
+
expect(events[1].title).toBe('Evening Show');
|
|
145
|
+
}, 10000);
|
|
146
|
+
it('returns empty array for day with no events', async () => {
|
|
147
|
+
global.fetch.mockResolvedValue({
|
|
148
|
+
ok: true,
|
|
149
|
+
json: () => Promise.resolve(mockEvents),
|
|
150
|
+
});
|
|
151
|
+
const date = new Date(Date.UTC(2025, 0, 20)); // Jan 20, 2025
|
|
152
|
+
const events = await fetchEventsForDay(date);
|
|
153
|
+
expect(events).toEqual([]);
|
|
154
|
+
}, 10000);
|
|
155
|
+
it('matches dates using UTC methods', async () => {
|
|
156
|
+
const dayEvents = [
|
|
157
|
+
{ ID: 1, startDateTime: '2025-06-15T23:00:00Z', title: 'Late Show' },
|
|
158
|
+
];
|
|
159
|
+
global.fetch.mockResolvedValue({
|
|
160
|
+
ok: true,
|
|
161
|
+
json: () => Promise.resolve(dayEvents),
|
|
162
|
+
});
|
|
163
|
+
const date = new Date(Date.UTC(2025, 5, 15)); // June 15, 2025 UTC
|
|
164
|
+
const events = await fetchEventsForDay(date);
|
|
165
|
+
expect(events.length).toBe(1);
|
|
166
|
+
}, 10000);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show.service.d.ts","sourceRoot":"","sources":["show.service.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,uCAJW,MAAM,GAAC,MAAM,YACb,MAAM,GACJ,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAC,CAAC,CAwBhD;AAED;;;;;GAKG;AACH,wCAJW,MAAM,GAAC,MAAM,YACb,MAAM,GACJ,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAC,CAAC,CAwBhD;AAED;;;;;GAKG;AACH,uCAJW,MAAM,GAAC,MAAM,YACb,MAAM,GACJ,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAC,CAAC,CAwBhD;AAED;;;;;GAKG;AACH,2CAJW,MAAM,GAAC,MAAM,WACb,MAAM,GACJ,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAC,CAAC,CAoChD;AAED;;;;GAIG;AACH,qCAHW,MAAM,GAAC,MAAM,GACX,MAAM,CAIlB"}
|