@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
|
@@ -4,6 +4,61 @@
|
|
|
4
4
|
* e.g. roundCurrency(167.79999999999) → 167.8
|
|
5
5
|
*/
|
|
6
6
|
export declare function roundCurrency(value: number): number;
|
|
7
|
+
/**
|
|
8
|
+
* Formats a currency value using Intl.NumberFormat.
|
|
9
|
+
* Returns empty string for null/undefined.
|
|
10
|
+
*
|
|
11
|
+
* @param value - Amount in dollars (e.g. 25.5)
|
|
12
|
+
* @param currency - ISO 4217 currency code (default: 'USD')
|
|
13
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
14
|
+
* @returns Formatted string (e.g. "$25.50")
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatCurrency(value: number | null | undefined, currency?: string, locale?: string): string;
|
|
17
|
+
type DateInput = Date | string | number | null | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Formats a date according to a locale.
|
|
20
|
+
* Default output: abbreviated month, day, year (e.g. "Dec 15, 2025" in en-US).
|
|
21
|
+
*
|
|
22
|
+
* @param value - Date, ISO string, or epoch ms
|
|
23
|
+
* @param options - Intl.DateTimeFormatOptions overrides
|
|
24
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatDate(value: DateInput, options?: Intl.DateTimeFormatOptions, locale?: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Formats a date with time.
|
|
29
|
+
* Default output: abbreviated month, day, year, hour, minute
|
|
30
|
+
* (e.g. "Dec 15, 2025, 3:30 PM" in en-US).
|
|
31
|
+
*
|
|
32
|
+
* @param value - Date, ISO string, or epoch ms
|
|
33
|
+
* @param options - Intl.DateTimeFormatOptions overrides
|
|
34
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatDateTime(value: DateInput, options?: Intl.DateTimeFormatOptions, locale?: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Formats time-only.
|
|
39
|
+
* Default output: hour and minute (e.g. "3:30 PM" in en-US).
|
|
40
|
+
*
|
|
41
|
+
* @param value - Date, ISO string, or epoch ms
|
|
42
|
+
* @param options - Intl.DateTimeFormatOptions overrides
|
|
43
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
44
|
+
*/
|
|
45
|
+
export declare function formatTime(value: DateInput, options?: Intl.DateTimeFormatOptions, locale?: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Formats a number according to a locale.
|
|
48
|
+
* Returns empty string for null/undefined.
|
|
49
|
+
*
|
|
50
|
+
* @param value - Number to format
|
|
51
|
+
* @param options - Intl.NumberFormatOptions overrides
|
|
52
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
53
|
+
*/
|
|
54
|
+
export declare function formatNumber(value: number | null | undefined, options?: Intl.NumberFormatOptions, locale?: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* Truncates a string to maxLength characters, appending "..." when truncated.
|
|
57
|
+
*
|
|
58
|
+
* @param title - Text to truncate
|
|
59
|
+
* @param maxLength - Maximum character count before truncation (default: 50)
|
|
60
|
+
*/
|
|
61
|
+
export declare function truncateTitle(title: string, maxLength?: number): string;
|
|
7
62
|
/**
|
|
8
63
|
* Format a credit card number with spaces every 4 digits
|
|
9
64
|
* @param value - Raw input (digits only)
|
|
@@ -16,4 +71,5 @@ export declare function formatCreditCardNumber(value: string): string;
|
|
|
16
71
|
* @returns Formatted phone number (e.g., "123-456-7890")
|
|
17
72
|
*/
|
|
18
73
|
export declare function formatPhoneNumber(value: string): string;
|
|
74
|
+
export {};
|
|
19
75
|
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/lib/utils/formatters.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/lib/utils/formatters.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ,SAAQ,EAChB,MAAM,SAAU,GACf,MAAM,CAMR;AAMD,KAAK,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAY3D;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,IAAI,CAAC,qBAAqB,EACpC,MAAM,SAAU,GACf,MAAM,CASR;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,IAAI,CAAC,qBAAqB,EACpC,MAAM,SAAU,GACf,MAAM,CAWR;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,IAAI,CAAC,qBAAqB,EACpC,MAAM,SAAU,GACf,MAAM,CAQR;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAClC,MAAM,SAAU,GACf,MAAM,CAGR;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAK,GAAG,MAAM,CAKnE;AAMD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOvD"}
|
package/dist/utils/formatters.js
CHANGED
|
@@ -1,11 +1,131 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Currency
|
|
3
|
+
// =============================================================================
|
|
1
4
|
/**
|
|
2
5
|
* Rounds a number to 2 decimal places (cents precision).
|
|
3
6
|
* Use after any arithmetic on currency values to avoid IEEE 754 drift.
|
|
4
7
|
* e.g. roundCurrency(167.79999999999) → 167.8
|
|
5
8
|
*/
|
|
6
9
|
export function roundCurrency(value) {
|
|
7
|
-
return Math.round(value * 100) / 100;
|
|
10
|
+
return Math.round((value + Number.EPSILON) * 100) / 100;
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Formats a currency value using Intl.NumberFormat.
|
|
14
|
+
* Returns empty string for null/undefined.
|
|
15
|
+
*
|
|
16
|
+
* @param value - Amount in dollars (e.g. 25.5)
|
|
17
|
+
* @param currency - ISO 4217 currency code (default: 'USD')
|
|
18
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
19
|
+
* @returns Formatted string (e.g. "$25.50")
|
|
20
|
+
*/
|
|
21
|
+
export function formatCurrency(value, currency = 'USD', locale = 'en-US') {
|
|
22
|
+
if (value === null || value === undefined)
|
|
23
|
+
return '';
|
|
24
|
+
return new Intl.NumberFormat(locale, {
|
|
25
|
+
style: 'currency',
|
|
26
|
+
currency,
|
|
27
|
+
}).format(value);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Converts various date input types to a Date object.
|
|
31
|
+
* Returns null for invalid or missing inputs.
|
|
32
|
+
*/
|
|
33
|
+
function toDate(value) {
|
|
34
|
+
if (value === null || value === undefined)
|
|
35
|
+
return null;
|
|
36
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
37
|
+
return isNaN(date.getTime()) ? null : date;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Formats a date according to a locale.
|
|
41
|
+
* Default output: abbreviated month, day, year (e.g. "Dec 15, 2025" in en-US).
|
|
42
|
+
*
|
|
43
|
+
* @param value - Date, ISO string, or epoch ms
|
|
44
|
+
* @param options - Intl.DateTimeFormatOptions overrides
|
|
45
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
46
|
+
*/
|
|
47
|
+
export function formatDate(value, options, locale = 'en-US') {
|
|
48
|
+
const date = toDate(value);
|
|
49
|
+
if (!date)
|
|
50
|
+
return '';
|
|
51
|
+
const defaults = {
|
|
52
|
+
year: 'numeric',
|
|
53
|
+
month: 'short',
|
|
54
|
+
day: 'numeric',
|
|
55
|
+
};
|
|
56
|
+
return new Intl.DateTimeFormat(locale, { ...defaults, ...options }).format(date);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Formats a date with time.
|
|
60
|
+
* Default output: abbreviated month, day, year, hour, minute
|
|
61
|
+
* (e.g. "Dec 15, 2025, 3:30 PM" in en-US).
|
|
62
|
+
*
|
|
63
|
+
* @param value - Date, ISO string, or epoch ms
|
|
64
|
+
* @param options - Intl.DateTimeFormatOptions overrides
|
|
65
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
66
|
+
*/
|
|
67
|
+
export function formatDateTime(value, options, locale = 'en-US') {
|
|
68
|
+
const date = toDate(value);
|
|
69
|
+
if (!date)
|
|
70
|
+
return '';
|
|
71
|
+
const defaults = {
|
|
72
|
+
year: 'numeric',
|
|
73
|
+
month: 'short',
|
|
74
|
+
day: 'numeric',
|
|
75
|
+
hour: 'numeric',
|
|
76
|
+
minute: '2-digit',
|
|
77
|
+
};
|
|
78
|
+
return new Intl.DateTimeFormat(locale, { ...defaults, ...options }).format(date);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Formats time-only.
|
|
82
|
+
* Default output: hour and minute (e.g. "3:30 PM" in en-US).
|
|
83
|
+
*
|
|
84
|
+
* @param value - Date, ISO string, or epoch ms
|
|
85
|
+
* @param options - Intl.DateTimeFormatOptions overrides
|
|
86
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
87
|
+
*/
|
|
88
|
+
export function formatTime(value, options, locale = 'en-US') {
|
|
89
|
+
const date = toDate(value);
|
|
90
|
+
if (!date)
|
|
91
|
+
return '';
|
|
92
|
+
const defaults = {
|
|
93
|
+
hour: 'numeric',
|
|
94
|
+
minute: '2-digit',
|
|
95
|
+
};
|
|
96
|
+
return new Intl.DateTimeFormat(locale, { ...defaults, ...options }).format(date);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Formats a number according to a locale.
|
|
100
|
+
* Returns empty string for null/undefined.
|
|
101
|
+
*
|
|
102
|
+
* @param value - Number to format
|
|
103
|
+
* @param options - Intl.NumberFormatOptions overrides
|
|
104
|
+
* @param locale - BCP 47 locale tag (default: 'en-US')
|
|
105
|
+
*/
|
|
106
|
+
export function formatNumber(value, options, locale = 'en-US') {
|
|
107
|
+
if (value === null || value === undefined)
|
|
108
|
+
return '';
|
|
109
|
+
return new Intl.NumberFormat(locale, options).format(value);
|
|
110
|
+
}
|
|
111
|
+
// =============================================================================
|
|
112
|
+
// Text
|
|
113
|
+
// =============================================================================
|
|
114
|
+
/**
|
|
115
|
+
* Truncates a string to maxLength characters, appending "..." when truncated.
|
|
116
|
+
*
|
|
117
|
+
* @param title - Text to truncate
|
|
118
|
+
* @param maxLength - Maximum character count before truncation (default: 50)
|
|
119
|
+
*/
|
|
120
|
+
export function truncateTitle(title, maxLength = 50) {
|
|
121
|
+
if (title.length > maxLength) {
|
|
122
|
+
return title.slice(0, maxLength) + '...';
|
|
123
|
+
}
|
|
124
|
+
return title;
|
|
125
|
+
}
|
|
126
|
+
// =============================================================================
|
|
127
|
+
// Input formatting (credit card, phone)
|
|
128
|
+
// =============================================================================
|
|
9
129
|
/**
|
|
10
130
|
* Format a credit card number with spaces every 4 digits
|
|
11
131
|
* @param value - Raw input (digits only)
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { expect, describe, test } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
formatCreditCardNumber,
|
|
4
|
+
formatPhoneNumber,
|
|
5
|
+
formatCurrency,
|
|
6
|
+
formatDate,
|
|
7
|
+
formatDateTime,
|
|
8
|
+
formatTime,
|
|
9
|
+
formatNumber,
|
|
10
|
+
truncateTitle,
|
|
11
|
+
roundCurrency,
|
|
12
|
+
} from './formatters.ts';
|
|
3
13
|
|
|
4
14
|
describe('formatCreditCardNumber', () => {
|
|
5
15
|
test('formats empty string', () => {
|
|
@@ -80,3 +90,120 @@ describe('formatPhoneNumber', () => {
|
|
|
80
90
|
expect(formatPhoneNumber('12345678901234')).toBe('123-456-7890');
|
|
81
91
|
});
|
|
82
92
|
});
|
|
93
|
+
|
|
94
|
+
describe('roundCurrency', () => {
|
|
95
|
+
test('rounds to 2 decimal places', () => {
|
|
96
|
+
expect(roundCurrency(167.79999999999)).toBe(167.8);
|
|
97
|
+
});
|
|
98
|
+
test('handles exact values', () => {
|
|
99
|
+
expect(roundCurrency(25.5)).toBe(25.5);
|
|
100
|
+
});
|
|
101
|
+
test('rounds up', () => {
|
|
102
|
+
expect(roundCurrency(10.005)).toBe(10.01);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('formatCurrency', () => {
|
|
107
|
+
test('formats USD by default', () => {
|
|
108
|
+
expect(formatCurrency(25.5)).toBe('$25.50');
|
|
109
|
+
});
|
|
110
|
+
test('returns empty string for null', () => {
|
|
111
|
+
expect(formatCurrency(null)).toBe('');
|
|
112
|
+
});
|
|
113
|
+
test('returns empty string for undefined', () => {
|
|
114
|
+
expect(formatCurrency(undefined)).toBe('');
|
|
115
|
+
});
|
|
116
|
+
test('formats zero', () => {
|
|
117
|
+
expect(formatCurrency(0)).toBe('$0.00');
|
|
118
|
+
});
|
|
119
|
+
test('formats negative values', () => {
|
|
120
|
+
expect(formatCurrency(-10)).toBe('-$10.00');
|
|
121
|
+
});
|
|
122
|
+
test('accepts custom currency', () => {
|
|
123
|
+
const result = formatCurrency(100, 'EUR', 'de-DE');
|
|
124
|
+
expect(result).toContain('100');
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe('formatDate', () => {
|
|
129
|
+
test('formats a Date object', () => {
|
|
130
|
+
const result = formatDate(new Date('2025-12-15T00:00:00Z'), undefined, 'en-US');
|
|
131
|
+
expect(result).toContain('Dec');
|
|
132
|
+
expect(result).toContain('2025');
|
|
133
|
+
});
|
|
134
|
+
test('formats an ISO string', () => {
|
|
135
|
+
const result = formatDate('2025-06-01T12:00:00Z', undefined, 'en-US');
|
|
136
|
+
expect(result).toContain('Jun');
|
|
137
|
+
});
|
|
138
|
+
test('returns empty string for null', () => {
|
|
139
|
+
expect(formatDate(null)).toBe('');
|
|
140
|
+
});
|
|
141
|
+
test('returns empty string for undefined', () => {
|
|
142
|
+
expect(formatDate(undefined)).toBe('');
|
|
143
|
+
});
|
|
144
|
+
test('returns empty string for invalid date', () => {
|
|
145
|
+
expect(formatDate('not-a-date')).toBe('');
|
|
146
|
+
});
|
|
147
|
+
test('accepts option overrides', () => {
|
|
148
|
+
const result = formatDate('2025-06-01T12:00:00Z', { month: 'long' }, 'en-US');
|
|
149
|
+
expect(result).toContain('June');
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe('formatDateTime', () => {
|
|
154
|
+
test('includes date and time', () => {
|
|
155
|
+
const result = formatDateTime('2025-12-15T15:30:00Z', undefined, 'en-US');
|
|
156
|
+
expect(result).toContain('Dec');
|
|
157
|
+
expect(result).toContain('2025');
|
|
158
|
+
expect(result).toContain('30');
|
|
159
|
+
});
|
|
160
|
+
test('returns empty string for null', () => {
|
|
161
|
+
expect(formatDateTime(null)).toBe('');
|
|
162
|
+
});
|
|
163
|
+
test('returns empty string for invalid date', () => {
|
|
164
|
+
expect(formatDateTime('bad')).toBe('');
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe('formatTime', () => {
|
|
169
|
+
test('formats time only', () => {
|
|
170
|
+
const result = formatTime('2025-12-15T15:30:00Z', undefined, 'en-US');
|
|
171
|
+
expect(result).toContain('30');
|
|
172
|
+
});
|
|
173
|
+
test('returns empty string for null', () => {
|
|
174
|
+
expect(formatTime(null)).toBe('');
|
|
175
|
+
});
|
|
176
|
+
test('returns empty string for invalid date', () => {
|
|
177
|
+
expect(formatTime('nope')).toBe('');
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe('formatNumber', () => {
|
|
182
|
+
test('formats a number with locale', () => {
|
|
183
|
+
expect(formatNumber(1000, undefined, 'en-US')).toBe('1,000');
|
|
184
|
+
});
|
|
185
|
+
test('returns empty string for null', () => {
|
|
186
|
+
expect(formatNumber(null)).toBe('');
|
|
187
|
+
});
|
|
188
|
+
test('returns empty string for undefined', () => {
|
|
189
|
+
expect(formatNumber(undefined)).toBe('');
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe('truncateTitle', () => {
|
|
194
|
+
test('truncates long text with ellipsis', () => {
|
|
195
|
+
expect(truncateTitle('Hello World', 5)).toBe('Hello...');
|
|
196
|
+
});
|
|
197
|
+
test('returns short text unchanged', () => {
|
|
198
|
+
expect(truncateTitle('Hi', 10)).toBe('Hi');
|
|
199
|
+
});
|
|
200
|
+
test('returns exact-length text unchanged', () => {
|
|
201
|
+
expect(truncateTitle('Hello', 5)).toBe('Hello');
|
|
202
|
+
});
|
|
203
|
+
test('uses default maxLength of 50', () => {
|
|
204
|
+
const short = 'Short string';
|
|
205
|
+
expect(truncateTitle(short)).toBe(short);
|
|
206
|
+
const long = 'A'.repeat(60);
|
|
207
|
+
expect(truncateTitle(long)).toBe('A'.repeat(50) + '...');
|
|
208
|
+
});
|
|
209
|
+
});
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized logger utility for MicDrop applications
|
|
3
3
|
* Can be disabled in production or configured for different log levels
|
|
4
|
+
*
|
|
5
|
+
* Usage (factory — recommended for consuming apps):
|
|
6
|
+
* import { createLogger } from '@getmicdrop/svelte-components/utils/logger';
|
|
7
|
+
* const log = createLogger('MF');
|
|
8
|
+
* log.info('booting'); // → [MF] [INFO] booting
|
|
9
|
+
*
|
|
10
|
+
* Usage (singleton — legacy, still works):
|
|
11
|
+
* import { logger, configureLogger } from '@getmicdrop/svelte-components/utils/logger';
|
|
12
|
+
* configureLogger({ prefix: '[MF]' });
|
|
13
|
+
* logger.info('booting');
|
|
4
14
|
*/
|
|
5
15
|
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
6
|
-
interface LoggerConfig {
|
|
16
|
+
export interface LoggerConfig {
|
|
7
17
|
enabled: boolean;
|
|
8
18
|
level: LogLevel;
|
|
9
19
|
prefix: string;
|
|
10
20
|
}
|
|
21
|
+
export interface Logger {
|
|
22
|
+
debug: (message: string, ...args: unknown[]) => void;
|
|
23
|
+
info: (message: string, ...args: unknown[]) => void;
|
|
24
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
25
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
26
|
+
configure: (options: Partial<LoggerConfig>) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create an independent logger instance with its own config.
|
|
30
|
+
*
|
|
31
|
+
* @param prefix - Tag shown in log output, e.g. 'MF' produces `[MF]`
|
|
32
|
+
* @param options - Optional overrides for enabled/level
|
|
33
|
+
*/
|
|
34
|
+
export declare function createLogger(prefix: string, options?: Partial<Omit<LoggerConfig, 'prefix'>>): Logger;
|
|
11
35
|
export declare function configureLogger(options: Partial<LoggerConfig>): void;
|
|
12
36
|
export declare const logger: {
|
|
13
37
|
debug: (message: string, ...args: unknown[]) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/utils/logger.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;CACrD;AAYD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAM,GAClD,MAAM,CA4CR;AAYD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAEpE;AAUD,eAAO,MAAM,MAAM;qBACA,MAAM,WAAW,OAAO,EAAE,KAAG,IAAI;oBAMlC,MAAM,WAAW,OAAO,EAAE,KAAG,IAAI;oBAMjC,MAAM,WAAW,OAAO,EAAE,KAAG,IAAI;qBAMhC,MAAM,WAAW,OAAO,EAAE,KAAG,IAAI;CAKnD,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized logger utility for MicDrop applications
|
|
3
3
|
* Can be disabled in production or configured for different log levels
|
|
4
|
+
*
|
|
5
|
+
* Usage (factory — recommended for consuming apps):
|
|
6
|
+
* import { createLogger } from '@getmicdrop/svelte-components/utils/logger';
|
|
7
|
+
* const log = createLogger('MF');
|
|
8
|
+
* log.info('booting'); // → [MF] [INFO] booting
|
|
9
|
+
*
|
|
10
|
+
* Usage (singleton — legacy, still works):
|
|
11
|
+
* import { logger, configureLogger } from '@getmicdrop/svelte-components/utils/logger';
|
|
12
|
+
* configureLogger({ prefix: '[MF]' });
|
|
13
|
+
* logger.info('booting');
|
|
4
14
|
*/
|
|
5
15
|
const LOG_LEVELS = {
|
|
6
16
|
debug: 0,
|
|
@@ -8,8 +18,56 @@ const LOG_LEVELS = {
|
|
|
8
18
|
warn: 2,
|
|
9
19
|
error: 3,
|
|
10
20
|
};
|
|
21
|
+
const isEnabled = () => typeof window !== 'undefined' && import.meta.env?.DEV !== false;
|
|
22
|
+
/**
|
|
23
|
+
* Create an independent logger instance with its own config.
|
|
24
|
+
*
|
|
25
|
+
* @param prefix - Tag shown in log output, e.g. 'MF' produces `[MF]`
|
|
26
|
+
* @param options - Optional overrides for enabled/level
|
|
27
|
+
*/
|
|
28
|
+
export function createLogger(prefix, options = {}) {
|
|
29
|
+
let config = {
|
|
30
|
+
enabled: options.enabled ?? isEnabled(),
|
|
31
|
+
level: options.level ?? 'debug',
|
|
32
|
+
prefix: prefix.startsWith('[') ? prefix : `[${prefix}]`,
|
|
33
|
+
};
|
|
34
|
+
function shouldLog(level) {
|
|
35
|
+
return config.enabled && LOG_LEVELS[level] >= LOG_LEVELS[config.level];
|
|
36
|
+
}
|
|
37
|
+
function formatMessage(level, message) {
|
|
38
|
+
return `${config.prefix} [${level.toUpperCase()}] ${message}`;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
debug(message, ...args) {
|
|
42
|
+
if (shouldLog('debug')) {
|
|
43
|
+
console.log(formatMessage('debug', message), ...args);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
info(message, ...args) {
|
|
47
|
+
if (shouldLog('info')) {
|
|
48
|
+
console.info(formatMessage('info', message), ...args);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
warn(message, ...args) {
|
|
52
|
+
if (shouldLog('warn')) {
|
|
53
|
+
console.warn(formatMessage('warn', message), ...args);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
error(message, ...args) {
|
|
57
|
+
if (shouldLog('error')) {
|
|
58
|
+
console.error(formatMessage('error', message), ...args);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
configure(opts) {
|
|
62
|
+
config = { ...config, ...opts };
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Singleton (backward-compatible) — uses the factory internally
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
11
69
|
let config = {
|
|
12
|
-
enabled:
|
|
70
|
+
enabled: isEnabled(),
|
|
13
71
|
level: 'debug',
|
|
14
72
|
prefix: '[MicDrop]',
|
|
15
73
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { logger, configureLogger } from './logger';
|
|
2
|
+
import { logger, configureLogger, createLogger } from './logger';
|
|
3
3
|
describe('logger', () => {
|
|
4
4
|
beforeEach(() => {
|
|
5
5
|
vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
@@ -93,3 +93,101 @@ describe('logger', () => {
|
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
95
|
});
|
|
96
|
+
describe('createLogger', () => {
|
|
97
|
+
beforeEach(() => {
|
|
98
|
+
vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
99
|
+
vi.spyOn(console, 'info').mockImplementation(() => { });
|
|
100
|
+
vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
101
|
+
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
102
|
+
});
|
|
103
|
+
afterEach(() => {
|
|
104
|
+
vi.restoreAllMocks();
|
|
105
|
+
});
|
|
106
|
+
it('wraps bare prefix in brackets', () => {
|
|
107
|
+
const log = createLogger('MF', { enabled: true });
|
|
108
|
+
log.info('hello');
|
|
109
|
+
expect(console.info).toHaveBeenCalledWith('[MF] [INFO] hello');
|
|
110
|
+
});
|
|
111
|
+
it('preserves prefix that already has brackets', () => {
|
|
112
|
+
const log = createLogger('[PP]', { enabled: true });
|
|
113
|
+
log.warn('oops');
|
|
114
|
+
expect(console.warn).toHaveBeenCalledWith('[PP] [WARN] oops');
|
|
115
|
+
});
|
|
116
|
+
it('each instance has independent config', () => {
|
|
117
|
+
const mf = createLogger('MF', { enabled: true });
|
|
118
|
+
const pp = createLogger('PP', { enabled: true, level: 'error' });
|
|
119
|
+
mf.debug('visible');
|
|
120
|
+
pp.debug('filtered');
|
|
121
|
+
expect(console.log).toHaveBeenCalledTimes(1);
|
|
122
|
+
expect(console.log).toHaveBeenCalledWith('[MF] [DEBUG] visible');
|
|
123
|
+
});
|
|
124
|
+
it('configure updates only that instance', () => {
|
|
125
|
+
const a = createLogger('A', { enabled: true });
|
|
126
|
+
const b = createLogger('B', { enabled: true });
|
|
127
|
+
a.configure({ level: 'error' });
|
|
128
|
+
a.info('filtered');
|
|
129
|
+
b.info('visible');
|
|
130
|
+
expect(console.info).toHaveBeenCalledTimes(1);
|
|
131
|
+
expect(console.info).toHaveBeenCalledWith('[B] [INFO] visible');
|
|
132
|
+
});
|
|
133
|
+
it('does not affect the singleton logger', () => {
|
|
134
|
+
configureLogger({ enabled: true, level: 'debug', prefix: '[MicDrop]' });
|
|
135
|
+
const custom = createLogger('Custom', { enabled: true });
|
|
136
|
+
custom.configure({ level: 'error' });
|
|
137
|
+
logger.debug('singleton still works');
|
|
138
|
+
expect(console.log).toHaveBeenCalledWith('[MicDrop] [DEBUG] singleton still works');
|
|
139
|
+
});
|
|
140
|
+
describe('log methods', () => {
|
|
141
|
+
it('debug logs with console.log', () => {
|
|
142
|
+
const log = createLogger('Test', { enabled: true });
|
|
143
|
+
log.debug('msg');
|
|
144
|
+
expect(console.log).toHaveBeenCalledWith('[Test] [DEBUG] msg');
|
|
145
|
+
});
|
|
146
|
+
it('info logs with console.info', () => {
|
|
147
|
+
const log = createLogger('Test', { enabled: true });
|
|
148
|
+
log.info('msg');
|
|
149
|
+
expect(console.info).toHaveBeenCalledWith('[Test] [INFO] msg');
|
|
150
|
+
});
|
|
151
|
+
it('warn logs with console.warn', () => {
|
|
152
|
+
const log = createLogger('Test', { enabled: true });
|
|
153
|
+
log.warn('msg');
|
|
154
|
+
expect(console.warn).toHaveBeenCalledWith('[Test] [WARN] msg');
|
|
155
|
+
});
|
|
156
|
+
it('error logs with console.error', () => {
|
|
157
|
+
const log = createLogger('Test', { enabled: true });
|
|
158
|
+
log.error('msg');
|
|
159
|
+
expect(console.error).toHaveBeenCalledWith('[Test] [ERROR] msg');
|
|
160
|
+
});
|
|
161
|
+
it('passes extra arguments through', () => {
|
|
162
|
+
const log = createLogger('Test', { enabled: true });
|
|
163
|
+
log.info('msg', { data: 1 }, 'extra');
|
|
164
|
+
expect(console.info).toHaveBeenCalledWith('[Test] [INFO] msg', { data: 1 }, 'extra');
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe('disabled logger', () => {
|
|
168
|
+
it('does not log when enabled is false', () => {
|
|
169
|
+
const log = createLogger('X', { enabled: false });
|
|
170
|
+
log.debug('nope');
|
|
171
|
+
log.info('nope');
|
|
172
|
+
log.warn('nope');
|
|
173
|
+
log.error('nope');
|
|
174
|
+
expect(console.log).not.toHaveBeenCalled();
|
|
175
|
+
expect(console.info).not.toHaveBeenCalled();
|
|
176
|
+
expect(console.warn).not.toHaveBeenCalled();
|
|
177
|
+
expect(console.error).not.toHaveBeenCalled();
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
describe('level filtering', () => {
|
|
181
|
+
it('filters below configured level', () => {
|
|
182
|
+
const log = createLogger('Test', { enabled: true, level: 'warn' });
|
|
183
|
+
log.debug('no');
|
|
184
|
+
log.info('no');
|
|
185
|
+
log.warn('yes');
|
|
186
|
+
log.error('yes');
|
|
187
|
+
expect(console.log).not.toHaveBeenCalled();
|
|
188
|
+
expect(console.info).not.toHaveBeenCalled();
|
|
189
|
+
expect(console.warn).toHaveBeenCalledTimes(1);
|
|
190
|
+
expect(console.error).toHaveBeenCalledTimes(1);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/lib/utils/permissions.ts"],"names":[],"mappings":"AAUA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,oBAAoB,EAAE,cAAc,EA2FhD,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import EventIcon from "../assets/svg/role/event.svg";
|
|
2
|
+
import BookingIcon from "../assets/svg/role/booking.svg";
|
|
3
|
+
import EmailIcon from "../assets/svg/role/emails.svg";
|
|
4
|
+
import VenueIcon from "../assets/svg/role/venue.svg";
|
|
5
|
+
import PayoutIcon from "../assets/svg/role/payout.svg";
|
|
6
|
+
import MarketingIcon from "../assets/svg/role/marketing.svg";
|
|
7
|
+
import OrdersIcon from "../assets/svg/role/orders.svg";
|
|
8
|
+
import OrganisationIcon from "../assets/svg/role/organisation.svg";
|
|
9
|
+
import ReportingIcon from "../assets/svg/role/reporting.svg";
|
|
10
|
+
export const ROLE_PERMISSION_LIST = [
|
|
11
|
+
{
|
|
12
|
+
icon: EventIcon,
|
|
13
|
+
title: "Event creation",
|
|
14
|
+
description: "Allow users to enter event info, create tickets & customize order forms",
|
|
15
|
+
checkbox: [
|
|
16
|
+
"Create Events",
|
|
17
|
+
"Edit Event Details",
|
|
18
|
+
"Manage event status",
|
|
19
|
+
"Manage tickets",
|
|
20
|
+
"Manage Collections",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
icon: BookingIcon,
|
|
25
|
+
title: "Booking",
|
|
26
|
+
description: "Allow users to manage performers, their invitations and statuses",
|
|
27
|
+
checkbox: [
|
|
28
|
+
"Access the roster page and view performer profiles",
|
|
29
|
+
"Edit performer profiles",
|
|
30
|
+
"Send booking invitations",
|
|
31
|
+
"Manually confirm/decline performers to spots",
|
|
32
|
+
"Send avails requests",
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
icon: VenueIcon,
|
|
37
|
+
title: "Venue creation",
|
|
38
|
+
description: "Allow users to create new venues",
|
|
39
|
+
checkbox: ["Add/edit/delete venues"],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
icon: MarketingIcon,
|
|
43
|
+
title: "Marketing",
|
|
44
|
+
description: "Sell more tickets by creating campaigns, tracking engagements, etc.",
|
|
45
|
+
checkbox: [
|
|
46
|
+
"Access social media posts",
|
|
47
|
+
"Manage tracking links",
|
|
48
|
+
"Manage promo codes",
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
icon: OrdersIcon,
|
|
53
|
+
title: "Orders & attendees",
|
|
54
|
+
description: "Allow users to view, update & refund orders, manage attendee guest or waitlists & release tickets",
|
|
55
|
+
checkbox: [
|
|
56
|
+
"Add attendees",
|
|
57
|
+
"Manage orders, refunds, transfers and attendees",
|
|
58
|
+
"View list of attendees",
|
|
59
|
+
"Check in attendees",
|
|
60
|
+
"Resend confirmation emails",
|
|
61
|
+
"Override ticket restrictions",
|
|
62
|
+
"Sell tickets at the door",
|
|
63
|
+
"Revoke and reissue barcodes",
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
icon: OrganisationIcon,
|
|
68
|
+
title: "Organization",
|
|
69
|
+
description: "Keep your users organized with assigned permissions per user, enable access to APIs & extensions",
|
|
70
|
+
checkbox: [
|
|
71
|
+
"Manage organization members & permissions",
|
|
72
|
+
"Edit organization infomation",
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
icon: EmailIcon,
|
|
77
|
+
title: "Contacts",
|
|
78
|
+
description: "Keep our users in the loop, select which emails you would like them to receive",
|
|
79
|
+
checkbox: ["Email attendees", "Email/SMS performers"],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
icon: ReportingIcon,
|
|
83
|
+
title: "Reporting",
|
|
84
|
+
description: "Allow users to access, filter & export data across your organization",
|
|
85
|
+
checkbox: ["Access reports pages"],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
icon: PayoutIcon,
|
|
89
|
+
title: "Payouts & billing",
|
|
90
|
+
description: "Users can configure payout methods, manage event payment options & track financials with reporting",
|
|
91
|
+
checkbox: ["Manage financial accounts (Stripe)"],
|
|
92
|
+
},
|
|
93
|
+
];
|