@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.
Files changed (277) hide show
  1. package/index.cjs.js +1 -1
  2. package/index.es.js +136 -533
  3. package/lib/CurrencyProvider.cjs.js +1 -0
  4. package/lib/CurrencyProvider.es.js +99 -0
  5. package/lib/cart-store.cjs.js +1 -0
  6. package/{cart-store.es.js → lib/cart-store.es.js} +13 -13
  7. package/lib/components/AccountNavigationMenu.cjs.js +1 -0
  8. package/lib/components/AccountNavigationMenu.es.js +44 -0
  9. package/lib/components/AddToCartButton.cjs.js +1 -0
  10. package/{AddToCartButton-ffE0DhHu.js → lib/components/AddToCartButton.es.js} +14 -13
  11. package/lib/components/Cart.cjs.js +1 -0
  12. package/lib/components/Cart.es.js +148 -0
  13. package/lib/components/CartDrawer.cjs.js +1 -0
  14. package/{components → lib/components}/CartDrawer.es.js +15 -14
  15. package/{components → lib/components}/CartIcon.cjs.js +1 -1
  16. package/{components → lib/components}/CartIcon.es.js +1 -0
  17. package/lib/components/Checkout.cjs.js +1 -0
  18. package/{components → lib/components}/Checkout.es.js +330 -363
  19. package/lib/components/CouponForm.cjs.js +1 -0
  20. package/lib/components/CouponForm.es.js +136 -0
  21. package/lib/components/CurrencySwitcher.cjs.js +1 -0
  22. package/{components → lib/components}/CurrencySwitcher.es.js +5 -4
  23. package/lib/components/CustomerProfileForm.cjs.js +1 -0
  24. package/lib/components/CustomerProfileForm.es.js +355 -0
  25. package/lib/components/FeaturedProduct.cjs.js +1 -0
  26. package/{components → lib/components}/FeaturedProduct.es.js +9 -8
  27. package/lib/components/InvoiceDocument.cjs.js +1 -0
  28. package/lib/components/InvoiceDocument.es.js +196 -0
  29. package/lib/components/InvoiceViewerShell.cjs.js +29 -0
  30. package/lib/components/InvoiceViewerShell.es.js +100 -0
  31. package/lib/components/ProductCard.cjs.js +1 -0
  32. package/lib/components/ProductCard.es.js +119 -0
  33. package/lib/components/ProductDetailsLayout.cjs.js +1 -0
  34. package/lib/components/ProductDetailsLayout.es.js +361 -0
  35. package/lib/components/ProductGallery.cjs.js +1 -0
  36. package/lib/components/ProductGallery.es.js +41 -0
  37. package/lib/components/ProductGrid.cjs.js +1 -0
  38. package/lib/components/ProductGrid.es.js +19 -0
  39. package/lib/components/ShippingEstimator.cjs.js +1 -0
  40. package/lib/components/ShippingEstimator.es.js +125 -0
  41. package/lib/components/SubscriptionSelector.cjs.js +1 -0
  42. package/lib/components/SubscriptionSelector.es.js +140 -0
  43. package/lib/countries.cjs.js +1 -0
  44. package/lib/countries.es.js +77 -0
  45. package/lib/coupon-server.cjs.js +1 -0
  46. package/{coupon-server-DUKVtyYs.js → lib/coupon-server.es.js} +68 -82
  47. package/lib/coupons.cjs.js +1 -0
  48. package/lib/coupons.es.js +17 -0
  49. package/lib/currency-store.cjs.js +1 -0
  50. package/lib/currency-store.es.js +27 -0
  51. package/lib/currency-sync.cjs.js +1 -0
  52. package/lib/currency-sync.es.js +180 -0
  53. package/lib/customer-addresses.cjs.js +1 -0
  54. package/lib/customer-addresses.es.js +116 -0
  55. package/lib/customer-orders.cjs.js +1 -0
  56. package/lib/customer-orders.es.js +45 -0
  57. package/lib/customer.cjs.js +1 -0
  58. package/{customer-C3xccjUg.js → lib/customer.es.js} +15 -14
  59. package/lib/export-helpers.cjs.js +1 -0
  60. package/lib/export-helpers.es.js +56 -0
  61. package/lib/factory.cjs.js +1 -0
  62. package/lib/factory.es.js +8 -0
  63. package/lib/freemius-coupons.cjs.js +1 -0
  64. package/lib/freemius-coupons.es.js +272 -0
  65. package/lib/freemius-order-sync.cjs.js +1 -0
  66. package/lib/freemius-order-sync.es.js +284 -0
  67. package/lib/inventory-settings.cjs.js +1 -0
  68. package/lib/inventory-settings.es.js +86 -0
  69. package/lib/invoice-server.cjs.js +33 -0
  70. package/lib/invoice-server.es.js +141 -0
  71. package/lib/invoice-ui.cjs.js +1 -0
  72. package/lib/invoice-ui.es.js +71 -0
  73. package/lib/invoice.cjs.js +1 -0
  74. package/lib/invoice.es.js +102 -0
  75. package/lib/order-inventory.cjs.js +61 -0
  76. package/lib/order-inventory.es.js +128 -0
  77. package/lib/order-tax-details.cjs.js +1 -0
  78. package/lib/order-tax-details.es.js +164 -0
  79. package/lib/pages/cms/coupons/CouponEditorForm.cjs.js +1 -0
  80. package/lib/pages/cms/coupons/CouponEditorForm.es.js +189 -0
  81. package/lib/pages/cms/coupons/CouponsPage.cjs.js +5 -0
  82. package/lib/pages/cms/coupons/CouponsPage.es.js +171 -0
  83. package/lib/pages/cms/coupons/CreateCouponDialog.cjs.js +1 -0
  84. package/lib/pages/cms/coupons/CreateCouponDialog.es.js +35 -0
  85. package/lib/pages/cms/coupons/EditCouponPage.cjs.js +1 -0
  86. package/lib/pages/cms/coupons/EditCouponPage.es.js +48 -0
  87. package/lib/pages/cms/coupons/ProductScopePicker.cjs.js +1 -0
  88. package/lib/pages/cms/coupons/ProductScopePicker.es.js +120 -0
  89. package/lib/pages/cms/coupons/actions.cjs.js +1 -0
  90. package/lib/pages/cms/coupons/actions.es.js +128 -0
  91. package/lib/pages/cms/coupons/product-options.cjs.js +1 -0
  92. package/lib/pages/cms/coupons/product-options.es.js +27 -0
  93. package/lib/pages/cms/orders/ExportReportsDialog.cjs.js +1 -0
  94. package/lib/pages/cms/orders/ExportReportsDialog.es.js +130 -0
  95. package/lib/pages/cms/orders/OrderDetailPage.cjs.js +1 -0
  96. package/lib/pages/cms/orders/OrderDetailPage.es.js +137 -0
  97. package/lib/pages/cms/orders/OrderPrintButton.cjs.js +1 -0
  98. package/lib/pages/cms/orders/OrderPrintButton.es.js +22 -0
  99. package/lib/pages/cms/orders/OrderStatusForm.cjs.js +1 -0
  100. package/lib/pages/cms/orders/OrderStatusForm.es.js +71 -0
  101. package/lib/pages/cms/orders/OrdersPage.cjs.js +1 -0
  102. package/lib/pages/cms/orders/OrdersPage.es.js +104 -0
  103. package/lib/pages/cms/orders/actions.cjs.js +7 -0
  104. package/lib/pages/cms/orders/actions.es.js +71 -0
  105. package/lib/pages/cms/orders/export-actions.cjs.js +1 -0
  106. package/lib/pages/cms/orders/export-actions.es.js +27 -0
  107. package/lib/pages/cms/orders/server-actions.cjs.js +1 -0
  108. package/lib/pages/cms/orders/server-actions.es.js +55 -0
  109. package/lib/pages/cms/payments/PaymentsClient.cjs.js +1 -0
  110. package/lib/pages/cms/payments/PaymentsClient.es.js +188 -0
  111. package/lib/pages/cms/payments/PaymentsPage.cjs.js +1 -0
  112. package/lib/pages/cms/payments/PaymentsPage.es.js +29 -0
  113. package/lib/pages/cms/payments/actions.cjs.js +1 -0
  114. package/lib/pages/cms/payments/actions.es.js +23 -0
  115. package/lib/pages/cms/payments/queries.cjs.js +1 -0
  116. package/lib/pages/cms/payments/queries.es.js +30 -0
  117. package/lib/pages/cms/products/ProductsPage.cjs.js +1 -0
  118. package/lib/pages/cms/products/ProductsPage.es.js +46 -0
  119. package/lib/pages/cms/products/_id_/edit/EditProductPage.cjs.js +1 -0
  120. package/lib/pages/cms/products/_id_/edit/EditProductPage.es.js +156 -0
  121. package/lib/pages/cms/products/actions.cjs.js +44 -0
  122. package/lib/pages/cms/products/actions.es.js +175 -0
  123. package/lib/pages/cms/products/attributes/AttributeManagementPage.cjs.js +1 -0
  124. package/lib/pages/cms/products/attributes/AttributeManagementPage.es.js +48 -0
  125. package/lib/pages/cms/products/attributes/components/AttributeManager.cjs.js +1 -0
  126. package/lib/pages/cms/products/attributes/components/AttributeManager.es.js +291 -0
  127. package/lib/pages/cms/products/categories/CategoryManagementPage.cjs.js +1 -0
  128. package/lib/pages/cms/products/categories/CategoryManagementPage.es.js +36 -0
  129. package/lib/pages/cms/products/categories/components/CategoryManager.cjs.js +1 -0
  130. package/lib/pages/cms/products/categories/components/CategoryManager.es.js +263 -0
  131. package/lib/pages/cms/products/components/CopyProductFromLanguage.cjs.js +1 -0
  132. package/lib/pages/cms/products/components/CopyProductFromLanguage.es.js +114 -0
  133. package/lib/pages/cms/products/components/CurrencyPriceFields.cjs.js +1 -0
  134. package/lib/pages/cms/products/components/CurrencyPriceFields.es.js +107 -0
  135. package/lib/pages/cms/products/components/DeleteProductButton.cjs.js +1 -0
  136. package/lib/pages/cms/products/components/DeleteProductButton.es.js +48 -0
  137. package/lib/pages/cms/products/components/FreemiusPricingDashboard.cjs.js +1 -0
  138. package/lib/pages/cms/products/components/FreemiusPricingDashboard.es.js +86 -0
  139. package/lib/pages/cms/products/components/ProductCategorySelector.cjs.js +1 -0
  140. package/lib/pages/cms/products/components/ProductCategorySelector.es.js +160 -0
  141. package/lib/pages/cms/products/components/ProductForm.cjs.js +1 -0
  142. package/lib/pages/cms/products/components/ProductForm.es.js +702 -0
  143. package/lib/pages/cms/products/components/ProductMediaManager.cjs.js +1 -0
  144. package/lib/pages/cms/products/components/ProductMediaManager.es.js +104 -0
  145. package/lib/pages/cms/products/components/ProductsBulkTable.cjs.js +1 -0
  146. package/lib/pages/cms/products/components/ProductsBulkTable.es.js +228 -0
  147. package/lib/pages/cms/products/components/SaleScheduleFields.cjs.js +1 -0
  148. package/lib/pages/cms/products/components/SaleScheduleFields.es.js +137 -0
  149. package/lib/pages/cms/products/components/SyncFreemiusButton.cjs.js +1 -0
  150. package/lib/pages/cms/products/components/SyncFreemiusButton.es.js +36 -0
  151. package/lib/pages/cms/products/components/SyncFreemiusPricingButton.cjs.js +1 -0
  152. package/lib/pages/cms/products/components/SyncFreemiusPricingButton.es.js +40 -0
  153. package/lib/pages/cms/products/components/VariationsEditor.cjs.js +1 -0
  154. package/lib/pages/cms/products/components/VariationsEditor.es.js +408 -0
  155. package/lib/pages/cms/products/inventory/InventoryPage.cjs.js +1 -0
  156. package/lib/pages/cms/products/inventory/InventoryPage.es.js +16 -0
  157. package/lib/pages/cms/products/inventory/InventoryTableClient.cjs.js +2 -0
  158. package/lib/pages/cms/products/inventory/InventoryTableClient.es.js +214 -0
  159. package/lib/pages/cms/products/inventory/actions.cjs.js +3 -0
  160. package/lib/pages/cms/products/inventory/actions.es.js +95 -0
  161. package/lib/pages/cms/products/new/NewProductPage.cjs.js +1 -0
  162. package/lib/pages/cms/products/new/NewProductPage.es.js +76 -0
  163. package/lib/pages/cms/products/product-price-sync.cjs.js +1 -0
  164. package/lib/pages/cms/products/product-price-sync.es.js +98 -0
  165. package/lib/pages/cms/products/server-actions.cjs.js +1 -0
  166. package/lib/pages/cms/products/server-actions.es.js +193 -0
  167. package/lib/pages/cms/shipping/ShippingPage.cjs.js +5 -0
  168. package/lib/pages/cms/shipping/ShippingPage.es.js +211 -0
  169. package/lib/pages/cms/shipping/components/RateForm.cjs.js +1 -0
  170. package/lib/pages/cms/shipping/components/RateForm.es.js +441 -0
  171. package/lib/pages/cms/shipping/components/ZoneForm.cjs.js +1 -0
  172. package/lib/pages/cms/shipping/components/ZoneForm.es.js +228 -0
  173. package/lib/pages/cms/shipping/server-actions.cjs.js +1 -0
  174. package/lib/pages/cms/shipping/server-actions.es.js +159 -0
  175. package/lib/pages/cms/taxes/TaxesPage.cjs.js +1 -0
  176. package/lib/pages/cms/taxes/TaxesPage.es.js +172 -0
  177. package/lib/pages/cms/taxes/actions.cjs.js +1 -0
  178. package/lib/pages/cms/taxes/actions.es.js +57 -0
  179. package/lib/pages/cms/taxes/components/TaxRateForm.cjs.js +1 -0
  180. package/lib/pages/cms/taxes/components/TaxRateForm.es.js +100 -0
  181. package/lib/product-actions.cjs.js +237 -0
  182. package/lib/product-actions.es.js +524 -0
  183. package/lib/product-context.cjs.js +1 -0
  184. package/lib/product-context.es.js +16 -0
  185. package/lib/product-schema.cjs.js +1 -0
  186. package/lib/product-schema.es.js +134 -0
  187. package/lib/providers/freemius.cjs.js +5 -0
  188. package/lib/providers/freemius.es.js +538 -0
  189. package/lib/providers/stripe.cjs.js +1 -0
  190. package/lib/providers/stripe.es.js +473 -0
  191. package/lib/server-actions/coupon-actions.cjs.js +1 -0
  192. package/lib/server-actions/coupon-actions.es.js +23 -0
  193. package/lib/server-actions/customer-actions.cjs.js +1 -0
  194. package/lib/server-actions/customer-actions.es.js +30 -0
  195. package/lib/server-actions/product-actions.cjs.js +1 -0
  196. package/{server-actions → lib/server-actions}/product-actions.es.js +5 -4
  197. package/lib/server-actions/shipping-actions.cjs.js +1 -0
  198. package/{shipping-actions-BnHjlo2q.js → lib/server-actions/shipping-actions.es.js} +9 -7
  199. package/lib/server-actions/tax-actions.cjs.js +1 -0
  200. package/lib/server-actions/tax-actions.es.js +40 -0
  201. package/lib/shared-inventory.cjs.js +15 -0
  202. package/lib/shared-inventory.es.js +171 -0
  203. package/lib/shipping/resolver.cjs.js +7 -0
  204. package/lib/shipping/resolver.es.js +62 -0
  205. package/lib/shipping-rate-currency.cjs.js +1 -0
  206. package/lib/shipping-rate-currency.es.js +72 -0
  207. package/lib/states.cjs.js +1 -0
  208. package/{states-DlHJezQ1.js → lib/states.es.js} +27 -100
  209. package/lib/stripe/checkout.cjs.js +1 -0
  210. package/lib/stripe/checkout.es.js +182 -0
  211. package/lib/stripe/client.cjs.js +1 -0
  212. package/lib/stripe/client.es.js +7 -0
  213. package/lib/stripe/order-sync.cjs.js +1 -0
  214. package/lib/stripe/order-sync.es.js +130 -0
  215. package/lib/stripe/webhooks.cjs.js +1 -0
  216. package/lib/stripe/webhooks.es.js +30 -0
  217. package/lib/tax-calculation.cjs.js +1 -0
  218. package/lib/tax-calculation.es.js +101 -0
  219. package/lib/trials.cjs.js +1 -0
  220. package/{trials-RDcRAZKx.js → lib/trials.es.js} +9 -9
  221. package/{use-cart.es.js → lib/use-cart.es.js} +1 -0
  222. package/lib/zod-config.cjs.js +1 -0
  223. package/lib/zod-config.es.js +6 -0
  224. package/package.json +4 -4
  225. package/server.cjs.js +1 -110
  226. package/server.es.js +178 -6052
  227. package/AddToCartButton-DsSEH9yp.cjs +0 -1
  228. package/CouponForm-BI_5SBHQ.js +0 -152
  229. package/CouponForm-D_uu2bLP.cjs +0 -1
  230. package/CurrencyProvider-Cg-Q6ucj.cjs +0 -1
  231. package/CurrencyProvider-OzlRN96V.js +0 -120
  232. package/CurrencyProvider.cjs.js +0 -1
  233. package/CurrencyProvider.es.js +0 -10
  234. package/ProductDetailsLayout-BxJH_BxR.cjs +0 -1
  235. package/ProductDetailsLayout-Dg8dRTYp.js +0 -530
  236. package/ProductGrid-BdL7iglO.cjs +0 -1
  237. package/ProductGrid-D3AWM8sr.js +0 -130
  238. package/actions-AHmBrS5e.cjs +0 -48
  239. package/actions-j5fuSZX-.js +0 -820
  240. package/cart-store.cjs.js +0 -1
  241. package/components/Cart.cjs.js +0 -1
  242. package/components/Cart.es.js +0 -259
  243. package/components/CartDrawer.cjs.js +0 -1
  244. package/components/Checkout.cjs.js +0 -1
  245. package/components/CurrencySwitcher.cjs.js +0 -1
  246. package/components/FeaturedProduct.cjs.js +0 -1
  247. package/components/ProductDetailsLayout.cjs.js +0 -1
  248. package/components/ProductDetailsLayout.es.js +0 -19
  249. package/components/ProductGrid.cjs.js +0 -1
  250. package/components/ProductGrid.es.js +0 -6
  251. package/coupon-server-C9ySm3I5.cjs +0 -1
  252. package/customer-C-UPvrYN.cjs +0 -1
  253. package/invoice-ui-CAnJPu6n.cjs +0 -29
  254. package/invoice-ui-DtpbTJE1.js +0 -2886
  255. package/product-actions-CONBF8i6.cjs +0 -251
  256. package/product-actions-DjlIWCMH.js +0 -691
  257. package/resolver-Fz_FKsfX.cjs +0 -7
  258. package/resolver-cfrCaHpE.js +0 -128
  259. package/server-actions/product-actions.cjs.js +0 -1
  260. package/shipping-actions-D6zt20gg.cjs +0 -1
  261. package/states-CWYRxV4B.cjs +0 -1
  262. package/tax-calculation-Dab89aHd.js +0 -181
  263. package/tax-calculation-MkDKOEkL.cjs +0 -1
  264. package/trials-DvZaOtNy.cjs +0 -1
  265. /package/{components → lib/components}/SimpleTiptapRenderer.cjs.js +0 -0
  266. /package/{components → lib/components}/SimpleTiptapRenderer.es.js +0 -0
  267. /package/{currency-constants.cjs.js → lib/currency-constants.cjs.js} +0 -0
  268. /package/{currency-constants.es.js → lib/currency-constants.es.js} +0 -0
  269. /package/{currency-rest-client-uolJxUkL.cjs → lib/currency-rest-client.cjs.js} +0 -0
  270. /package/{currency-rest-client-CwoqdgAP.js → lib/currency-rest-client.es.js} +0 -0
  271. /package/{currency.cjs.js → lib/currency.cjs.js} +0 -0
  272. /package/{currency.es.js → lib/currency.es.js} +0 -0
  273. /package/{types.cjs.js → lib/types.cjs.js} +0 -0
  274. /package/{types.es.js → lib/types.es.js} +0 -0
  275. /package/{use-cart.cjs.js → lib/use-cart.cjs.js} +0 -0
  276. /package/{variation-utils.cjs.js → lib/variation-utils.cjs.js} +0 -0
  277. /package/{variation-utils.es.js → lib/variation-utils.es.js} +0 -0
