@getmicdrop/venue-calendar 3.3.1 → 3.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{VenueCalendar-Xppig0q_.js → VenueCalendar-qwLPhCFH.js} +2698 -2693
- package/dist/VenueCalendar-qwLPhCFH.js.map +1 -0
- package/dist/api/api.cjs +2 -0
- package/dist/api/api.cjs.map +1 -0
- package/dist/api/api.mjs +787 -0
- package/dist/api/api.mjs.map +1 -0
- package/dist/api/client.d.ts +46 -0
- package/dist/api/events.d.ts +102 -0
- package/dist/api/index.d.ts +38 -0
- package/dist/api/orders.d.ts +104 -0
- package/dist/api/promo.d.ts +45 -0
- package/dist/api/transformers/event.d.ts +86 -0
- package/dist/api/transformers/index.d.ts +9 -0
- package/dist/api/transformers/order.d.ts +105 -0
- package/dist/api/transformers/venue.d.ts +48 -0
- package/dist/api/venues.d.ts +33 -0
- package/dist/{index-BjErG0CG.js → index-TUrDiCfO.js} +2 -2
- package/dist/{index-BjErG0CG.js.map → index-TUrDiCfO.js.map} +1 -1
- package/dist/venue-calendar.css +1 -1
- package/dist/venue-calendar.es.js +1 -1
- package/dist/venue-calendar.iife.js +14 -14
- package/dist/venue-calendar.iife.js.map +1 -1
- package/dist/venue-calendar.umd.js +14 -14
- package/dist/venue-calendar.umd.js.map +1 -1
- package/package.json +96 -94
- package/dist/VenueCalendar-Xppig0q_.js.map +0 -1
- package/src/lib/api/client.ts +0 -210
- package/src/lib/api/events.ts +0 -358
- package/src/lib/api/index.ts +0 -182
- package/src/lib/api/orders.ts +0 -390
- package/src/lib/api/promo.ts +0 -164
- package/src/lib/api/transformers/event.ts +0 -248
- package/src/lib/api/transformers/index.ts +0 -29
- package/src/lib/api/transformers/order.ts +0 -207
- package/src/lib/api/transformers/venue.ts +0 -118
- package/src/lib/api/venues.ts +0 -100
- package/src/lib/utils/api.js +0 -790
- package/src/lib/utils/api.test.js +0 -1284
- package/src/lib/utils/constants.js +0 -8
- package/src/lib/utils/constants.test.js +0 -39
- package/src/lib/utils/datetime.js +0 -266
- package/src/lib/utils/datetime.test.js +0 -340
- package/src/lib/utils/event-transform.js +0 -464
- package/src/lib/utils/event-transform.test.js +0 -413
- package/src/lib/utils/logger.js +0 -105
- package/src/lib/utils/timezone.js +0 -109
- package/src/lib/utils/timezone.test.js +0 -222
- package/src/lib/utils/utils.js +0 -806
- package/src/lib/utils/utils.test.js +0 -959
- /package/{src/lib/api/types.ts → dist/api/types.d.ts} +0 -0
package/src/lib/api/promo.ts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Promo Codes API
|
|
3
|
-
*
|
|
4
|
-
* Functions for validating and checking promo codes
|
|
5
|
-
* in the public checkout flow.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { logger } from '../utils/logger.js';
|
|
9
|
-
import { getPublicBaseUrl } from './client.js';
|
|
10
|
-
import type { PromoValidationResponse, HasPromoCodesResponse } from './types.js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Validate a promo code for an event
|
|
14
|
-
*
|
|
15
|
-
* Checks if a promo code is valid and returns its effects:
|
|
16
|
-
* - Discount amount and type
|
|
17
|
-
* - Hidden ticket reveal
|
|
18
|
-
*
|
|
19
|
-
* @param eventId - The event ID
|
|
20
|
-
* @param code - The promo code to validate
|
|
21
|
-
* @returns Validation result with discount info
|
|
22
|
-
*/
|
|
23
|
-
export async function validatePromoCode(
|
|
24
|
-
eventId: string | number,
|
|
25
|
-
code: string
|
|
26
|
-
): Promise<PromoValidationResponse> {
|
|
27
|
-
try {
|
|
28
|
-
if (!code || !code.trim()) {
|
|
29
|
-
return { valid: false, error: 'Promo code is required' };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// API uses GET with code in URL path
|
|
33
|
-
const encodedCode = encodeURIComponent(code.trim());
|
|
34
|
-
const response = await fetch(
|
|
35
|
-
`${getPublicBaseUrl()}/promo-codes/validate/${eventId}/${encodedCode}`
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
if (!response.ok) {
|
|
39
|
-
// 404 = invalid code, other errors are server issues
|
|
40
|
-
if (response.status === 404) {
|
|
41
|
-
return { valid: false, error: 'Invalid promo code' };
|
|
42
|
-
}
|
|
43
|
-
const errorData = await response.json().catch(() => ({}));
|
|
44
|
-
return { valid: false, error: errorData.error || 'Failed to validate code' };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const result = await response.json();
|
|
48
|
-
return {
|
|
49
|
-
valid: result.valid ?? true,
|
|
50
|
-
revealHiddenTickets: result.revealHiddenTickets,
|
|
51
|
-
revealTicketIds: result.revealTicketIds,
|
|
52
|
-
provideDiscount: result.provideDiscount,
|
|
53
|
-
discountType: result.discountType,
|
|
54
|
-
amount: result.amount,
|
|
55
|
-
code: result.code || code,
|
|
56
|
-
};
|
|
57
|
-
} catch (error) {
|
|
58
|
-
logger.error('Error validating promo code:', error);
|
|
59
|
-
return { valid: false, error: 'Network error validating code' };
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Check if promo codes are available for an event
|
|
65
|
-
*
|
|
66
|
-
* Used to conditionally show/hide the promo code input field.
|
|
67
|
-
*
|
|
68
|
-
* @param eventId - The event ID
|
|
69
|
-
* @returns Whether promo codes exist for this event
|
|
70
|
-
*/
|
|
71
|
-
export async function hasPromoCodes(eventId: string | number): Promise<boolean> {
|
|
72
|
-
try {
|
|
73
|
-
const response = await fetch(
|
|
74
|
-
`${getPublicBaseUrl()}/promo-codes/check/${eventId}`
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
if (!response.ok) {
|
|
78
|
-
// If endpoint doesn't exist or errors, default to showing the input
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const result: HasPromoCodesResponse = await response.json();
|
|
83
|
-
return result.hasPromoCodes === true;
|
|
84
|
-
} catch (error) {
|
|
85
|
-
logger.error('Error checking promo codes availability:', error);
|
|
86
|
-
// Default to showing promo input if we can't check
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Apply a promo code to a cart
|
|
93
|
-
*
|
|
94
|
-
* This updates the cart with the promo code discount.
|
|
95
|
-
*
|
|
96
|
-
* @param cartId - The cart UUID
|
|
97
|
-
* @param code - The promo code to apply
|
|
98
|
-
* @returns Success status
|
|
99
|
-
*/
|
|
100
|
-
export async function applyPromoCode(
|
|
101
|
-
cartId: string,
|
|
102
|
-
code: string
|
|
103
|
-
): Promise<{ success: boolean; error?: string }> {
|
|
104
|
-
try {
|
|
105
|
-
const response = await fetch(
|
|
106
|
-
`${getPublicBaseUrl()}/orders/${cartId}/apply-promo`,
|
|
107
|
-
{
|
|
108
|
-
method: 'POST',
|
|
109
|
-
headers: {
|
|
110
|
-
'Content-Type': 'application/json',
|
|
111
|
-
},
|
|
112
|
-
body: JSON.stringify({ code }),
|
|
113
|
-
}
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
if (!response.ok) {
|
|
117
|
-
const errorData = await response.json().catch(() => ({}));
|
|
118
|
-
return {
|
|
119
|
-
success: false,
|
|
120
|
-
error: errorData.error || 'Failed to apply promo code',
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return { success: true };
|
|
125
|
-
} catch (error) {
|
|
126
|
-
logger.error('Error applying promo code:', error);
|
|
127
|
-
return { success: false, error: 'Network error applying code' };
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Remove a promo code from a cart
|
|
133
|
-
*
|
|
134
|
-
* @param cartId - The cart UUID
|
|
135
|
-
* @returns Success status
|
|
136
|
-
*/
|
|
137
|
-
export async function removePromoCode(
|
|
138
|
-
cartId: string
|
|
139
|
-
): Promise<{ success: boolean; error?: string }> {
|
|
140
|
-
try {
|
|
141
|
-
const response = await fetch(
|
|
142
|
-
`${getPublicBaseUrl()}/orders/${cartId}/remove-promo`,
|
|
143
|
-
{
|
|
144
|
-
method: 'POST',
|
|
145
|
-
headers: {
|
|
146
|
-
'Content-Type': 'application/json',
|
|
147
|
-
},
|
|
148
|
-
}
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
if (!response.ok) {
|
|
152
|
-
const errorData = await response.json().catch(() => ({}));
|
|
153
|
-
return {
|
|
154
|
-
success: false,
|
|
155
|
-
error: errorData.error || 'Failed to remove promo code',
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return { success: true };
|
|
160
|
-
} catch (error) {
|
|
161
|
-
logger.error('Error removing promo code:', error);
|
|
162
|
-
return { success: false, error: 'Network error removing code' };
|
|
163
|
-
}
|
|
164
|
-
}
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Event Transformer
|
|
3
|
-
*
|
|
4
|
-
* Normalizes API event responses to a consistent format.
|
|
5
|
-
* Handles image URL resolution and CTA state calculation.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { Event, AvailableTicket } from '../types.js';
|
|
9
|
-
|
|
10
|
-
// CDN base URL for images
|
|
11
|
-
const CDN_BASE_URL = 'https://micdrop-images.sfo3.digitaloceanspaces.com';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Raw API event response (may have varying field names)
|
|
15
|
-
*/
|
|
16
|
-
interface ApiEvent {
|
|
17
|
-
eventID?: number;
|
|
18
|
-
id?: number;
|
|
19
|
-
ID?: number;
|
|
20
|
-
name?: string;
|
|
21
|
-
title?: string;
|
|
22
|
-
slug?: string;
|
|
23
|
-
description?: string;
|
|
24
|
-
date?: string;
|
|
25
|
-
startDateTime?: string;
|
|
26
|
-
start_date_time?: string;
|
|
27
|
-
endDateTime?: string;
|
|
28
|
-
end_date_time?: string;
|
|
29
|
-
doorsOpenTime?: string;
|
|
30
|
-
doors_open_time?: string;
|
|
31
|
-
timezone?: string;
|
|
32
|
-
time_zone?: string;
|
|
33
|
-
venueId?: number;
|
|
34
|
-
venue_id?: number;
|
|
35
|
-
venueName?: string;
|
|
36
|
-
venue_name?: string;
|
|
37
|
-
venueAddress?: string;
|
|
38
|
-
venue_address?: string;
|
|
39
|
-
location?: string;
|
|
40
|
-
imageUrl?: string;
|
|
41
|
-
imageURL?: string;
|
|
42
|
-
image_url?: string;
|
|
43
|
-
image?: string;
|
|
44
|
-
status?: string;
|
|
45
|
-
isPublished?: boolean;
|
|
46
|
-
is_published?: boolean;
|
|
47
|
-
isCancelled?: boolean;
|
|
48
|
-
is_cancelled?: boolean;
|
|
49
|
-
availableTickets?: any[];
|
|
50
|
-
available_tickets?: any[];
|
|
51
|
-
tickets?: any[];
|
|
52
|
-
ticketsAvailable?: number;
|
|
53
|
-
tickets_available?: number;
|
|
54
|
-
ticketsSold?: number;
|
|
55
|
-
tickets_sold?: number;
|
|
56
|
-
minPrice?: number;
|
|
57
|
-
min_price?: number;
|
|
58
|
-
maxPrice?: number;
|
|
59
|
-
max_price?: number;
|
|
60
|
-
ctaText?: string;
|
|
61
|
-
cta_text?: string;
|
|
62
|
-
ctaState?: string;
|
|
63
|
-
cta_state?: string;
|
|
64
|
-
showPerformers?: boolean;
|
|
65
|
-
show_performers?: boolean;
|
|
66
|
-
eventSeriesId?: number;
|
|
67
|
-
event_series_id?: number;
|
|
68
|
-
seriesInstanceNumber?: number;
|
|
69
|
-
series_instance_number?: number;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Get CDN image URL
|
|
74
|
-
*
|
|
75
|
-
* Prepends the CDN base URL if the path is relative.
|
|
76
|
-
*/
|
|
77
|
-
export function getCDNImageUrl(path: string | undefined): string {
|
|
78
|
-
if (!path) return '';
|
|
79
|
-
if (path.startsWith('http')) return path;
|
|
80
|
-
return `${CDN_BASE_URL}/${path.replace(/^\//, '')}`;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Extract image URL from event with fallbacks
|
|
85
|
-
*/
|
|
86
|
-
export function getEventImageUrl(apiEvent: ApiEvent): string {
|
|
87
|
-
const rawUrl =
|
|
88
|
-
apiEvent.imageUrl ||
|
|
89
|
-
apiEvent.imageURL ||
|
|
90
|
-
apiEvent.image_url ||
|
|
91
|
-
apiEvent.image ||
|
|
92
|
-
'';
|
|
93
|
-
|
|
94
|
-
return getCDNImageUrl(rawUrl);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Calculate CTA state based on ticket availability
|
|
99
|
-
*/
|
|
100
|
-
export function calculateCtaState(
|
|
101
|
-
apiEvent: ApiEvent
|
|
102
|
-
): 'available' | 'sold_out' | 'coming_soon' | 'ended' {
|
|
103
|
-
// Check explicit CTA state first
|
|
104
|
-
const explicitState = apiEvent.ctaState || apiEvent.cta_state;
|
|
105
|
-
if (explicitState) {
|
|
106
|
-
return explicitState as any;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Check if event is cancelled or ended
|
|
110
|
-
if (apiEvent.isCancelled || apiEvent.is_cancelled) {
|
|
111
|
-
return 'ended';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Check event date
|
|
115
|
-
const eventDate = apiEvent.startDateTime || apiEvent.start_date_time || apiEvent.date;
|
|
116
|
-
if (eventDate) {
|
|
117
|
-
const eventTime = new Date(eventDate).getTime();
|
|
118
|
-
const now = Date.now();
|
|
119
|
-
|
|
120
|
-
if (eventTime < now) {
|
|
121
|
-
return 'ended';
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Check ticket availability
|
|
126
|
-
const availableCount =
|
|
127
|
-
apiEvent.ticketsAvailable ?? apiEvent.tickets_available;
|
|
128
|
-
|
|
129
|
-
if (availableCount !== undefined) {
|
|
130
|
-
if (availableCount <= 0) {
|
|
131
|
-
return 'sold_out';
|
|
132
|
-
}
|
|
133
|
-
return 'available';
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Check tickets array
|
|
137
|
-
const tickets =
|
|
138
|
-
apiEvent.availableTickets ||
|
|
139
|
-
apiEvent.available_tickets ||
|
|
140
|
-
apiEvent.tickets ||
|
|
141
|
-
[];
|
|
142
|
-
|
|
143
|
-
if (tickets.length === 0) {
|
|
144
|
-
return 'coming_soon';
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const totalAvailable = tickets.reduce((sum: number, t: any) => {
|
|
148
|
-
const qty =
|
|
149
|
-
t.quantityAvailable ?? t.quantity_available ?? t.quantity ?? 0;
|
|
150
|
-
const sold = t.quantitySold ?? t.quantity_sold ?? 0;
|
|
151
|
-
return sum + Math.max(0, qty - sold);
|
|
152
|
-
}, 0);
|
|
153
|
-
|
|
154
|
-
if (totalAvailable <= 0) {
|
|
155
|
-
return 'sold_out';
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return 'available';
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Transform a raw API ticket to normalized AvailableTicket
|
|
163
|
-
*/
|
|
164
|
-
export function transformTicket(apiTicket: any): AvailableTicket {
|
|
165
|
-
return {
|
|
166
|
-
id: apiTicket.id || apiTicket.ID,
|
|
167
|
-
name: apiTicket.name || apiTicket.ticketName || '',
|
|
168
|
-
description: apiTicket.description,
|
|
169
|
-
price: apiTicket.price || 0,
|
|
170
|
-
quantity: apiTicket.quantity || apiTicket.totalQuantity || 0,
|
|
171
|
-
quantitySold: apiTicket.quantitySold || apiTicket.quantity_sold || 0,
|
|
172
|
-
quantityAvailable:
|
|
173
|
-
apiTicket.quantityAvailable ||
|
|
174
|
-
apiTicket.quantity_available ||
|
|
175
|
-
(apiTicket.quantity || 0) - (apiTicket.quantitySold || 0),
|
|
176
|
-
minPerOrder: apiTicket.minPerOrder || apiTicket.min_per_order || 1,
|
|
177
|
-
maxPerOrder: apiTicket.maxPerOrder || apiTicket.max_per_order || 10,
|
|
178
|
-
saleStartDate: apiTicket.saleStartDate || apiTicket.sale_start_date,
|
|
179
|
-
saleEndDate: apiTicket.saleEndDate || apiTicket.sale_end_date,
|
|
180
|
-
isHidden: apiTicket.isHidden || apiTicket.is_hidden || false,
|
|
181
|
-
revealWithPromoCode:
|
|
182
|
-
apiTicket.revealWithPromoCode || apiTicket.reveal_with_promo_code,
|
|
183
|
-
ticketType: apiTicket.ticketType || apiTicket.ticket_type || 0,
|
|
184
|
-
sectionId: apiTicket.sectionId || apiTicket.section_id,
|
|
185
|
-
sortOrder: apiTicket.sortOrder || apiTicket.sort_order || 0,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Transform a raw API event to normalized Event
|
|
191
|
-
*/
|
|
192
|
-
export function transformEvent(apiEvent: ApiEvent): Event {
|
|
193
|
-
// Extract tickets array from various possible field names
|
|
194
|
-
const rawTickets =
|
|
195
|
-
apiEvent.availableTickets ||
|
|
196
|
-
apiEvent.available_tickets ||
|
|
197
|
-
apiEvent.tickets ||
|
|
198
|
-
[];
|
|
199
|
-
|
|
200
|
-
const tickets = rawTickets.map(transformTicket);
|
|
201
|
-
|
|
202
|
-
// Calculate min/max prices from tickets
|
|
203
|
-
const prices = tickets.map((t) => t.price).filter((p) => p > 0);
|
|
204
|
-
const minPrice = prices.length > 0 ? Math.min(...prices) : undefined;
|
|
205
|
-
const maxPrice = prices.length > 0 ? Math.max(...prices) : undefined;
|
|
206
|
-
|
|
207
|
-
return {
|
|
208
|
-
eventID: apiEvent.eventID || apiEvent.id || apiEvent.ID || 0,
|
|
209
|
-
id: apiEvent.id || apiEvent.ID,
|
|
210
|
-
name: apiEvent.name || apiEvent.title || '',
|
|
211
|
-
title: apiEvent.title || apiEvent.name,
|
|
212
|
-
slug: apiEvent.slug,
|
|
213
|
-
description: apiEvent.description,
|
|
214
|
-
date: apiEvent.date || apiEvent.startDateTime || apiEvent.start_date_time || '',
|
|
215
|
-
startDateTime: apiEvent.startDateTime || apiEvent.start_date_time,
|
|
216
|
-
endDateTime: apiEvent.endDateTime || apiEvent.end_date_time,
|
|
217
|
-
doorsOpenTime: apiEvent.doorsOpenTime || apiEvent.doors_open_time,
|
|
218
|
-
timezone: apiEvent.timezone || apiEvent.time_zone,
|
|
219
|
-
venueId: apiEvent.venueId || apiEvent.venue_id,
|
|
220
|
-
venueName: apiEvent.venueName || apiEvent.venue_name,
|
|
221
|
-
venueAddress: apiEvent.venueAddress || apiEvent.venue_address,
|
|
222
|
-
location: apiEvent.location || apiEvent.venueAddress || apiEvent.venue_address,
|
|
223
|
-
imageUrl: getEventImageUrl(apiEvent),
|
|
224
|
-
imageURL: getEventImageUrl(apiEvent),
|
|
225
|
-
status: apiEvent.status,
|
|
226
|
-
isPublished: apiEvent.isPublished ?? apiEvent.is_published,
|
|
227
|
-
isCancelled: apiEvent.isCancelled ?? apiEvent.is_cancelled,
|
|
228
|
-
availableTickets: tickets,
|
|
229
|
-
ticketsAvailable:
|
|
230
|
-
apiEvent.ticketsAvailable ??
|
|
231
|
-
apiEvent.tickets_available ??
|
|
232
|
-
tickets.reduce((sum, t) => sum + (t.quantityAvailable || 0), 0),
|
|
233
|
-
ticketsSold: apiEvent.ticketsSold ?? apiEvent.tickets_sold,
|
|
234
|
-
minPrice: apiEvent.minPrice ?? apiEvent.min_price ?? minPrice,
|
|
235
|
-
maxPrice: apiEvent.maxPrice ?? apiEvent.max_price ?? maxPrice,
|
|
236
|
-
ctaText: apiEvent.ctaText || apiEvent.cta_text,
|
|
237
|
-
ctaState: calculateCtaState(apiEvent),
|
|
238
|
-
showPerformers: apiEvent.showPerformers ?? apiEvent.show_performers,
|
|
239
|
-
eventSeriesId: apiEvent.eventSeriesId || apiEvent.event_series_id,
|
|
240
|
-
seriesInstanceNumber:
|
|
241
|
-
apiEvent.seriesInstanceNumber || apiEvent.series_instance_number,
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Legacy transformer name for backwards compatibility
|
|
247
|
-
*/
|
|
248
|
-
export const transformEventData = transformEvent;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transformers Index
|
|
3
|
-
*
|
|
4
|
-
* Re-exports all transformer functions for convenient importing.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Order transformers
|
|
8
|
-
export {
|
|
9
|
-
transformOrder,
|
|
10
|
-
transformTicket,
|
|
11
|
-
transformOrderForDisplay,
|
|
12
|
-
} from './order.js';
|
|
13
|
-
|
|
14
|
-
// Event transformers
|
|
15
|
-
export {
|
|
16
|
-
transformEvent,
|
|
17
|
-
transformEventData, // Legacy alias
|
|
18
|
-
transformTicket as transformAvailableTicket,
|
|
19
|
-
getCDNImageUrl,
|
|
20
|
-
getEventImageUrl,
|
|
21
|
-
calculateCtaState,
|
|
22
|
-
} from './event.js';
|
|
23
|
-
|
|
24
|
-
// Venue transformers
|
|
25
|
-
export {
|
|
26
|
-
transformVenue,
|
|
27
|
-
extractVenueFees,
|
|
28
|
-
formatVenueAddress,
|
|
29
|
-
} from './venue.js';
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Order Transformer
|
|
3
|
-
*
|
|
4
|
-
* Normalizes API order responses to a consistent format.
|
|
5
|
-
* Handles variations in field names between different API versions.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { Order, PurchasedTicket } from '../types.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Raw API order response (may have varying field names)
|
|
12
|
-
*/
|
|
13
|
-
interface ApiOrder {
|
|
14
|
-
uuid?: string;
|
|
15
|
-
id?: number;
|
|
16
|
-
ID?: number;
|
|
17
|
-
customerEmail?: string;
|
|
18
|
-
email?: string;
|
|
19
|
-
customer_email?: string;
|
|
20
|
-
customerFirstName?: string;
|
|
21
|
-
firstName?: string;
|
|
22
|
-
first_name?: string;
|
|
23
|
-
customerLastName?: string;
|
|
24
|
-
lastName?: string;
|
|
25
|
-
last_name?: string;
|
|
26
|
-
status?: string;
|
|
27
|
-
totalAmount?: number;
|
|
28
|
-
total?: number;
|
|
29
|
-
total_amount?: number;
|
|
30
|
-
subtotal?: number;
|
|
31
|
-
serviceFeesAmount?: number;
|
|
32
|
-
serviceFee?: number;
|
|
33
|
-
service_fee?: number;
|
|
34
|
-
service_fees_amount?: number;
|
|
35
|
-
taxAmount?: number;
|
|
36
|
-
tax?: number;
|
|
37
|
-
tax_amount?: number;
|
|
38
|
-
discount?: number;
|
|
39
|
-
paymentIntentId?: string;
|
|
40
|
-
payment_intent_id?: string;
|
|
41
|
-
paymentMethod?: string;
|
|
42
|
-
payment_method?: string;
|
|
43
|
-
purchasedTickets?: any[];
|
|
44
|
-
tickets?: any[];
|
|
45
|
-
purchased_tickets?: any[];
|
|
46
|
-
createdAt?: string;
|
|
47
|
-
created_at?: string;
|
|
48
|
-
updatedAt?: string;
|
|
49
|
-
updated_at?: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Raw API ticket response
|
|
54
|
-
*/
|
|
55
|
-
interface ApiTicket {
|
|
56
|
-
uuid?: string;
|
|
57
|
-
id?: number;
|
|
58
|
-
ID?: number;
|
|
59
|
-
ticketNumber?: string;
|
|
60
|
-
ticket_number?: string;
|
|
61
|
-
orderId?: string | number;
|
|
62
|
-
order_id?: string | number;
|
|
63
|
-
attendeeFirstName?: string;
|
|
64
|
-
attendee_first_name?: string;
|
|
65
|
-
firstName?: string;
|
|
66
|
-
attendeeLastName?: string;
|
|
67
|
-
attendee_last_name?: string;
|
|
68
|
-
lastName?: string;
|
|
69
|
-
attendeeEmail?: string;
|
|
70
|
-
attendee_email?: string;
|
|
71
|
-
email?: string;
|
|
72
|
-
ticketName?: string;
|
|
73
|
-
ticket_name?: string;
|
|
74
|
-
name?: string;
|
|
75
|
-
ticketTypeId?: number;
|
|
76
|
-
ticket_type_id?: number;
|
|
77
|
-
purchasePrice?: number;
|
|
78
|
-
purchase_price?: number;
|
|
79
|
-
price?: number;
|
|
80
|
-
status?: string;
|
|
81
|
-
checkedIn?: boolean;
|
|
82
|
-
checked_in?: boolean;
|
|
83
|
-
checkedInAt?: string;
|
|
84
|
-
checked_in_at?: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Transform a raw API ticket to normalized PurchasedTicket
|
|
89
|
-
*/
|
|
90
|
-
export function transformTicket(apiTicket: ApiTicket): PurchasedTicket {
|
|
91
|
-
return {
|
|
92
|
-
uuid: apiTicket.uuid || String(apiTicket.id || apiTicket.ID || ''),
|
|
93
|
-
id: apiTicket.id || apiTicket.ID,
|
|
94
|
-
ticketNumber: apiTicket.ticketNumber || apiTicket.ticket_number,
|
|
95
|
-
orderId: apiTicket.orderId || apiTicket.order_id,
|
|
96
|
-
attendeeFirstName:
|
|
97
|
-
apiTicket.attendeeFirstName ||
|
|
98
|
-
apiTicket.attendee_first_name ||
|
|
99
|
-
apiTicket.firstName,
|
|
100
|
-
attendeeLastName:
|
|
101
|
-
apiTicket.attendeeLastName ||
|
|
102
|
-
apiTicket.attendee_last_name ||
|
|
103
|
-
apiTicket.lastName,
|
|
104
|
-
attendeeEmail:
|
|
105
|
-
apiTicket.attendeeEmail || apiTicket.attendee_email || apiTicket.email,
|
|
106
|
-
ticketName:
|
|
107
|
-
apiTicket.ticketName || apiTicket.ticket_name || apiTicket.name || '',
|
|
108
|
-
ticketTypeId: apiTicket.ticketTypeId || apiTicket.ticket_type_id,
|
|
109
|
-
purchasePrice:
|
|
110
|
-
apiTicket.purchasePrice ||
|
|
111
|
-
apiTicket.purchase_price ||
|
|
112
|
-
apiTicket.price ||
|
|
113
|
-
0,
|
|
114
|
-
status: apiTicket.status,
|
|
115
|
-
checkedIn: apiTicket.checkedIn || apiTicket.checked_in,
|
|
116
|
-
checkedInAt: apiTicket.checkedInAt || apiTicket.checked_in_at,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Transform a raw API order to normalized Order
|
|
122
|
-
*
|
|
123
|
-
* Handles various field name patterns:
|
|
124
|
-
* - camelCase (customerEmail)
|
|
125
|
-
* - snake_case (customer_email)
|
|
126
|
-
* - Shortened names (email)
|
|
127
|
-
*/
|
|
128
|
-
export function transformOrder(apiOrder: ApiOrder): Order {
|
|
129
|
-
// Extract tickets array from various possible field names
|
|
130
|
-
const rawTickets =
|
|
131
|
-
apiOrder.purchasedTickets ||
|
|
132
|
-
apiOrder.tickets ||
|
|
133
|
-
apiOrder.purchased_tickets ||
|
|
134
|
-
[];
|
|
135
|
-
|
|
136
|
-
return {
|
|
137
|
-
uuid: apiOrder.uuid || String(apiOrder.id || apiOrder.ID || ''),
|
|
138
|
-
id: apiOrder.id || apiOrder.ID,
|
|
139
|
-
customerEmail:
|
|
140
|
-
apiOrder.customerEmail ||
|
|
141
|
-
apiOrder.email ||
|
|
142
|
-
apiOrder.customer_email ||
|
|
143
|
-
'',
|
|
144
|
-
customerFirstName:
|
|
145
|
-
apiOrder.customerFirstName ||
|
|
146
|
-
apiOrder.firstName ||
|
|
147
|
-
apiOrder.first_name,
|
|
148
|
-
customerLastName:
|
|
149
|
-
apiOrder.customerLastName ||
|
|
150
|
-
apiOrder.lastName ||
|
|
151
|
-
apiOrder.last_name,
|
|
152
|
-
status: apiOrder.status || 'unknown',
|
|
153
|
-
totalAmount:
|
|
154
|
-
apiOrder.totalAmount ||
|
|
155
|
-
apiOrder.total ||
|
|
156
|
-
apiOrder.total_amount ||
|
|
157
|
-
0,
|
|
158
|
-
subtotal: apiOrder.subtotal,
|
|
159
|
-
serviceFeesAmount:
|
|
160
|
-
apiOrder.serviceFeesAmount ||
|
|
161
|
-
apiOrder.serviceFee ||
|
|
162
|
-
apiOrder.service_fee ||
|
|
163
|
-
apiOrder.service_fees_amount ||
|
|
164
|
-
0,
|
|
165
|
-
taxAmount:
|
|
166
|
-
apiOrder.taxAmount || apiOrder.tax || apiOrder.tax_amount || 0,
|
|
167
|
-
discount: apiOrder.discount || 0,
|
|
168
|
-
paymentIntentId:
|
|
169
|
-
apiOrder.paymentIntentId || apiOrder.payment_intent_id,
|
|
170
|
-
paymentMethod: apiOrder.paymentMethod || apiOrder.payment_method,
|
|
171
|
-
purchasedTickets: rawTickets.map(transformTicket),
|
|
172
|
-
createdAt: apiOrder.createdAt || apiOrder.created_at,
|
|
173
|
-
updatedAt: apiOrder.updatedAt || apiOrder.updated_at,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Transform order for display on success page
|
|
179
|
-
*
|
|
180
|
-
* Returns a simplified object with display-ready values.
|
|
181
|
-
*/
|
|
182
|
-
export function transformOrderForDisplay(apiOrder: ApiOrder): {
|
|
183
|
-
orderId: string;
|
|
184
|
-
displayOrderId: string;
|
|
185
|
-
email: string;
|
|
186
|
-
customerName: string;
|
|
187
|
-
total: number;
|
|
188
|
-
formattedTotal: string;
|
|
189
|
-
ticketCount: number;
|
|
190
|
-
status: string;
|
|
191
|
-
} {
|
|
192
|
-
const order = transformOrder(apiOrder);
|
|
193
|
-
const displayId = order.uuid.split('-')[0] || order.uuid;
|
|
194
|
-
|
|
195
|
-
return {
|
|
196
|
-
orderId: order.uuid,
|
|
197
|
-
displayOrderId: displayId,
|
|
198
|
-
email: order.customerEmail,
|
|
199
|
-
customerName: [order.customerFirstName, order.customerLastName]
|
|
200
|
-
.filter(Boolean)
|
|
201
|
-
.join(' '),
|
|
202
|
-
total: order.totalAmount,
|
|
203
|
-
formattedTotal: `$${(order.totalAmount / 100).toFixed(2)}`,
|
|
204
|
-
ticketCount: order.purchasedTickets.length,
|
|
205
|
-
status: order.status,
|
|
206
|
-
};
|
|
207
|
-
}
|