@burdenoff/microfe-store 2026.915.2 → 2026.916.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/cart/CartDrawer.d.ts +2 -0
- package/dist/components/cart/CartDrawer.js +24 -24
- package/dist/components/cart/CartDrawer.js.map +1 -1
- package/dist/pages/CartPage.js +57 -57
- package/dist/pages/CartPage.js.map +1 -1
- package/dist/pages/MarketplaceHomePage.js +135 -134
- package/dist/pages/MarketplaceHomePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,11 +3,11 @@ import { useTr as t } from "../../shared/hooks/useTr.js";
|
|
|
3
3
|
import { Minus as n, Plus as r, ShoppingCart as i, Trash2 as a, X as o } from "lucide-react";
|
|
4
4
|
import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
5
5
|
//#region src/components/cart/CartDrawer.tsx
|
|
6
|
-
var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m,
|
|
7
|
-
let
|
|
6
|
+
var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, currency: h, subtotal: g, tax: _, total: v, updateQuantity: y, removeProduct: b }) => {
|
|
7
|
+
let x = t();
|
|
8
8
|
return u ? /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("button", {
|
|
9
9
|
type: "button",
|
|
10
|
-
"aria-label":
|
|
10
|
+
"aria-label": x("cart.closeCart", "Close cart"),
|
|
11
11
|
className: "fixed inset-0 z-40 bg-bg-overlay/50 transition-opacity",
|
|
12
12
|
onClick: d
|
|
13
13
|
}), /* @__PURE__ */ c("div", {
|
|
@@ -23,7 +23,7 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
23
23
|
/* @__PURE__ */ c(i, { className: "size-5 text-text-primary" }),
|
|
24
24
|
/* @__PURE__ */ c("h2", {
|
|
25
25
|
className: "text-lg font-semibold text-text-primary",
|
|
26
|
-
children:
|
|
26
|
+
children: x("cart.title", "Shopping Cart")
|
|
27
27
|
}),
|
|
28
28
|
m > 0 && /* @__PURE__ */ c("span", {
|
|
29
29
|
className: "rounded-full bg-bg-accent px-2 py-0.5 text-xs font-medium tabular-nums text-text-link",
|
|
@@ -33,7 +33,7 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
33
33
|
}), /* @__PURE__ */ c("button", {
|
|
34
34
|
type: "button",
|
|
35
35
|
onClick: d,
|
|
36
|
-
"aria-label":
|
|
36
|
+
"aria-label": x("cart.closeCart", "Close cart"),
|
|
37
37
|
className: "cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary",
|
|
38
38
|
children: /* @__PURE__ */ c(o, { className: "size-5" })
|
|
39
39
|
})]
|
|
@@ -41,7 +41,7 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
41
41
|
/* @__PURE__ */ c("div", {
|
|
42
42
|
className: "flex-1 overflow-y-auto px-4 sm:px-6 py-4",
|
|
43
43
|
children: p.length === 0 ? /* @__PURE__ */ l("output", {
|
|
44
|
-
"aria-label":
|
|
44
|
+
"aria-label": x("cart.empty", "Your cart is empty"),
|
|
45
45
|
className: "flex h-full flex-col items-center justify-center text-center",
|
|
46
46
|
children: [
|
|
47
47
|
/* @__PURE__ */ c(i, {
|
|
@@ -50,11 +50,11 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
50
50
|
}),
|
|
51
51
|
/* @__PURE__ */ c("h3", {
|
|
52
52
|
className: "mb-2 text-lg font-semibold text-text-primary",
|
|
53
|
-
children:
|
|
53
|
+
children: x("cart.empty", "Your cart is empty")
|
|
54
54
|
}),
|
|
55
55
|
/* @__PURE__ */ c("p", {
|
|
56
56
|
className: "text-sm text-text-muted",
|
|
57
|
-
children:
|
|
57
|
+
children: x("cart.emptyHint", "Start shopping to add items to your cart")
|
|
58
58
|
})
|
|
59
59
|
]
|
|
60
60
|
}) : /* @__PURE__ */ c("div", {
|
|
@@ -76,7 +76,7 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
76
76
|
children: [
|
|
77
77
|
/* @__PURE__ */ c("h4", {
|
|
78
78
|
className: "mb-1 font-semibold text-text-primary",
|
|
79
|
-
children: t.productName || t.product?.name ||
|
|
79
|
+
children: t.productName || t.product?.name || x("common.product", "Product")
|
|
80
80
|
}),
|
|
81
81
|
t.variantName && /* @__PURE__ */ c("p", {
|
|
82
82
|
className: "mb-2 text-xs text-text-muted",
|
|
@@ -89,8 +89,8 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
89
89
|
children: [
|
|
90
90
|
/* @__PURE__ */ c("button", {
|
|
91
91
|
type: "button",
|
|
92
|
-
onClick: () =>
|
|
93
|
-
"aria-label":
|
|
92
|
+
onClick: () => y(t.id, t.quantity - 1),
|
|
93
|
+
"aria-label": x("cart.decreaseQuantity", "Decrease quantity of {{name}}", { name: t.productName || t.product?.name || x("common.item", "item") }),
|
|
94
94
|
className: "cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50",
|
|
95
95
|
disabled: t.quantity <= 1,
|
|
96
96
|
children: /* @__PURE__ */ c(n, {
|
|
@@ -100,13 +100,13 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
100
100
|
}),
|
|
101
101
|
/* @__PURE__ */ c("span", {
|
|
102
102
|
className: "min-w-[2rem] text-center text-sm font-medium",
|
|
103
|
-
"aria-label":
|
|
103
|
+
"aria-label": x("cart.quantity", "Quantity: {{quantity}}", { quantity: t.quantity }),
|
|
104
104
|
children: t.quantity
|
|
105
105
|
}),
|
|
106
106
|
/* @__PURE__ */ c("button", {
|
|
107
107
|
type: "button",
|
|
108
|
-
onClick: () =>
|
|
109
|
-
"aria-label":
|
|
108
|
+
onClick: () => y(t.id, t.quantity + 1),
|
|
109
|
+
"aria-label": x("cart.increaseQuantity", "Increase quantity of {{name}}", { name: t.productName || t.product?.name || x("common.item", "item") }),
|
|
110
110
|
className: "cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken",
|
|
111
111
|
children: /* @__PURE__ */ c(r, {
|
|
112
112
|
className: "size-4",
|
|
@@ -116,8 +116,8 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
116
116
|
]
|
|
117
117
|
}), /* @__PURE__ */ c("button", {
|
|
118
118
|
type: "button",
|
|
119
|
-
onClick: () =>
|
|
120
|
-
"aria-label":
|
|
119
|
+
onClick: () => b(t.id),
|
|
120
|
+
"aria-label": x("cart.removeItem", "Remove {{name}} from cart", { name: t.productName || t.product?.name || x("common.item", "item") }),
|
|
121
121
|
className: "cursor-pointer ml-auto text-status-error-text transition-colors hover:text-status-error-text-emphasis",
|
|
122
122
|
children: /* @__PURE__ */ c(a, {
|
|
123
123
|
className: "size-4",
|
|
@@ -129,7 +129,7 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
129
129
|
className: "mt-2 text-right",
|
|
130
130
|
children: /* @__PURE__ */ c("span", {
|
|
131
131
|
className: "font-semibold tabular-nums text-text-primary",
|
|
132
|
-
children: e(t.subtotal)
|
|
132
|
+
children: e(t.subtotal, h)
|
|
133
133
|
})
|
|
134
134
|
})
|
|
135
135
|
]
|
|
@@ -146,30 +146,30 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
146
146
|
className: "flex justify-between text-sm",
|
|
147
147
|
children: [/* @__PURE__ */ c("span", {
|
|
148
148
|
className: "text-text-muted",
|
|
149
|
-
children:
|
|
149
|
+
children: x("cart.subtotal", "Subtotal")
|
|
150
150
|
}), /* @__PURE__ */ c("span", {
|
|
151
151
|
className: "font-medium tabular-nums text-text-primary",
|
|
152
|
-
children: e(h)
|
|
152
|
+
children: e(g, h)
|
|
153
153
|
})]
|
|
154
154
|
}),
|
|
155
155
|
/* @__PURE__ */ l("div", {
|
|
156
156
|
className: "flex justify-between text-sm",
|
|
157
157
|
children: [/* @__PURE__ */ c("span", {
|
|
158
158
|
className: "text-text-muted",
|
|
159
|
-
children:
|
|
159
|
+
children: x("cart.tax", "Tax")
|
|
160
160
|
}), /* @__PURE__ */ c("span", {
|
|
161
161
|
className: "font-medium tabular-nums text-text-primary",
|
|
162
|
-
children: e(
|
|
162
|
+
children: e(_, h)
|
|
163
163
|
})]
|
|
164
164
|
}),
|
|
165
165
|
/* @__PURE__ */ l("div", {
|
|
166
166
|
className: "flex justify-between border-t border-border-seam pt-2",
|
|
167
167
|
children: [/* @__PURE__ */ c("span", {
|
|
168
168
|
className: "font-semibold text-text-primary",
|
|
169
|
-
children:
|
|
169
|
+
children: x("cart.total", "Total")
|
|
170
170
|
}), /* @__PURE__ */ c("span", {
|
|
171
171
|
className: "text-lg font-bold tabular-nums text-text-primary",
|
|
172
|
-
children: e(
|
|
172
|
+
children: e(v, h)
|
|
173
173
|
})]
|
|
174
174
|
})
|
|
175
175
|
]
|
|
@@ -177,7 +177,7 @@ var u = ({ isOpen: u, onClose: d, onCheckout: f, cartItems: p, itemCount: m, sub
|
|
|
177
177
|
type: "button",
|
|
178
178
|
onClick: f,
|
|
179
179
|
className: "cursor-pointer mt-4 w-full rounded-lg bg-action-primary-bg py-3 font-bold text-action-primary-text shadow-elevation-1 transition-[opacity,box-shadow] hover:opacity-90 hover:shadow-[var(--shadow-pop)]",
|
|
180
|
-
children:
|
|
180
|
+
children: x("cart.checkout", "Proceed to Checkout")
|
|
181
181
|
})]
|
|
182
182
|
})
|
|
183
183
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartDrawer.js","names":[],"sources":["../../../src/components/cart/CartDrawer.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { X, ShoppingCart, Trash2, Plus, Minus } from 'lucide-react';\nimport { formatPrice } from '../../utils';\nimport { useTr } from '../../shared/hooks/useTr';\n\n/**\n * Props for CartDrawer\n */\ninterface CartDrawerProps {\n isOpen: boolean;\n onClose: () => void;\n onCheckout: () => void;\n cartItems: Array<{\n id: string;\n quantity: number;\n subtotal: number;\n productName?: string;\n productIcon?: string;\n variantName?: string;\n product?: { icon?: string; name?: string };\n }>;\n itemCount: number;\n subtotal: number;\n tax: number;\n total: number;\n updateQuantity: (cartItemId: string, quantity: number) => Promise<void>;\n removeProduct: (cartItemId: string) => Promise<void>;\n}\n\n/**\n * CartDrawer component\n *\n * Sliding drawer for cart management\n */\nexport const CartDrawer: FC<CartDrawerProps> = ({\n isOpen,\n onClose,\n onCheckout,\n cartItems,\n itemCount,\n subtotal,\n tax,\n total,\n updateQuantity,\n removeProduct,\n}) => {\n const tr = useTr();\n if (!isOpen) return null;\n\n return (\n <>\n {/* Backdrop */}\n <button\n type=\"button\"\n aria-label={tr('cart.closeCart', 'Close cart')}\n className=\"fixed inset-0 z-40 bg-bg-overlay/50 transition-opacity\"\n onClick={onClose}\n />\n\n {/* Drawer */}\n <div className=\"fixed right-0 top-0 z-50 size-full sm:max-w-md bg-bg-surface shadow-xl\">\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border-seam px-4 sm:px-6 py-4\">\n <div className=\"flex items-center gap-2\">\n <ShoppingCart className=\"size-5 text-text-primary\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('cart.title', 'Shopping Cart')}\n </h2>\n {itemCount > 0 && (\n <span className=\"rounded-full bg-bg-accent px-2 py-0.5 text-xs font-medium tabular-nums text-text-link\">\n {itemCount}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={tr('cart.closeCart', 'Close cart')}\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {/* Cart Items */}\n <div className=\"flex-1 overflow-y-auto px-4 sm:px-6 py-4\">\n {cartItems.length === 0 ? (\n <output\n aria-label={tr('cart.empty', 'Your cart is empty')}\n className=\"flex h-full flex-col items-center justify-center text-center\"\n >\n <ShoppingCart className=\"mb-4 size-16 text-text-muted\" aria-hidden=\"true\" />\n <h3 className=\"mb-2 text-lg font-semibold text-text-primary\">\n {tr('cart.empty', 'Your cart is empty')}\n </h3>\n <p className=\"text-sm text-text-muted\">\n {tr('cart.emptyHint', 'Start shopping to add items to your cart')}\n </p>\n </output>\n ) : (\n <div className=\"space-y-4\">\n {cartItems.map((item) => (\n <div\n key={item.id}\n className=\"flex gap-4 rounded-lg border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]\"\n >\n {/* Product Image */}\n <div className=\"size-20 flex-shrink-0 overflow-hidden rounded bg-bg-sunken\">\n {item.productIcon || item.product?.icon ? (\n <img\n src={item.productIcon || item.product?.icon}\n alt={item.productName || item.product?.name}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center\">\n <ShoppingCart className=\"size-8 text-text-muted\" />\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"flex flex-1 flex-col\">\n <h4 className=\"mb-1 font-semibold text-text-primary\">\n {item.productName || item.product?.name || tr('common.product', 'Product')}\n </h4>\n {item.variantName && (\n <p className=\"mb-2 text-xs text-text-muted\">{item.variantName}</p>\n )}\n\n {/* Quantity Controls */}\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center rounded border border-border-default\">\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity - 1)}\n aria-label={tr(\n 'cart.decreaseQuantity',\n 'Decrease quantity of {{name}}',\n {\n name:\n item.productName ||\n item.product?.name ||\n tr('common.item', 'item'),\n }\n )}\n className=\"cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={item.quantity <= 1}\n >\n <Minus className=\"size-4\" aria-hidden=\"true\" />\n </button>\n <span\n className=\"min-w-[2rem] text-center text-sm font-medium\"\n aria-label={tr('cart.quantity', 'Quantity: {{quantity}}', {\n quantity: item.quantity,\n })}\n >\n {item.quantity}\n </span>\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity + 1)}\n aria-label={tr(\n 'cart.increaseQuantity',\n 'Increase quantity of {{name}}',\n {\n name:\n item.productName ||\n item.product?.name ||\n tr('common.item', 'item'),\n }\n )}\n className=\"cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken\"\n >\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n onClick={() => removeProduct(item.id)}\n aria-label={tr('cart.removeItem', 'Remove {{name}} from cart', {\n name:\n item.productName || item.product?.name || tr('common.item', 'item'),\n })}\n className=\"cursor-pointer ml-auto text-status-error-text transition-colors hover:text-status-error-text-emphasis\"\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n {/* Price */}\n <div className=\"mt-2 text-right\">\n <span className=\"font-semibold tabular-nums text-text-primary\">\n {formatPrice(item.subtotal)}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer with Summary */}\n {cartItems.length > 0 && (\n <div className=\"border-t border-border-seam bg-accent-wash px-4 sm:px-6 py-4\">\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">{tr('cart.subtotal', 'Subtotal')}</span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {formatPrice(subtotal)}\n </span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">{tr('cart.tax', 'Tax')}</span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {formatPrice(tax)}\n </span>\n </div>\n <div className=\"flex justify-between border-t border-border-seam pt-2\">\n <span className=\"font-semibold text-text-primary\">\n {tr('cart.total', 'Total')}\n </span>\n <span className=\"text-lg font-bold tabular-nums text-text-primary\">\n {formatPrice(total)}\n </span>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={onCheckout}\n className=\"cursor-pointer mt-4 w-full rounded-lg bg-action-primary-bg py-3 font-bold text-action-primary-text shadow-elevation-1 transition-[opacity,box-shadow] hover:opacity-90 hover:shadow-[var(--shadow-pop)]\"\n >\n {tr('cart.checkout', 'Proceed to Checkout')}\n </button>\n </div>\n )}\n </div>\n </div>\n </>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CartDrawer.js","names":[],"sources":["../../../src/components/cart/CartDrawer.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { X, ShoppingCart, Trash2, Plus, Minus } from 'lucide-react';\nimport { formatPrice } from '../../utils';\nimport { useTr } from '../../shared/hooks/useTr';\n\n/**\n * Props for CartDrawer\n */\ninterface CartDrawerProps {\n isOpen: boolean;\n onClose: () => void;\n onCheckout: () => void;\n cartItems: Array<{\n id: string;\n quantity: number;\n subtotal: number;\n productName?: string;\n productIcon?: string;\n variantName?: string;\n product?: { icon?: string; name?: string };\n }>;\n itemCount: number;\n /** Cart-wide currency — see useBackendCart.ts's Cart type (one currency per cart). */\n currency: string;\n subtotal: number;\n tax: number;\n total: number;\n updateQuantity: (cartItemId: string, quantity: number) => Promise<void>;\n removeProduct: (cartItemId: string) => Promise<void>;\n}\n\n/**\n * CartDrawer component\n *\n * Sliding drawer for cart management\n */\nexport const CartDrawer: FC<CartDrawerProps> = ({\n isOpen,\n onClose,\n onCheckout,\n cartItems,\n itemCount,\n currency,\n subtotal,\n tax,\n total,\n updateQuantity,\n removeProduct,\n}) => {\n const tr = useTr();\n if (!isOpen) return null;\n\n return (\n <>\n {/* Backdrop */}\n <button\n type=\"button\"\n aria-label={tr('cart.closeCart', 'Close cart')}\n className=\"fixed inset-0 z-40 bg-bg-overlay/50 transition-opacity\"\n onClick={onClose}\n />\n\n {/* Drawer */}\n <div className=\"fixed right-0 top-0 z-50 size-full sm:max-w-md bg-bg-surface shadow-xl\">\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border-seam px-4 sm:px-6 py-4\">\n <div className=\"flex items-center gap-2\">\n <ShoppingCart className=\"size-5 text-text-primary\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('cart.title', 'Shopping Cart')}\n </h2>\n {itemCount > 0 && (\n <span className=\"rounded-full bg-bg-accent px-2 py-0.5 text-xs font-medium tabular-nums text-text-link\">\n {itemCount}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={tr('cart.closeCart', 'Close cart')}\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {/* Cart Items */}\n <div className=\"flex-1 overflow-y-auto px-4 sm:px-6 py-4\">\n {cartItems.length === 0 ? (\n <output\n aria-label={tr('cart.empty', 'Your cart is empty')}\n className=\"flex h-full flex-col items-center justify-center text-center\"\n >\n <ShoppingCart className=\"mb-4 size-16 text-text-muted\" aria-hidden=\"true\" />\n <h3 className=\"mb-2 text-lg font-semibold text-text-primary\">\n {tr('cart.empty', 'Your cart is empty')}\n </h3>\n <p className=\"text-sm text-text-muted\">\n {tr('cart.emptyHint', 'Start shopping to add items to your cart')}\n </p>\n </output>\n ) : (\n <div className=\"space-y-4\">\n {cartItems.map((item) => (\n <div\n key={item.id}\n className=\"flex gap-4 rounded-lg border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]\"\n >\n {/* Product Image */}\n <div className=\"size-20 flex-shrink-0 overflow-hidden rounded bg-bg-sunken\">\n {item.productIcon || item.product?.icon ? (\n <img\n src={item.productIcon || item.product?.icon}\n alt={item.productName || item.product?.name}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center\">\n <ShoppingCart className=\"size-8 text-text-muted\" />\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"flex flex-1 flex-col\">\n <h4 className=\"mb-1 font-semibold text-text-primary\">\n {item.productName || item.product?.name || tr('common.product', 'Product')}\n </h4>\n {item.variantName && (\n <p className=\"mb-2 text-xs text-text-muted\">{item.variantName}</p>\n )}\n\n {/* Quantity Controls */}\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center rounded border border-border-default\">\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity - 1)}\n aria-label={tr(\n 'cart.decreaseQuantity',\n 'Decrease quantity of {{name}}',\n {\n name:\n item.productName ||\n item.product?.name ||\n tr('common.item', 'item'),\n }\n )}\n className=\"cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={item.quantity <= 1}\n >\n <Minus className=\"size-4\" aria-hidden=\"true\" />\n </button>\n <span\n className=\"min-w-[2rem] text-center text-sm font-medium\"\n aria-label={tr('cart.quantity', 'Quantity: {{quantity}}', {\n quantity: item.quantity,\n })}\n >\n {item.quantity}\n </span>\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity + 1)}\n aria-label={tr(\n 'cart.increaseQuantity',\n 'Increase quantity of {{name}}',\n {\n name:\n item.productName ||\n item.product?.name ||\n tr('common.item', 'item'),\n }\n )}\n className=\"cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken\"\n >\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n onClick={() => removeProduct(item.id)}\n aria-label={tr('cart.removeItem', 'Remove {{name}} from cart', {\n name:\n item.productName || item.product?.name || tr('common.item', 'item'),\n })}\n className=\"cursor-pointer ml-auto text-status-error-text transition-colors hover:text-status-error-text-emphasis\"\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n {/* Price */}\n <div className=\"mt-2 text-right\">\n <span className=\"font-semibold tabular-nums text-text-primary\">\n {formatPrice(item.subtotal, currency)}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer with Summary */}\n {cartItems.length > 0 && (\n <div className=\"border-t border-border-seam bg-accent-wash px-4 sm:px-6 py-4\">\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">{tr('cart.subtotal', 'Subtotal')}</span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {formatPrice(subtotal, currency)}\n </span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">{tr('cart.tax', 'Tax')}</span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {formatPrice(tax, currency)}\n </span>\n </div>\n <div className=\"flex justify-between border-t border-border-seam pt-2\">\n <span className=\"font-semibold text-text-primary\">\n {tr('cart.total', 'Total')}\n </span>\n <span className=\"text-lg font-bold tabular-nums text-text-primary\">\n {formatPrice(total, currency)}\n </span>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={onCheckout}\n className=\"cursor-pointer mt-4 w-full rounded-lg bg-action-primary-bg py-3 font-bold text-action-primary-text shadow-elevation-1 transition-[opacity,box-shadow] hover:opacity-90 hover:shadow-[var(--shadow-pop)]\"\n >\n {tr('cart.checkout', 'Proceed to Checkout')}\n </button>\n </div>\n )}\n </div>\n </div>\n </>\n );\n};\n"],"mappings":"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"}
|
package/dist/pages/CartPage.js
CHANGED
|
@@ -13,16 +13,16 @@ import { useEventBus as C } from "@burdenoff/fe-libs/shared/events";
|
|
|
13
13
|
import { useQuotaErrorToast as w } from "@burdenoff/fe-libs/shared/hooks";
|
|
14
14
|
//#region src/pages/CartPage.tsx
|
|
15
15
|
var T = () => {
|
|
16
|
-
let T = a(), { basePath: E } = e(), {
|
|
16
|
+
let T = a(), { basePath: E } = e(), { cart: D, cartItems: O, itemCount: k, total: A, updateQuantity: j, removeProduct: M, clearCart: N, createOrder: P } = t(), F = D?.currency || "USD", [I, L] = i(!1), [R, z] = i(null), { t: B } = o(), V = r(), H = C(), { report: U } = w(), W = O.some((e) => e.itemType === "physical"), G = async () => {
|
|
17
17
|
try {
|
|
18
|
-
|
|
18
|
+
L(!0), z(null), H.emit("store.cart.checkout_started", {
|
|
19
19
|
cartId: "",
|
|
20
|
-
itemCount:
|
|
21
|
-
total:
|
|
20
|
+
itemCount: k,
|
|
21
|
+
total: A
|
|
22
22
|
});
|
|
23
|
-
let e = await
|
|
24
|
-
total:
|
|
25
|
-
lineItems:
|
|
23
|
+
let e = await P({
|
|
24
|
+
total: A,
|
|
25
|
+
lineItems: O.map((e) => ({
|
|
26
26
|
productId: e.productId,
|
|
27
27
|
name: e.product?.displayName || "Product",
|
|
28
28
|
quantity: e.quantity,
|
|
@@ -33,19 +33,19 @@ var T = () => {
|
|
|
33
33
|
pricingModel: e.product?.pricingModel || "PAID_ONETIME"
|
|
34
34
|
}))
|
|
35
35
|
});
|
|
36
|
-
e?.id ? (
|
|
36
|
+
e?.id ? (H.emit("store.order.placed", {
|
|
37
37
|
orderId: e.id,
|
|
38
|
-
total:
|
|
39
|
-
itemCount:
|
|
40
|
-
}),
|
|
38
|
+
total: A,
|
|
39
|
+
itemCount: k
|
|
40
|
+
}), N().catch(() => {}), T(`/billing/checkout/store/${e.id}`)) : (z(B("pages.cart.failedToCreate", { defaultValue: "Failed to create order. Please try again." })), L(!1));
|
|
41
41
|
} catch (e) {
|
|
42
42
|
if (console.error("Checkout error:", e), y(e)) {
|
|
43
|
-
|
|
43
|
+
U(e), L(!1);
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
z(e instanceof Error ? e.message : V("pages.cart.checkoutError", "An error occurred during checkout")), L(!1);
|
|
47
47
|
}
|
|
48
|
-
},
|
|
48
|
+
}, K = () => {
|
|
49
49
|
T(`${E}/marketplace`);
|
|
50
50
|
};
|
|
51
51
|
return /* @__PURE__ */ v("div", {
|
|
@@ -59,7 +59,7 @@ var T = () => {
|
|
|
59
59
|
children: [/* @__PURE__ */ _("button", {
|
|
60
60
|
type: "button",
|
|
61
61
|
onClick: () => T(-1),
|
|
62
|
-
"aria-label":
|
|
62
|
+
"aria-label": V("common.goBack", "Go back"),
|
|
63
63
|
className: "cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary",
|
|
64
64
|
children: /* @__PURE__ */ _(s, { className: "size-5" })
|
|
65
65
|
}), /* @__PURE__ */ v("div", {
|
|
@@ -68,19 +68,19 @@ var T = () => {
|
|
|
68
68
|
/* @__PURE__ */ _(f, { className: "size-6 text-text-primary" }),
|
|
69
69
|
/* @__PURE__ */ _("h1", {
|
|
70
70
|
className: "text-xl font-bold text-text-primary",
|
|
71
|
-
children:
|
|
71
|
+
children: B("cart.title", { defaultValue: "Shopping Cart" })
|
|
72
72
|
}),
|
|
73
|
-
|
|
73
|
+
k > 0 && /* @__PURE__ */ v("span", {
|
|
74
74
|
className: "rounded-full bg-action-primary-bg px-2.5 py-0.5 text-sm font-medium text-action-primary-text",
|
|
75
75
|
children: [
|
|
76
|
-
|
|
76
|
+
k,
|
|
77
77
|
" ",
|
|
78
|
-
|
|
79
|
-
defaultValue: `${
|
|
80
|
-
count:
|
|
81
|
-
}) :
|
|
82
|
-
defaultValue: `${
|
|
83
|
-
count:
|
|
78
|
+
k === 1 ? B("pages.cart.item", {
|
|
79
|
+
defaultValue: `${k} item`,
|
|
80
|
+
count: k
|
|
81
|
+
}) : B("pages.cart.items", {
|
|
82
|
+
defaultValue: `${k} items`,
|
|
83
|
+
count: k
|
|
84
84
|
})
|
|
85
85
|
]
|
|
86
86
|
})
|
|
@@ -90,40 +90,40 @@ var T = () => {
|
|
|
90
90
|
})
|
|
91
91
|
}), /* @__PURE__ */ _("main", {
|
|
92
92
|
className: "mx-auto max-w-6xl p-6",
|
|
93
|
-
children:
|
|
93
|
+
children: O.length === 0 ? /* @__PURE__ */ _(x, {
|
|
94
94
|
illustration: "empty-generic",
|
|
95
|
-
title:
|
|
96
|
-
description:
|
|
95
|
+
title: B("cart.empty", { defaultValue: "Your cart is empty" }),
|
|
96
|
+
description: B("pages.cart.emptyDescription", { defaultValue: "Looks like you have not added any apps or products to your cart yet. Start exploring the marketplace to find something you will love!" }),
|
|
97
97
|
action: /* @__PURE__ */ v("button", {
|
|
98
98
|
type: "button",
|
|
99
|
-
onClick:
|
|
99
|
+
onClick: K,
|
|
100
100
|
className: "cursor-pointer flex items-center gap-2 rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90",
|
|
101
|
-
children: [/* @__PURE__ */ _(d, { className: "size-5" }),
|
|
101
|
+
children: [/* @__PURE__ */ _(d, { className: "size-5" }), B("pages.cart.browseMarketplace", { defaultValue: "Browse Marketplace" })]
|
|
102
102
|
})
|
|
103
103
|
}) : /* @__PURE__ */ v("div", {
|
|
104
104
|
className: "mx-auto max-w-3xl",
|
|
105
105
|
children: [/* @__PURE__ */ _(S, {
|
|
106
106
|
className: "mb-6",
|
|
107
|
-
children:
|
|
107
|
+
children: V("pages.cart.purpose", "Review the apps and products you're about to buy, adjust quantities for physical items, and confirm the total before checkout. Nothing is charged until you proceed — once you do, your purchases become licenses you can install into a workspace.")
|
|
108
108
|
}), /* @__PURE__ */ v("div", { children: [
|
|
109
109
|
/* @__PURE__ */ v("div", {
|
|
110
110
|
className: "mb-4 flex items-center justify-between",
|
|
111
111
|
children: [/* @__PURE__ */ _("h2", {
|
|
112
112
|
className: "text-lg font-semibold text-text-primary",
|
|
113
|
-
children:
|
|
114
|
-
defaultValue: `Cart Items (${
|
|
115
|
-
count:
|
|
113
|
+
children: B("pages.cart.cartItems", {
|
|
114
|
+
defaultValue: `Cart Items (${k})`,
|
|
115
|
+
count: k
|
|
116
116
|
})
|
|
117
117
|
}), /* @__PURE__ */ v("button", {
|
|
118
118
|
type: "button",
|
|
119
|
-
onClick:
|
|
119
|
+
onClick: N,
|
|
120
120
|
className: "cursor-pointer flex items-center gap-1 text-sm text-text-muted transition-colors hover:text-status-error-text",
|
|
121
|
-
children: [/* @__PURE__ */ _(m, { className: "size-4" }),
|
|
121
|
+
children: [/* @__PURE__ */ _(m, { className: "size-4" }), B("cart.clearCart", { defaultValue: "Clear Cart" })]
|
|
122
122
|
})]
|
|
123
123
|
}),
|
|
124
124
|
/* @__PURE__ */ _("ul", {
|
|
125
125
|
className: "space-y-4",
|
|
126
|
-
children:
|
|
126
|
+
children: O.map((e) => /* @__PURE__ */ v("li", {
|
|
127
127
|
className: "flex gap-4 rounded-xl border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]",
|
|
128
128
|
children: [/* @__PURE__ */ _("div", {
|
|
129
129
|
className: "size-24 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken",
|
|
@@ -155,10 +155,10 @@ var T = () => {
|
|
|
155
155
|
})
|
|
156
156
|
] }), /* @__PURE__ */ _("button", {
|
|
157
157
|
type: "button",
|
|
158
|
-
onClick: () =>
|
|
158
|
+
onClick: () => M(e.id),
|
|
159
159
|
className: "cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-status-error-bg-subtle/10 hover:text-status-error-text",
|
|
160
|
-
"aria-label":
|
|
161
|
-
title:
|
|
160
|
+
"aria-label": V("cart.removeItem", "Remove {{name}} from cart", { name: e.product?.displayName ?? V("common.item", "item") }),
|
|
161
|
+
title: V("cart.removeItemTitle", "Remove item"),
|
|
162
162
|
children: /* @__PURE__ */ _(m, { className: "size-5" })
|
|
163
163
|
})]
|
|
164
164
|
}),
|
|
@@ -166,10 +166,10 @@ var T = () => {
|
|
|
166
166
|
className: "mt-2 flex items-center gap-2",
|
|
167
167
|
children: [/* @__PURE__ */ _("span", {
|
|
168
168
|
className: "inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-muted",
|
|
169
|
-
children: e.itemType === "digital" ? /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(h, { className: "size-3" }),
|
|
169
|
+
children: e.itemType === "digital" ? /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(h, { className: "size-3" }), B("pages.cart.digital", { defaultValue: "Digital" })] }) : /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(p, { className: "size-3" }), B("pages.cart.physical", { defaultValue: "Physical" })] })
|
|
170
170
|
}), e.product?.pricingModel === "SUBSCRIPTION" && /* @__PURE__ */ _("span", {
|
|
171
171
|
className: "inline-flex items-center gap-1 rounded-full bg-bg-accent/10 px-2 py-0.5 text-xs font-medium text-text-link",
|
|
172
|
-
children:
|
|
172
|
+
children: B("store.pricingModels.subscription", { defaultValue: "Subscription" })
|
|
173
173
|
})]
|
|
174
174
|
}),
|
|
175
175
|
/* @__PURE__ */ v("div", {
|
|
@@ -178,13 +178,13 @@ var T = () => {
|
|
|
178
178
|
className: "flex items-center gap-3",
|
|
179
179
|
children: [/* @__PURE__ */ _("span", {
|
|
180
180
|
className: "text-sm text-text-muted",
|
|
181
|
-
children:
|
|
181
|
+
children: V("pages.cart.qty", "Qty:")
|
|
182
182
|
}), /* @__PURE__ */ v("div", {
|
|
183
183
|
className: "flex items-center rounded-lg border border-border-default",
|
|
184
184
|
children: [
|
|
185
185
|
/* @__PURE__ */ _("button", {
|
|
186
186
|
type: "button",
|
|
187
|
-
onClick: () =>
|
|
187
|
+
onClick: () => j(e.id, e.quantity - 1),
|
|
188
188
|
className: "cursor-pointer rounded-l-lg p-2 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50",
|
|
189
189
|
disabled: e.quantity <= 1,
|
|
190
190
|
children: /* @__PURE__ */ _(l, { className: "size-4" })
|
|
@@ -195,7 +195,7 @@ var T = () => {
|
|
|
195
195
|
}),
|
|
196
196
|
/* @__PURE__ */ _("button", {
|
|
197
197
|
type: "button",
|
|
198
|
-
onClick: () =>
|
|
198
|
+
onClick: () => j(e.id, e.quantity + 1),
|
|
199
199
|
className: "cursor-pointer rounded-r-lg p-2 transition-colors hover:bg-bg-sunken",
|
|
200
200
|
children: /* @__PURE__ */ _(u, { className: "size-4" })
|
|
201
201
|
})
|
|
@@ -203,15 +203,15 @@ var T = () => {
|
|
|
203
203
|
})]
|
|
204
204
|
}) : /* @__PURE__ */ _("div", {
|
|
205
205
|
className: "text-sm text-text-muted",
|
|
206
|
-
children:
|
|
206
|
+
children: B("pages.cart.singleLicense", { defaultValue: "Single license" })
|
|
207
207
|
}), /* @__PURE__ */ v("div", {
|
|
208
208
|
className: "text-right",
|
|
209
209
|
children: [/* @__PURE__ */ _("p", {
|
|
210
210
|
className: "text-lg font-bold text-text-primary",
|
|
211
|
-
children: n(e.totalPrice)
|
|
211
|
+
children: n(e.totalPrice, F)
|
|
212
212
|
}), e.quantity > 1 && e.itemType === "physical" && /* @__PURE__ */ _("p", {
|
|
213
213
|
className: "text-xs text-text-muted",
|
|
214
|
-
children:
|
|
214
|
+
children: V("pages.cart.each", "{{price}} each", { price: n(e.unitPrice, F) })
|
|
215
215
|
})]
|
|
216
216
|
})]
|
|
217
217
|
})
|
|
@@ -222,38 +222,38 @@ var T = () => {
|
|
|
222
222
|
/* @__PURE__ */ v(b, {
|
|
223
223
|
className: "mt-8",
|
|
224
224
|
children: [
|
|
225
|
-
|
|
225
|
+
R && /* @__PURE__ */ _("div", {
|
|
226
226
|
role: "alert",
|
|
227
227
|
className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
|
|
228
|
-
children:
|
|
228
|
+
children: R
|
|
229
229
|
}),
|
|
230
230
|
/* @__PURE__ */ _("p", {
|
|
231
231
|
className: "mb-3 text-xs text-text-muted",
|
|
232
|
-
children:
|
|
232
|
+
children: W ? V("pages.cart.physicalNotice", "Physical orders ship to your delivery address. Returns and refunds are handled by the seller per their store policy.") : V("pages.cart.digitalNotice", "All digital app purchases are final and non-refundable. Once an order is completed it cannot be cancelled or reversed.")
|
|
233
233
|
}),
|
|
234
234
|
/* @__PURE__ */ v("div", {
|
|
235
235
|
className: "flex items-center justify-between",
|
|
236
236
|
children: [/* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
|
|
237
237
|
className: "text-sm text-text-muted",
|
|
238
|
-
children:
|
|
238
|
+
children: V("cart.total", "Total")
|
|
239
239
|
}), /* @__PURE__ */ _("p", {
|
|
240
240
|
className: "text-2xl font-bold tabular-nums text-text-primary",
|
|
241
|
-
children: n(
|
|
241
|
+
children: n(A, F)
|
|
242
242
|
})] }), /* @__PURE__ */ _("button", {
|
|
243
243
|
type: "button",
|
|
244
|
-
onClick:
|
|
245
|
-
disabled:
|
|
244
|
+
onClick: G,
|
|
245
|
+
disabled: I,
|
|
246
246
|
className: "flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-70",
|
|
247
|
-
children:
|
|
247
|
+
children: I ? /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(c, { className: "size-4 animate-spin" }), B("pages.cart.processing", { defaultValue: "Processing..." })] }) : /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(h, { className: "size-4" }), B("pages.cart.proceedToCheckout", { defaultValue: "Proceed to Checkout" })] })
|
|
248
248
|
})]
|
|
249
249
|
})
|
|
250
250
|
]
|
|
251
251
|
}),
|
|
252
252
|
/* @__PURE__ */ v("button", {
|
|
253
253
|
type: "button",
|
|
254
|
-
onClick:
|
|
254
|
+
onClick: K,
|
|
255
255
|
className: "cursor-pointer mt-4 flex items-center gap-2 text-sm font-medium text-text-link hover:underline",
|
|
256
|
-
children: [/* @__PURE__ */ _(s, { className: "size-4" }),
|
|
256
|
+
children: [/* @__PURE__ */ _(s, { className: "size-4" }), B("cart.continueShopping", { defaultValue: "Continue Shopping" })]
|
|
257
257
|
})
|
|
258
258
|
] })]
|
|
259
259
|
})
|