@@ -0,0 +1,30 @@
1
+ import { createClient as r } from "@nextblock-cms/db/server";
2
+ import { DEFAULT_ENABLED_PAYMENT_PROVIDERS as n, normalizeEnabledPaymentProviders as t } from "../../../types.es.js";
3
+ async function o() {
4
+ const e = [];
5
+ process.env.STRIPE_SECRET_KEY || e.push("STRIPE_SECRET_KEY"), process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || e.push("NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY"), process.env.STRIPE_WEBHOOK_SECRET || e.push("STRIPE_WEBHOOK_SECRET");
6
+ const s = [];
7
+ return process.env.FREEMIUS_PUBLIC_KEY || s.push("FREEMIUS_PUBLIC_KEY"), process.env.FREEMIUS_SECRET_KEY || s.push("FREEMIUS_SECRET_KEY"), {
8
+ stripe: {
9
+ hasKeys: e.length === 0,
10
+ missing: e
11
+ },
12
+ freemius: {
13
+ hasKeys: s.length === 0,
14
+ missing: s
15
+ }
16
+ };
17
+ }
18
+ async function i() {
19
+ const e = r(), { data: s, error: E } = await e.from("site_settings").select("value").eq("key", "enabled_payment_providers").maybeSingle();
20
+ return E || !s ? { ...n } : t(s.value);
21
+ }
22
+ async function S() {
23
+ const e = await i();
24
+ return e.stripe ? "stripe" : e.freemius ? "freemius" : "stripe";
25
+ }
26
+ export {
27
+ i as getEnabledPaymentProviders,
28
+ S as getPaymentSettings,
29
+ o as getStoreConfigStatus
30
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),b=require("@nextblock-cms/ui"),m=require("next/link"),x=require("./actions.cjs.js"),P=require("./components/ProductsBulkTable.cjs.js"),p=require("./components/SyncFreemiusButton.cjs.js"),s=require("./server-actions.cjs.js"),n=require("@nextblock-cms/db/server");async function j({searchParams:c,languageFilterNode:o,transferControlsNode:i}){const a=n.getServiceRoleSupabaseClient(),[u,{data:r}]=await Promise.all([n.getActiveLanguagesServerSide(),a.from("currencies").select("code, is_default").eq("is_active",!0).order("is_default",{ascending:!1}).order("code",{ascending:!0})]),d=c?.lang?parseInt(c.lang,10):void 0,{data:l}=await x.getProducts({languageId:d}),g=Object.fromEntries(u.map(t=>[String(t.id),t.code.toUpperCase()])),f=r?.find(t=>t.is_default)?.code||r?.[0]?.code||"USD";return e.jsxs("div",{className:"p-8 space-y-6",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("h1",{className:"text-3xl font-bold",children:"Products"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[e.jsx("div",{className:"h-10 w-[1px] bg-slate-200 dark:bg-slate-800 mx-2 hidden sm:block"}),i,o,e.jsx(p.SyncFreemiusButton,{title:"Sync Full Store"}),e.jsx(m,{href:"/cms/products/new",children:e.jsx(b.Button,{children:"New Product"})})]})]}),e.jsx(P.ProductsBulkTable,{products:l||[],languageLabels:g,defaultCurrencyCode:f,deleteProductAction:s.deleteProductAction,bulkDeleteProductsAction:s.bulkDeleteProductsAction,bulkDraftProductsAction:s.bulkDraftProductsAction})]})}exports.ProductsPage=j;
@@ -0,0 +1,46 @@
1
+ import { jsxs as r, jsx as e } from "react/jsx-runtime";
2
+ import { Button as f } from "@nextblock-cms/ui";
3
+ import p from "next/link";
4
+ import { getProducts as g } from "./actions.es.js";
5
+ import { ProductsBulkTable as b } from "./components/ProductsBulkTable.es.js";
6
+ import { SyncFreemiusButton as x } from "./components/SyncFreemiusButton.es.js";
7
+ import { bulkDraftProductsAction as h, bulkDeleteProductsAction as v, deleteProductAction as P } from "./server-actions.es.js";
8
+ import { getServiceRoleSupabaseClient as S, getActiveLanguagesServerSide as w } from "@nextblock-cms/db/server";
9
+ async function B({
10
+ searchParams: o,
11
+ languageFilterNode: s,
12
+ transferControlsNode: a
13
+ }) {
14
+ const i = S(), [d, { data: c }] = await Promise.all([
15
+ w(),
16
+ i.from("currencies").select("code, is_default").eq("is_active", !0).order("is_default", { ascending: !1 }).order("code", { ascending: !0 })
17
+ ]), n = o?.lang ? parseInt(o.lang, 10) : void 0, { data: l } = await g({ languageId: n }), u = Object.fromEntries(
18
+ d.map((t) => [String(t.id), t.code.toUpperCase()])
19
+ ), m = c?.find((t) => t.is_default)?.code || c?.[0]?.code || "USD";
20
+ return /* @__PURE__ */ r("div", { className: "p-8 space-y-6", children: [
21
+ /* @__PURE__ */ r("div", { className: "flex justify-between items-center", children: [
22
+ /* @__PURE__ */ e("h1", { className: "text-3xl font-bold", children: "Products" }),
23
+ /* @__PURE__ */ r("div", { className: "flex flex-wrap items-center gap-4", children: [
24
+ /* @__PURE__ */ e("div", { className: "h-10 w-[1px] bg-slate-200 dark:bg-slate-800 mx-2 hidden sm:block" }),
25
+ a,
26
+ s,
27
+ /* @__PURE__ */ e(x, { title: "Sync Full Store" }),
28
+ /* @__PURE__ */ e(p, { href: "/cms/products/new", children: /* @__PURE__ */ e(f, { children: "New Product" }) })
29
+ ] })
30
+ ] }),
31
+ /* @__PURE__ */ e(
32
+ b,
33
+ {
34
+ products: l || [],
35
+ languageLabels: u,
36
+ defaultCurrencyCode: m,
37
+ deleteProductAction: P,
38
+ bulkDeleteProductsAction: v,
39
+ bulkDraftProductsAction: h
40
+ }
41
+ )
42
+ ] });
43
+ }
44
+ export {
45
+ B as ProductsPage
46
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),S=require("../../components/ProductForm.cjs.js"),a=require("../../actions.cjs.js"),E=require("../../components/FreemiusPricingDashboard.cjs.js"),T=require("../../components/DeleteProductButton.cjs.js"),M=require("next/navigation"),_=require("lucide-react"),m=require("next/link"),g=require("@nextblock-cms/ui"),O=require("../../../../../variation-utils.cjs.js"),x=require("../../server-actions.cjs.js"),b=require("../../../payments/queries.cjs.js"),U=require("@nextblock-cms/db/server"),o=require("@nextblock-cms/utils"),C=require("../../../../../currency.cjs.js");async function I({params:f,mediaPickerNode:h,availableLanguagesProp:u,languageSwitcherNode:j,copyContentNode:P,translationCtaNode:v}){const{id:y}=await f,e=await a.getProduct(y);e||M.notFound();const c=e.product_type==="digital"||e.payment_provider==="freemius",[q,w,d,A,N]=await Promise.all([b.getEnabledPaymentProviders(),b.getStoreConfigStatus(),c&&e.freemius_product_id?a.getFreemiusPricingByProductId(e.id):Promise.resolve(null),a.getGlobalProductAttributes(),U.getServiceRoleSupabaseClient().from("currencies").select("code, symbol, exchange_rate, is_default, is_active, auto_sync_product_prices, auto_update_exchange_rate, exchange_rate_source, exchange_rate_updated_at, rounding_mode, rounding_increment, rounding_charm_amount").eq("is_active",!0).order("code",{ascending:!0}).then(t=>t.data||[])]),D=(N||[]).map(t=>C.normalizeCurrencyRecord(t)),k=u.find(t=>t.id===e.language_id)?.code,{attributes:R,variants:B}=O.mapRawVariantRelations(e.product_variants||[],k),F=(A||[]).map(t=>({id:t.id,name:t.name,name_translations:t.name_translations||{},slug:t.slug,terms:(t.product_attribute_terms||[]).map(r=>({...r,value_translations:r.value_translations||{}}))})),l=T.DeleteProductButton,p=E.FreemiusPricingDashboard;return i.jsxs("div",{className:"space-y-8 w-full max-w-[1400px] mx-auto px-6 py-8",children:[i.jsxs("div",{className:"flex justify-between items-center flex-wrap gap-4 w-full",children:[i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx(g.Button,{variant:"outline",size:"icon","aria-label":"Back to products",asChild:!0,children:i.jsx(m,{href:"/cms/products",children:i.jsx(_.ArrowLeft,{className:"h-4 w-4"})})}),i.jsxs("div",{children:[i.jsx("h1",{className:"text-2xl font-bold",children:"Edit Product"}),i.jsx("p",{className:"text-sm text-muted-foreground truncate max-w-md",title:e.title,children:e.title})]})]}),i.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[j,P,v,l?i.jsx(l,{productName:e.title,redirectTo:"/cms/products",className:"border-red-200 hover:bg-red-50 hover:text-red-700",deleteAction:x.deleteProductAction.bind(null,e.id)}):null,e.slug&&e.status==="active"&&i.jsx(g.Button,{variant:"outline",asChild:!0,children:i.jsxs(m,{href:`/product/${e.slug}`,target:"_blank",children:[i.jsx(_.ExternalLink,{className:"w-4 h-4 mr-2"}),"View"]})})]})]}),i.jsx(S.ProductForm,{initialData:{id:e.id,title:e.title,slug:e.slug,sku:e.sku,upc:e.upc??void 0,stock:e.stock||0,price:e.price||0,prices:Object.entries(e.prices||{}).reduce((t,[r,s])=>(t[r]=o.minorUnitAmountToMajor(s,r),t),{}),is_taxable:typeof e.is_taxable=="boolean"?e.is_taxable:!0,product_type:e.product_type,payment_provider:e.payment_provider,status:e.status,short_description:e.short_description??void 0,description_json:e.description_json,sale_price:typeof e.sale_price=="number"?e.sale_price:void 0,sale_prices:Object.entries(e.sale_prices||{}).reduce((t,[r,s])=>(t[r]=typeof s=="number"?o.minorUnitAmountToMajor(s,r):null,t),{}),freemius_plan_id:e.freemius_plan_id??void 0,freemius_product_id:e.freemius_product_id??void 0,trial_period_days:e.trial_period_days??0,trial_requires_payment_method:e.trial_requires_payment_method??!1,language_id:e.language_id,translation_group_id:e.translation_group_id,product_media:e.product_media,variation_attributes:R.map(t=>({attribute_id:t.id,term_ids:t.terms.map(r=>r.id)})),variants:B.map(t=>({...t,upc:t.upc??null,price:t.price/100,prices:Object.entries(t.prices||{}).reduce((r,[s,n])=>(r[s]=o.minorUnitAmountToMajor(n,s),r),{}),sale_price:typeof t.sale_price=="number"?t.sale_price/100:null,sale_prices:Object.entries(t.sale_prices||{}).reduce((r,[s,n])=>(r[s]=typeof n=="number"?o.minorUnitAmountToMajor(n,s):null,r),{}),main_media_id:t.main_media_id??null,main_image_url:t.image_url??null}))},isEdit:!0,mediaPickerNode:h,availableLanguagesProp:u,globalAttributesProp:F,currenciesProp:D,enabledProviders:q,configStatus:w,updateAction:x.updateProductAction.bind(null,e.id),freemiusDashboardNode:c&&e.freemius_product_id&&d&&p?i.jsx(p,{productId:e.id,freemiusProductId:e.freemius_product_id,plans:d}):void 0})]})}exports.EditProductPage=I;
@@ -0,0 +1,156 @@
1
+ import { jsxs as s, jsx as o } from "react/jsx-runtime";
2
+ import { ProductForm as B } from "../../components/ProductForm.es.js";
3
+ import { getProduct as E, getFreemiusPricingByProductId as F, getGlobalProductAttributes as S } from "../../actions.es.js";
4
+ import { FreemiusPricingDashboard as C } from "../../components/FreemiusPricingDashboard.es.js";
5
+ import { DeleteProductButton as O } from "../../components/DeleteProductButton.es.js";
6
+ import { notFound as q } from "next/navigation";
7
+ import { ArrowLeft as I, ExternalLink as L } from "lucide-react";
8
+ import m from "next/link";
9
+ import { Button as _ } from "@nextblock-cms/ui";
10
+ import { mapRawVariantRelations as z } from "../../../../../variation-utils.es.js";
11
+ import { deleteProductAction as T, updateProductAction as V } from "../../server-actions.es.js";
12
+ import { getEnabledPaymentProviders as G, getStoreConfigStatus as M } from "../../../payments/queries.es.js";
13
+ import { getServiceRoleSupabaseClient as U } from "@nextblock-cms/db/server";
14
+ import { minorUnitAmountToMajor as d } from "@nextblock-cms/utils";
15
+ import { normalizeCurrencyRecord as $ } from "../../../../../currency.es.js";
16
+ async function de({
17
+ params: f,
18
+ mediaPickerNode: g,
19
+ availableLanguagesProp: n,
20
+ languageSwitcherNode: b,
21
+ copyContentNode: h,
22
+ translationCtaNode: x
23
+ }) {
24
+ const { id: P } = await f, e = await E(P);
25
+ e || q();
26
+ const c = e.product_type === "digital" || e.payment_provider === "freemius", [v, y, l, w, A] = await Promise.all([
27
+ G(),
28
+ M(),
29
+ c && e.freemius_product_id ? F(e.id) : Promise.resolve(null),
30
+ S(),
31
+ U().from("currencies").select(
32
+ "code, symbol, exchange_rate, is_default, is_active, auto_sync_product_prices, auto_update_exchange_rate, exchange_rate_source, exchange_rate_updated_at, rounding_mode, rounding_increment, rounding_charm_amount"
33
+ ).eq("is_active", !0).order("code", { ascending: !0 }).then((t) => t.data || [])
34
+ ]), N = (A || []).map(
35
+ (t) => $(t)
36
+ ), j = n.find((t) => t.id === e.language_id)?.code, { attributes: k, variants: D } = z(
37
+ e.product_variants || [],
38
+ j
39
+ ), R = (w || []).map((t) => ({
40
+ id: t.id,
41
+ name: t.name,
42
+ name_translations: t.name_translations || {},
43
+ slug: t.slug,
44
+ terms: (t.product_attribute_terms || []).map((r) => ({
45
+ ...r,
46
+ value_translations: r.value_translations || {}
47
+ }))
48
+ })), u = O, p = C;
49
+ return /* @__PURE__ */ s("div", { className: "space-y-8 w-full max-w-[1400px] mx-auto px-6 py-8", children: [
50
+ /* @__PURE__ */ s("div", { className: "flex justify-between items-center flex-wrap gap-4 w-full", children: [
51
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-3", children: [
52
+ /* @__PURE__ */ o(
53
+ _,
54
+ {
55
+ variant: "outline",
56
+ size: "icon",
57
+ "aria-label": "Back to products",
58
+ asChild: !0,
59
+ children: /* @__PURE__ */ o(m, { href: "/cms/products", children: /* @__PURE__ */ o(I, { className: "h-4 w-4" }) })
60
+ }
61
+ ),
62
+ /* @__PURE__ */ s("div", { children: [
63
+ /* @__PURE__ */ o("h1", { className: "text-2xl font-bold", children: "Edit Product" }),
64
+ /* @__PURE__ */ o("p", { className: "text-sm text-muted-foreground truncate max-w-md", title: e.title, children: e.title })
65
+ ] })
66
+ ] }),
67
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-3 flex-wrap", children: [
68
+ b,
69
+ h,
70
+ x,
71
+ u ? /* @__PURE__ */ o(
72
+ u,
73
+ {
74
+ productName: e.title,
75
+ redirectTo: "/cms/products",
76
+ className: "border-red-200 hover:bg-red-50 hover:text-red-700",
77
+ deleteAction: T.bind(null, e.id)
78
+ }
79
+ ) : null,
80
+ e.slug && e.status === "active" && /* @__PURE__ */ o(_, { variant: "outline", asChild: !0, children: /* @__PURE__ */ s(m, { href: `/product/${e.slug}`, target: "_blank", children: [
81
+ /* @__PURE__ */ o(L, { className: "w-4 h-4 mr-2" }),
82
+ "View"
83
+ ] }) })
84
+ ] })
85
+ ] }),
86
+ /* @__PURE__ */ o(
87
+ B,
88
+ {
89
+ initialData: {
90
+ id: e.id,
91
+ title: e.title,
92
+ slug: e.slug,
93
+ sku: e.sku,
94
+ upc: e.upc ?? void 0,
95
+ stock: e.stock || 0,
96
+ price: e.price || 0,
97
+ prices: Object.entries(e.prices || {}).reduce(
98
+ (t, [r, i]) => (t[r] = d(i, r), t),
99
+ {}
100
+ ),
101
+ is_taxable: typeof e.is_taxable == "boolean" ? e.is_taxable : !0,
102
+ product_type: e.product_type,
103
+ payment_provider: e.payment_provider,
104
+ status: e.status,
105
+ short_description: e.short_description ?? void 0,
106
+ description_json: e.description_json,
107
+ sale_price: typeof e.sale_price == "number" ? e.sale_price : void 0,
108
+ sale_prices: Object.entries(e.sale_prices || {}).reduce((t, [r, i]) => (t[r] = typeof i == "number" ? d(i, r) : null, t), {}),
109
+ freemius_plan_id: e.freemius_plan_id ?? void 0,
110
+ freemius_product_id: e.freemius_product_id ?? void 0,
111
+ trial_period_days: e.trial_period_days ?? 0,
112
+ trial_requires_payment_method: e.trial_requires_payment_method ?? !1,
113
+ language_id: e.language_id,
114
+ translation_group_id: e.translation_group_id,
115
+ product_media: e.product_media,
116
+ variation_attributes: k.map((t) => ({
117
+ attribute_id: t.id,
118
+ term_ids: t.terms.map((r) => r.id)
119
+ })),
120
+ variants: D.map((t) => ({
121
+ ...t,
122
+ upc: t.upc ?? null,
123
+ price: t.price / 100,
124
+ prices: Object.entries(t.prices || {}).reduce(
125
+ (r, [i, a]) => (r[i] = d(a, i), r),
126
+ {}
127
+ ),
128
+ sale_price: typeof t.sale_price == "number" ? t.sale_price / 100 : null,
129
+ sale_prices: Object.entries(t.sale_prices || {}).reduce((r, [i, a]) => (r[i] = typeof a == "number" ? d(a, i) : null, r), {}),
130
+ main_media_id: t.main_media_id ?? null,
131
+ main_image_url: t.image_url ?? null
132
+ }))
133
+ },
134
+ isEdit: !0,
135
+ mediaPickerNode: g,
136
+ availableLanguagesProp: n,
137
+ globalAttributesProp: R,
138
+ currenciesProp: N,
139
+ enabledProviders: v,
140
+ configStatus: y,
141
+ updateAction: V.bind(null, e.id),
142
+ freemiusDashboardNode: c && e.freemius_product_id && l && p ? /* @__PURE__ */ o(
143
+ p,
144
+ {
145
+ productId: e.id,
146
+ freemiusProductId: e.freemius_product_id,
147
+ plans: l
148
+ }
149
+ ) : void 0
150
+ }
151
+ )
152
+ ] });
153
+ }
154
+ export {
155
+ de as EditProductPage
156
+ };
@@ -0,0 +1,44 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("@nextblock-cms/db/server"),d=require("../../../product-actions.cjs.js"),l=require("../../../providers/freemius.cjs.js"),u=require("next/cache");async function _(t){const r=o.createClient(),{data:a,count:e,error:i}=await await d.getProducts(r,t);if(i)throw new Error(i.message);return{data:a,count:e}}async function m(t){const r=o.createClient(),{data:a,error:e}=await d.getProduct(r,t);if(e)throw new Error(e.message);return a}async function p(){try{const t=await l.syncFreemiusProductsToSupabase();return u.revalidatePath("/cms/products","page"),{success:!0,data:t}}catch(t){return{error:t.message||"Failed to sync with Freemius"}}}async function g(t){try{const r=await l.syncSingleFreemiusProduct(t);return u.revalidatePath("/cms/products","page"),{success:!0,data:r}}catch(r){return{error:r.message||"Failed to sync product with Freemius"}}}async function f(t,r){try{const a=o.createClient();return await d.copyProductFromLanguage(a,t,r),u.revalidatePath("/cms/products"),u.revalidatePath(`/cms/products/${t}/edit`),{success:!0}}catch(a){return{success:!1,error:a.message||"Failed to copy product content"}}}async function y(t){const r=o.createClient(),{data:a,error:e}=await r.from("products").select("id, title, language_id, slug").eq("translation_group_id",t);if(e)throw new Error(e.message);return a}async function w(){const t=o.getServiceRoleSupabaseClient(),{data:r,error:a}=await t.from("product_attributes").select(`
2
+ id,
3
+ name,
4
+ name_translations,
5
+ slug,
6
+ product_attribute_terms (
7
+ id,
8
+ attribute_id,
9
+ value,
10
+ slug,
11
+ sort_order,
12
+ value_translations
13
+ )
14
+ `);if(a)throw new Error(a.message);return(r||[]).map(e=>({...e,product_attribute_terms:(e.product_attribute_terms||[]).sort((i,c)=>(i.sort_order??Number.MAX_SAFE_INTEGER)-(c.sort_order??Number.MAX_SAFE_INTEGER)||i.value.localeCompare(c.value))})).sort((e,i)=>e.name.localeCompare(i.name))}async function P(t){const r=o.createClient(),{data:a,error:e}=await r.from("freemius_plans").select(`
15
+ id,
16
+ name,
17
+ title,
18
+ freemius_pricing (
19
+ id,
20
+ license_quota,
21
+ api_monthly_price,
22
+ api_annual_price,
23
+ api_lifetime_price,
24
+ override_monthly_price,
25
+ override_annual_price,
26
+ override_lifetime_price,
27
+ is_active
28
+ )
29
+ `).eq("product_id",t);if(e)throw new Error(e.message);return a}async function b(t,r){const a=o.createClient(),{error:e}=await a.from("freemius_pricing").update({...r,updated_at:new Date().toISOString()}).eq("id",t);return e?{success:!1,error:e.message}:(u.revalidatePath("/cms/products"),{success:!0})}async function h(t){const r=o.createClient(),{data:a}=await r.from("products").select("translation_group_id").eq("id",t).maybeSingle();let e=[t];if(a?.translation_group_id){const{data:n}=await r.from("products").select("id").eq("translation_group_id",a.translation_group_id);n&&n.length>0&&(e=n.map(s=>s.id))}const{data:i,error:c}=await r.from("freemius_plans").select(`
30
+ id,
31
+ name,
32
+ title,
33
+ freemius_pricing (
34
+ id,
35
+ license_quota,
36
+ api_monthly_price,
37
+ api_annual_price,
38
+ api_lifetime_price,
39
+ override_monthly_price,
40
+ override_annual_price,
41
+ override_lifetime_price,
42
+ is_active
43
+ )
44
+ `).in("product_id",e);if(c)throw new Error(c.message);return(i||[]).map(n=>({id:n.id,name:n.name,title:n.title,pricing:(n.freemius_pricing||[]).filter(s=>s.is_active!==!1).map(s=>({id:s.id,license_quota:s.license_quota,monthly_price:s.override_monthly_price??s.api_monthly_price,annual_price:s.override_annual_price??s.api_annual_price,lifetime_price:s.override_lifetime_price??s.api_lifetime_price,is_active:s.is_active}))}))}async function v(){const t=o.createClient(),{data:r,error:a}=await t.from("categories").select("id, name, slug, description, created_at, name_translations, description_translations, product_categories(count)").order("name",{ascending:!0});if(a)throw new Error(a.message);return(r||[]).map(e=>{const i=e.product_categories?.[0]?.count??e.product_categories?.count??0;return{id:e.id,name:e.name,slug:e.slug,description:e.description??"",created_at:e.created_at,productCount:Number(i),name_translations:e.name_translations||{},description_translations:e.description_translations||{}}})}async function C(t){const r=o.createClient(),{data:a,error:e}=await r.from("categories").select("id, name, slug, description, created_at").eq("slug",t).maybeSingle();if(e)throw new Error(e.message);return a}async function F(t){const r=o.createClient(),{data:a,error:e}=await r.from("product_categories").select("category:categories(id, name, slug, description, name_translations, description_translations, created_at)").eq("product_id",t);if(e)throw new Error(e.message);return(a||[]).map(i=>i.category).filter(Boolean)}exports.copyProductFromLanguageAction=f;exports.getCategoriesWithCount=v;exports.getCategoryBySlug=C;exports.getFreemiusPricingByProductId=P;exports.getGlobalProductAttributes=w;exports.getProduct=m;exports.getProductCategories=F;exports.getProductTranslations=y;exports.getProducts=_;exports.getPublicFreemiusPricing=h;exports.triggerFreemiusSync=p;exports.triggerSingleProductSync=g;exports.updateFreemiusOverride=b;
@@ -0,0 +1,175 @@
1
+ 'use server';
2
+ import { createClient as o, getServiceRoleSupabaseClient as d } from "@nextblock-cms/db/server";
3
+ import { getProduct as l, getProducts as _, copyProductFromLanguage as m } from "../../../product-actions.es.js";
4
+ import { syncSingleFreemiusProduct as p, syncFreemiusProductsToSupabase as g } from "../../../providers/freemius.es.js";
5
+ import { revalidatePath as u } from "next/cache";
6
+ async function v(r) {
7
+ const t = o(), { data: a, count: e, error: s } = await await _(t, r);
8
+ if (s) throw new Error(s.message);
9
+ return { data: a, count: e };
10
+ }
11
+ async function P(r) {
12
+ const t = o(), { data: a, error: e } = await l(t, r);
13
+ if (e) throw new Error(e.message);
14
+ return a;
15
+ }
16
+ async function E() {
17
+ try {
18
+ const r = await g();
19
+ return u("/cms/products", "page"), { success: !0, data: r };
20
+ } catch (r) {
21
+ return { error: r.message || "Failed to sync with Freemius" };
22
+ }
23
+ }
24
+ async function F(r) {
25
+ try {
26
+ const t = await p(r);
27
+ return u("/cms/products", "page"), { success: !0, data: t };
28
+ } catch (t) {
29
+ return { error: t.message || "Failed to sync product with Freemius" };
30
+ }
31
+ }
32
+ async function S(r, t) {
33
+ try {
34
+ const a = o();
35
+ return await m(a, r, t), u("/cms/products"), u(`/cms/products/${r}/edit`), { success: !0 };
36
+ } catch (a) {
37
+ return { success: !1, error: a.message || "Failed to copy product content" };
38
+ }
39
+ }
40
+ async function q(r) {
41
+ const t = o(), { data: a, error: e } = await t.from("products").select("id, title, language_id, slug").eq("translation_group_id", r);
42
+ if (e) throw new Error(e.message);
43
+ return a;
44
+ }
45
+ async function C() {
46
+ const r = d(), { data: t, error: a } = await r.from("product_attributes").select(`
47
+ id,
48
+ name,
49
+ name_translations,
50
+ slug,
51
+ product_attribute_terms (
52
+ id,
53
+ attribute_id,
54
+ value,
55
+ slug,
56
+ sort_order,
57
+ value_translations
58
+ )
59
+ `);
60
+ if (a)
61
+ throw new Error(a.message);
62
+ return (t || []).map((e) => ({
63
+ ...e,
64
+ product_attribute_terms: (e.product_attribute_terms || []).sort(
65
+ (s, c) => (s.sort_order ?? Number.MAX_SAFE_INTEGER) - (c.sort_order ?? Number.MAX_SAFE_INTEGER) || s.value.localeCompare(c.value)
66
+ )
67
+ })).sort((e, s) => e.name.localeCompare(s.name));
68
+ }
69
+ async function A(r) {
70
+ const t = o(), { data: a, error: e } = await t.from("freemius_plans").select(`
71
+ id,
72
+ name,
73
+ title,
74
+ freemius_pricing (
75
+ id,
76
+ license_quota,
77
+ api_monthly_price,
78
+ api_annual_price,
79
+ api_lifetime_price,
80
+ override_monthly_price,
81
+ override_annual_price,
82
+ override_lifetime_price,
83
+ is_active
84
+ )
85
+ `).eq("product_id", r);
86
+ if (e) throw new Error(e.message);
87
+ return a;
88
+ }
89
+ async function N(r, t) {
90
+ const a = o(), { error: e } = await a.from("freemius_pricing").update({
91
+ ...t,
92
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
93
+ }).eq("id", r);
94
+ return e ? { success: !1, error: e.message } : (u("/cms/products"), { success: !0 });
95
+ }
96
+ async function T(r) {
97
+ const t = o(), { data: a } = await t.from("products").select("translation_group_id").eq("id", r).maybeSingle();
98
+ let e = [r];
99
+ if (a?.translation_group_id) {
100
+ const { data: n } = await t.from("products").select("id").eq("translation_group_id", a.translation_group_id);
101
+ n && n.length > 0 && (e = n.map((i) => i.id));
102
+ }
103
+ const { data: s, error: c } = await t.from("freemius_plans").select(`
104
+ id,
105
+ name,
106
+ title,
107
+ freemius_pricing (
108
+ id,
109
+ license_quota,
110
+ api_monthly_price,
111
+ api_annual_price,
112
+ api_lifetime_price,
113
+ override_monthly_price,
114
+ override_annual_price,
115
+ override_lifetime_price,
116
+ is_active
117
+ )
118
+ `).in("product_id", e);
119
+ if (c) throw new Error(c.message);
120
+ return (s || []).map((n) => ({
121
+ id: n.id,
122
+ name: n.name,
123
+ title: n.title,
124
+ pricing: (n.freemius_pricing || []).filter((i) => i.is_active !== !1).map((i) => ({
125
+ id: i.id,
126
+ license_quota: i.license_quota,
127
+ monthly_price: i.override_monthly_price ?? i.api_monthly_price,
128
+ annual_price: i.override_annual_price ?? i.api_annual_price,
129
+ lifetime_price: i.override_lifetime_price ?? i.api_lifetime_price,
130
+ is_active: i.is_active
131
+ }))
132
+ }));
133
+ }
134
+ async function B() {
135
+ const r = o(), { data: t, error: a } = await r.from("categories").select("id, name, slug, description, created_at, name_translations, description_translations, product_categories(count)").order("name", { ascending: !0 });
136
+ if (a) throw new Error(a.message);
137
+ return (t || []).map((e) => {
138
+ const s = e.product_categories?.[0]?.count ?? e.product_categories?.count ?? 0;
139
+ return {
140
+ id: e.id,
141
+ name: e.name,
142
+ slug: e.slug,
143
+ description: e.description ?? "",
144
+ created_at: e.created_at,
145
+ productCount: Number(s),
146
+ name_translations: e.name_translations || {},
147
+ description_translations: e.description_translations || {}
148
+ };
149
+ });
150
+ }
151
+ async function G(r) {
152
+ const t = o(), { data: a, error: e } = await t.from("categories").select("id, name, slug, description, created_at").eq("slug", r).maybeSingle();
153
+ if (e) throw new Error(e.message);
154
+ return a;
155
+ }
156
+ async function I(r) {
157
+ const t = o(), { data: a, error: e } = await t.from("product_categories").select("category:categories(id, name, slug, description, name_translations, description_translations, created_at)").eq("product_id", r);
158
+ if (e) throw new Error(e.message);
159
+ return (a || []).map((s) => s.category).filter(Boolean);
160
+ }
161
+ export {
162
+ S as copyProductFromLanguageAction,
163
+ B as getCategoriesWithCount,
164
+ G as getCategoryBySlug,
165
+ A as getFreemiusPricingByProductId,
166
+ C as getGlobalProductAttributes,
167
+ P as getProduct,
168
+ I as getProductCategories,
169
+ q as getProductTranslations,
170
+ v as getProducts,
171
+ T as getPublicFreemiusPricing,
172
+ E as triggerFreemiusSync,
173
+ F as triggerSingleProductSync,
174
+ N as updateFreemiusOverride
175
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("next/link"),o=require("lucide-react"),u=require("@nextblock-cms/ui"),l=require("@nextblock-cms/db/server"),d=require("../actions.cjs.js"),t=require("../server-actions.cjs.js"),m=require("./components/AttributeManager.cjs.js");async function A(){const[a,i]=await Promise.all([d.getGlobalProductAttributes(),l.getActiveLanguagesServerSide()]),n=(a||[]).map(r=>({id:r.id,name:r.name,name_translations:r.name_translations||{},slug:r.slug,terms:(r.product_attribute_terms||[]).map(s=>({...s,value_translations:s.value_translations||{}}))}));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(u.Button,{variant:"outline",size:"icon",asChild:!0,children:e.jsx(c,{href:"/cms/products",children:e.jsx(o.ArrowLeft,{className:"h-4 w-4"})})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Global Attribute Management"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Define reusable attributes and terms for variation-based physical products."})]})]})}),e.jsx(m.AttributeManager,{attributes:n,createAttributeAction:t.createProductAttributeAction,deleteAttributeAction:t.deleteProductAttributeAction,createTermAction:t.createProductAttributeTermAction,deleteTermAction:t.deleteProductAttributeTermAction,reorderTermsAction:t.reorderProductAttributeTermsAction,updateTranslationsAction:t.updateProductAttributeTranslationsAction,languages:i})]})}exports.AttributeManagementPage=A;
@@ -0,0 +1,48 @@
1
+ import { jsxs as r, jsx as t } from "react/jsx-runtime";
2
+ import s from "next/link";
3
+ import { ArrowLeft as c } from "lucide-react";
4
+ import { Button as l } from "@nextblock-cms/ui";
5
+ import { getActiveLanguagesServerSide as m } from "@nextblock-cms/db/server";
6
+ import { getGlobalProductAttributes as u } from "../actions.es.js";
7
+ import { updateProductAttributeTranslationsAction as d, reorderProductAttributeTermsAction as A, deleteProductAttributeTermAction as p, createProductAttributeTermAction as f, deleteProductAttributeAction as b, createProductAttributeAction as g } from "../server-actions.es.js";
8
+ import { AttributeManager as x } from "./components/AttributeManager.es.js";
9
+ async function j() {
10
+ const [i, o] = await Promise.all([
11
+ u(),
12
+ m()
13
+ ]), n = (i || []).map((e) => ({
14
+ id: e.id,
15
+ name: e.name,
16
+ name_translations: e.name_translations || {},
17
+ slug: e.slug,
18
+ terms: (e.product_attribute_terms || []).map((a) => ({
19
+ ...a,
20
+ value_translations: a.value_translations || {}
21
+ }))
22
+ }));
23
+ return /* @__PURE__ */ r("div", { className: "space-y-8 w-full max-w-[1200px] mx-auto px-6 py-8", children: [
24
+ /* @__PURE__ */ t("div", { className: "flex flex-wrap items-center justify-between gap-4", children: /* @__PURE__ */ r("div", { className: "flex items-center gap-3", children: [
25
+ /* @__PURE__ */ t(l, { variant: "outline", size: "icon", asChild: !0, children: /* @__PURE__ */ t(s, { href: "/cms/products", children: /* @__PURE__ */ t(c, { className: "h-4 w-4" }) }) }),
26
+ /* @__PURE__ */ r("div", { children: [
27
+ /* @__PURE__ */ t("h1", { className: "text-2xl font-bold", children: "Global Attribute Management" }),
28
+ /* @__PURE__ */ t("p", { className: "text-sm text-muted-foreground", children: "Define reusable attributes and terms for variation-based physical products." })
29
+ ] })
30
+ ] }) }),
31
+ /* @__PURE__ */ t(
32
+ x,
33
+ {
34
+ attributes: n,
35
+ createAttributeAction: g,
36
+ deleteAttributeAction: b,
37
+ createTermAction: f,
38
+ deleteTermAction: p,
39
+ reorderTermsAction: A,
40
+ updateTranslationsAction: d,
41
+ languages: o
42
+ }
43
+ )
44
+ ] });
45
+ }
46
+ export {
47
+ j as AttributeManagementPage
48
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),d=require("react"),H=require("next/navigation"),t=require("@nextblock-cms/ui"),c=require("lucide-react");function J({attributes:o,languages:C,createAttributeAction:F,deleteAttributeAction:B,createTermAction:D,deleteTermAction:P,reorderTermsAction:k,updateTranslationsAction:q}){const i=H.useRouter(),[m,v]=d.useState(""),[f,j]=d.useState(null),[z,g]=d.useState(null),[N,y]=d.useState(null),[w,T]=d.useState(null),[h,b]=d.useState({}),[A,L]=d.useState(()=>o.reduce((e,n)=>(e[n.id]=n.name_translations||{},e),{})),[S,M]=d.useState(()=>o.reduce((e,n)=>{for(const r of n.terms)e[r.id]=r.value_translations||{};return e},{})),u=C.filter(e=>!e.is_default),R=async e=>{e.preventDefault();const n=await F({name:m});if(!n.success){alert(n.error||"Failed to create attribute.");return}v(""),i.refresh()},_=async(e,n)=>{e.preventDefault(),j(n);const r=await D({attributeId:n,value:h[n]||""});if(j(null),!r.success){alert(r.error||"Failed to create term.");return}b(a=>({...a,[n]:""})),i.refresh()},O=async e=>{if(!window.confirm("Delete this attribute and all of its terms?"))return;const r=await B(e);if(!r.success){alert(r.error||"Failed to delete attribute.");return}i.refresh()},U=async e=>{g(e);const n=await P(e);if(g(null),!n.success){alert(n.error||"Failed to delete term.");return}i.refresh()},I=async(e,n,r)=>{const a=e.terms.findIndex(p=>p.id===n),l=a+r;if(a===-1||l<0||l>=e.terms.length)return;const x=[...e.terms],[G]=x.splice(a,1);x.splice(l,0,G),y(e.id);const $=await k({attributeId:e.id,orderedTermIds:x.map(p=>p.id)});if(y(null),!$.success){alert($.error||"Failed to reorder terms.");return}i.refresh()},E=async e=>{T(e.id);const n=await q({attributeId:e.id,nameTranslations:A[e.id]||{},termTranslations:e.terms.map(r=>({termId:r.id,valueTranslations:S[r.id]||{}}))});if(T(null),!n.success){alert(n.error||"Failed to save translations.");return}i.refresh()};return s.jsxs("div",{className:"space-y-6",children:[s.jsx("form",{onSubmit:R,className:"rounded-lg border bg-card p-6 shadow-sm",children:s.jsxs("div",{className:"flex flex-wrap items-end gap-4",children:[s.jsxs("div",{className:"flex-1 min-w-[220px] space-y-2",children:[s.jsx(t.Label,{htmlFor:"attribute-name",children:"New Attribute"}),s.jsx(t.Input,{id:"attribute-name",value:m,onChange:e=>v(e.target.value),placeholder:"Material, Size, Color..."})]}),s.jsxs(t.Button,{type:"submit",disabled:!m.trim(),children:[s.jsx(c.Plus,{className:"mr-2 h-4 w-4"}),"Create Attribute"]})]})}),o.length===0?s.jsx("div",{className:"rounded-lg border border-dashed p-6 text-sm text-muted-foreground",children:"No global attributes have been created yet."}):s.jsx("div",{className:"grid gap-6",children:o.map(e=>s.jsxs("div",{className:"rounded-lg border bg-card p-6 shadow-sm",children:[s.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-lg font-semibold",children:e.name}),s.jsx("p",{className:"text-sm text-muted-foreground",children:e.slug})]}),s.jsx(t.Button,{type:"button",variant:"ghost",size:"icon",onClick:()=>O(e.id),className:"text-muted-foreground hover:text-destructive",children:s.jsx(c.Trash2,{className:"h-4 w-4"})})]}),s.jsx("div",{className:"mt-4 space-y-2",children:e.terms.map((n,r)=>s.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-lg border bg-muted/20 px-3 py-2",children:[s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(t.Badge,{variant:"secondary",className:"py-1.5",children:n.value}),s.jsxs("span",{className:"text-xs text-muted-foreground",children:["Position ",r+1]})]}),s.jsxs("div",{className:"flex items-center gap-1",children:[s.jsx(t.Button,{type:"button",variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>I(e,n.id,-1),disabled:r===0||N===e.id,children:s.jsx(c.ChevronUp,{className:"h-4 w-4"})}),s.jsx(t.Button,{type:"button",variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>I(e,n.id,1),disabled:r===e.terms.length-1||N===e.id,children:s.jsx(c.ChevronDown,{className:"h-4 w-4"})}),s.jsx(t.Button,{type:"button",variant:"ghost",size:"icon",onClick:()=>U(n.id),className:"h-8 w-8 text-muted-foreground hover:text-destructive",disabled:z===n.id,children:s.jsx(c.Trash2,{className:"h-4 w-4"})})]})]},n.id))}),s.jsxs("form",{onSubmit:n=>_(n,e.id),className:"mt-6 flex flex-wrap items-end gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-[220px] space-y-2",children:[s.jsx(t.Label,{htmlFor:`term-input-${e.id}`,children:"Add Term"}),s.jsx(t.Input,{id:`term-input-${e.id}`,value:h[e.id]||"",onChange:n=>b(r=>({...r,[e.id]:n.target.value})),placeholder:`Add a term for ${e.name}`})]}),s.jsxs(t.Button,{type:"submit",variant:"outline",disabled:!h[e.id]?.trim()||f===e.id,children:[s.jsx(c.Plus,{className:"mr-2 h-4 w-4"}),f===e.id?"Saving...":"Add Term"]})]}),u.length>0&&s.jsxs("div",{className:"mt-6 border-t pt-6 space-y-4",children:[s.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[s.jsxs("div",{children:[s.jsx("h3",{className:"font-medium",children:"Translations"}),s.jsx("p",{className:"text-sm text-muted-foreground",children:"Translate the attribute label and each term for every active site language."})]}),s.jsx(t.Button,{type:"button",variant:"outline",onClick:()=>E(e),disabled:w===e.id,children:w===e.id?"Saving...":"Save Translations"})]}),s.jsx("div",{className:"grid gap-4 md:grid-cols-2",children:u.map(n=>s.jsxs("div",{className:"space-y-2",children:[s.jsxs(t.Label,{htmlFor:`attribute-translation-${e.id}-${n.code}`,children:["Attribute Name (",n.name,")"]}),s.jsx(t.Input,{id:`attribute-translation-${e.id}-${n.code}`,value:A[e.id]?.[n.code]||"",onChange:r=>L(a=>({...a,[e.id]:{...a[e.id]||{},[n.code]:r.target.value}})),placeholder:e.name})]},`${e.id}-${n.code}`))}),s.jsx("div",{className:"space-y-3",children:e.terms.map(n=>s.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[s.jsxs("div",{children:[s.jsx("p",{className:"font-medium",children:n.value}),s.jsx("p",{className:"text-xs text-muted-foreground",children:"Translate this term for each language."})]}),s.jsx("div",{className:"grid gap-4 md:grid-cols-2",children:u.map(r=>s.jsxs("div",{className:"space-y-2",children:[s.jsx(t.Label,{htmlFor:`term-translation-${n.id}-${r.code}`,children:r.name}),s.jsx(t.Input,{id:`term-translation-${n.id}-${r.code}`,value:S[n.id]?.[r.code]||"",onChange:a=>M(l=>({...l,[n.id]:{...l[n.id]||{},[r.code]:a.target.value}})),placeholder:n.value})]},`${n.id}-${r.code}`))})]},`translations-${n.id}`))})]})]},e.id))})]})}exports.AttributeManager=J;