@omnikit-js/ui 0.9.46 → 0.9.48

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.
@@ -0,0 +1,2205 @@
1
+ import { BillingContent, PaymentForm } from './chunk-SRPYYSJZ.js';
2
+ import { Alert, Table, Card, Button } from '@marcoschwartz/lite-ui';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
+
5
+ // src/lib/omnikit-client.ts
6
+ var OmniKitClient = class {
7
+ constructor(config) {
8
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
9
+ this.apiKey = config.apiKey;
10
+ this.jwt = config.jwt;
11
+ }
12
+ getHeaders() {
13
+ const headers = {
14
+ "Content-Type": "application/json"
15
+ };
16
+ if (this.jwt) {
17
+ headers["Authorization"] = `Bearer ${this.jwt}`;
18
+ } else if (this.apiKey) {
19
+ headers["X-API-Key"] = this.apiKey;
20
+ }
21
+ return headers;
22
+ }
23
+ async request(endpoint, options) {
24
+ const url = `${this.baseUrl}${endpoint}`;
25
+ const response = await fetch(url, {
26
+ ...options,
27
+ headers: {
28
+ ...this.getHeaders(),
29
+ ...options?.headers
30
+ }
31
+ });
32
+ if (!response.ok) {
33
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
34
+ throw new Error(error.error || `HTTP ${response.status}`);
35
+ }
36
+ return response.json();
37
+ }
38
+ /**
39
+ * Query records from a table
40
+ */
41
+ async query(table, options) {
42
+ const params = new URLSearchParams();
43
+ if (options?.filter) {
44
+ params.append("filter", JSON.stringify(options.filter));
45
+ }
46
+ if (options?.sort) {
47
+ params.append("sort", options.sort);
48
+ }
49
+ if (options?.limit) {
50
+ params.append("limit", options.limit.toString());
51
+ }
52
+ if (options?.offset) {
53
+ params.append("offset", options.offset.toString());
54
+ }
55
+ const queryString = params.toString();
56
+ const endpoint = `/data/${table}${queryString ? `?${queryString}` : ""}`;
57
+ return this.request(endpoint);
58
+ }
59
+ /**
60
+ * Find a record by ID
61
+ */
62
+ async findById(table, id) {
63
+ return this.request(`/data/${table}/${id}`);
64
+ }
65
+ /**
66
+ * Insert a new record
67
+ */
68
+ async insert(table, data) {
69
+ return this.request(`/data/${table}`, {
70
+ method: "POST",
71
+ body: JSON.stringify(data)
72
+ });
73
+ }
74
+ /**
75
+ * Update an existing record
76
+ */
77
+ async update(table, id, data) {
78
+ return this.request(`/data/${table}/${id}`, {
79
+ method: "PUT",
80
+ body: JSON.stringify(data)
81
+ });
82
+ }
83
+ /**
84
+ * Delete a record
85
+ */
86
+ async delete(table, id) {
87
+ return this.request(`/data/${table}/${id}`, {
88
+ method: "DELETE"
89
+ });
90
+ }
91
+ /**
92
+ * Upsert a record (insert or update)
93
+ */
94
+ async upsert(table, data) {
95
+ return this.request(`/data/${table}`, {
96
+ method: "PUT",
97
+ body: JSON.stringify(data)
98
+ });
99
+ }
100
+ };
101
+ function createOmniKitClient(config) {
102
+ return new OmniKitClient(config);
103
+ }
104
+ function normalizeColumn(column) {
105
+ if (typeof column === "string") {
106
+ return {
107
+ key: column,
108
+ label: column.charAt(0).toUpperCase() + column.slice(1).replace(/_/g, " "),
109
+ sortable: true
110
+ };
111
+ }
112
+ return {
113
+ ...column,
114
+ label: column.label || column.key.charAt(0).toUpperCase() + column.key.slice(1).replace(/_/g, " ")
115
+ };
116
+ }
117
+ async function DataList({
118
+ table,
119
+ baseUrl,
120
+ apiKey,
121
+ jwt,
122
+ columns,
123
+ keyField = "id",
124
+ filter,
125
+ sort,
126
+ limit,
127
+ offset,
128
+ className = "",
129
+ emptyMessage = "No data found",
130
+ errorMessage = "Failed to load data"
131
+ }) {
132
+ const client = createOmniKitClient({ baseUrl, apiKey, jwt });
133
+ let data = [];
134
+ let error = null;
135
+ try {
136
+ const response = await client.query(table, {
137
+ filter,
138
+ sort,
139
+ limit,
140
+ offset
141
+ });
142
+ if (response.success) {
143
+ data = response.data;
144
+ } else {
145
+ error = response.error || errorMessage;
146
+ }
147
+ } catch (err) {
148
+ error = err instanceof Error ? err.message : errorMessage;
149
+ }
150
+ const normalizedColumns = columns.map(normalizeColumn);
151
+ const processedData = data.map((row) => {
152
+ const processedRow = { ...row };
153
+ normalizedColumns.forEach((col) => {
154
+ if (col.render) {
155
+ const value = col.key.split(".").reduce((obj, k) => obj?.[k], row);
156
+ processedRow[`__rendered_${col.key}`] = col.render(value, row);
157
+ }
158
+ });
159
+ return processedRow;
160
+ });
161
+ const tableColumns = normalizedColumns.map((col) => ({
162
+ key: col.render ? `__rendered_${col.key}` : col.key,
163
+ title: col.label || col.key
164
+ }));
165
+ if (error) {
166
+ return /* @__PURE__ */ jsxs(Alert, { variant: "error", className, children: [
167
+ /* @__PURE__ */ jsx("p", { className: "font-medium", children: "Error" }),
168
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm", children: error })
169
+ ] });
170
+ }
171
+ if (data.length === 0) {
172
+ return /* @__PURE__ */ jsx(Alert, { variant: "info", className, children: emptyMessage });
173
+ }
174
+ return /* @__PURE__ */ jsx(
175
+ Table,
176
+ {
177
+ columns: tableColumns,
178
+ data: processedData,
179
+ keyField: String(keyField),
180
+ hoverable: true,
181
+ responsive: true,
182
+ className
183
+ }
184
+ );
185
+ }
186
+
187
+ // src/components/server/Billing/client.ts
188
+ function createHeaders(config) {
189
+ const headers = {
190
+ "Content-Type": "application/json"
191
+ };
192
+ if (config.accessToken) {
193
+ headers["Authorization"] = `Bearer ${config.accessToken}`;
194
+ }
195
+ if (config.apiKey) {
196
+ headers["X-API-Key"] = config.apiKey;
197
+ }
198
+ return headers;
199
+ }
200
+ async function fetchAPI(config, url, options = {}) {
201
+ try {
202
+ const response = await fetch(url, {
203
+ ...options,
204
+ headers: {
205
+ ...createHeaders(config),
206
+ ...options.headers
207
+ },
208
+ // Prevent infinite re-fetching in Next.js
209
+ cache: "no-store"
210
+ });
211
+ if (!response.ok) {
212
+ try {
213
+ const errorData = await response.json();
214
+ return {
215
+ success: false,
216
+ error: errorData.error || `HTTP ${response.status}: ${response.statusText}`
217
+ };
218
+ } catch {
219
+ return {
220
+ success: false,
221
+ error: `HTTP ${response.status}: ${response.statusText}`
222
+ };
223
+ }
224
+ }
225
+ const contentType = response.headers.get("content-type");
226
+ if (!contentType || !contentType.includes("application/json")) {
227
+ return {
228
+ success: false,
229
+ error: "Invalid response: expected JSON"
230
+ };
231
+ }
232
+ const data = await response.json();
233
+ return data;
234
+ } catch (error) {
235
+ return {
236
+ success: false,
237
+ error: error instanceof Error ? error.message : "API request failed"
238
+ };
239
+ }
240
+ }
241
+ async function getOrCreateCustomer(config, userId, organizationId, email, name, testMode = true) {
242
+ const { baseUrl, projectId } = config;
243
+ const customerData = await fetchAPI(
244
+ config,
245
+ `${baseUrl}/billing/customers/by-user/${userId}?project_id=${projectId}`
246
+ );
247
+ if (customerData.success && customerData.data) {
248
+ return customerData;
249
+ }
250
+ const createData = await fetchAPI(
251
+ config,
252
+ `${baseUrl}/billing/customers`,
253
+ {
254
+ method: "POST",
255
+ body: JSON.stringify({
256
+ project_id: projectId,
257
+ user_id: userId,
258
+ organization_id: organizationId,
259
+ email,
260
+ name,
261
+ test_mode: testMode,
262
+ sync_to_stripe: true
263
+ })
264
+ }
265
+ );
266
+ return createData;
267
+ }
268
+ async function fetchUserData(config, userId) {
269
+ const { baseUrl } = config;
270
+ return fetchAPI(
271
+ config,
272
+ `${baseUrl}/data/users/${userId}`
273
+ );
274
+ }
275
+ async function fetchBillingData(props) {
276
+ const {
277
+ baseUrl,
278
+ apiKey,
279
+ accessToken,
280
+ projectId,
281
+ userId,
282
+ organizationId,
283
+ userEmail,
284
+ userName,
285
+ testMode = true
286
+ } = props;
287
+ const config = { baseUrl, apiKey, accessToken, projectId };
288
+ try {
289
+ let email = userEmail;
290
+ let name = userName;
291
+ let orgId = organizationId;
292
+ if (!email) {
293
+ const userResult = await fetchUserData(config, userId);
294
+ if (userResult.success && userResult.data) {
295
+ email = userResult.data.email;
296
+ name = name || userResult.data.full_name || userResult.data.display_name;
297
+ orgId = orgId || userResult.data.organization_id;
298
+ } else {
299
+ return { success: false, error: userResult.error || "User not found. Please provide userEmail." };
300
+ }
301
+ }
302
+ const finalOrgId = orgId || 1;
303
+ const customerResult = await getOrCreateCustomer(
304
+ config,
305
+ userId,
306
+ finalOrgId,
307
+ email,
308
+ name,
309
+ testMode
310
+ );
311
+ if (!customerResult.success || !customerResult.data) {
312
+ return { success: false, error: customerResult.error || "Failed to get customer" };
313
+ }
314
+ const customer = customerResult.data;
315
+ const customerId = customer.id;
316
+ const [
317
+ subsData,
318
+ productsData,
319
+ pricesData,
320
+ entitlementsData,
321
+ invoicesData,
322
+ pmData,
323
+ usageData
324
+ ] = await Promise.all([
325
+ fetchAPI(config, `${baseUrl}/billing/subscriptions?project_id=${projectId}&customer_id=${customerId}&status=active&include_items=true`),
326
+ fetchAPI(config, `${baseUrl}/billing/products?project_id=${projectId}&limit=100&include_prices=false`),
327
+ fetchAPI(config, `${baseUrl}/billing/products/prices?project_id=${projectId}&limit=1000`),
328
+ fetchAPI(config, `${baseUrl}/billing/entitlements/list-entitlements?project_id=${projectId}&customer_id=${customerId}`),
329
+ fetchAPI(config, `${baseUrl}/billing/invoices?project_id=${projectId}&customer_id=${customerId}&limit=10&sort=due_date:desc&include_line_items=true`),
330
+ fetchAPI(config, `${baseUrl}/billing/customers/${customerId}/payment-methods?project_id=${projectId}&status=active`),
331
+ fetchAPI(config, `${baseUrl}/billing/usage/get-all?project_id=${projectId}&customer_id=${customerId}`)
332
+ ]);
333
+ const currentSubscription = subsData.success && subsData.data && subsData.data.length > 0 ? subsData.data[0] : null;
334
+ const products = productsData.success && productsData.data ? productsData.data : [];
335
+ const allPrices = pricesData.success && pricesData.data ? pricesData.data : [];
336
+ const entitlements = entitlementsData.success && entitlementsData.data ? entitlementsData.data : [];
337
+ const invoices = invoicesData.success && invoicesData.data ? invoicesData.data : [];
338
+ const paymentMethods = pmData.success && pmData.data ? pmData.data : [];
339
+ const featureUsage = usageData.success && usageData.data ? usageData.data : {};
340
+ const pricesByProduct = {};
341
+ allPrices.forEach((price) => {
342
+ if (!pricesByProduct[price.product_id]) {
343
+ pricesByProduct[price.product_id] = [];
344
+ }
345
+ pricesByProduct[price.product_id].push(price);
346
+ });
347
+ products.forEach((product) => {
348
+ product.prices = pricesByProduct[product.id] || [];
349
+ });
350
+ const productFeatures = {};
351
+ await Promise.all(
352
+ products.map(async (product) => {
353
+ const featuresData = await fetchAPI(
354
+ config,
355
+ `${baseUrl}/billing/features/product/${product.id}?project_id=${projectId}&limit=100`
356
+ );
357
+ productFeatures[product.id] = featuresData.success && featuresData.data ? featuresData.data : [];
358
+ })
359
+ );
360
+ const billingData = {
361
+ customer,
362
+ currentSubscription,
363
+ products,
364
+ productFeatures,
365
+ entitlements,
366
+ invoices,
367
+ paymentMethods,
368
+ featureUsage
369
+ };
370
+ return { success: true, data: billingData };
371
+ } catch (error) {
372
+ console.error("Error fetching billing data:", error);
373
+ return {
374
+ success: false,
375
+ error: error instanceof Error ? error.message : "Failed to fetch billing data"
376
+ };
377
+ }
378
+ }
379
+ async function fetchProject(config) {
380
+ const { baseUrl, projectId } = config;
381
+ return fetchAPI(
382
+ config,
383
+ `${baseUrl}/data/projects/${projectId}`
384
+ );
385
+ }
386
+ async function fetchTaxInfo(config, customerId, referenceAmount = 1e4) {
387
+ const { baseUrl, projectId } = config;
388
+ return fetchAPI(
389
+ config,
390
+ `${baseUrl}/billing/tax/calculate`,
391
+ {
392
+ method: "POST",
393
+ body: JSON.stringify({
394
+ project_id: projectId,
395
+ customer_id: customerId,
396
+ amount: referenceAmount,
397
+ product_type: "digital"
398
+ })
399
+ }
400
+ );
401
+ }
402
+ async function Billing(props) {
403
+ const {
404
+ className = "",
405
+ errorMessage = "Failed to load billing information"
406
+ } = props;
407
+ const result = await fetchBillingData(props);
408
+ if (!result.success || !result.data) {
409
+ return /* @__PURE__ */ jsxs(Alert, { variant: "error", className, children: [
410
+ /* @__PURE__ */ jsx("p", { className: "font-medium", children: "Error" }),
411
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm", children: result.error || errorMessage })
412
+ ] });
413
+ }
414
+ const { data } = result;
415
+ const apiConfig = {
416
+ baseUrl: props.baseUrl,
417
+ apiKey: props.apiKey,
418
+ accessToken: props.accessToken,
419
+ projectId: props.projectId
420
+ };
421
+ let initialTaxInfo = null;
422
+ if (data.customer?.id) {
423
+ const taxResult = await fetchTaxInfo(apiConfig, data.customer.id, 1e4);
424
+ if (taxResult.success && taxResult.data) {
425
+ initialTaxInfo = taxResult.data;
426
+ }
427
+ }
428
+ let businessName;
429
+ const projectResult = await fetchProject(apiConfig);
430
+ if (projectResult.success && projectResult.data?.name) {
431
+ businessName = projectResult.data.name;
432
+ }
433
+ const currentSubscriptionPriceId = data.currentSubscription?.items?.[0]?.price_id;
434
+ const currentPlan = currentSubscriptionPriceId ? data.products.find((p) => p.prices?.some((price) => price.id === currentSubscriptionPriceId)) : null;
435
+ const currentPrice = currentPlan?.prices?.find((p) => p.id === currentSubscriptionPriceId);
436
+ const subscription = data.currentSubscription ? {
437
+ id: data.currentSubscription.id,
438
+ plan: currentPlan?.name || "Unknown Plan",
439
+ status: data.currentSubscription.status,
440
+ price: formatCurrency(
441
+ currentPrice?.unit_amount || currentPrice?.amount || 0,
442
+ data.currentSubscription.currency
443
+ ),
444
+ period: currentPrice?.recurring_interval || "month",
445
+ nextBilling: formatDate(data.currentSubscription.current_period_end),
446
+ cancelAtPeriodEnd: data.currentSubscription.cancel_at_period_end
447
+ } : null;
448
+ const invoices = data.invoices.map((inv) => ({
449
+ id: inv.number || inv.uuid,
450
+ date: formatDate(inv.due_date || inv.created_at),
451
+ amount: formatCurrency(inv.total || inv.amount_due, inv.currency),
452
+ status: inv.status,
453
+ url: inv.pdf_url || "#"
454
+ }));
455
+ const plans = data.products.filter((p) => p.active && p.prices && p.prices.length > 0).map((product) => {
456
+ const price = product.prices?.find((p) => p.active) || product.prices?.[0];
457
+ const features = data.productFeatures[product.id] || [];
458
+ const isCurrentPlan = currentSubscriptionPriceId ? product.prices?.some((p) => p.id === currentSubscriptionPriceId) : false;
459
+ const priceAmount = price?.unit_amount || 0;
460
+ return {
461
+ id: product.id,
462
+ priceId: price?.id || 0,
463
+ name: product.name,
464
+ description: product.description,
465
+ price: formatCurrency(priceAmount, price?.currency || "usd"),
466
+ priceAmount,
467
+ // Raw amount in cents for sorting
468
+ period: price?.recurring_interval || "month",
469
+ features: features.map((f) => {
470
+ const featureName = f.feature_name || f.feature_key || "Feature";
471
+ const featureValue = typeof f.value === "object" && f.value !== null && "value" in f.value ? f.value.value : f.value;
472
+ const featureUnit = f.feature_unit || "";
473
+ if (featureValue === true) {
474
+ return featureName;
475
+ }
476
+ if (featureValue === false) {
477
+ return null;
478
+ }
479
+ if (typeof featureValue === "number" && featureValue === -1) {
480
+ return `Unlimited ${featureUnit || featureName.toLowerCase()}`;
481
+ }
482
+ if (typeof featureValue === "number") {
483
+ const formattedValue = featureValue.toLocaleString();
484
+ return `${formattedValue} ${featureUnit || featureName.toLowerCase()}`;
485
+ }
486
+ if (typeof featureValue === "string" && featureValue) {
487
+ return `${featureName}: ${featureValue}`;
488
+ }
489
+ return featureName;
490
+ }).filter(Boolean),
491
+ current: isCurrentPlan || false,
492
+ popular: product.name.toLowerCase().includes("pro") || product.name.toLowerCase().includes("professional")
493
+ };
494
+ }).sort((a, b) => a.priceAmount - b.priceAmount);
495
+ return /* @__PURE__ */ jsx(
496
+ BillingContent,
497
+ {
498
+ subscription,
499
+ invoices,
500
+ paymentMethods: data.paymentMethods,
501
+ plans,
502
+ customer: data.customer,
503
+ entitlements: data.entitlements,
504
+ featureUsage: data.featureUsage,
505
+ actionConfig: apiConfig,
506
+ initialTaxInfo,
507
+ businessName,
508
+ className
509
+ }
510
+ );
511
+ }
512
+ function formatCurrency(amount, currency = "usd") {
513
+ const formatter = new Intl.NumberFormat("en-US", {
514
+ style: "currency",
515
+ currency: currency.toUpperCase()
516
+ });
517
+ return formatter.format(amount / 100);
518
+ }
519
+ function formatDate(dateString) {
520
+ if (!dateString) return "N/A";
521
+ const date = new Date(dateString);
522
+ return date.toLocaleDateString("en-US", {
523
+ year: "numeric",
524
+ month: "long",
525
+ day: "numeric"
526
+ });
527
+ }
528
+ var MOCK_CART = {
529
+ items: [
530
+ {
531
+ id: "item_001",
532
+ product: {
533
+ id: "prod_001",
534
+ name: "Wireless Bluetooth Headphones",
535
+ slug: "wireless-bluetooth-headphones",
536
+ description: "Premium noise-cancelling headphones",
537
+ price: 149.99,
538
+ compareAtPrice: 199.99,
539
+ images: ["/placeholder-product.jpg"],
540
+ sku: "WBH-001",
541
+ category: "Electronics",
542
+ inStock: true,
543
+ stockQuantity: 50
544
+ },
545
+ quantity: 1,
546
+ price: 149.99
547
+ },
548
+ {
549
+ id: "item_002",
550
+ product: {
551
+ id: "prod_002",
552
+ name: "USB-C Charging Cable (2-Pack)",
553
+ slug: "usb-c-charging-cable-2pack",
554
+ description: "Fast charging braided cables",
555
+ price: 24.99,
556
+ images: ["/placeholder-product.jpg"],
557
+ sku: "USBC-002",
558
+ category: "Accessories",
559
+ inStock: true,
560
+ stockQuantity: 200
561
+ },
562
+ quantity: 2,
563
+ price: 24.99
564
+ },
565
+ {
566
+ id: "item_003",
567
+ product: {
568
+ id: "prod_003",
569
+ name: "Laptop Stand - Aluminum",
570
+ slug: "laptop-stand-aluminum",
571
+ description: "Ergonomic adjustable laptop stand",
572
+ price: 79.99,
573
+ images: ["/placeholder-product.jpg"],
574
+ sku: "LS-003",
575
+ category: "Office",
576
+ inStock: true,
577
+ stockQuantity: 30
578
+ },
579
+ quantity: 1,
580
+ price: 79.99
581
+ }
582
+ ],
583
+ itemCount: 4,
584
+ subtotal: 279.96,
585
+ tax: 22.4,
586
+ discount: 0,
587
+ total: 302.36,
588
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
589
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
590
+ };
591
+ function LinkButton({ href, children, variant = "primary", size = "md", className = "" }) {
592
+ const baseStyles = "inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2";
593
+ const variantStyles = variant === "primary" ? "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500" : "bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500 border border-gray-300";
594
+ const sizeStyles = size === "sm" ? "px-3 py-1.5 text-sm" : size === "lg" ? "px-6 py-3 text-base" : "px-4 py-2 text-sm";
595
+ return /* @__PURE__ */ jsx("a", { href, className: `${baseStyles} ${variantStyles} ${sizeStyles} ${className}`, children });
596
+ }
597
+ async function Cart({
598
+ // API config - will be used when connected to real API
599
+ baseUrl: _baseUrl,
600
+ apiKey: _apiKey,
601
+ accessToken: _accessToken,
602
+ projectId: _projectId,
603
+ userId: _userId,
604
+ cartId: _cartId,
605
+ // Display options
606
+ showImages = true,
607
+ showQuantityControls = true,
608
+ showRemoveButton = true,
609
+ continueShoppingUrl = "/products",
610
+ checkoutUrl = "/checkout",
611
+ currencySymbol = "$",
612
+ emptyMessage = "Your cart is empty",
613
+ emptyActionText = "Continue Shopping",
614
+ emptyActionUrl = "/products",
615
+ className = ""
616
+ }) {
617
+ const cart = MOCK_CART;
618
+ if (!cart || cart.items.length === 0) {
619
+ return /* @__PURE__ */ jsxs("div", { className: `text-center py-12 ${className}`, children: [
620
+ /* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsx("svg", { className: "mx-auto h-16 w-16 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" }) }) }),
621
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900 mb-2", children: emptyMessage }),
622
+ /* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-6", children: "Add some items to get started" }),
623
+ /* @__PURE__ */ jsx(LinkButton, { href: emptyActionUrl, children: emptyActionText })
624
+ ] });
625
+ }
626
+ return /* @__PURE__ */ jsxs("div", { className: `space-y-6 ${className}`, children: [
627
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
628
+ /* @__PURE__ */ jsxs("h1", { className: "text-2xl font-bold text-gray-900", children: [
629
+ "Shopping Cart (",
630
+ cart.itemCount,
631
+ " ",
632
+ "items",
633
+ ")"
634
+ ] }),
635
+ continueShoppingUrl && /* @__PURE__ */ jsx("a", { href: continueShoppingUrl, className: "text-sm text-blue-600 hover:text-blue-800", children: "Continue Shopping" })
636
+ ] }),
637
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
638
+ /* @__PURE__ */ jsx("div", { className: "lg:col-span-2 space-y-4", children: cart.items.map((item) => /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
639
+ showImages && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 w-24 h-24 bg-gray-100 rounded-lg overflow-hidden", children: /* @__PURE__ */ jsx(
640
+ "img",
641
+ {
642
+ src: item.product.images[0] || "/placeholder-product.jpg",
643
+ alt: item.product.name,
644
+ className: "w-full h-full object-cover"
645
+ }
646
+ ) }),
647
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
648
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
649
+ /* @__PURE__ */ jsxs("div", { children: [
650
+ /* @__PURE__ */ jsx("h3", { className: "text-base font-medium text-gray-900 truncate", children: /* @__PURE__ */ jsx("a", { href: `/products/${item.product.slug}`, className: "hover:text-blue-600", children: item.product.name }) }),
651
+ item.product.sku && /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500", children: [
652
+ "SKU: ",
653
+ item.product.sku
654
+ ] }),
655
+ item.variant && /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: Object.entries(item.variant.attributes).map(([key, value]) => `${key}: ${value}`).join(", ") })
656
+ ] }),
657
+ /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
658
+ /* @__PURE__ */ jsxs("p", { className: "text-base font-semibold text-gray-900", children: [
659
+ currencySymbol,
660
+ (item.price * item.quantity).toFixed(2)
661
+ ] }),
662
+ item.quantity > 1 && /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500", children: [
663
+ currencySymbol,
664
+ item.price.toFixed(2),
665
+ " each"
666
+ ] })
667
+ ] })
668
+ ] }),
669
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-between", children: [
670
+ showQuantityControls ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
671
+ /* @__PURE__ */ jsx(
672
+ "button",
673
+ {
674
+ type: "button",
675
+ className: "w-8 h-8 flex items-center justify-center rounded-md border border-gray-300 bg-white text-gray-600 hover:bg-gray-50",
676
+ "aria-label": "Decrease quantity",
677
+ children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20 12H4" }) })
678
+ }
679
+ ),
680
+ /* @__PURE__ */ jsx("span", { className: "w-12 text-center text-sm font-medium", children: item.quantity }),
681
+ /* @__PURE__ */ jsx(
682
+ "button",
683
+ {
684
+ type: "button",
685
+ className: "w-8 h-8 flex items-center justify-center rounded-md border border-gray-300 bg-white text-gray-600 hover:bg-gray-50",
686
+ "aria-label": "Increase quantity",
687
+ children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" }) })
688
+ }
689
+ )
690
+ ] }) : /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600", children: [
691
+ "Qty: ",
692
+ item.quantity
693
+ ] }),
694
+ showRemoveButton && /* @__PURE__ */ jsx(
695
+ "button",
696
+ {
697
+ type: "button",
698
+ className: "text-sm text-red-600 hover:text-red-800",
699
+ children: "Remove"
700
+ }
701
+ )
702
+ ] })
703
+ ] })
704
+ ] }) }, item.id)) }),
705
+ /* @__PURE__ */ jsx("div", { className: "lg:col-span-1", children: /* @__PURE__ */ jsxs(Card, { className: "p-6 sticky top-4", children: [
706
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-4", children: "Order Summary" }),
707
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
708
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
709
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Subtotal" }),
710
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
711
+ currencySymbol,
712
+ cart.subtotal.toFixed(2)
713
+ ] })
714
+ ] }),
715
+ cart.discount > 0,
716
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
717
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Shipping" }),
718
+ /* @__PURE__ */ jsx("span", { className: "text-gray-900", children: "Free" })
719
+ ] }),
720
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
721
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Tax" }),
722
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
723
+ currencySymbol,
724
+ cart.tax.toFixed(2)
725
+ ] })
726
+ ] }),
727
+ /* @__PURE__ */ jsx("div", { className: "border-t pt-3 mt-3", children: /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
728
+ /* @__PURE__ */ jsx("span", { className: "text-base font-semibold text-gray-900", children: "Total" }),
729
+ /* @__PURE__ */ jsxs("span", { className: "text-xl font-bold text-gray-900", children: [
730
+ currencySymbol,
731
+ cart.total.toFixed(2)
732
+ ] })
733
+ ] }) })
734
+ ] }),
735
+ /* @__PURE__ */ jsx("div", { className: "mt-6", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
736
+ /* @__PURE__ */ jsx(
737
+ "input",
738
+ {
739
+ type: "text",
740
+ placeholder: "Coupon code",
741
+ className: "flex-1 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
742
+ }
743
+ ),
744
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", children: "Apply" })
745
+ ] }) }),
746
+ /* @__PURE__ */ jsx("div", { className: "mt-6", children: /* @__PURE__ */ jsx(LinkButton, { href: checkoutUrl, className: "w-full", size: "lg", children: "Proceed to Checkout" }) }),
747
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 pt-6 border-t", children: [
748
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-4 text-gray-400", children: [
749
+ /* @__PURE__ */ jsx("svg", { className: "w-8 h-8", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { d: "M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z" }) }),
750
+ /* @__PURE__ */ jsx("svg", { className: "w-8 h-8", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { d: "M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z" }) })
751
+ ] }),
752
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 text-center mt-2", children: "Secure checkout with SSL encryption" })
753
+ ] })
754
+ ] }) })
755
+ ] })
756
+ ] });
757
+ }
758
+ var MOCK_CART2 = {
759
+ items: [
760
+ {
761
+ id: "item_001",
762
+ product: {
763
+ id: "prod_001",
764
+ name: "Wireless Bluetooth Headphones",
765
+ slug: "wireless-bluetooth-headphones",
766
+ price: 149.99,
767
+ images: ["/placeholder-product.jpg"],
768
+ inStock: true
769
+ },
770
+ quantity: 1,
771
+ price: 149.99
772
+ },
773
+ {
774
+ id: "item_002",
775
+ product: {
776
+ id: "prod_002",
777
+ name: "USB-C Charging Cable",
778
+ slug: "usb-c-charging-cable",
779
+ price: 24.99,
780
+ images: ["/placeholder-product.jpg"],
781
+ inStock: true
782
+ },
783
+ quantity: 2,
784
+ price: 24.99
785
+ }
786
+ ],
787
+ itemCount: 3,
788
+ subtotal: 199.97,
789
+ shipping: 0,
790
+ total: 215.97,
791
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
792
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
793
+ };
794
+ function LinkButton2({ href, children, variant = "primary", size = "md", className = "" }) {
795
+ const baseStyles = "inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2";
796
+ const variantStyles = variant === "primary" ? "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500" : "bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500 border border-gray-300";
797
+ const sizeStyles = size === "sm" ? "px-3 py-1.5 text-sm" : size === "lg" ? "px-6 py-3 text-base" : "px-4 py-2 text-sm";
798
+ return /* @__PURE__ */ jsx("a", { href, className: `${baseStyles} ${variantStyles} ${sizeStyles} ${className}`, children });
799
+ }
800
+ async function CartSummary({
801
+ // API config - will be used when connected to real API
802
+ baseUrl: _baseUrl,
803
+ apiKey: _apiKey,
804
+ accessToken: _accessToken,
805
+ projectId: _projectId,
806
+ userId: _userId,
807
+ cartId: _cartId,
808
+ // Display options
809
+ variant = "compact",
810
+ showBadge = true,
811
+ showTotal = true,
812
+ cartUrl = "/cart",
813
+ checkoutUrl = "/checkout",
814
+ currencySymbol = "$",
815
+ className = ""
816
+ }) {
817
+ const cart = MOCK_CART2;
818
+ if (variant === "mini") {
819
+ return /* @__PURE__ */ jsxs(
820
+ "a",
821
+ {
822
+ href: cartUrl,
823
+ className: `relative inline-flex items-center justify-center p-2 text-gray-600 hover:text-gray-900 ${className}`,
824
+ children: [
825
+ /* @__PURE__ */ jsx("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx(
826
+ "path",
827
+ {
828
+ strokeLinecap: "round",
829
+ strokeLinejoin: "round",
830
+ strokeWidth: 2,
831
+ d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"
832
+ }
833
+ ) }),
834
+ showBadge && cart.itemCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 w-5 h-5 flex items-center justify-center text-xs font-bold text-white bg-blue-600 rounded-full", children: cart.itemCount })
835
+ ]
836
+ }
837
+ );
838
+ }
839
+ if (variant === "compact") {
840
+ return /* @__PURE__ */ jsxs(
841
+ "a",
842
+ {
843
+ href: cartUrl,
844
+ className: `inline-flex items-center gap-2 px-3 py-2 text-sm text-gray-600 hover:text-gray-900 rounded-lg hover:bg-gray-100 transition-colors ${className}`,
845
+ children: [
846
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
847
+ /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx(
848
+ "path",
849
+ {
850
+ strokeLinecap: "round",
851
+ strokeLinejoin: "round",
852
+ strokeWidth: 2,
853
+ d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"
854
+ }
855
+ ) }),
856
+ showBadge && cart.itemCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-2 -right-2 w-4 h-4 flex items-center justify-center text-[10px] font-bold text-white bg-blue-600 rounded-full", children: cart.itemCount })
857
+ ] }),
858
+ showTotal && cart.total > 0 && /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
859
+ currencySymbol,
860
+ cart.total.toFixed(2)
861
+ ] })
862
+ ]
863
+ }
864
+ );
865
+ }
866
+ return /* @__PURE__ */ jsxs(Card, { className: `p-4 w-80 ${className}`, children: [
867
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
868
+ /* @__PURE__ */ jsxs("h3", { className: "text-sm font-semibold text-gray-900", children: [
869
+ "Cart (",
870
+ cart.itemCount,
871
+ " ",
872
+ "items",
873
+ ")"
874
+ ] }),
875
+ /* @__PURE__ */ jsx("a", { href: cartUrl, className: "text-xs text-blue-600 hover:text-blue-800", children: "View All" })
876
+ ] }),
877
+ cart.items.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 text-center py-4", children: "Your cart is empty" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
878
+ /* @__PURE__ */ jsx("div", { className: "space-y-3 mb-4", children: cart.items.slice(0, 3).map((item) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
879
+ /* @__PURE__ */ jsx("div", { className: "w-12 h-12 bg-gray-100 rounded-md overflow-hidden flex-shrink-0", children: /* @__PURE__ */ jsx(
880
+ "img",
881
+ {
882
+ src: item.product.images[0] || "/placeholder-product.jpg",
883
+ alt: item.product.name,
884
+ className: "w-full h-full object-cover"
885
+ }
886
+ ) }),
887
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
888
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 truncate", children: item.product.name }),
889
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500", children: [
890
+ "Qty: ",
891
+ item.quantity,
892
+ " \xD7 ",
893
+ currencySymbol,
894
+ item.price.toFixed(2)
895
+ ] })
896
+ ] }),
897
+ /* @__PURE__ */ jsxs("p", { className: "text-sm font-medium text-gray-900", children: [
898
+ currencySymbol,
899
+ (item.price * item.quantity).toFixed(2)
900
+ ] })
901
+ ] }, item.id)) }),
902
+ cart.items.length > 3 && /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 text-center mb-4", children: [
903
+ "+",
904
+ cart.items.length - 3,
905
+ " more ",
906
+ cart.items.length - 3 === 1 ? "item" : "items"
907
+ ] }),
908
+ /* @__PURE__ */ jsxs("div", { className: "border-t pt-4 space-y-2", children: [
909
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
910
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Subtotal" }),
911
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
912
+ currencySymbol,
913
+ cart.subtotal.toFixed(2)
914
+ ] })
915
+ ] }),
916
+ cart.shipping > 0,
917
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm font-semibold", children: [
918
+ /* @__PURE__ */ jsx("span", { className: "text-gray-900", children: "Total" }),
919
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
920
+ currencySymbol,
921
+ cart.total.toFixed(2)
922
+ ] })
923
+ ] })
924
+ ] }),
925
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-2", children: [
926
+ /* @__PURE__ */ jsx(LinkButton2, { href: checkoutUrl, className: "w-full", size: "sm", children: "Checkout" }),
927
+ /* @__PURE__ */ jsx(LinkButton2, { href: cartUrl, variant: "secondary", className: "w-full", size: "sm", children: "View Cart" })
928
+ ] })
929
+ ] })
930
+ ] });
931
+ }
932
+ var MOCK_CART3 = {
933
+ items: [
934
+ {
935
+ id: "item_001",
936
+ product: {
937
+ id: "prod_001",
938
+ name: "Wireless Bluetooth Headphones",
939
+ slug: "wireless-bluetooth-headphones",
940
+ price: 149.99,
941
+ images: ["/placeholder-product.jpg"],
942
+ inStock: true
943
+ },
944
+ quantity: 1,
945
+ price: 149.99
946
+ },
947
+ {
948
+ id: "item_002",
949
+ product: {
950
+ id: "prod_002",
951
+ name: "USB-C Charging Cable (2-Pack)",
952
+ slug: "usb-c-charging-cable",
953
+ price: 24.99,
954
+ images: ["/placeholder-product.jpg"],
955
+ inStock: true
956
+ },
957
+ quantity: 2,
958
+ price: 24.99
959
+ }
960
+ ],
961
+ subtotal: 199.97,
962
+ tax: 16,
963
+ shipping: 9.99,
964
+ discount: 0,
965
+ total: 225.96,
966
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
967
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
968
+ };
969
+ var MOCK_ADDRESSES = [
970
+ {
971
+ id: "addr_001",
972
+ firstName: "John",
973
+ lastName: "Doe",
974
+ address1: "123 Main Street",
975
+ address2: "Apt 4B",
976
+ city: "New York",
977
+ state: "NY",
978
+ postalCode: "10001",
979
+ country: "US",
980
+ phone: "+1 (555) 123-4567",
981
+ isDefault: true
982
+ }
983
+ ];
984
+ var MOCK_SHIPPING_METHODS = [
985
+ {
986
+ id: "ship_001",
987
+ name: "Standard Shipping",
988
+ description: "Delivered in 5-7 business days",
989
+ price: 9.99,
990
+ estimatedDays: "5-7 business days",
991
+ carrier: "USPS"
992
+ },
993
+ {
994
+ id: "ship_002",
995
+ name: "Express Shipping",
996
+ description: "Delivered in 2-3 business days",
997
+ price: 19.99,
998
+ estimatedDays: "2-3 business days",
999
+ carrier: "FedEx"
1000
+ },
1001
+ {
1002
+ id: "ship_003",
1003
+ name: "Next Day Delivery",
1004
+ description: "Delivered by tomorrow",
1005
+ price: 34.99,
1006
+ estimatedDays: "1 business day",
1007
+ carrier: "UPS"
1008
+ }
1009
+ ];
1010
+ var DEFAULT_COUNTRIES = [
1011
+ { code: "US", name: "United States" },
1012
+ { code: "CA", name: "Canada" },
1013
+ { code: "GB", name: "United Kingdom" },
1014
+ { code: "DE", name: "Germany" },
1015
+ { code: "FR", name: "France" },
1016
+ { code: "AU", name: "Australia" }
1017
+ ];
1018
+ var CHECKOUT_STEPS = [
1019
+ { id: "shipping", title: "Shipping", description: "Enter your address", completed: false, active: true },
1020
+ { id: "delivery", title: "Delivery", description: "Choose shipping method", completed: false, active: false },
1021
+ { id: "payment", title: "Payment", description: "Enter payment details", completed: false, active: false },
1022
+ { id: "review", title: "Review", description: "Confirm your order", completed: false, active: false }
1023
+ ];
1024
+ function LinkButton3({ href, children, variant = "primary", size = "md", className = "" }) {
1025
+ const baseStyles = "inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2";
1026
+ const variantStyles = variant === "primary" ? "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500" : "bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500 border border-gray-300";
1027
+ const sizeStyles = size === "sm" ? "px-3 py-1.5 text-sm" : size === "lg" ? "px-6 py-3 text-base" : "px-4 py-2 text-sm";
1028
+ return /* @__PURE__ */ jsx("a", { href, className: `${baseStyles} ${variantStyles} ${sizeStyles} ${className}`, children });
1029
+ }
1030
+ async function Checkout({
1031
+ // API config - will be used when connected to real API
1032
+ baseUrl: _baseUrl,
1033
+ apiKey: _apiKey,
1034
+ accessToken: _accessToken,
1035
+ projectId: _projectId,
1036
+ userId: _userId,
1037
+ cartId: _cartId,
1038
+ // Display options
1039
+ step = 1,
1040
+ showOrderSummary = true,
1041
+ showStepIndicator = true,
1042
+ successUrl: _successUrl = "/order-confirmation",
1043
+ cancelUrl = "/cart",
1044
+ currencySymbol = "$",
1045
+ shippingMethods,
1046
+ savedAddresses,
1047
+ allowGuestCheckout: _allowGuestCheckout = true,
1048
+ requirePhone = false,
1049
+ countries = DEFAULT_COUNTRIES,
1050
+ className = ""
1051
+ }) {
1052
+ const cart = MOCK_CART3;
1053
+ const addresses = savedAddresses || MOCK_ADDRESSES;
1054
+ const shipping = shippingMethods || MOCK_SHIPPING_METHODS;
1055
+ const steps = CHECKOUT_STEPS.map((s, i) => ({
1056
+ ...s,
1057
+ completed: i < step - 1,
1058
+ active: i === step - 1
1059
+ }));
1060
+ if (!cart || cart.items.length === 0) {
1061
+ return /* @__PURE__ */ jsxs(Alert, { variant: "warning", className, children: [
1062
+ /* @__PURE__ */ jsx("p", { className: "font-medium", children: "Your cart is empty" }),
1063
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm", children: "Add some items before checking out." }),
1064
+ /* @__PURE__ */ jsx(LinkButton3, { href: cancelUrl, variant: "secondary", size: "sm", className: "mt-3", children: "Return to Cart" })
1065
+ ] });
1066
+ }
1067
+ return /* @__PURE__ */ jsxs("div", { className: `space-y-6 ${className}`, children: [
1068
+ showStepIndicator && /* @__PURE__ */ jsx("nav", { "aria-label": "Checkout progress", className: "mb-8", children: /* @__PURE__ */ jsx("ol", { className: "flex items-center justify-between", children: steps.map((s, index) => /* @__PURE__ */ jsxs("li", { className: "flex items-center", children: [
1069
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
1070
+ /* @__PURE__ */ jsx(
1071
+ "span",
1072
+ {
1073
+ className: `
1074
+ flex items-center justify-center w-10 h-10 rounded-full text-sm font-semibold
1075
+ ${s.completed ? "bg-green-500 text-white" : s.active ? "bg-blue-600 text-white" : "bg-gray-200 text-gray-500"}
1076
+ `,
1077
+ children: s.completed ? /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : index + 1
1078
+ }
1079
+ ),
1080
+ /* @__PURE__ */ jsxs("div", { className: "ml-3 hidden sm:block", children: [
1081
+ /* @__PURE__ */ jsx("p", { className: `text-sm font-medium ${s.active ? "text-blue-600" : "text-gray-900"}`, children: s.title }),
1082
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: s.description })
1083
+ ] })
1084
+ ] }),
1085
+ index < steps.length - 1 && /* @__PURE__ */ jsx("div", { className: `w-12 sm:w-24 h-0.5 mx-2 sm:mx-4 ${s.completed ? "bg-green-500" : "bg-gray-200"}` })
1086
+ ] }, s.id)) }) }),
1087
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8", children: [
1088
+ /* @__PURE__ */ jsxs("div", { className: "lg:col-span-2", children: [
1089
+ step === 1 && /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1090
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900 mb-6", children: "Shipping Address" }),
1091
+ addresses.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
1092
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-700 mb-3", children: "Saved Addresses" }),
1093
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: addresses.map((addr) => /* @__PURE__ */ jsxs(
1094
+ "label",
1095
+ {
1096
+ className: "flex items-start gap-3 p-4 border rounded-lg cursor-pointer hover:border-blue-500 transition-colors",
1097
+ children: [
1098
+ /* @__PURE__ */ jsx(
1099
+ "input",
1100
+ {
1101
+ type: "radio",
1102
+ name: "address",
1103
+ value: addr.id,
1104
+ defaultChecked: addr.isDefault,
1105
+ className: "mt-1"
1106
+ }
1107
+ ),
1108
+ /* @__PURE__ */ jsxs("div", { children: [
1109
+ /* @__PURE__ */ jsxs("p", { className: "font-medium text-gray-900", children: [
1110
+ addr.firstName,
1111
+ " ",
1112
+ addr.lastName
1113
+ ] }),
1114
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-600", children: [
1115
+ addr.address1,
1116
+ addr.address2 && `, ${addr.address2}`
1117
+ ] }),
1118
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-600", children: [
1119
+ addr.city,
1120
+ ", ",
1121
+ addr.state,
1122
+ " ",
1123
+ addr.postalCode
1124
+ ] }),
1125
+ addr.phone && /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: addr.phone })
1126
+ ] })
1127
+ ]
1128
+ },
1129
+ addr.id
1130
+ )) })
1131
+ ] }),
1132
+ /* @__PURE__ */ jsxs("div", { children: [
1133
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-700 mb-3", children: addresses.length > 0 ? "Or enter a new address" : "Enter your address" }),
1134
+ /* @__PURE__ */ jsxs("form", { className: "space-y-4", children: [
1135
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [
1136
+ /* @__PURE__ */ jsxs("div", { children: [
1137
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "First Name" }),
1138
+ /* @__PURE__ */ jsx(
1139
+ "input",
1140
+ {
1141
+ type: "text",
1142
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1143
+ placeholder: "John"
1144
+ }
1145
+ )
1146
+ ] }),
1147
+ /* @__PURE__ */ jsxs("div", { children: [
1148
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Last Name" }),
1149
+ /* @__PURE__ */ jsx(
1150
+ "input",
1151
+ {
1152
+ type: "text",
1153
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1154
+ placeholder: "Doe"
1155
+ }
1156
+ )
1157
+ ] })
1158
+ ] }),
1159
+ /* @__PURE__ */ jsxs("div", { children: [
1160
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Address" }),
1161
+ /* @__PURE__ */ jsx(
1162
+ "input",
1163
+ {
1164
+ type: "text",
1165
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1166
+ placeholder: "123 Main Street"
1167
+ }
1168
+ )
1169
+ ] }),
1170
+ /* @__PURE__ */ jsxs("div", { children: [
1171
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Apartment, suite, etc. (optional)" }),
1172
+ /* @__PURE__ */ jsx(
1173
+ "input",
1174
+ {
1175
+ type: "text",
1176
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1177
+ placeholder: "Apt 4B"
1178
+ }
1179
+ )
1180
+ ] }),
1181
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-4", children: [
1182
+ /* @__PURE__ */ jsxs("div", { className: "col-span-2 sm:col-span-1", children: [
1183
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "City" }),
1184
+ /* @__PURE__ */ jsx(
1185
+ "input",
1186
+ {
1187
+ type: "text",
1188
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1189
+ placeholder: "New York"
1190
+ }
1191
+ )
1192
+ ] }),
1193
+ /* @__PURE__ */ jsxs("div", { children: [
1194
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "State" }),
1195
+ /* @__PURE__ */ jsx(
1196
+ "input",
1197
+ {
1198
+ type: "text",
1199
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1200
+ placeholder: "NY"
1201
+ }
1202
+ )
1203
+ ] }),
1204
+ /* @__PURE__ */ jsxs("div", { children: [
1205
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "ZIP Code" }),
1206
+ /* @__PURE__ */ jsx(
1207
+ "input",
1208
+ {
1209
+ type: "text",
1210
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1211
+ placeholder: "10001"
1212
+ }
1213
+ )
1214
+ ] })
1215
+ ] }),
1216
+ /* @__PURE__ */ jsxs("div", { children: [
1217
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Country" }),
1218
+ /* @__PURE__ */ jsx("select", { className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500", children: countries.map((c) => /* @__PURE__ */ jsx("option", { value: c.code, children: c.name }, c.code)) })
1219
+ ] }),
1220
+ requirePhone && /* @__PURE__ */ jsxs("div", { children: [
1221
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Phone Number" }),
1222
+ /* @__PURE__ */ jsx(
1223
+ "input",
1224
+ {
1225
+ type: "tel",
1226
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1227
+ placeholder: "+1 (555) 123-4567"
1228
+ }
1229
+ )
1230
+ ] })
1231
+ ] })
1232
+ ] }),
1233
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 flex justify-between", children: [
1234
+ /* @__PURE__ */ jsx(LinkButton3, { href: cancelUrl, variant: "secondary", children: "Back to Cart" }),
1235
+ /* @__PURE__ */ jsx(Button, { children: "Continue to Delivery" })
1236
+ ] })
1237
+ ] }),
1238
+ step === 2 && /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1239
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900 mb-6", children: "Delivery Method" }),
1240
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: shipping.map((method, index) => /* @__PURE__ */ jsxs(
1241
+ "label",
1242
+ {
1243
+ className: "flex items-center justify-between p-4 border rounded-lg cursor-pointer hover:border-blue-500 transition-colors",
1244
+ children: [
1245
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1246
+ /* @__PURE__ */ jsx(
1247
+ "input",
1248
+ {
1249
+ type: "radio",
1250
+ name: "shipping",
1251
+ value: method.id,
1252
+ defaultChecked: index === 0
1253
+ }
1254
+ ),
1255
+ /* @__PURE__ */ jsxs("div", { children: [
1256
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-gray-900", children: method.name }),
1257
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600", children: method.description }),
1258
+ method.carrier && /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500", children: [
1259
+ "via ",
1260
+ method.carrier
1261
+ ] })
1262
+ ] })
1263
+ ] }),
1264
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-gray-900", children: method.price === 0 ? "Free" : `${currencySymbol}${method.price.toFixed(2)}` })
1265
+ ]
1266
+ },
1267
+ method.id
1268
+ )) }),
1269
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 flex justify-between", children: [
1270
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Back" }),
1271
+ /* @__PURE__ */ jsx(Button, { children: "Continue to Payment" })
1272
+ ] })
1273
+ ] }),
1274
+ step === 3 && /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1275
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900 mb-6", children: "Payment Method" }),
1276
+ /* @__PURE__ */ jsxs("form", { className: "space-y-6", children: [
1277
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
1278
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 p-4 border rounded-lg cursor-pointer hover:border-blue-500 border-blue-500 bg-blue-50", children: [
1279
+ /* @__PURE__ */ jsx("input", { type: "radio", name: "payment_type", value: "card", defaultChecked: true }),
1280
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1281
+ /* @__PURE__ */ jsx("svg", { className: "w-8 h-8 text-gray-600", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { d: "M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z" }) }),
1282
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Credit / Debit Card" })
1283
+ ] })
1284
+ ] }),
1285
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 p-4 border rounded-lg cursor-pointer hover:border-blue-500", children: [
1286
+ /* @__PURE__ */ jsx("input", { type: "radio", name: "payment_type", value: "paypal" }),
1287
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1288
+ /* @__PURE__ */ jsx("svg", { className: "w-8 h-8", viewBox: "0 0 24 24", fill: "#003087", children: /* @__PURE__ */ jsx("path", { d: "M7.076 21.337H2.47a.641.641 0 0 1-.633-.74L4.944.901C5.026.382 5.474 0 5.998 0h7.46c2.57 0 4.578.543 5.69 1.81 1.01 1.15 1.304 2.42 1.012 4.287-.023.143-.047.288-.077.437-.983 5.05-4.349 6.797-8.647 6.797h-2.19c-.524 0-.968.382-1.05.9l-1.12 7.106z" }) }),
1289
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: "PayPal" })
1290
+ ] })
1291
+ ] })
1292
+ ] }),
1293
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1294
+ /* @__PURE__ */ jsxs("div", { children: [
1295
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Card Number" }),
1296
+ /* @__PURE__ */ jsx(
1297
+ "input",
1298
+ {
1299
+ type: "text",
1300
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1301
+ placeholder: "1234 5678 9012 3456"
1302
+ }
1303
+ )
1304
+ ] }),
1305
+ /* @__PURE__ */ jsxs("div", { children: [
1306
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Name on Card" }),
1307
+ /* @__PURE__ */ jsx(
1308
+ "input",
1309
+ {
1310
+ type: "text",
1311
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1312
+ placeholder: "John Doe"
1313
+ }
1314
+ )
1315
+ ] }),
1316
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
1317
+ /* @__PURE__ */ jsxs("div", { children: [
1318
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Expiry Date" }),
1319
+ /* @__PURE__ */ jsx(
1320
+ "input",
1321
+ {
1322
+ type: "text",
1323
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1324
+ placeholder: "MM/YY"
1325
+ }
1326
+ )
1327
+ ] }),
1328
+ /* @__PURE__ */ jsxs("div", { children: [
1329
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "CVC" }),
1330
+ /* @__PURE__ */ jsx(
1331
+ "input",
1332
+ {
1333
+ type: "text",
1334
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1335
+ placeholder: "123"
1336
+ }
1337
+ )
1338
+ ] })
1339
+ ] })
1340
+ ] }),
1341
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
1342
+ /* @__PURE__ */ jsx("input", { type: "checkbox", defaultChecked: true }),
1343
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-700", children: "Billing address same as shipping" })
1344
+ ] }) })
1345
+ ] }),
1346
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 flex justify-between", children: [
1347
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Back" }),
1348
+ /* @__PURE__ */ jsx(Button, { children: "Review Order" })
1349
+ ] })
1350
+ ] }),
1351
+ step === 4 && /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1352
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900 mb-6", children: "Review Your Order" }),
1353
+ /* @__PURE__ */ jsxs("div", { className: "mb-6 p-4 bg-gray-50 rounded-lg", children: [
1354
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-start mb-2", children: [
1355
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-900", children: "Shipping Address" }),
1356
+ /* @__PURE__ */ jsx("button", { className: "text-sm text-blue-600 hover:text-blue-800", children: "Edit" })
1357
+ ] }),
1358
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-600", children: [
1359
+ "John Doe",
1360
+ /* @__PURE__ */ jsx("br", {}),
1361
+ "123 Main Street, Apt 4B",
1362
+ /* @__PURE__ */ jsx("br", {}),
1363
+ "New York, NY 10001",
1364
+ /* @__PURE__ */ jsx("br", {}),
1365
+ "United States"
1366
+ ] })
1367
+ ] }),
1368
+ /* @__PURE__ */ jsxs("div", { className: "mb-6 p-4 bg-gray-50 rounded-lg", children: [
1369
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-start mb-2", children: [
1370
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-900", children: "Delivery Method" }),
1371
+ /* @__PURE__ */ jsx("button", { className: "text-sm text-blue-600 hover:text-blue-800", children: "Edit" })
1372
+ ] }),
1373
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-600", children: [
1374
+ "Standard Shipping - ",
1375
+ currencySymbol,
1376
+ "9.99",
1377
+ /* @__PURE__ */ jsx("br", {}),
1378
+ "Estimated delivery: 5-7 business days"
1379
+ ] })
1380
+ ] }),
1381
+ /* @__PURE__ */ jsxs("div", { className: "mb-6 p-4 bg-gray-50 rounded-lg", children: [
1382
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-start mb-2", children: [
1383
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-900", children: "Payment Method" }),
1384
+ /* @__PURE__ */ jsx("button", { className: "text-sm text-blue-600 hover:text-blue-800", children: "Edit" })
1385
+ ] }),
1386
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-600", children: [
1387
+ "Credit Card ending in 3456",
1388
+ /* @__PURE__ */ jsx("br", {}),
1389
+ "Expires 12/25"
1390
+ ] })
1391
+ ] }),
1392
+ /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
1393
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-900 mb-3", children: "Order Items" }),
1394
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: cart.items.map((item) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 py-3 border-b last:border-0", children: [
1395
+ /* @__PURE__ */ jsx("div", { className: "w-16 h-16 bg-gray-100 rounded-md overflow-hidden", children: /* @__PURE__ */ jsx(
1396
+ "img",
1397
+ {
1398
+ src: item.product.images[0] || "/placeholder-product.jpg",
1399
+ alt: item.product.name,
1400
+ className: "w-full h-full object-cover"
1401
+ }
1402
+ ) }),
1403
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
1404
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-gray-900", children: item.product.name }),
1405
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500", children: [
1406
+ "Qty: ",
1407
+ item.quantity
1408
+ ] })
1409
+ ] }),
1410
+ /* @__PURE__ */ jsxs("p", { className: "font-medium text-gray-900", children: [
1411
+ currencySymbol,
1412
+ (item.price * item.quantity).toFixed(2)
1413
+ ] })
1414
+ ] }, item.id)) })
1415
+ ] }),
1416
+ /* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsxs("label", { className: "flex items-start gap-2", children: [
1417
+ /* @__PURE__ */ jsx("input", { type: "checkbox", className: "mt-1" }),
1418
+ /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600", children: [
1419
+ "I agree to the",
1420
+ " ",
1421
+ /* @__PURE__ */ jsx("a", { href: "/terms", className: "text-blue-600 hover:text-blue-800", children: "Terms of Service" }),
1422
+ " ",
1423
+ "and",
1424
+ " ",
1425
+ /* @__PURE__ */ jsx("a", { href: "/privacy", className: "text-blue-600 hover:text-blue-800", children: "Privacy Policy" })
1426
+ ] })
1427
+ ] }) }),
1428
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
1429
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Back" }),
1430
+ /* @__PURE__ */ jsxs(Button, { size: "lg", children: [
1431
+ "Place Order - ",
1432
+ currencySymbol,
1433
+ cart.total.toFixed(2)
1434
+ ] })
1435
+ ] })
1436
+ ] })
1437
+ ] }),
1438
+ showOrderSummary && /* @__PURE__ */ jsx("div", { className: "lg:col-span-1", children: /* @__PURE__ */ jsxs(Card, { className: "p-6 sticky top-4", children: [
1439
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-4", children: "Order Summary" }),
1440
+ /* @__PURE__ */ jsx("div", { className: "space-y-3 mb-4", children: cart.items.map((item) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1441
+ /* @__PURE__ */ jsxs("div", { className: "relative w-12 h-12 bg-gray-100 rounded-md overflow-hidden flex-shrink-0", children: [
1442
+ /* @__PURE__ */ jsx(
1443
+ "img",
1444
+ {
1445
+ src: item.product.images[0] || "/placeholder-product.jpg",
1446
+ alt: item.product.name,
1447
+ className: "w-full h-full object-cover"
1448
+ }
1449
+ ),
1450
+ /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 w-5 h-5 flex items-center justify-center text-xs font-bold text-white bg-gray-600 rounded-full", children: item.quantity })
1451
+ ] }),
1452
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 truncate", children: item.product.name }) }),
1453
+ /* @__PURE__ */ jsxs("p", { className: "text-sm font-medium text-gray-900", children: [
1454
+ currencySymbol,
1455
+ (item.price * item.quantity).toFixed(2)
1456
+ ] })
1457
+ ] }, item.id)) }),
1458
+ /* @__PURE__ */ jsxs("div", { className: "border-t pt-4 space-y-2", children: [
1459
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
1460
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Subtotal" }),
1461
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
1462
+ currencySymbol,
1463
+ cart.subtotal.toFixed(2)
1464
+ ] })
1465
+ ] }),
1466
+ cart.discount > 0,
1467
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
1468
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Shipping" }),
1469
+ /* @__PURE__ */ jsx("span", { className: "text-gray-900", children: `${currencySymbol}${cart.shipping.toFixed(2)}` })
1470
+ ] }),
1471
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
1472
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Tax" }),
1473
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
1474
+ currencySymbol,
1475
+ cart.tax.toFixed(2)
1476
+ ] })
1477
+ ] }),
1478
+ /* @__PURE__ */ jsx("div", { className: "border-t pt-3 mt-3", children: /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
1479
+ /* @__PURE__ */ jsx("span", { className: "text-base font-semibold text-gray-900", children: "Total" }),
1480
+ /* @__PURE__ */ jsxs("span", { className: "text-xl font-bold text-gray-900", children: [
1481
+ currencySymbol,
1482
+ cart.total.toFixed(2)
1483
+ ] })
1484
+ ] }) })
1485
+ ] })
1486
+ ] }) })
1487
+ ] })
1488
+ ] });
1489
+ }
1490
+ var MOCK_ORDER = {
1491
+ orderNumber: "ORD-2024-001234",
1492
+ email: "john.doe@example.com",
1493
+ status: "processing",
1494
+ items: [
1495
+ {
1496
+ id: "item_001",
1497
+ product: {
1498
+ id: "prod_001",
1499
+ name: "Wireless Bluetooth Headphones",
1500
+ slug: "wireless-bluetooth-headphones",
1501
+ price: 149.99,
1502
+ images: ["/placeholder-product.jpg"],
1503
+ inStock: true
1504
+ },
1505
+ quantity: 1,
1506
+ price: 149.99
1507
+ },
1508
+ {
1509
+ id: "item_002",
1510
+ product: {
1511
+ id: "prod_002",
1512
+ name: "USB-C Charging Cable (2-Pack)",
1513
+ slug: "usb-c-charging-cable",
1514
+ price: 24.99,
1515
+ images: ["/placeholder-product.jpg"],
1516
+ inStock: true
1517
+ },
1518
+ quantity: 2,
1519
+ price: 24.99
1520
+ }
1521
+ ],
1522
+ subtotal: 199.97,
1523
+ tax: 16,
1524
+ shipping: 9.99,
1525
+ discount: 0,
1526
+ total: 225.96,
1527
+ shippingAddress: {
1528
+ firstName: "John",
1529
+ lastName: "Doe",
1530
+ address1: "123 Main Street",
1531
+ address2: "Apt 4B",
1532
+ city: "New York",
1533
+ state: "NY",
1534
+ postalCode: "10001",
1535
+ country: "US",
1536
+ phone: "+1 (555) 123-4567"
1537
+ },
1538
+ billingAddress: {
1539
+ firstName: "John",
1540
+ lastName: "Doe",
1541
+ address1: "123 Main Street",
1542
+ address2: "Apt 4B",
1543
+ city: "New York",
1544
+ state: "NY",
1545
+ postalCode: "10001",
1546
+ country: "US"
1547
+ },
1548
+ shippingMethod: {
1549
+ name: "Standard Shipping",
1550
+ estimatedDays: "5-7 business days",
1551
+ carrier: "USPS"
1552
+ },
1553
+ paymentMethod: {
1554
+ last4: "3456",
1555
+ brand: "Visa",
1556
+ expiryMonth: 12,
1557
+ expiryYear: 2025
1558
+ },
1559
+ trackingNumber: "9400111899223456789012",
1560
+ trackingUrl: "https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899223456789012",
1561
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1562
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1563
+ };
1564
+ var STATUS_CONFIG = {
1565
+ pending: { label: "Pending", color: "text-yellow-600 bg-yellow-100" },
1566
+ processing: { label: "Processing", color: "text-blue-600 bg-blue-100" },
1567
+ shipped: { label: "Shipped", color: "text-purple-600 bg-purple-100" },
1568
+ delivered: { label: "Delivered", color: "text-green-600 bg-green-100" },
1569
+ cancelled: { label: "Cancelled", color: "text-red-600 bg-red-100" },
1570
+ refunded: { label: "Refunded", color: "text-gray-600 bg-gray-100" }
1571
+ };
1572
+ function LinkButton4({ href, children, variant = "primary", size = "md", className = "", target, rel }) {
1573
+ const baseStyles = "inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2";
1574
+ const variantStyles = variant === "primary" ? "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500" : "bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500 border border-gray-300";
1575
+ const sizeStyles = size === "sm" ? "px-3 py-1.5 text-sm" : size === "lg" ? "px-6 py-3 text-base" : "px-4 py-2 text-sm";
1576
+ return /* @__PURE__ */ jsx("a", { href, className: `${baseStyles} ${variantStyles} ${sizeStyles} ${className}`, target, rel, children });
1577
+ }
1578
+ async function OrderConfirmation({
1579
+ // API config - will be used when connected to real API
1580
+ baseUrl: _baseUrl,
1581
+ apiKey: _apiKey,
1582
+ accessToken: _accessToken,
1583
+ projectId: _projectId,
1584
+ // Required props
1585
+ orderId,
1586
+ // Display options
1587
+ showItems = true,
1588
+ showShippingAddress = true,
1589
+ showBillingAddress = false,
1590
+ showPaymentMethod = true,
1591
+ showTimeline = true,
1592
+ continueShoppingUrl = "/products",
1593
+ trackOrderUrl,
1594
+ currencySymbol = "$",
1595
+ className = ""
1596
+ }) {
1597
+ const order = MOCK_ORDER;
1598
+ if (!order) {
1599
+ return /* @__PURE__ */ jsxs(Alert, { variant: "error", className, children: [
1600
+ /* @__PURE__ */ jsx("p", { className: "font-medium", children: "Order not found" }),
1601
+ /* @__PURE__ */ jsxs("p", { className: "mt-1 text-sm", children: [
1602
+ "We couldn't find an order with ID: ",
1603
+ orderId
1604
+ ] }),
1605
+ /* @__PURE__ */ jsx(LinkButton4, { href: continueShoppingUrl, variant: "secondary", size: "sm", className: "mt-3", children: "Continue Shopping" })
1606
+ ] });
1607
+ }
1608
+ const statusConfig = STATUS_CONFIG[order.status];
1609
+ return /* @__PURE__ */ jsxs("div", { className: `max-w-3xl mx-auto space-y-8 ${className}`, children: [
1610
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
1611
+ /* @__PURE__ */ jsx("div", { className: "mx-auto w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx("svg", { className: "w-8 h-8 text-green-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) }),
1612
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold text-gray-900 mb-2", children: "Thank you for your order!" }),
1613
+ /* @__PURE__ */ jsxs("p", { className: "text-gray-600", children: [
1614
+ "Your order ",
1615
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: order.orderNumber }),
1616
+ " has been placed successfully."
1617
+ ] }),
1618
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mt-1", children: [
1619
+ "A confirmation email has been sent to ",
1620
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: order.email })
1621
+ ] })
1622
+ ] }),
1623
+ /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1624
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-6", children: [
1625
+ /* @__PURE__ */ jsxs("div", { children: [
1626
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Order Status" }),
1627
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500", children: [
1628
+ "Order #",
1629
+ order.orderNumber
1630
+ ] })
1631
+ ] }),
1632
+ /* @__PURE__ */ jsx("span", { className: `px-3 py-1 text-sm font-medium rounded-full ${statusConfig.color}`, children: statusConfig.label })
1633
+ ] }),
1634
+ showTimeline && /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1635
+ /* @__PURE__ */ jsx("div", { className: "flex justify-between", children: ["Order Placed", "Processing", "Shipped", "Delivered"].map((step, index) => {
1636
+ const isCompleted = index <= ["pending", "processing", "shipped", "delivered"].indexOf(order.status);
1637
+ const isCurrent = index === ["pending", "processing", "shipped", "delivered"].indexOf(order.status);
1638
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center flex-1", children: [
1639
+ /* @__PURE__ */ jsx(
1640
+ "div",
1641
+ {
1642
+ className: `
1643
+ w-10 h-10 rounded-full flex items-center justify-center z-10
1644
+ ${isCompleted ? "bg-green-500 text-white" : "bg-gray-200 text-gray-500"}
1645
+ ${isCurrent ? "ring-4 ring-green-100" : ""}
1646
+ `,
1647
+ children: isCompleted ? /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: index + 1 })
1648
+ }
1649
+ ),
1650
+ /* @__PURE__ */ jsx("p", { className: `mt-2 text-xs font-medium ${isCompleted ? "text-green-600" : "text-gray-500"}`, children: step })
1651
+ ] }, step);
1652
+ }) }),
1653
+ /* @__PURE__ */ jsx("div", { className: "absolute top-5 left-0 right-0 h-0.5 bg-gray-200 -z-0", children: /* @__PURE__ */ jsx(
1654
+ "div",
1655
+ {
1656
+ className: "h-full bg-green-500 transition-all",
1657
+ style: {
1658
+ width: `${["pending", "processing", "shipped", "delivered"].indexOf(order.status) / 3 * 100}%`
1659
+ }
1660
+ }
1661
+ ) })
1662
+ ] }),
1663
+ /* @__PURE__ */ jsx("div", { className: "mt-6 p-4 bg-gray-50 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
1664
+ /* @__PURE__ */ jsxs("div", { children: [
1665
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900", children: "Tracking Number" }),
1666
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 font-mono", children: order.trackingNumber })
1667
+ ] }),
1668
+ /* @__PURE__ */ jsx(LinkButton4, { href: order.trackingUrl, target: "_blank", rel: "noopener noreferrer", size: "sm", children: "Track Package" })
1669
+ ] }) })
1670
+ ] }),
1671
+ showItems && /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1672
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-4", children: "Order Items" }),
1673
+ /* @__PURE__ */ jsx("div", { className: "space-y-4", children: order.items.map((item) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 py-3 border-b last:border-0", children: [
1674
+ /* @__PURE__ */ jsx("div", { className: "w-16 h-16 bg-gray-100 rounded-md overflow-hidden flex-shrink-0", children: /* @__PURE__ */ jsx(
1675
+ "img",
1676
+ {
1677
+ src: item.product.images[0] || "/placeholder-product.jpg",
1678
+ alt: item.product.name,
1679
+ className: "w-full h-full object-cover"
1680
+ }
1681
+ ) }),
1682
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
1683
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-gray-900", children: item.product.name }),
1684
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500", children: [
1685
+ "Qty: ",
1686
+ item.quantity
1687
+ ] })
1688
+ ] }),
1689
+ /* @__PURE__ */ jsxs("p", { className: "font-medium text-gray-900", children: [
1690
+ currencySymbol,
1691
+ (item.price * item.quantity).toFixed(2)
1692
+ ] })
1693
+ ] }, item.id)) }),
1694
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 pt-4 border-t space-y-2", children: [
1695
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
1696
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Subtotal" }),
1697
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
1698
+ currencySymbol,
1699
+ order.subtotal.toFixed(2)
1700
+ ] })
1701
+ ] }),
1702
+ order.discount > 0,
1703
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
1704
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Shipping" }),
1705
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
1706
+ currencySymbol,
1707
+ order.shipping.toFixed(2)
1708
+ ] })
1709
+ ] }),
1710
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
1711
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Tax" }),
1712
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
1713
+ currencySymbol,
1714
+ order.tax.toFixed(2)
1715
+ ] })
1716
+ ] }),
1717
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-base font-semibold pt-2 border-t", children: [
1718
+ /* @__PURE__ */ jsx("span", { className: "text-gray-900", children: "Total" }),
1719
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-900", children: [
1720
+ currencySymbol,
1721
+ order.total.toFixed(2)
1722
+ ] })
1723
+ ] })
1724
+ ] })
1725
+ ] }),
1726
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [
1727
+ showShippingAddress && /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1728
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-3", children: "Shipping Address" }),
1729
+ /* @__PURE__ */ jsxs("address", { className: "text-sm text-gray-600 not-italic", children: [
1730
+ order.shippingAddress.firstName,
1731
+ " ",
1732
+ order.shippingAddress.lastName,
1733
+ /* @__PURE__ */ jsx("br", {}),
1734
+ order.shippingAddress.address1,
1735
+ /* @__PURE__ */ jsx("br", {}),
1736
+ /* @__PURE__ */ jsxs(Fragment, { children: [
1737
+ order.shippingAddress.address2,
1738
+ /* @__PURE__ */ jsx("br", {})
1739
+ ] }),
1740
+ order.shippingAddress.city,
1741
+ ", ",
1742
+ order.shippingAddress.state,
1743
+ " ",
1744
+ order.shippingAddress.postalCode,
1745
+ /* @__PURE__ */ jsx("br", {}),
1746
+ order.shippingAddress.country,
1747
+ /* @__PURE__ */ jsxs(Fragment, { children: [
1748
+ /* @__PURE__ */ jsx("br", {}),
1749
+ /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: order.shippingAddress.phone })
1750
+ ] })
1751
+ ] })
1752
+ ] }),
1753
+ showBillingAddress && /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1754
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-3", children: "Billing Address" }),
1755
+ /* @__PURE__ */ jsxs("address", { className: "text-sm text-gray-600 not-italic", children: [
1756
+ order.billingAddress.firstName,
1757
+ " ",
1758
+ order.billingAddress.lastName,
1759
+ /* @__PURE__ */ jsx("br", {}),
1760
+ order.billingAddress.address1,
1761
+ /* @__PURE__ */ jsx("br", {}),
1762
+ /* @__PURE__ */ jsxs(Fragment, { children: [
1763
+ order.billingAddress.address2,
1764
+ /* @__PURE__ */ jsx("br", {})
1765
+ ] }),
1766
+ order.billingAddress.city,
1767
+ ", ",
1768
+ order.billingAddress.state,
1769
+ " ",
1770
+ order.billingAddress.postalCode,
1771
+ /* @__PURE__ */ jsx("br", {}),
1772
+ order.billingAddress.country
1773
+ ] })
1774
+ ] }),
1775
+ showPaymentMethod && /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1776
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-3", children: "Payment Method" }),
1777
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1778
+ /* @__PURE__ */ jsx("div", { className: "w-10 h-6 bg-gray-100 rounded flex items-center justify-center", children: /* @__PURE__ */ jsxs("svg", { className: "w-8 h-4 text-gray-600", fill: "currentColor", viewBox: "0 0 32 16", children: [
1779
+ /* @__PURE__ */ jsx("rect", { width: "32", height: "16", rx: "2", fill: "#1A1F71" }),
1780
+ /* @__PURE__ */ jsx("text", { x: "6", y: "12", fontSize: "8", fill: "white", fontFamily: "Arial, sans-serif", fontWeight: "bold", children: "VISA" })
1781
+ ] }) }),
1782
+ /* @__PURE__ */ jsxs("div", { children: [
1783
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-900", children: [
1784
+ order.paymentMethod.brand,
1785
+ " ending in ",
1786
+ order.paymentMethod.last4
1787
+ ] }),
1788
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500", children: [
1789
+ "Expires ",
1790
+ order.paymentMethod.expiryMonth,
1791
+ "/",
1792
+ order.paymentMethod.expiryYear
1793
+ ] })
1794
+ ] })
1795
+ ] })
1796
+ ] }),
1797
+ /* @__PURE__ */ jsxs(Card, { className: "p-6", children: [
1798
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-3", children: "Delivery Method" }),
1799
+ /* @__PURE__ */ jsxs("div", { children: [
1800
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-900", children: order.shippingMethod.name }),
1801
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500", children: [
1802
+ order.shippingMethod.estimatedDays,
1803
+ ` via ${order.shippingMethod.carrier}`
1804
+ ] })
1805
+ ] })
1806
+ ] })
1807
+ ] }),
1808
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row gap-4 justify-center", children: [
1809
+ /* @__PURE__ */ jsx(LinkButton4, { href: continueShoppingUrl, variant: "secondary", size: "lg", children: "Continue Shopping" }),
1810
+ trackOrderUrl && /* @__PURE__ */ jsx(LinkButton4, { href: trackOrderUrl, size: "lg", children: "View Order Details" })
1811
+ ] }),
1812
+ /* @__PURE__ */ jsx("div", { className: "text-center text-sm text-gray-500", children: /* @__PURE__ */ jsxs("p", { children: [
1813
+ "Need help?",
1814
+ " ",
1815
+ /* @__PURE__ */ jsx("a", { href: "/contact", className: "text-blue-600 hover:text-blue-800", children: "Contact our support team" })
1816
+ ] }) })
1817
+ ] });
1818
+ }
1819
+
1820
+ // src/components/server/Payment/client.ts
1821
+ function createHeaders2(config) {
1822
+ const headers = {
1823
+ "Content-Type": "application/json"
1824
+ };
1825
+ if (config.accessToken) {
1826
+ headers["Authorization"] = `Bearer ${config.accessToken}`;
1827
+ }
1828
+ if (config.apiKey) {
1829
+ headers["X-API-Key"] = config.apiKey;
1830
+ }
1831
+ return headers;
1832
+ }
1833
+ async function fetchAPI2(config, url, options = {}) {
1834
+ try {
1835
+ const response = await fetch(url, {
1836
+ ...options,
1837
+ headers: {
1838
+ ...createHeaders2(config),
1839
+ ...options.headers
1840
+ },
1841
+ cache: "no-store"
1842
+ });
1843
+ if (!response.ok) {
1844
+ try {
1845
+ const errorData = await response.json();
1846
+ return {
1847
+ success: false,
1848
+ error: errorData.error || `HTTP ${response.status}: ${response.statusText}`
1849
+ };
1850
+ } catch {
1851
+ return {
1852
+ success: false,
1853
+ error: `HTTP ${response.status}: ${response.statusText}`
1854
+ };
1855
+ }
1856
+ }
1857
+ const contentType = response.headers.get("content-type");
1858
+ if (!contentType || !contentType.includes("application/json")) {
1859
+ return {
1860
+ success: false,
1861
+ error: "Invalid response: expected JSON"
1862
+ };
1863
+ }
1864
+ const data = await response.json();
1865
+ return data;
1866
+ } catch (error) {
1867
+ return {
1868
+ success: false,
1869
+ error: error instanceof Error ? error.message : "API request failed"
1870
+ };
1871
+ }
1872
+ }
1873
+ async function fetchProducts(config, productIds) {
1874
+ const { baseUrl } = config;
1875
+ try {
1876
+ const productFilter = productIds.length === 1 ? { id: productIds[0] } : { id: { operator: "in", value: productIds } };
1877
+ const productsResult = await fetchAPI2(
1878
+ config,
1879
+ `${baseUrl}/data/products?filter=${encodeURIComponent(JSON.stringify(productFilter))}`
1880
+ );
1881
+ if (!productsResult.success || !productsResult.data || productsResult.data.length === 0) {
1882
+ return { success: false, error: productsResult.error || "No products found" };
1883
+ }
1884
+ const rawProducts = productsResult.data;
1885
+ const numericProductIds = rawProducts.map((p) => p.id);
1886
+ const priceFilter = {
1887
+ product_id: { operator: "in", value: numericProductIds },
1888
+ active: true
1889
+ };
1890
+ const pricesResult = await fetchAPI2(
1891
+ config,
1892
+ `${baseUrl}/data/prices?filter=${encodeURIComponent(JSON.stringify(priceFilter))}&limit=200`
1893
+ );
1894
+ const rawPrices = pricesResult.success ? pricesResult.data || [] : [];
1895
+ const priceMap = /* @__PURE__ */ new Map();
1896
+ for (const price of rawPrices) {
1897
+ if (!priceMap.has(price.product_id)) {
1898
+ priceMap.set(price.product_id, price);
1899
+ }
1900
+ }
1901
+ const products = rawProducts.map((product) => {
1902
+ const price = priceMap.get(product.id);
1903
+ return {
1904
+ id: String(product.id),
1905
+ name: product.name,
1906
+ description: product.description,
1907
+ price: price ? price.unit_amount / 100 : 0,
1908
+ type: price?.type === "recurring" ? "subscription" : "one-time",
1909
+ interval: price?.interval
1910
+ };
1911
+ });
1912
+ return { success: true, data: products };
1913
+ } catch (error) {
1914
+ return {
1915
+ success: false,
1916
+ error: error instanceof Error ? error.message : "Failed to fetch products"
1917
+ };
1918
+ }
1919
+ }
1920
+ async function getCustomerByUserId(config, userId) {
1921
+ const { baseUrl, projectId } = config;
1922
+ return fetchAPI2(
1923
+ config,
1924
+ `${baseUrl}/billing/customers/by-user/${userId}?project_id=${projectId}`
1925
+ );
1926
+ }
1927
+ async function getPaymentMethods(config, customerId) {
1928
+ const { baseUrl, projectId } = config;
1929
+ return fetchAPI2(
1930
+ config,
1931
+ `${baseUrl}/billing/customers/${customerId}/payment-methods?project_id=${projectId}&status=active`
1932
+ );
1933
+ }
1934
+ async function fetchPaymentConfig(config) {
1935
+ const { baseUrl, projectId } = config;
1936
+ return fetchAPI2(
1937
+ config,
1938
+ `${baseUrl}/billing/payment-config?project_id=${projectId}&test_mode=true`
1939
+ );
1940
+ }
1941
+ var MOCK_PRODUCTS = {
1942
+ "prod_pro": {
1943
+ id: "prod_pro",
1944
+ name: "Pro Plan",
1945
+ description: "Unlock all premium features and priority support",
1946
+ price: 29.99,
1947
+ type: "subscription",
1948
+ interval: "month",
1949
+ image: "/placeholder-product.jpg",
1950
+ features: [
1951
+ "Unlimited projects",
1952
+ "Priority support",
1953
+ "Advanced analytics",
1954
+ "Custom integrations",
1955
+ "Team collaboration"
1956
+ ]
1957
+ },
1958
+ "prod_starter": {
1959
+ id: "prod_starter",
1960
+ name: "Starter Plan",
1961
+ description: "Perfect for getting started",
1962
+ price: 9.99,
1963
+ type: "subscription",
1964
+ interval: "month",
1965
+ image: "/placeholder-product.jpg",
1966
+ features: [
1967
+ "5 projects",
1968
+ "Email support",
1969
+ "Basic analytics"
1970
+ ]
1971
+ },
1972
+ "prod_lifetime": {
1973
+ id: "prod_lifetime",
1974
+ name: "Lifetime Access",
1975
+ description: "One-time payment, forever access",
1976
+ price: 299.99,
1977
+ type: "one-time",
1978
+ image: "/placeholder-product.jpg",
1979
+ features: [
1980
+ "All Pro features",
1981
+ "Lifetime updates",
1982
+ "Priority support forever"
1983
+ ]
1984
+ }
1985
+ };
1986
+ async function Payment({
1987
+ // API config
1988
+ baseUrl,
1989
+ apiKey,
1990
+ accessToken,
1991
+ projectId,
1992
+ userId,
1993
+ // Product options
1994
+ productId,
1995
+ productIds: productIdsProp,
1996
+ product: productProp,
1997
+ quantity = 1,
1998
+ email: _email,
1999
+ successUrl = "/success",
2000
+ cancelUrl,
2001
+ currencySymbol = "$",
2002
+ showImage = true,
2003
+ showFeatures = true,
2004
+ submitText: _submitText,
2005
+ showSecurityBadges = true,
2006
+ allowPromoCode = true,
2007
+ sellerName,
2008
+ sellerLogo,
2009
+ termsUrl,
2010
+ privacyUrl,
2011
+ className = "",
2012
+ layout = "two-column"
2013
+ }) {
2014
+ const productIds = productIdsProp || (productId ? [productId] : []);
2015
+ const apiConfig = {
2016
+ baseUrl,
2017
+ apiKey,
2018
+ accessToken,
2019
+ projectId
2020
+ };
2021
+ let products = [];
2022
+ if (productProp) {
2023
+ products = [productProp];
2024
+ } else if (productIds.length > 0 && baseUrl) {
2025
+ try {
2026
+ const result = await fetchProducts(apiConfig, productIds);
2027
+ if (result.success && result.data) {
2028
+ products = result.data;
2029
+ }
2030
+ } catch (error) {
2031
+ console.error("Failed to fetch products:", error);
2032
+ products = productIds.map((id) => MOCK_PRODUCTS[id]).filter(Boolean);
2033
+ }
2034
+ } else if (productIds.length > 0) {
2035
+ products = productIds.map((id) => MOCK_PRODUCTS[id]).filter(Boolean);
2036
+ }
2037
+ if (products.length === 0) {
2038
+ products = [MOCK_PRODUCTS["prod_pro"]];
2039
+ }
2040
+ let customer = null;
2041
+ let paymentMethods = [];
2042
+ let stripePublishableKey = null;
2043
+ if (baseUrl && projectId) {
2044
+ const configResult = await fetchPaymentConfig(apiConfig);
2045
+ if (configResult.success && configResult.data?.public_key) {
2046
+ stripePublishableKey = configResult.data.public_key;
2047
+ }
2048
+ if (userId) {
2049
+ const customerResult = await getCustomerByUserId(apiConfig, userId);
2050
+ if (customerResult.success && customerResult.data) {
2051
+ customer = customerResult.data;
2052
+ const pmResult = await getPaymentMethods(apiConfig, customer.id);
2053
+ if (pmResult.success && pmResult.data) {
2054
+ paymentMethods = pmResult.data;
2055
+ }
2056
+ }
2057
+ }
2058
+ }
2059
+ const subtotal = products.reduce((sum, p) => sum + p.price * quantity, 0);
2060
+ const total = subtotal;
2061
+ const isMultiProduct = products.length > 1;
2062
+ const primaryProduct = products[0];
2063
+ const ProductSection = () => /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
2064
+ (sellerLogo || sellerName) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
2065
+ sellerLogo && /* @__PURE__ */ jsx(
2066
+ "img",
2067
+ {
2068
+ src: sellerLogo,
2069
+ alt: sellerName || "Seller",
2070
+ className: "h-8"
2071
+ }
2072
+ ),
2073
+ sellerName && /* @__PURE__ */ jsx("span", { className: "text-lg font-medium text-gray-900 dark:text-white", children: sellerName })
2074
+ ] }),
2075
+ !isMultiProduct && /* @__PURE__ */ jsxs(Fragment, { children: [
2076
+ /* @__PURE__ */ jsxs("div", { children: [
2077
+ showImage && primaryProduct.image && /* @__PURE__ */ jsx("div", { className: "w-full h-48 bg-gray-100 dark:bg-neutral-800 rounded-xl overflow-hidden mb-4", children: /* @__PURE__ */ jsx(
2078
+ "img",
2079
+ {
2080
+ src: primaryProduct.image,
2081
+ alt: primaryProduct.name,
2082
+ className: "w-full h-full object-cover"
2083
+ }
2084
+ ) }),
2085
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold text-gray-900 dark:text-white", children: primaryProduct.name }),
2086
+ primaryProduct.description && /* @__PURE__ */ jsx("p", { className: "text-gray-600 dark:text-gray-400 mt-1", children: primaryProduct.description }),
2087
+ /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
2088
+ /* @__PURE__ */ jsxs("span", { className: "text-4xl font-bold text-gray-900 dark:text-white", children: [
2089
+ currencySymbol,
2090
+ primaryProduct.price.toFixed(2)
2091
+ ] }),
2092
+ primaryProduct.type === "subscription" && primaryProduct.interval && /* @__PURE__ */ jsxs("span", { className: "text-gray-500 dark:text-gray-400 text-lg ml-1", children: [
2093
+ "/",
2094
+ primaryProduct.interval
2095
+ ] }),
2096
+ quantity > 1 && /* @__PURE__ */ jsxs("span", { className: "text-gray-500 dark:text-gray-400 text-sm ml-2", children: [
2097
+ "x ",
2098
+ quantity
2099
+ ] })
2100
+ ] })
2101
+ ] }),
2102
+ showFeatures && primaryProduct.features && primaryProduct.features.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-6 border-t border-gray-200 dark:border-neutral-700", children: [
2103
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-3", children: "What's included" }),
2104
+ /* @__PURE__ */ jsx("ul", { className: "space-y-3", children: primaryProduct.features.map((feature, index) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-3 text-sm text-gray-600 dark:text-gray-400", children: [
2105
+ /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 text-green-500 flex-shrink-0 mt-0.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
2106
+ feature
2107
+ ] }, index)) })
2108
+ ] })
2109
+ ] }),
2110
+ isMultiProduct && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
2111
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-gray-900 dark:text-white", children: "Order Summary" }),
2112
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: products.map((product) => /* @__PURE__ */ jsxs("div", { className: "flex gap-3 items-start p-3 bg-gray-50 dark:bg-neutral-800 rounded-lg", children: [
2113
+ showImage && product.image && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 w-12 h-12 bg-gray-200 dark:bg-neutral-700 rounded-lg overflow-hidden", children: /* @__PURE__ */ jsx(
2114
+ "img",
2115
+ {
2116
+ src: product.image,
2117
+ alt: product.name,
2118
+ className: "w-full h-full object-cover"
2119
+ }
2120
+ ) }),
2121
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2122
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-gray-900 dark:text-white", children: product.name }),
2123
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 truncate", children: product.description })
2124
+ ] }),
2125
+ /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
2126
+ /* @__PURE__ */ jsxs("p", { className: "font-semibold text-gray-900 dark:text-white", children: [
2127
+ currencySymbol,
2128
+ product.price.toFixed(2)
2129
+ ] }),
2130
+ product.type === "subscription" && product.interval && /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
2131
+ "/",
2132
+ product.interval
2133
+ ] })
2134
+ ] })
2135
+ ] }, product.id)) }),
2136
+ /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-neutral-700 flex justify-between items-center", children: [
2137
+ /* @__PURE__ */ jsx("span", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "Total" }),
2138
+ /* @__PURE__ */ jsxs("span", { className: "text-2xl font-bold text-gray-900 dark:text-white", children: [
2139
+ currencySymbol,
2140
+ total.toFixed(2)
2141
+ ] })
2142
+ ] })
2143
+ ] }),
2144
+ showSecurityBadges && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-gray-400 dark:text-gray-500 text-sm", children: [
2145
+ /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { d: "M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z" }) }),
2146
+ /* @__PURE__ */ jsx("span", { children: "Secure payment powered by Stripe" })
2147
+ ] })
2148
+ ] });
2149
+ const FormSection = () => /* @__PURE__ */ jsxs("div", { className: "bg-white dark:bg-neutral-900 rounded-2xl shadow-xl border border-gray-200 dark:border-neutral-800 p-6 lg:p-8", children: [
2150
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900 dark:text-white mb-6", children: "Payment Details" }),
2151
+ /* @__PURE__ */ jsx(
2152
+ PaymentForm,
2153
+ {
2154
+ products,
2155
+ customerId: customer?.id || null,
2156
+ paymentMethods,
2157
+ stripePublishableKey,
2158
+ actionConfig: apiConfig,
2159
+ quantity,
2160
+ currencySymbol,
2161
+ successUrl,
2162
+ cancelUrl,
2163
+ allowPromoCode,
2164
+ termsUrl,
2165
+ privacyUrl
2166
+ }
2167
+ )
2168
+ ] });
2169
+ if (layout === "two-column") {
2170
+ return /* @__PURE__ */ jsx("div", { className: `min-h-screen bg-gray-50 dark:bg-neutral-950 ${className}`, children: /* @__PURE__ */ jsx("div", { className: "max-w-6xl mx-auto px-4 py-8 lg:py-12", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16", children: [
2171
+ /* @__PURE__ */ jsx("div", { className: "lg:sticky lg:top-8 lg:self-start", children: /* @__PURE__ */ jsx(ProductSection, {}) }),
2172
+ /* @__PURE__ */ jsxs("div", { children: [
2173
+ /* @__PURE__ */ jsx(FormSection, {}),
2174
+ /* @__PURE__ */ jsx("div", { className: "mt-6 text-center", children: /* @__PURE__ */ jsx("a", { href: "/", className: "text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300", children: "Return to site" }) })
2175
+ ] })
2176
+ ] }) }) });
2177
+ }
2178
+ return /* @__PURE__ */ jsx("div", { className: `min-h-screen bg-gray-50 dark:bg-neutral-950 py-8 px-4 ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "max-w-lg mx-auto", children: [
2179
+ /* @__PURE__ */ jsxs("div", { className: "bg-white dark:bg-neutral-900 rounded-2xl shadow-xl border border-gray-200 dark:border-neutral-800 overflow-hidden", children: [
2180
+ /* @__PURE__ */ jsx("div", { className: "p-6 border-b border-gray-200 dark:border-neutral-700", children: /* @__PURE__ */ jsx(ProductSection, {}) }),
2181
+ /* @__PURE__ */ jsx("div", { className: "p-6 bg-gray-50 dark:bg-neutral-800", children: /* @__PURE__ */ jsx(
2182
+ PaymentForm,
2183
+ {
2184
+ products,
2185
+ customerId: customer?.id || null,
2186
+ paymentMethods,
2187
+ stripePublishableKey,
2188
+ actionConfig: apiConfig,
2189
+ quantity,
2190
+ currencySymbol,
2191
+ successUrl,
2192
+ cancelUrl,
2193
+ allowPromoCode,
2194
+ termsUrl,
2195
+ privacyUrl
2196
+ }
2197
+ ) })
2198
+ ] }),
2199
+ /* @__PURE__ */ jsx("div", { className: "mt-6 text-center", children: /* @__PURE__ */ jsx("a", { href: "/", className: "text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300", children: "Return to site" }) })
2200
+ ] }) });
2201
+ }
2202
+
2203
+ export { Billing, Cart, CartSummary, Checkout, DataList, OmniKitClient, OrderConfirmation, Payment, createOmniKitClient };
2204
+ //# sourceMappingURL=chunk-LIZKLYHH.js.map
2205
+ //# sourceMappingURL=chunk-LIZKLYHH.js.map