@nextblock-cms/ecom 0.8.6 → 0.8.7
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/index.cjs.js +1 -1
- package/index.es.js +136 -533
- package/lib/CurrencyProvider.cjs.js +1 -0
- package/lib/CurrencyProvider.es.js +99 -0
- package/lib/cart-store.cjs.js +1 -0
- package/{cart-store.es.js → lib/cart-store.es.js} +13 -13
- package/lib/components/AccountNavigationMenu.cjs.js +1 -0
- package/lib/components/AccountNavigationMenu.es.js +44 -0
- package/lib/components/AddToCartButton.cjs.js +1 -0
- package/{AddToCartButton-ffE0DhHu.js → lib/components/AddToCartButton.es.js} +14 -13
- package/lib/components/Cart.cjs.js +1 -0
- package/lib/components/Cart.es.js +148 -0
- package/lib/components/CartDrawer.cjs.js +1 -0
- package/{components → lib/components}/CartDrawer.es.js +15 -14
- package/{components → lib/components}/CartIcon.cjs.js +1 -1
- package/{components → lib/components}/CartIcon.es.js +1 -0
- package/lib/components/Checkout.cjs.js +1 -0
- package/{components → lib/components}/Checkout.es.js +330 -363
- package/lib/components/CouponForm.cjs.js +1 -0
- package/lib/components/CouponForm.es.js +136 -0
- package/lib/components/CurrencySwitcher.cjs.js +1 -0
- package/{components → lib/components}/CurrencySwitcher.es.js +5 -4
- package/lib/components/CustomerProfileForm.cjs.js +1 -0
- package/lib/components/CustomerProfileForm.es.js +355 -0
- package/lib/components/FeaturedProduct.cjs.js +1 -0
- package/{components → lib/components}/FeaturedProduct.es.js +9 -8
- package/lib/components/InvoiceDocument.cjs.js +1 -0
- package/lib/components/InvoiceDocument.es.js +196 -0
- package/lib/components/InvoiceViewerShell.cjs.js +29 -0
- package/lib/components/InvoiceViewerShell.es.js +100 -0
- package/lib/components/ProductCard.cjs.js +1 -0
- package/lib/components/ProductCard.es.js +119 -0
- package/lib/components/ProductDetailsLayout.cjs.js +1 -0
- package/lib/components/ProductDetailsLayout.es.js +361 -0
- package/lib/components/ProductGallery.cjs.js +1 -0
- package/lib/components/ProductGallery.es.js +41 -0
- package/lib/components/ProductGrid.cjs.js +1 -0
- package/lib/components/ProductGrid.es.js +19 -0
- package/lib/components/ShippingEstimator.cjs.js +1 -0
- package/lib/components/ShippingEstimator.es.js +125 -0
- package/lib/components/SubscriptionSelector.cjs.js +1 -0
- package/lib/components/SubscriptionSelector.es.js +140 -0
- package/lib/countries.cjs.js +1 -0
- package/lib/countries.es.js +77 -0
- package/lib/coupon-server.cjs.js +1 -0
- package/{coupon-server-DUKVtyYs.js → lib/coupon-server.es.js} +68 -82
- package/lib/coupons.cjs.js +1 -0
- package/lib/coupons.es.js +17 -0
- package/lib/currency-store.cjs.js +1 -0
- package/lib/currency-store.es.js +27 -0
- package/lib/currency-sync.cjs.js +1 -0
- package/lib/currency-sync.es.js +180 -0
- package/lib/customer-addresses.cjs.js +1 -0
- package/lib/customer-addresses.es.js +116 -0
- package/lib/customer-orders.cjs.js +1 -0
- package/lib/customer-orders.es.js +45 -0
- package/lib/customer.cjs.js +1 -0
- package/{customer-C3xccjUg.js → lib/customer.es.js} +15 -14
- package/lib/export-helpers.cjs.js +1 -0
- package/lib/export-helpers.es.js +56 -0
- package/lib/factory.cjs.js +1 -0
- package/lib/factory.es.js +8 -0
- package/lib/freemius-coupons.cjs.js +1 -0
- package/lib/freemius-coupons.es.js +272 -0
- package/lib/freemius-order-sync.cjs.js +1 -0
- package/lib/freemius-order-sync.es.js +284 -0
- package/lib/inventory-settings.cjs.js +1 -0
- package/lib/inventory-settings.es.js +86 -0
- package/lib/invoice-server.cjs.js +33 -0
- package/lib/invoice-server.es.js +141 -0
- package/lib/invoice-ui.cjs.js +1 -0
- package/lib/invoice-ui.es.js +71 -0
- package/lib/invoice.cjs.js +1 -0
- package/lib/invoice.es.js +102 -0
- package/lib/order-inventory.cjs.js +61 -0
- package/lib/order-inventory.es.js +128 -0
- package/lib/order-tax-details.cjs.js +1 -0
- package/lib/order-tax-details.es.js +164 -0
- package/lib/pages/cms/coupons/CouponEditorForm.cjs.js +1 -0
- package/lib/pages/cms/coupons/CouponEditorForm.es.js +189 -0
- package/lib/pages/cms/coupons/CouponsPage.cjs.js +5 -0
- package/lib/pages/cms/coupons/CouponsPage.es.js +171 -0
- package/lib/pages/cms/coupons/CreateCouponDialog.cjs.js +1 -0
- package/lib/pages/cms/coupons/CreateCouponDialog.es.js +35 -0
- package/lib/pages/cms/coupons/EditCouponPage.cjs.js +1 -0
- package/lib/pages/cms/coupons/EditCouponPage.es.js +48 -0
- package/lib/pages/cms/coupons/ProductScopePicker.cjs.js +1 -0
- package/lib/pages/cms/coupons/ProductScopePicker.es.js +120 -0
- package/lib/pages/cms/coupons/actions.cjs.js +1 -0
- package/lib/pages/cms/coupons/actions.es.js +128 -0
- package/lib/pages/cms/coupons/product-options.cjs.js +1 -0
- package/lib/pages/cms/coupons/product-options.es.js +27 -0
- package/lib/pages/cms/orders/ExportReportsDialog.cjs.js +1 -0
- package/lib/pages/cms/orders/ExportReportsDialog.es.js +130 -0
- package/lib/pages/cms/orders/OrderDetailPage.cjs.js +1 -0
- package/lib/pages/cms/orders/OrderDetailPage.es.js +137 -0
- package/lib/pages/cms/orders/OrderPrintButton.cjs.js +1 -0
- package/lib/pages/cms/orders/OrderPrintButton.es.js +22 -0
- package/lib/pages/cms/orders/OrderStatusForm.cjs.js +1 -0
- package/lib/pages/cms/orders/OrderStatusForm.es.js +71 -0
- package/lib/pages/cms/orders/OrdersPage.cjs.js +1 -0
- package/lib/pages/cms/orders/OrdersPage.es.js +104 -0
- package/lib/pages/cms/orders/actions.cjs.js +7 -0
- package/lib/pages/cms/orders/actions.es.js +71 -0
- package/lib/pages/cms/orders/export-actions.cjs.js +1 -0
- package/lib/pages/cms/orders/export-actions.es.js +27 -0
- package/lib/pages/cms/orders/server-actions.cjs.js +1 -0
- package/lib/pages/cms/orders/server-actions.es.js +55 -0
- package/lib/pages/cms/payments/PaymentsClient.cjs.js +1 -0
- package/lib/pages/cms/payments/PaymentsClient.es.js +188 -0
- package/lib/pages/cms/payments/PaymentsPage.cjs.js +1 -0
- package/lib/pages/cms/payments/PaymentsPage.es.js +29 -0
- package/lib/pages/cms/payments/actions.cjs.js +1 -0
- package/lib/pages/cms/payments/actions.es.js +23 -0
- package/lib/pages/cms/payments/queries.cjs.js +1 -0
- package/lib/pages/cms/payments/queries.es.js +30 -0
- package/lib/pages/cms/products/ProductsPage.cjs.js +1 -0
- package/lib/pages/cms/products/ProductsPage.es.js +46 -0
- package/lib/pages/cms/products/_id_/edit/EditProductPage.cjs.js +1 -0
- package/lib/pages/cms/products/_id_/edit/EditProductPage.es.js +156 -0
- package/lib/pages/cms/products/actions.cjs.js +44 -0
- package/lib/pages/cms/products/actions.es.js +175 -0
- package/lib/pages/cms/products/attributes/AttributeManagementPage.cjs.js +1 -0
- package/lib/pages/cms/products/attributes/AttributeManagementPage.es.js +48 -0
- package/lib/pages/cms/products/attributes/components/AttributeManager.cjs.js +1 -0
- package/lib/pages/cms/products/attributes/components/AttributeManager.es.js +291 -0
- package/lib/pages/cms/products/categories/CategoryManagementPage.cjs.js +1 -0
- package/lib/pages/cms/products/categories/CategoryManagementPage.es.js +36 -0
- package/lib/pages/cms/products/categories/components/CategoryManager.cjs.js +1 -0
- package/lib/pages/cms/products/categories/components/CategoryManager.es.js +263 -0
- package/lib/pages/cms/products/components/CopyProductFromLanguage.cjs.js +1 -0
- package/lib/pages/cms/products/components/CopyProductFromLanguage.es.js +114 -0
- package/lib/pages/cms/products/components/CurrencyPriceFields.cjs.js +1 -0
- package/lib/pages/cms/products/components/CurrencyPriceFields.es.js +107 -0
- package/lib/pages/cms/products/components/DeleteProductButton.cjs.js +1 -0
- package/lib/pages/cms/products/components/DeleteProductButton.es.js +48 -0
- package/lib/pages/cms/products/components/FreemiusPricingDashboard.cjs.js +1 -0
- package/lib/pages/cms/products/components/FreemiusPricingDashboard.es.js +86 -0
- package/lib/pages/cms/products/components/ProductCategorySelector.cjs.js +1 -0
- package/lib/pages/cms/products/components/ProductCategorySelector.es.js +160 -0
- package/lib/pages/cms/products/components/ProductForm.cjs.js +1 -0
- package/lib/pages/cms/products/components/ProductForm.es.js +702 -0
- package/lib/pages/cms/products/components/ProductMediaManager.cjs.js +1 -0
- package/lib/pages/cms/products/components/ProductMediaManager.es.js +104 -0
- package/lib/pages/cms/products/components/ProductsBulkTable.cjs.js +1 -0
- package/lib/pages/cms/products/components/ProductsBulkTable.es.js +228 -0
- package/lib/pages/cms/products/components/SaleScheduleFields.cjs.js +1 -0
- package/lib/pages/cms/products/components/SaleScheduleFields.es.js +137 -0
- package/lib/pages/cms/products/components/SyncFreemiusButton.cjs.js +1 -0
- package/lib/pages/cms/products/components/SyncFreemiusButton.es.js +36 -0
- package/lib/pages/cms/products/components/SyncFreemiusPricingButton.cjs.js +1 -0
- package/lib/pages/cms/products/components/SyncFreemiusPricingButton.es.js +40 -0
- package/lib/pages/cms/products/components/VariationsEditor.cjs.js +1 -0
- package/lib/pages/cms/products/components/VariationsEditor.es.js +408 -0
- package/lib/pages/cms/products/inventory/InventoryPage.cjs.js +1 -0
- package/lib/pages/cms/products/inventory/InventoryPage.es.js +16 -0
- package/lib/pages/cms/products/inventory/InventoryTableClient.cjs.js +2 -0
- package/lib/pages/cms/products/inventory/InventoryTableClient.es.js +214 -0
- package/lib/pages/cms/products/inventory/actions.cjs.js +3 -0
- package/lib/pages/cms/products/inventory/actions.es.js +95 -0
- package/lib/pages/cms/products/new/NewProductPage.cjs.js +1 -0
- package/lib/pages/cms/products/new/NewProductPage.es.js +76 -0
- package/lib/pages/cms/products/product-price-sync.cjs.js +1 -0
- package/lib/pages/cms/products/product-price-sync.es.js +98 -0
- package/lib/pages/cms/products/server-actions.cjs.js +1 -0
- package/lib/pages/cms/products/server-actions.es.js +193 -0
- package/lib/pages/cms/shipping/ShippingPage.cjs.js +5 -0
- package/lib/pages/cms/shipping/ShippingPage.es.js +211 -0
- package/lib/pages/cms/shipping/components/RateForm.cjs.js +1 -0
- package/lib/pages/cms/shipping/components/RateForm.es.js +441 -0
- package/lib/pages/cms/shipping/components/ZoneForm.cjs.js +1 -0
- package/lib/pages/cms/shipping/components/ZoneForm.es.js +228 -0
- package/lib/pages/cms/shipping/server-actions.cjs.js +1 -0
- package/lib/pages/cms/shipping/server-actions.es.js +159 -0
- package/lib/pages/cms/taxes/TaxesPage.cjs.js +1 -0
- package/lib/pages/cms/taxes/TaxesPage.es.js +172 -0
- package/lib/pages/cms/taxes/actions.cjs.js +1 -0
- package/lib/pages/cms/taxes/actions.es.js +57 -0
- package/lib/pages/cms/taxes/components/TaxRateForm.cjs.js +1 -0
- package/lib/pages/cms/taxes/components/TaxRateForm.es.js +100 -0
- package/lib/product-actions.cjs.js +237 -0
- package/lib/product-actions.es.js +524 -0
- package/lib/product-context.cjs.js +1 -0
- package/lib/product-context.es.js +16 -0
- package/lib/product-schema.cjs.js +1 -0
- package/lib/product-schema.es.js +134 -0
- package/lib/providers/freemius.cjs.js +5 -0
- package/lib/providers/freemius.es.js +538 -0
- package/lib/providers/stripe.cjs.js +1 -0
- package/lib/providers/stripe.es.js +473 -0
- package/lib/server-actions/coupon-actions.cjs.js +1 -0
- package/lib/server-actions/coupon-actions.es.js +23 -0
- package/lib/server-actions/customer-actions.cjs.js +1 -0
- package/lib/server-actions/customer-actions.es.js +30 -0
- package/lib/server-actions/product-actions.cjs.js +1 -0
- package/{server-actions → lib/server-actions}/product-actions.es.js +5 -4
- package/lib/server-actions/shipping-actions.cjs.js +1 -0
- package/{shipping-actions-BnHjlo2q.js → lib/server-actions/shipping-actions.es.js} +9 -7
- package/lib/server-actions/tax-actions.cjs.js +1 -0
- package/lib/server-actions/tax-actions.es.js +40 -0
- package/lib/shared-inventory.cjs.js +15 -0
- package/lib/shared-inventory.es.js +171 -0
- package/lib/shipping/resolver.cjs.js +7 -0
- package/lib/shipping/resolver.es.js +62 -0
- package/lib/shipping-rate-currency.cjs.js +1 -0
- package/lib/shipping-rate-currency.es.js +72 -0
- package/lib/states.cjs.js +1 -0
- package/{states-DlHJezQ1.js → lib/states.es.js} +27 -100
- package/lib/stripe/checkout.cjs.js +1 -0
- package/lib/stripe/checkout.es.js +182 -0
- package/lib/stripe/client.cjs.js +1 -0
- package/lib/stripe/client.es.js +7 -0
- package/lib/stripe/order-sync.cjs.js +1 -0
- package/lib/stripe/order-sync.es.js +130 -0
- package/lib/stripe/webhooks.cjs.js +1 -0
- package/lib/stripe/webhooks.es.js +30 -0
- package/lib/tax-calculation.cjs.js +1 -0
- package/lib/tax-calculation.es.js +101 -0
- package/lib/trials.cjs.js +1 -0
- package/{trials-RDcRAZKx.js → lib/trials.es.js} +9 -9
- package/{use-cart.es.js → lib/use-cart.es.js} +1 -0
- package/lib/zod-config.cjs.js +1 -0
- package/lib/zod-config.es.js +6 -0
- package/package.json +4 -4
- package/server.cjs.js +1 -110
- package/server.es.js +178 -6052
- package/AddToCartButton-DsSEH9yp.cjs +0 -1
- package/CouponForm-BI_5SBHQ.js +0 -152
- package/CouponForm-D_uu2bLP.cjs +0 -1
- package/CurrencyProvider-Cg-Q6ucj.cjs +0 -1
- package/CurrencyProvider-OzlRN96V.js +0 -120
- package/CurrencyProvider.cjs.js +0 -1
- package/CurrencyProvider.es.js +0 -10
- package/ProductDetailsLayout-BxJH_BxR.cjs +0 -1
- package/ProductDetailsLayout-Dg8dRTYp.js +0 -530
- package/ProductGrid-BdL7iglO.cjs +0 -1
- package/ProductGrid-D3AWM8sr.js +0 -130
- package/actions-AHmBrS5e.cjs +0 -48
- package/actions-j5fuSZX-.js +0 -820
- package/cart-store.cjs.js +0 -1
- package/components/Cart.cjs.js +0 -1
- package/components/Cart.es.js +0 -259
- package/components/CartDrawer.cjs.js +0 -1
- package/components/Checkout.cjs.js +0 -1
- package/components/CurrencySwitcher.cjs.js +0 -1
- package/components/FeaturedProduct.cjs.js +0 -1
- package/components/ProductDetailsLayout.cjs.js +0 -1
- package/components/ProductDetailsLayout.es.js +0 -19
- package/components/ProductGrid.cjs.js +0 -1
- package/components/ProductGrid.es.js +0 -6
- package/coupon-server-C9ySm3I5.cjs +0 -1
- package/customer-C-UPvrYN.cjs +0 -1
- package/invoice-ui-CAnJPu6n.cjs +0 -29
- package/invoice-ui-DtpbTJE1.js +0 -2886
- package/product-actions-CONBF8i6.cjs +0 -251
- package/product-actions-DjlIWCMH.js +0 -691
- package/resolver-Fz_FKsfX.cjs +0 -7
- package/resolver-cfrCaHpE.js +0 -128
- package/server-actions/product-actions.cjs.js +0 -1
- package/shipping-actions-D6zt20gg.cjs +0 -1
- package/states-CWYRxV4B.cjs +0 -1
- package/tax-calculation-Dab89aHd.js +0 -181
- package/tax-calculation-MkDKOEkL.cjs +0 -1
- package/trials-DvZaOtNy.cjs +0 -1
- /package/{components → lib/components}/SimpleTiptapRenderer.cjs.js +0 -0
- /package/{components → lib/components}/SimpleTiptapRenderer.es.js +0 -0
- /package/{currency-constants.cjs.js → lib/currency-constants.cjs.js} +0 -0
- /package/{currency-constants.es.js → lib/currency-constants.es.js} +0 -0
- /package/{currency-rest-client-uolJxUkL.cjs → lib/currency-rest-client.cjs.js} +0 -0
- /package/{currency-rest-client-CwoqdgAP.js → lib/currency-rest-client.es.js} +0 -0
- /package/{currency.cjs.js → lib/currency.cjs.js} +0 -0
- /package/{currency.es.js → lib/currency.es.js} +0 -0
- /package/{types.cjs.js → lib/types.cjs.js} +0 -0
- /package/{types.es.js → lib/types.es.js} +0 -0
- /package/{use-cart.cjs.js → lib/use-cart.cjs.js} +0 -0
- /package/{variation-utils.cjs.js → lib/variation-utils.cjs.js} +0 -0
- /package/{variation-utils.es.js → lib/variation-utils.es.js} +0 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs as a, jsx as r } from "react/jsx-runtime";
|
|
3
|
+
import { useState as i } from "react";
|
|
4
|
+
import { useRouter as V } from "next/navigation";
|
|
5
|
+
import { Label as m, Input as h, Button as t, Badge as W } from "@nextblock-cms/ui";
|
|
6
|
+
import { Plus as j, Trash2 as k, ChevronUp as X, ChevronDown as Y } from "lucide-react";
|
|
7
|
+
function ae({
|
|
8
|
+
attributes: o,
|
|
9
|
+
languages: z,
|
|
10
|
+
createAttributeAction: P,
|
|
11
|
+
deleteAttributeAction: M,
|
|
12
|
+
createTermAction: _,
|
|
13
|
+
deleteTermAction: B,
|
|
14
|
+
reorderTermsAction: L,
|
|
15
|
+
updateTranslationsAction: R
|
|
16
|
+
}) {
|
|
17
|
+
const l = V(), [p, N] = i(""), [x, w] = i(null), [U, y] = i(null), [T, b] = i(null), [A, $] = i(null), [u, C] = i({}), [I, q] = i(
|
|
18
|
+
() => o.reduce((e, s) => (e[s.id] = s.name_translations || {}, e), {})
|
|
19
|
+
), [F, E] = i(
|
|
20
|
+
() => o.reduce((e, s) => {
|
|
21
|
+
for (const n of s.terms)
|
|
22
|
+
e[n.id] = n.value_translations || {};
|
|
23
|
+
return e;
|
|
24
|
+
}, {})
|
|
25
|
+
), v = z.filter((e) => !e.is_default), G = async (e) => {
|
|
26
|
+
e.preventDefault();
|
|
27
|
+
const s = await P({ name: p });
|
|
28
|
+
if (!s.success) {
|
|
29
|
+
alert(s.error || "Failed to create attribute.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
N(""), l.refresh();
|
|
33
|
+
}, H = async (e, s) => {
|
|
34
|
+
e.preventDefault(), w(s);
|
|
35
|
+
const n = await _({
|
|
36
|
+
attributeId: s,
|
|
37
|
+
value: u[s] || ""
|
|
38
|
+
});
|
|
39
|
+
if (w(null), !n.success) {
|
|
40
|
+
alert(n.error || "Failed to create term.");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
C((d) => ({
|
|
44
|
+
...d,
|
|
45
|
+
[s]: ""
|
|
46
|
+
})), l.refresh();
|
|
47
|
+
}, J = async (e) => {
|
|
48
|
+
if (!window.confirm("Delete this attribute and all of its terms?"))
|
|
49
|
+
return;
|
|
50
|
+
const n = await M(e);
|
|
51
|
+
if (!n.success) {
|
|
52
|
+
alert(n.error || "Failed to delete attribute.");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
l.refresh();
|
|
56
|
+
}, K = async (e) => {
|
|
57
|
+
y(e);
|
|
58
|
+
const s = await B(e);
|
|
59
|
+
if (y(null), !s.success) {
|
|
60
|
+
alert(s.error || "Failed to delete term.");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
l.refresh();
|
|
64
|
+
}, S = async (e, s, n) => {
|
|
65
|
+
const d = e.terms.findIndex((g) => g.id === s), c = d + n;
|
|
66
|
+
if (d === -1 || c < 0 || c >= e.terms.length)
|
|
67
|
+
return;
|
|
68
|
+
const f = [...e.terms], [Q] = f.splice(d, 1);
|
|
69
|
+
f.splice(c, 0, Q), b(e.id);
|
|
70
|
+
const D = await L({
|
|
71
|
+
attributeId: e.id,
|
|
72
|
+
orderedTermIds: f.map((g) => g.id)
|
|
73
|
+
});
|
|
74
|
+
if (b(null), !D.success) {
|
|
75
|
+
alert(D.error || "Failed to reorder terms.");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
l.refresh();
|
|
79
|
+
}, O = async (e) => {
|
|
80
|
+
$(e.id);
|
|
81
|
+
const s = await R({
|
|
82
|
+
attributeId: e.id,
|
|
83
|
+
nameTranslations: I[e.id] || {},
|
|
84
|
+
termTranslations: e.terms.map((n) => ({
|
|
85
|
+
termId: n.id,
|
|
86
|
+
valueTranslations: F[n.id] || {}
|
|
87
|
+
}))
|
|
88
|
+
});
|
|
89
|
+
if ($(null), !s.success) {
|
|
90
|
+
alert(s.error || "Failed to save translations.");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
l.refresh();
|
|
94
|
+
};
|
|
95
|
+
return /* @__PURE__ */ a("div", { className: "space-y-6", children: [
|
|
96
|
+
/* @__PURE__ */ r("form", { onSubmit: G, className: "rounded-lg border bg-card p-6 shadow-sm", children: /* @__PURE__ */ a("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
97
|
+
/* @__PURE__ */ a("div", { className: "flex-1 min-w-[220px] space-y-2", children: [
|
|
98
|
+
/* @__PURE__ */ r(m, { htmlFor: "attribute-name", children: "New Attribute" }),
|
|
99
|
+
/* @__PURE__ */ r(
|
|
100
|
+
h,
|
|
101
|
+
{
|
|
102
|
+
id: "attribute-name",
|
|
103
|
+
value: p,
|
|
104
|
+
onChange: (e) => N(e.target.value),
|
|
105
|
+
placeholder: "Material, Size, Color..."
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
] }),
|
|
109
|
+
/* @__PURE__ */ a(t, { type: "submit", disabled: !p.trim(), children: [
|
|
110
|
+
/* @__PURE__ */ r(j, { className: "mr-2 h-4 w-4" }),
|
|
111
|
+
"Create Attribute"
|
|
112
|
+
] })
|
|
113
|
+
] }) }),
|
|
114
|
+
o.length === 0 ? /* @__PURE__ */ r("div", { className: "rounded-lg border border-dashed p-6 text-sm text-muted-foreground", children: "No global attributes have been created yet." }) : /* @__PURE__ */ r("div", { className: "grid gap-6", children: o.map((e) => /* @__PURE__ */ a("div", { className: "rounded-lg border bg-card p-6 shadow-sm", children: [
|
|
115
|
+
/* @__PURE__ */ a("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [
|
|
116
|
+
/* @__PURE__ */ a("div", { children: [
|
|
117
|
+
/* @__PURE__ */ r("h2", { className: "text-lg font-semibold", children: e.name }),
|
|
118
|
+
/* @__PURE__ */ r("p", { className: "text-sm text-muted-foreground", children: e.slug })
|
|
119
|
+
] }),
|
|
120
|
+
/* @__PURE__ */ r(
|
|
121
|
+
t,
|
|
122
|
+
{
|
|
123
|
+
type: "button",
|
|
124
|
+
variant: "ghost",
|
|
125
|
+
size: "icon",
|
|
126
|
+
onClick: () => J(e.id),
|
|
127
|
+
className: "text-muted-foreground hover:text-destructive",
|
|
128
|
+
children: /* @__PURE__ */ r(k, { className: "h-4 w-4" })
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ r("div", { className: "mt-4 space-y-2", children: e.terms.map((s, n) => /* @__PURE__ */ a(
|
|
133
|
+
"div",
|
|
134
|
+
{
|
|
135
|
+
className: "flex flex-wrap items-center justify-between gap-3 rounded-lg border bg-muted/20 px-3 py-2",
|
|
136
|
+
children: [
|
|
137
|
+
/* @__PURE__ */ a("div", { className: "flex items-center gap-2", children: [
|
|
138
|
+
/* @__PURE__ */ r(W, { variant: "secondary", className: "py-1.5", children: s.value }),
|
|
139
|
+
/* @__PURE__ */ a("span", { className: "text-xs text-muted-foreground", children: [
|
|
140
|
+
"Position ",
|
|
141
|
+
n + 1
|
|
142
|
+
] })
|
|
143
|
+
] }),
|
|
144
|
+
/* @__PURE__ */ a("div", { className: "flex items-center gap-1", children: [
|
|
145
|
+
/* @__PURE__ */ r(
|
|
146
|
+
t,
|
|
147
|
+
{
|
|
148
|
+
type: "button",
|
|
149
|
+
variant: "ghost",
|
|
150
|
+
size: "icon",
|
|
151
|
+
className: "h-8 w-8",
|
|
152
|
+
onClick: () => S(e, s.id, -1),
|
|
153
|
+
disabled: n === 0 || T === e.id,
|
|
154
|
+
children: /* @__PURE__ */ r(X, { className: "h-4 w-4" })
|
|
155
|
+
}
|
|
156
|
+
),
|
|
157
|
+
/* @__PURE__ */ r(
|
|
158
|
+
t,
|
|
159
|
+
{
|
|
160
|
+
type: "button",
|
|
161
|
+
variant: "ghost",
|
|
162
|
+
size: "icon",
|
|
163
|
+
className: "h-8 w-8",
|
|
164
|
+
onClick: () => S(e, s.id, 1),
|
|
165
|
+
disabled: n === e.terms.length - 1 || T === e.id,
|
|
166
|
+
children: /* @__PURE__ */ r(Y, { className: "h-4 w-4" })
|
|
167
|
+
}
|
|
168
|
+
),
|
|
169
|
+
/* @__PURE__ */ r(
|
|
170
|
+
t,
|
|
171
|
+
{
|
|
172
|
+
type: "button",
|
|
173
|
+
variant: "ghost",
|
|
174
|
+
size: "icon",
|
|
175
|
+
onClick: () => K(s.id),
|
|
176
|
+
className: "h-8 w-8 text-muted-foreground hover:text-destructive",
|
|
177
|
+
disabled: U === s.id,
|
|
178
|
+
children: /* @__PURE__ */ r(k, { className: "h-4 w-4" })
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
] })
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
s.id
|
|
185
|
+
)) }),
|
|
186
|
+
/* @__PURE__ */ a(
|
|
187
|
+
"form",
|
|
188
|
+
{
|
|
189
|
+
onSubmit: (s) => H(s, e.id),
|
|
190
|
+
className: "mt-6 flex flex-wrap items-end gap-3",
|
|
191
|
+
children: [
|
|
192
|
+
/* @__PURE__ */ a("div", { className: "flex-1 min-w-[220px] space-y-2", children: [
|
|
193
|
+
/* @__PURE__ */ r(m, { htmlFor: `term-input-${e.id}`, children: "Add Term" }),
|
|
194
|
+
/* @__PURE__ */ r(
|
|
195
|
+
h,
|
|
196
|
+
{
|
|
197
|
+
id: `term-input-${e.id}`,
|
|
198
|
+
value: u[e.id] || "",
|
|
199
|
+
onChange: (s) => C((n) => ({
|
|
200
|
+
...n,
|
|
201
|
+
[e.id]: s.target.value
|
|
202
|
+
})),
|
|
203
|
+
placeholder: `Add a term for ${e.name}`
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
] }),
|
|
207
|
+
/* @__PURE__ */ a(
|
|
208
|
+
t,
|
|
209
|
+
{
|
|
210
|
+
type: "submit",
|
|
211
|
+
variant: "outline",
|
|
212
|
+
disabled: !u[e.id]?.trim() || x === e.id,
|
|
213
|
+
children: [
|
|
214
|
+
/* @__PURE__ */ r(j, { className: "mr-2 h-4 w-4" }),
|
|
215
|
+
x === e.id ? "Saving..." : "Add Term"
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
)
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
),
|
|
222
|
+
v.length > 0 && /* @__PURE__ */ a("div", { className: "mt-6 border-t pt-6 space-y-4", children: [
|
|
223
|
+
/* @__PURE__ */ a("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
|
|
224
|
+
/* @__PURE__ */ a("div", { children: [
|
|
225
|
+
/* @__PURE__ */ r("h3", { className: "font-medium", children: "Translations" }),
|
|
226
|
+
/* @__PURE__ */ r("p", { className: "text-sm text-muted-foreground", children: "Translate the attribute label and each term for every active site language." })
|
|
227
|
+
] }),
|
|
228
|
+
/* @__PURE__ */ r(
|
|
229
|
+
t,
|
|
230
|
+
{
|
|
231
|
+
type: "button",
|
|
232
|
+
variant: "outline",
|
|
233
|
+
onClick: () => O(e),
|
|
234
|
+
disabled: A === e.id,
|
|
235
|
+
children: A === e.id ? "Saving..." : "Save Translations"
|
|
236
|
+
}
|
|
237
|
+
)
|
|
238
|
+
] }),
|
|
239
|
+
/* @__PURE__ */ r("div", { className: "grid gap-4 md:grid-cols-2", children: v.map((s) => /* @__PURE__ */ a("div", { className: "space-y-2", children: [
|
|
240
|
+
/* @__PURE__ */ a(m, { htmlFor: `attribute-translation-${e.id}-${s.code}`, children: [
|
|
241
|
+
"Attribute Name (",
|
|
242
|
+
s.name,
|
|
243
|
+
")"
|
|
244
|
+
] }),
|
|
245
|
+
/* @__PURE__ */ r(
|
|
246
|
+
h,
|
|
247
|
+
{
|
|
248
|
+
id: `attribute-translation-${e.id}-${s.code}`,
|
|
249
|
+
value: I[e.id]?.[s.code] || "",
|
|
250
|
+
onChange: (n) => q((d) => ({
|
|
251
|
+
...d,
|
|
252
|
+
[e.id]: {
|
|
253
|
+
...d[e.id] || {},
|
|
254
|
+
[s.code]: n.target.value
|
|
255
|
+
}
|
|
256
|
+
})),
|
|
257
|
+
placeholder: e.name
|
|
258
|
+
}
|
|
259
|
+
)
|
|
260
|
+
] }, `${e.id}-${s.code}`)) }),
|
|
261
|
+
/* @__PURE__ */ r("div", { className: "space-y-3", children: e.terms.map((s) => /* @__PURE__ */ a("div", { className: "rounded-lg border p-4 space-y-3", children: [
|
|
262
|
+
/* @__PURE__ */ a("div", { children: [
|
|
263
|
+
/* @__PURE__ */ r("p", { className: "font-medium", children: s.value }),
|
|
264
|
+
/* @__PURE__ */ r("p", { className: "text-xs text-muted-foreground", children: "Translate this term for each language." })
|
|
265
|
+
] }),
|
|
266
|
+
/* @__PURE__ */ r("div", { className: "grid gap-4 md:grid-cols-2", children: v.map((n) => /* @__PURE__ */ a("div", { className: "space-y-2", children: [
|
|
267
|
+
/* @__PURE__ */ r(m, { htmlFor: `term-translation-${s.id}-${n.code}`, children: n.name }),
|
|
268
|
+
/* @__PURE__ */ r(
|
|
269
|
+
h,
|
|
270
|
+
{
|
|
271
|
+
id: `term-translation-${s.id}-${n.code}`,
|
|
272
|
+
value: F[s.id]?.[n.code] || "",
|
|
273
|
+
onChange: (d) => E((c) => ({
|
|
274
|
+
...c,
|
|
275
|
+
[s.id]: {
|
|
276
|
+
...c[s.id] || {},
|
|
277
|
+
[n.code]: d.target.value
|
|
278
|
+
}
|
|
279
|
+
})),
|
|
280
|
+
placeholder: s.value
|
|
281
|
+
}
|
|
282
|
+
)
|
|
283
|
+
] }, `${s.id}-${n.code}`)) })
|
|
284
|
+
] }, `translations-${s.id}`)) })
|
|
285
|
+
] })
|
|
286
|
+
] }, e.id)) })
|
|
287
|
+
] });
|
|
288
|
+
}
|
|
289
|
+
export {
|
|
290
|
+
ae as AttributeManager
|
|
291
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),s=require("next/link"),i=require("lucide-react"),n=require("@nextblock-cms/ui"),o=require("@nextblock-cms/db/server"),c=require("../actions.cjs.js"),t=require("../server-actions.cjs.js"),g=require("./components/CategoryManager.cjs.js");async function l(){const[r,a]=await Promise.all([c.getCategoriesWithCount(),o.getActiveLanguagesServerSide()]);return e.jsxs("div",{className:"space-y-8 w-full max-w-[1200px] mx-auto px-6 py-8",children:[e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(n.Button,{variant:"outline",size:"icon",asChild:!0,children:e.jsx(s,{href:"/cms/products",children:e.jsx(i.ArrowLeft,{className:"h-4 w-4"})})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Category Management"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Create and manage product categories for organizing your e-commerce catalog."})]})]})}),e.jsx(g.CategoryManager,{initialCategories:r,createCategory:t.createCategoryAction,updateCategory:t.updateCategoryAction,deleteCategory:t.deleteCategoryAction,languages:a})]})}exports.CategoryManagementPage=l;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsxs as t, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import o from "next/link";
|
|
3
|
+
import { ArrowLeft as i } from "lucide-react";
|
|
4
|
+
import { Button as n } from "@nextblock-cms/ui";
|
|
5
|
+
import { getActiveLanguagesServerSide as c } from "@nextblock-cms/db/server";
|
|
6
|
+
import { getCategoriesWithCount as m } from "../actions.es.js";
|
|
7
|
+
import { deleteCategoryAction as s, updateCategoryAction as g, createCategoryAction as l } from "../server-actions.es.js";
|
|
8
|
+
import { CategoryManager as d } from "./components/CategoryManager.es.js";
|
|
9
|
+
async function w() {
|
|
10
|
+
const [r, a] = await Promise.all([
|
|
11
|
+
m(),
|
|
12
|
+
c()
|
|
13
|
+
]);
|
|
14
|
+
return /* @__PURE__ */ t("div", { className: "space-y-8 w-full max-w-[1200px] mx-auto px-6 py-8", children: [
|
|
15
|
+
/* @__PURE__ */ e("div", { className: "flex flex-wrap items-center justify-between gap-4", children: /* @__PURE__ */ t("div", { className: "flex items-center gap-3", children: [
|
|
16
|
+
/* @__PURE__ */ e(n, { variant: "outline", size: "icon", asChild: !0, children: /* @__PURE__ */ e(o, { href: "/cms/products", children: /* @__PURE__ */ e(i, { className: "h-4 w-4" }) }) }),
|
|
17
|
+
/* @__PURE__ */ t("div", { children: [
|
|
18
|
+
/* @__PURE__ */ e("h1", { className: "text-2xl font-bold", children: "Category Management" }),
|
|
19
|
+
/* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: "Create and manage product categories for organizing your e-commerce catalog." })
|
|
20
|
+
] })
|
|
21
|
+
] }) }),
|
|
22
|
+
/* @__PURE__ */ e(
|
|
23
|
+
d,
|
|
24
|
+
{
|
|
25
|
+
initialCategories: r,
|
|
26
|
+
createCategory: l,
|
|
27
|
+
updateCategory: g,
|
|
28
|
+
deleteCategory: s,
|
|
29
|
+
languages: a
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
] });
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
w as CategoryManagementPage
|
|
36
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("react"),c=require("lucide-react"),l=require("sonner"),_=require("next/navigation"),s=require("@nextblock-cms/ui");function O({initialCategories:g=[],languages:q=[],createCategory:A,updateCategory:L,deleteCategory:E}){const y=_.useRouter(),[v,I]=n.useState(g),[o,m]=n.useState(!1),[d,w]=n.useState(null),[u,h]=n.useState(""),[C,x]=n.useState(""),[k,p]=n.useState(""),[S,b]=n.useState({}),[T,f]=n.useState({}),[F,j]=n.useState(!1),z=(q||[]).filter(t=>!t.is_default);n.useEffect(()=>{I(g)},[g]);const D=t=>t.toLowerCase().trim().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"").replace(/-+/g,"-").replace(/^-|-$/g,""),$=t=>{const r=t.target.value;h(r),!F&&!d&&x(D(r))},M=t=>{x(D(t.target.value)),j(!0)},P=t=>{w(t),h(t.name),x(t.slug),p(t.description||""),b(t.name_translations||{}),f(t.description_translations||{}),j(!0)},N=()=>{w(null),h(""),x(""),p(""),b({}),f({}),j(!1)},B=async t=>{if(t.preventDefault(),!u.trim()){l.toast.error("Category name is required.");return}m(!0);const r=l.toast.loading(d?"Updating category...":"Creating category...");try{const a={name:u.trim(),slug:C.trim()||void 0,description:k.trim()||void 0,nameTranslations:S,descriptionTranslations:T};let i;d?i=await L(d.id,a):i=await A(a),i.success?(l.toast.success(d?"Category updated successfully!":"Category created successfully!",{id:r}),N(),y.refresh()):l.toast.error(i.error||"Failed to save category.",{id:r})}catch(a){l.toast.error(a.message||"An unexpected error occurred.",{id:r})}finally{m(!1)}},R=async t=>{const r=`Are you sure you want to delete the category "${t.name}"? This will detach it from any assigned products.`;if(!window.confirm(r))return;m(!0);const a=l.toast.loading("Deleting category...");try{const i=await E(t.id);i.success?(l.toast.success("Category deleted successfully!",{id:a}),d?.id===t.id&&N(),y.refresh()):l.toast.error(i.error||"Failed to delete category.",{id:a})}catch(i){l.toast.error(i.message||"An unexpected error occurred.",{id:a})}finally{m(!1)}};return e.jsxs("div",{className:"grid gap-6 md:grid-cols-12 items-start",children:[e.jsx("div",{className:"md:col-span-4 space-y-4",children:e.jsxs(s.Card,{className:"p-5 shadow-lg border-t-4 border-t-amber-500 bg-card/65 backdrop-blur-md transition-all duration-300",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-4",children:[e.jsx(c.FolderPlus,{className:"h-5 w-5 text-amber-500"}),e.jsx("h2",{className:"text-base font-bold tracking-tight",children:d?"Edit Category":"Add New Category"})]}),e.jsxs("form",{onSubmit:B,className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(s.Label,{htmlFor:"name",className:"text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none",children:"Name"}),e.jsx(s.Input,{id:"name",placeholder:"e.g. T-Shirts",value:u,onChange:$,disabled:o,className:"h-8 text-sm",required:!0})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsxs(s.Label,{htmlFor:"slug",className:"text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none flex items-center justify-between w-full",children:[e.jsx("span",{children:"Slug"}),!F&&!d&&e.jsx("span",{className:"text-[10px] text-amber-600 dark:text-amber-400 capitalize",children:"Auto-generating"})]}),e.jsx(s.Input,{id:"slug",placeholder:"e.g. t-shirts",value:C,onChange:M,disabled:o,className:"h-8 text-sm font-mono"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(s.Label,{htmlFor:"description",className:"text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none",children:"Description"}),e.jsx(s.Textarea,{id:"description",placeholder:"Optional description of the category...",value:k,onChange:t=>p(t.target.value),disabled:o,className:"text-sm min-h-[90px] resize-none"})]}),z.length>0&&e.jsxs("div",{className:"border-t border-border/50 pt-4 mt-4 space-y-4",children:[e.jsx("h3",{className:"text-xs uppercase font-bold text-muted-foreground tracking-wider",children:"Translations"}),z.map(t=>e.jsxs("div",{className:"space-y-3 p-3 rounded-md bg-muted/30 border border-border/30",children:[e.jsx("span",{className:"text-[11px] font-bold text-amber-600 dark:text-amber-400 uppercase tracking-wider",children:t.name}),e.jsxs("div",{className:"space-y-1",children:[e.jsxs(s.Label,{htmlFor:`name-${t.code}`,className:"text-[10px] uppercase font-bold text-muted-foreground tracking-wider leading-none",children:["Name (",t.code,")"]}),e.jsx(s.Input,{id:`name-${t.code}`,placeholder:`Translation for ${u||"Name"}`,value:S[t.code]||"",onChange:r=>b(a=>({...a,[t.code]:r.target.value})),disabled:o,className:"h-8 text-sm"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsxs(s.Label,{htmlFor:`desc-${t.code}`,className:"text-[10px] uppercase font-bold text-muted-foreground tracking-wider leading-none",children:["Description (",t.code,")"]}),e.jsx(s.Textarea,{id:`desc-${t.code}`,placeholder:"Translation for Description",value:T[t.code]||"",onChange:r=>f(a=>({...a,[t.code]:r.target.value})),disabled:o,className:"text-sm min-h-[60px] resize-none"})]})]},t.code))]}),e.jsxs("div",{className:"flex items-center gap-2 pt-2",children:[e.jsx(s.Button,{type:"submit",disabled:o,size:"sm",className:"flex-1 bg-amber-600 hover:bg-amber-500 text-white font-medium shadow-md shadow-amber-600/10 h-8 text-xs cursor-pointer",children:o?e.jsxs(e.Fragment,{children:[e.jsx(c.Loader2,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}),"Saving..."]}):d?"Update Category":"Create Category"}),d&&e.jsx(s.Button,{type:"button",onClick:N,disabled:o,variant:"outline",size:"sm",className:"h-8 text-xs border-dashed cursor-pointer",children:"Cancel"})]})]})]})}),e.jsx("div",{className:"md:col-span-8",children:e.jsxs(s.Card,{className:"p-4 shadow-lg bg-card/65 backdrop-blur-md border border-border/40",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-4 pb-2 border-b border-border/50",children:[e.jsx(c.FolderKanban,{className:"h-5 w-5 text-muted-foreground"}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-bold tracking-tight",children:"Active Categories"}),e.jsx("p",{className:"text-[11px] text-muted-foreground leading-none mt-0.5",children:"Categories are shared globally across languages."})]})]}),v.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 px-4 text-center border-2 border-dashed border-border/60 rounded-lg bg-muted/20 animate-in fade-in duration-300",children:[e.jsx(c.HelpCircle,{className:"h-10 w-10 text-muted-foreground/50 mb-3"}),e.jsx("h3",{className:"text-sm font-bold text-muted-foreground",children:"No Categories Found"}),e.jsx("p",{className:"text-xs text-muted-foreground/80 max-w-sm mt-1",children:"Add your first category using the form on the left to start organizing your catalog products."})]}):e.jsx("div",{className:"overflow-x-auto border rounded-lg bg-background/50",children:e.jsxs("table",{className:"w-full text-left border-collapse text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b bg-muted/40 font-bold uppercase tracking-wider text-muted-foreground/85 select-none",children:[e.jsx("th",{className:"p-3 pl-4",children:"Name"}),e.jsx("th",{className:"p-3",children:"Slug"}),e.jsx("th",{className:"p-3 text-center",children:"Products"}),e.jsx("th",{className:"p-3 pr-4 text-right",children:"Actions"})]})}),e.jsx("tbody",{className:"divide-y divide-border/60",children:v.map(t=>e.jsxs("tr",{className:"hover:bg-muted/10 transition-colors group",children:[e.jsxs("td",{className:"p-3 pl-4",children:[e.jsx("div",{className:"font-semibold text-slate-800 dark:text-slate-100",children:t.name}),t.description&&e.jsx("div",{className:"text-[10px] text-muted-foreground mt-0.5 max-w-xs truncate leading-normal",title:t.description,children:t.description})]}),e.jsx("td",{className:"p-3",children:e.jsxs("code",{className:"px-1.5 py-0.5 rounded bg-muted/65 font-mono text-[10px]",children:["/",t.slug]})}),e.jsx("td",{className:"p-3 text-center",children:e.jsx("span",{className:"inline-flex items-center justify-center px-2 py-0.5 rounded-full text-[10px] font-bold bg-amber-500/10 text-amber-800 dark:text-amber-300 border border-amber-500/15",children:t.productCount})}),e.jsx("td",{className:"p-3 pr-4 text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",children:[e.jsx(s.Button,{variant:"outline",size:"icon",disabled:o,onClick:()=>P(t),className:"h-7 w-7 opacity-85 hover:opacity-100 group-hover:border-amber-500/30 cursor-pointer",title:"Edit Category",children:e.jsx(c.Edit2,{className:"h-3.5 w-3.5 text-muted-foreground group-hover:text-amber-600 dark:group-hover:text-amber-400"})}),e.jsx(s.Button,{variant:"outline",size:"icon",disabled:o,onClick:()=>R(t),className:"h-7 w-7 opacity-85 hover:opacity-100 group-hover:border-red-500/30 cursor-pointer",title:"Delete Category",children:e.jsx(c.Trash2,{className:"h-3.5 w-3.5 text-muted-foreground group-hover:text-red-500"})})]})})]},t.id))})]})})]})})]})}exports.CategoryManager=O;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs as t, jsx as r, Fragment as R } from "react/jsx-runtime";
|
|
3
|
+
import { useState as i, useEffect as G } from "react";
|
|
4
|
+
import { FolderPlus as J, Loader2 as Q, FolderKanban as V, HelpCircle as W, Edit2 as X, Trash2 as Y } from "lucide-react";
|
|
5
|
+
import { toast as l } from "sonner";
|
|
6
|
+
import { useRouter as Z } from "next/navigation";
|
|
7
|
+
import { Card as j, Label as c, Input as w, Textarea as I, Button as g } from "@nextblock-cms/ui";
|
|
8
|
+
function oe({
|
|
9
|
+
initialCategories: h = [],
|
|
10
|
+
languages: L = [],
|
|
11
|
+
createCategory: M,
|
|
12
|
+
updateCategory: P,
|
|
13
|
+
deleteCategory: _
|
|
14
|
+
}) {
|
|
15
|
+
const C = Z(), [k, q] = i(h), [d, m] = i(!1), [o, F] = i(null), [u, b] = i(""), [S, p] = i(""), [T, x] = i(""), [z, f] = i({}), [D, N] = i({}), [A, y] = i(!1), E = (L || []).filter((e) => !e.is_default);
|
|
16
|
+
G(() => {
|
|
17
|
+
q(h);
|
|
18
|
+
}, [h]);
|
|
19
|
+
const $ = (e) => e.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, ""), U = (e) => {
|
|
20
|
+
const a = e.target.value;
|
|
21
|
+
b(a), !A && !o && p($(a));
|
|
22
|
+
}, B = (e) => {
|
|
23
|
+
p($(e.target.value)), y(!0);
|
|
24
|
+
}, H = (e) => {
|
|
25
|
+
F(e), b(e.name), p(e.slug), x(e.description || ""), f(e.name_translations || {}), N(e.description_translations || {}), y(!0);
|
|
26
|
+
}, v = () => {
|
|
27
|
+
F(null), b(""), p(""), x(""), f({}), N({}), y(!1);
|
|
28
|
+
}, K = async (e) => {
|
|
29
|
+
if (e.preventDefault(), !u.trim()) {
|
|
30
|
+
l.error("Category name is required.");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
m(!0);
|
|
34
|
+
const a = l.loading(
|
|
35
|
+
o ? "Updating category..." : "Creating category..."
|
|
36
|
+
);
|
|
37
|
+
try {
|
|
38
|
+
const s = {
|
|
39
|
+
name: u.trim(),
|
|
40
|
+
slug: S.trim() || void 0,
|
|
41
|
+
description: T.trim() || void 0,
|
|
42
|
+
nameTranslations: z,
|
|
43
|
+
descriptionTranslations: D
|
|
44
|
+
};
|
|
45
|
+
let n;
|
|
46
|
+
o ? n = await P(o.id, s) : n = await M(s), n.success ? (l.success(
|
|
47
|
+
o ? "Category updated successfully!" : "Category created successfully!",
|
|
48
|
+
{ id: a }
|
|
49
|
+
), v(), C.refresh()) : l.error(n.error || "Failed to save category.", { id: a });
|
|
50
|
+
} catch (s) {
|
|
51
|
+
l.error(s.message || "An unexpected error occurred.", { id: a });
|
|
52
|
+
} finally {
|
|
53
|
+
m(!1);
|
|
54
|
+
}
|
|
55
|
+
}, O = async (e) => {
|
|
56
|
+
const a = `Are you sure you want to delete the category "${e.name}"? This will detach it from any assigned products.`;
|
|
57
|
+
if (!window.confirm(a))
|
|
58
|
+
return;
|
|
59
|
+
m(!0);
|
|
60
|
+
const s = l.loading("Deleting category...");
|
|
61
|
+
try {
|
|
62
|
+
const n = await _(e.id);
|
|
63
|
+
n.success ? (l.success("Category deleted successfully!", { id: s }), o?.id === e.id && v(), C.refresh()) : l.error(n.error || "Failed to delete category.", { id: s });
|
|
64
|
+
} catch (n) {
|
|
65
|
+
l.error(n.message || "An unexpected error occurred.", { id: s });
|
|
66
|
+
} finally {
|
|
67
|
+
m(!1);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
return /* @__PURE__ */ t("div", { className: "grid gap-6 md:grid-cols-12 items-start", children: [
|
|
71
|
+
/* @__PURE__ */ r("div", { className: "md:col-span-4 space-y-4", children: /* @__PURE__ */ t(j, { className: "p-5 shadow-lg border-t-4 border-t-amber-500 bg-card/65 backdrop-blur-md transition-all duration-300", children: [
|
|
72
|
+
/* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-4", children: [
|
|
73
|
+
/* @__PURE__ */ r(J, { className: "h-5 w-5 text-amber-500" }),
|
|
74
|
+
/* @__PURE__ */ r("h2", { className: "text-base font-bold tracking-tight", children: o ? "Edit Category" : "Add New Category" })
|
|
75
|
+
] }),
|
|
76
|
+
/* @__PURE__ */ t("form", { onSubmit: K, className: "space-y-4", children: [
|
|
77
|
+
/* @__PURE__ */ t("div", { className: "space-y-1", children: [
|
|
78
|
+
/* @__PURE__ */ r(c, { htmlFor: "name", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Name" }),
|
|
79
|
+
/* @__PURE__ */ r(
|
|
80
|
+
w,
|
|
81
|
+
{
|
|
82
|
+
id: "name",
|
|
83
|
+
placeholder: "e.g. T-Shirts",
|
|
84
|
+
value: u,
|
|
85
|
+
onChange: U,
|
|
86
|
+
disabled: d,
|
|
87
|
+
className: "h-8 text-sm",
|
|
88
|
+
required: !0
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
] }),
|
|
92
|
+
/* @__PURE__ */ t("div", { className: "space-y-1", children: [
|
|
93
|
+
/* @__PURE__ */ t(c, { htmlFor: "slug", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none flex items-center justify-between w-full", children: [
|
|
94
|
+
/* @__PURE__ */ r("span", { children: "Slug" }),
|
|
95
|
+
!A && !o && /* @__PURE__ */ r("span", { className: "text-[10px] text-amber-600 dark:text-amber-400 capitalize", children: "Auto-generating" })
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ r(
|
|
98
|
+
w,
|
|
99
|
+
{
|
|
100
|
+
id: "slug",
|
|
101
|
+
placeholder: "e.g. t-shirts",
|
|
102
|
+
value: S,
|
|
103
|
+
onChange: B,
|
|
104
|
+
disabled: d,
|
|
105
|
+
className: "h-8 text-sm font-mono"
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
] }),
|
|
109
|
+
/* @__PURE__ */ t("div", { className: "space-y-1", children: [
|
|
110
|
+
/* @__PURE__ */ r(c, { htmlFor: "description", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Description" }),
|
|
111
|
+
/* @__PURE__ */ r(
|
|
112
|
+
I,
|
|
113
|
+
{
|
|
114
|
+
id: "description",
|
|
115
|
+
placeholder: "Optional description of the category...",
|
|
116
|
+
value: T,
|
|
117
|
+
onChange: (e) => x(e.target.value),
|
|
118
|
+
disabled: d,
|
|
119
|
+
className: "text-sm min-h-[90px] resize-none"
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
] }),
|
|
123
|
+
E.length > 0 && /* @__PURE__ */ t("div", { className: "border-t border-border/50 pt-4 mt-4 space-y-4", children: [
|
|
124
|
+
/* @__PURE__ */ r("h3", { className: "text-xs uppercase font-bold text-muted-foreground tracking-wider", children: "Translations" }),
|
|
125
|
+
E.map((e) => /* @__PURE__ */ t("div", { className: "space-y-3 p-3 rounded-md bg-muted/30 border border-border/30", children: [
|
|
126
|
+
/* @__PURE__ */ r("span", { className: "text-[11px] font-bold text-amber-600 dark:text-amber-400 uppercase tracking-wider", children: e.name }),
|
|
127
|
+
/* @__PURE__ */ t("div", { className: "space-y-1", children: [
|
|
128
|
+
/* @__PURE__ */ t(c, { htmlFor: `name-${e.code}`, className: "text-[10px] uppercase font-bold text-muted-foreground tracking-wider leading-none", children: [
|
|
129
|
+
"Name (",
|
|
130
|
+
e.code,
|
|
131
|
+
")"
|
|
132
|
+
] }),
|
|
133
|
+
/* @__PURE__ */ r(
|
|
134
|
+
w,
|
|
135
|
+
{
|
|
136
|
+
id: `name-${e.code}`,
|
|
137
|
+
placeholder: `Translation for ${u || "Name"}`,
|
|
138
|
+
value: z[e.code] || "",
|
|
139
|
+
onChange: (a) => f((s) => ({ ...s, [e.code]: a.target.value })),
|
|
140
|
+
disabled: d,
|
|
141
|
+
className: "h-8 text-sm"
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ t("div", { className: "space-y-1", children: [
|
|
146
|
+
/* @__PURE__ */ t(c, { htmlFor: `desc-${e.code}`, className: "text-[10px] uppercase font-bold text-muted-foreground tracking-wider leading-none", children: [
|
|
147
|
+
"Description (",
|
|
148
|
+
e.code,
|
|
149
|
+
")"
|
|
150
|
+
] }),
|
|
151
|
+
/* @__PURE__ */ r(
|
|
152
|
+
I,
|
|
153
|
+
{
|
|
154
|
+
id: `desc-${e.code}`,
|
|
155
|
+
placeholder: "Translation for Description",
|
|
156
|
+
value: D[e.code] || "",
|
|
157
|
+
onChange: (a) => N((s) => ({ ...s, [e.code]: a.target.value })),
|
|
158
|
+
disabled: d,
|
|
159
|
+
className: "text-sm min-h-[60px] resize-none"
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
] })
|
|
163
|
+
] }, e.code))
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ t("div", { className: "flex items-center gap-2 pt-2", children: [
|
|
166
|
+
/* @__PURE__ */ r(
|
|
167
|
+
g,
|
|
168
|
+
{
|
|
169
|
+
type: "submit",
|
|
170
|
+
disabled: d,
|
|
171
|
+
size: "sm",
|
|
172
|
+
className: "flex-1 bg-amber-600 hover:bg-amber-500 text-white font-medium shadow-md shadow-amber-600/10 h-8 text-xs cursor-pointer",
|
|
173
|
+
children: d ? /* @__PURE__ */ t(R, { children: [
|
|
174
|
+
/* @__PURE__ */ r(Q, { className: "mr-1.5 h-3.5 w-3.5 animate-spin" }),
|
|
175
|
+
"Saving..."
|
|
176
|
+
] }) : o ? "Update Category" : "Create Category"
|
|
177
|
+
}
|
|
178
|
+
),
|
|
179
|
+
o && /* @__PURE__ */ r(
|
|
180
|
+
g,
|
|
181
|
+
{
|
|
182
|
+
type: "button",
|
|
183
|
+
onClick: v,
|
|
184
|
+
disabled: d,
|
|
185
|
+
variant: "outline",
|
|
186
|
+
size: "sm",
|
|
187
|
+
className: "h-8 text-xs border-dashed cursor-pointer",
|
|
188
|
+
children: "Cancel"
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
] })
|
|
192
|
+
] })
|
|
193
|
+
] }) }),
|
|
194
|
+
/* @__PURE__ */ r("div", { className: "md:col-span-8", children: /* @__PURE__ */ t(j, { className: "p-4 shadow-lg bg-card/65 backdrop-blur-md border border-border/40", children: [
|
|
195
|
+
/* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-4 pb-2 border-b border-border/50", children: [
|
|
196
|
+
/* @__PURE__ */ r(V, { className: "h-5 w-5 text-muted-foreground" }),
|
|
197
|
+
/* @__PURE__ */ t("div", { children: [
|
|
198
|
+
/* @__PURE__ */ r("h2", { className: "text-base font-bold tracking-tight", children: "Active Categories" }),
|
|
199
|
+
/* @__PURE__ */ r("p", { className: "text-[11px] text-muted-foreground leading-none mt-0.5", children: "Categories are shared globally across languages." })
|
|
200
|
+
] })
|
|
201
|
+
] }),
|
|
202
|
+
k.length === 0 ? /* @__PURE__ */ t("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center border-2 border-dashed border-border/60 rounded-lg bg-muted/20 animate-in fade-in duration-300", children: [
|
|
203
|
+
/* @__PURE__ */ r(W, { className: "h-10 w-10 text-muted-foreground/50 mb-3" }),
|
|
204
|
+
/* @__PURE__ */ r("h3", { className: "text-sm font-bold text-muted-foreground", children: "No Categories Found" }),
|
|
205
|
+
/* @__PURE__ */ r("p", { className: "text-xs text-muted-foreground/80 max-w-sm mt-1", children: "Add your first category using the form on the left to start organizing your catalog products." })
|
|
206
|
+
] }) : /* @__PURE__ */ r("div", { className: "overflow-x-auto border rounded-lg bg-background/50", children: /* @__PURE__ */ t("table", { className: "w-full text-left border-collapse text-xs", children: [
|
|
207
|
+
/* @__PURE__ */ r("thead", { children: /* @__PURE__ */ t("tr", { className: "border-b bg-muted/40 font-bold uppercase tracking-wider text-muted-foreground/85 select-none", children: [
|
|
208
|
+
/* @__PURE__ */ r("th", { className: "p-3 pl-4", children: "Name" }),
|
|
209
|
+
/* @__PURE__ */ r("th", { className: "p-3", children: "Slug" }),
|
|
210
|
+
/* @__PURE__ */ r("th", { className: "p-3 text-center", children: "Products" }),
|
|
211
|
+
/* @__PURE__ */ r("th", { className: "p-3 pr-4 text-right", children: "Actions" })
|
|
212
|
+
] }) }),
|
|
213
|
+
/* @__PURE__ */ r("tbody", { className: "divide-y divide-border/60", children: k.map((e) => /* @__PURE__ */ t(
|
|
214
|
+
"tr",
|
|
215
|
+
{
|
|
216
|
+
className: "hover:bg-muted/10 transition-colors group",
|
|
217
|
+
children: [
|
|
218
|
+
/* @__PURE__ */ t("td", { className: "p-3 pl-4", children: [
|
|
219
|
+
/* @__PURE__ */ r("div", { className: "font-semibold text-slate-800 dark:text-slate-100", children: e.name }),
|
|
220
|
+
e.description && /* @__PURE__ */ r("div", { className: "text-[10px] text-muted-foreground mt-0.5 max-w-xs truncate leading-normal", title: e.description, children: e.description })
|
|
221
|
+
] }),
|
|
222
|
+
/* @__PURE__ */ r("td", { className: "p-3", children: /* @__PURE__ */ t("code", { className: "px-1.5 py-0.5 rounded bg-muted/65 font-mono text-[10px]", children: [
|
|
223
|
+
"/",
|
|
224
|
+
e.slug
|
|
225
|
+
] }) }),
|
|
226
|
+
/* @__PURE__ */ r("td", { className: "p-3 text-center", children: /* @__PURE__ */ r("span", { className: "inline-flex items-center justify-center px-2 py-0.5 rounded-full text-[10px] font-bold bg-amber-500/10 text-amber-800 dark:text-amber-300 border border-amber-500/15", children: e.productCount }) }),
|
|
227
|
+
/* @__PURE__ */ r("td", { className: "p-3 pr-4 text-right", children: /* @__PURE__ */ t("div", { className: "flex items-center justify-end gap-1.5", children: [
|
|
228
|
+
/* @__PURE__ */ r(
|
|
229
|
+
g,
|
|
230
|
+
{
|
|
231
|
+
variant: "outline",
|
|
232
|
+
size: "icon",
|
|
233
|
+
disabled: d,
|
|
234
|
+
onClick: () => H(e),
|
|
235
|
+
className: "h-7 w-7 opacity-85 hover:opacity-100 group-hover:border-amber-500/30 cursor-pointer",
|
|
236
|
+
title: "Edit Category",
|
|
237
|
+
children: /* @__PURE__ */ r(X, { className: "h-3.5 w-3.5 text-muted-foreground group-hover:text-amber-600 dark:group-hover:text-amber-400" })
|
|
238
|
+
}
|
|
239
|
+
),
|
|
240
|
+
/* @__PURE__ */ r(
|
|
241
|
+
g,
|
|
242
|
+
{
|
|
243
|
+
variant: "outline",
|
|
244
|
+
size: "icon",
|
|
245
|
+
disabled: d,
|
|
246
|
+
onClick: () => O(e),
|
|
247
|
+
className: "h-7 w-7 opacity-85 hover:opacity-100 group-hover:border-red-500/30 cursor-pointer",
|
|
248
|
+
title: "Delete Category",
|
|
249
|
+
children: /* @__PURE__ */ r(Y, { className: "h-3.5 w-3.5 text-muted-foreground group-hover:text-red-500" })
|
|
250
|
+
}
|
|
251
|
+
)
|
|
252
|
+
] }) })
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
e.id
|
|
256
|
+
)) })
|
|
257
|
+
] }) })
|
|
258
|
+
] }) })
|
|
259
|
+
] });
|
|
260
|
+
}
|
|
261
|
+
export {
|
|
262
|
+
oe as CategoryManager
|
|
263
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("react"),t=require("@nextblock-cms/ui"),j=require("../actions.cjs.js"),L=require("next/navigation"),h=require("lucide-react");function k({productId:i,currentLanguageId:C,translationGroupId:l,allSiteLanguages:x}){const[d,p]=n.useState(!1),[r,S]=n.useState(null),[y,v]=n.useState([]),[m,f]=n.useState(!1),[o,c]=n.useState(null),[u,b]=n.useTransition(),P=L.useRouter();n.useEffect(()=>{d&&l&&(async()=>{f(!0);try{const g=(await j.getProductTranslations(l)).filter(D=>D.id!==i);v(g)}catch(a){console.error("Error fetching translations:",a)}finally{f(!1)}})()},[d,l,i]);const T=async()=>{if(!r){c({type:"error",text:"Please select a source version to copy from."});return}c(null),b(async()=>{const s=await j.copyProductFromLanguageAction(i,r);s.success?(c({type:"success",text:"Content copied successfully. The page will now refresh."}),setTimeout(()=>{p(!1),P.refresh()},1500)):c({type:"error",text:s.error||"Failed to copy content."})})},w=x.find(s=>s.id===C);return e.jsxs(t.Dialog,{open:d,onOpenChange:p,children:[e.jsx(t.DialogTrigger,{asChild:!0,children:e.jsxs(t.Button,{variant:"outline",title:"Copy content from another language",children:[e.jsx(h.Copy,{className:"h-4 w-4 mr-2"}),"Copy Content..."]})}),e.jsxs(t.DialogContent,{children:[e.jsxs(t.DialogHeader,{children:[e.jsx(t.DialogTitle,{children:"Copy Content from Another Language"}),e.jsxs(t.DialogDescription,{children:["Select a source version to copy from. This will replace the title, description, and media of the current product (",w?.name,"). This action cannot be undone."]})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(t.Label,{htmlFor:"sourceProduct",children:"Select Source Version"}),e.jsxs(t.Select,{onValueChange:s=>S(s),disabled:u||m,value:r||void 0,children:[e.jsx(t.SelectTrigger,{id:"sourceProduct",children:e.jsx(t.SelectValue,{placeholder:m?"Loading versions...":"Select a version..."})}),e.jsx(t.SelectContent,{children:y.length>0?y.map(s=>{const a=x.find(g=>g.id===s.language_id);return e.jsxs(t.SelectItem,{value:s.id,children:[s.title," (",a?.name||"Unknown Language",")"]},s.id)}):e.jsx(t.SelectItem,{value:"none",disabled:!0,children:"No other versions available"})})]})]}),o&&e.jsxs("div",{className:`p-3 rounded-md text-sm flex items-center gap-2 ${o.type==="success"?"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400":"bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400"}`,children:[o.type==="success"?e.jsx(h.CheckCircle2,{className:"h-5 w-5"}):e.jsx(h.AlertCircle,{className:"h-5 w-5"}),o.text]})]}),e.jsxs(t.DialogFooter,{children:[e.jsx(t.DialogClose,{asChild:!0,children:e.jsx(t.Button,{variant:"outline",children:"Cancel"})}),e.jsx(t.Button,{onClick:T,disabled:u||!r||r==="none",children:u?"Copying...":"Copy Content & Replace"})]})]})]})}exports.CopyProductFromLanguage=k;
|