@gnar-engine/cli 1.0.3 → 1.0.5

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 (259) hide show
  1. package/bootstrap/deploy.localdev.yml +44 -30
  2. package/bootstrap/secrets.localdev.yml +20 -14
  3. package/bootstrap/services/control/src/config.js +4 -0
  4. package/bootstrap/services/{agent → page}/Dockerfile +3 -3
  5. package/bootstrap/services/page/package.json +16 -0
  6. package/bootstrap/services/page/src/app.js +50 -0
  7. package/bootstrap/services/page/src/commands/block.handler.js +94 -0
  8. package/bootstrap/services/page/src/commands/page.handler.js +167 -0
  9. package/bootstrap/services/page/src/config.js +62 -0
  10. package/bootstrap/services/page/src/controllers/block.http.controller.js +87 -0
  11. package/bootstrap/services/page/src/controllers/message.controller.js +51 -0
  12. package/bootstrap/services/page/src/controllers/page.http.controller.js +89 -0
  13. package/bootstrap/services/page/src/policies/block.policy.js +50 -0
  14. package/bootstrap/services/page/src/policies/page.policy.js +49 -0
  15. package/bootstrap/services/page/src/schema/page.schema.js +139 -0
  16. package/bootstrap/services/page/src/services/block.service.js +83 -0
  17. package/bootstrap/services/page/src/services/page.service.js +83 -0
  18. package/bootstrap/services/portal/Dockerfile +7 -10
  19. package/bootstrap/services/portal/README.md +66 -15
  20. package/bootstrap/services/portal/index.html +13 -0
  21. package/bootstrap/services/portal/nginx.conf +5 -12
  22. package/bootstrap/services/portal/package.json +27 -53
  23. package/bootstrap/services/portal/public/vite.svg +1 -0
  24. package/bootstrap/services/portal/react-router.config.js +7 -0
  25. package/bootstrap/services/portal/src/App.jsx +16 -0
  26. package/bootstrap/services/portal/src/assets/gnar-engine-white-logo.svg +9 -0
  27. package/bootstrap/services/portal/src/assets/icon-agent.svg +6 -0
  28. package/bootstrap/services/portal/src/assets/icon-cog.svg +4 -0
  29. package/bootstrap/services/portal/src/assets/icon-delete.svg +3 -0
  30. package/bootstrap/services/portal/src/assets/icon-home.svg +3 -0
  31. package/bootstrap/services/portal/src/assets/icon-padlock.svg +3 -0
  32. package/bootstrap/services/portal/src/assets/icon-page.svg +6 -0
  33. package/bootstrap/services/portal/src/assets/icon-reports.svg +3 -0
  34. package/bootstrap/services/portal/src/assets/icon-user.svg +3 -0
  35. package/bootstrap/services/portal/src/assets/icon-users.svg +3 -0
  36. package/bootstrap/services/portal/src/assets/login-green-rad-back-1.jpg +0 -0
  37. package/bootstrap/services/portal/src/assets/react.svg +1 -0
  38. package/bootstrap/services/portal/src/components/CrudList/CrudList.jsx +85 -0
  39. package/bootstrap/services/portal/src/components/CrudList/CrudList.less +59 -0
  40. package/bootstrap/services/portal/src/{ui/customSelect → components/CustomSelect}/CustomSelect.jsx +21 -3
  41. package/bootstrap/services/portal/src/components/LoginForm/LoginForm.jsx +58 -0
  42. package/bootstrap/services/portal/src/components/PageBlockSwitch/PageBlockSwitch.jsx +129 -0
  43. package/bootstrap/services/portal/src/components/Sidebar/Sidebar.jsx +33 -0
  44. package/bootstrap/services/portal/src/components/Sidebar/Sidebar.less +37 -0
  45. package/bootstrap/services/portal/src/components/Topbar/Topbar.jsx +19 -0
  46. package/bootstrap/services/portal/src/components/Topbar/Topbar.less +22 -0
  47. package/bootstrap/services/portal/src/components/UserInfo/UserInfo.jsx +33 -0
  48. package/bootstrap/services/portal/src/components/UserInfo/UserInfo.less +21 -0
  49. package/bootstrap/services/portal/src/css/style.css +446 -742
  50. package/bootstrap/services/portal/src/data/pages.data.js +10 -0
  51. package/bootstrap/services/portal/src/elements/CustomSelect/CustomSelect.jsx +65 -0
  52. package/bootstrap/services/portal/src/{ui/customSelect/customSelect.less → elements/CustomSelect/CustomSelect.less} +17 -7
  53. package/bootstrap/services/portal/src/elements/ImageInput/ImageInput.jsx +115 -0
  54. package/bootstrap/services/portal/src/elements/ImageInput/ImageInput.less +43 -0
  55. package/bootstrap/services/portal/src/elements/ImageMultiInput/ImageMultiInput.jsx +124 -0
  56. package/bootstrap/services/portal/src/elements/ImageMultiInput/ImageMultiInput.less +0 -0
  57. package/bootstrap/services/portal/src/elements/Repeater/Repeater.jsx +52 -0
  58. package/bootstrap/services/portal/src/elements/Repeater/Repeater.less +70 -0
  59. package/bootstrap/services/portal/src/elements/RichTextInput/RichTextInput.jsx +18 -0
  60. package/bootstrap/services/portal/src/elements/RichTextInput/RichTextInput.less +37 -0
  61. package/bootstrap/services/portal/src/elements/SaveButton/SaveButton.jsx +45 -0
  62. package/bootstrap/services/portal/src/elements/SelectRepeater/SelectRepeater.jsx +63 -0
  63. package/bootstrap/services/portal/src/elements/SelectRepeater/SelectRepeater.less +23 -0
  64. package/bootstrap/services/portal/src/elements/TextInput/TextInput.jsx +17 -0
  65. package/bootstrap/services/portal/src/layouts/Card/Card.jsx +15 -0
  66. package/bootstrap/services/portal/src/layouts/PortalLayout/PortalLayout.jsx +29 -0
  67. package/bootstrap/services/portal/src/layouts/PortalLayout/PortalLayout.less +49 -0
  68. package/bootstrap/services/portal/src/main.jsx +51 -0
  69. package/bootstrap/services/portal/src/pages/BlockSinglePage/BlockSinglePage.jsx +277 -0
  70. package/bootstrap/services/portal/src/pages/BlocksPage/BlocksPage.jsx +23 -0
  71. package/bootstrap/services/portal/src/pages/DashboardPage/DashboardPage.jsx +11 -0
  72. package/bootstrap/services/portal/src/pages/DashboardPage/DashboardPage.less +0 -0
  73. package/bootstrap/services/portal/src/pages/LoginPage/LoginPage.jsx +21 -0
  74. package/bootstrap/services/portal/src/pages/LoginPage/LoginPage.less +51 -0
  75. package/bootstrap/services/portal/src/pages/PageSinglePage/PageSinglePage.jsx +338 -0
  76. package/bootstrap/services/portal/src/pages/PagesPage/PagesPage.jsx +23 -0
  77. package/bootstrap/services/portal/src/pages/UserSinglePage/UserSinglePage.jsx +9 -0
  78. package/bootstrap/services/portal/src/pages/UserSinglePage/UserSinglePage.less +0 -0
  79. package/bootstrap/services/portal/src/pages/UsersPage/UsersPage.jsx +25 -0
  80. package/bootstrap/services/portal/src/pages/UsersPage/UsersPage.less +0 -0
  81. package/bootstrap/services/portal/src/services/block.js +28 -0
  82. package/bootstrap/services/portal/src/services/client.js +67 -0
  83. package/bootstrap/services/portal/src/services/gravatar.js +14 -0
  84. package/bootstrap/services/portal/src/services/page.js +28 -0
  85. package/bootstrap/services/portal/src/services/storage.js +62 -0
  86. package/bootstrap/services/portal/src/services/user.js +41 -0
  87. package/bootstrap/services/portal/src/slices/authSlice.js +44 -14
  88. package/bootstrap/services/portal/src/store/configureStore.js +1 -3
  89. package/bootstrap/services/portal/src/style/cards.less +57 -0
  90. package/bootstrap/services/portal/src/{styles → style}/global.less +90 -45
  91. package/bootstrap/services/portal/src/style/icons.less +21 -0
  92. package/bootstrap/services/portal/src/style/inputs.less +52 -0
  93. package/bootstrap/services/portal/src/style/main.less +28 -0
  94. package/bootstrap/services/portal/src/utils/utils.js +9 -0
  95. package/bootstrap/services/portal/vite.config.js +12 -0
  96. package/bootstrap/services/user/Dockerfile +1 -1
  97. package/bootstrap/services/user/src/app.js +6 -1
  98. package/bootstrap/services/user/src/commands/user.handler.js +0 -3
  99. package/bootstrap/services/user/src/config.js +5 -1
  100. package/bootstrap/services/user/src/policies/user.policy.js +3 -1
  101. package/bootstrap/services/user/src/tests/commands/user.test.js +22 -0
  102. package/install-from-clone.sh +30 -0
  103. package/package.json +1 -1
  104. package/src/cli.js +8 -0
  105. package/src/config.js +2 -1
  106. package/src/dev/commands.js +10 -2
  107. package/src/dev/dev.service.js +167 -52
  108. package/src/provisioner/Dockerfile +27 -0
  109. package/src/provisioner/package.json +19 -0
  110. package/src/provisioner/src/app.js +56 -0
  111. package/src/provisioner/src/services/mongodb.js +58 -0
  112. package/src/provisioner/src/services/mysql.js +51 -0
  113. package/src/provisioner/src/services/secrets.js +84 -0
  114. package/src/scaffolder/commands.js +12 -5
  115. package/src/scaffolder/scaffolder.handler.js +256 -58
  116. package/templates/service/Dockerfile.hbs +4 -1
  117. package/templates/service/package.json.hbs +14 -16
  118. package/templates/service/src/app.js.hbs +53 -0
  119. package/templates/service/{commands → src/commands}/{{serviceName}}.handler.js.hbs +2 -3
  120. package/templates/service/src/mongodb.config.js.hbs +49 -0
  121. package/templates/service/{config.js.hbs → src/mysql.config.js.hbs} +10 -0
  122. package/{bootstrap/services/agent/src/schema/Agent.schema.js → templates/service/src/schema/{{serviceName}}.schema.js.hbs} +3 -3
  123. package/templates/service/src/services/mongodb.{{serviceName}}.service.js.hbs +70 -0
  124. package/bootstrap/services/agent/notes.md +0 -28
  125. package/bootstrap/services/agent/package.json +0 -16
  126. package/bootstrap/services/agent/src/app.js +0 -52
  127. package/bootstrap/services/agent/src/commands/agent.handler.js +0 -104
  128. package/bootstrap/services/agent/src/config.js +0 -52
  129. package/bootstrap/services/agent/src/controllers/http.controller.js +0 -44
  130. package/bootstrap/services/agent/src/controllers/message.controller.js +0 -51
  131. package/bootstrap/services/agent/src/db/migrations/01-init.js +0 -50
  132. package/bootstrap/services/agent/src/db/migrations/02-agent-service-init.js +0 -36
  133. package/bootstrap/services/agent/src/policies/agent.policy.js +0 -13
  134. package/bootstrap/services/agent/src/services/agent.service.js +0 -259
  135. package/bootstrap/services/agent/src/services/chatgpt.service.js +0 -46
  136. package/bootstrap/services/agent/src/services/manifest.service.js +0 -21
  137. package/bootstrap/services/portal/Dockerfile.remote +0 -40
  138. package/bootstrap/services/portal/public/favicon.ico +0 -0
  139. package/bootstrap/services/portal/public/gnar-white.png +0 -0
  140. package/bootstrap/services/portal/public/gnarengine-logo-black.png +0 -0
  141. package/bootstrap/services/portal/public/index.html +0 -43
  142. package/bootstrap/services/portal/public/logo192.png +0 -0
  143. package/bootstrap/services/portal/public/logo512.png +0 -0
  144. package/bootstrap/services/portal/public/manifest.json +0 -25
  145. package/bootstrap/services/portal/public/robots.txt +0 -3
  146. package/bootstrap/services/portal/src/App.js +0 -56
  147. package/bootstrap/services/portal/src/assets/Logo_Anchord_Black.svg +0 -1
  148. package/bootstrap/services/portal/src/assets/Logo_Anchord_Black_Green.svg +0 -1
  149. package/bootstrap/services/portal/src/assets/Logo_Anchord_White_Green.svg +0 -1
  150. package/bootstrap/services/portal/src/assets/activity.svg +0 -3
  151. package/bootstrap/services/portal/src/assets/arrow.svg +0 -3
  152. package/bootstrap/services/portal/src/assets/bin-white.svg +0 -3
  153. package/bootstrap/services/portal/src/assets/bin.svg +0 -3
  154. package/bootstrap/services/portal/src/assets/check.svg +0 -3
  155. package/bootstrap/services/portal/src/assets/chevron.svg +0 -3
  156. package/bootstrap/services/portal/src/assets/contact.svg +0 -3
  157. package/bootstrap/services/portal/src/assets/dots-vertical.svg +0 -5
  158. package/bootstrap/services/portal/src/assets/eye-off.svg +0 -3
  159. package/bootstrap/services/portal/src/assets/eye.svg +0 -4
  160. package/bootstrap/services/portal/src/assets/gnar-engine-black.svg +0 -47
  161. package/bootstrap/services/portal/src/assets/gnar-engine-white.svg +0 -47
  162. package/bootstrap/services/portal/src/assets/gnar_engine.svg +0 -3
  163. package/bootstrap/services/portal/src/assets/gnarengine-logo-black.png +0 -0
  164. package/bootstrap/services/portal/src/assets/home.svg +0 -3
  165. package/bootstrap/services/portal/src/assets/link.svg +0 -3
  166. package/bootstrap/services/portal/src/assets/lock.svg +0 -3
  167. package/bootstrap/services/portal/src/assets/package.svg +0 -4
  168. package/bootstrap/services/portal/src/assets/raffle.svg +0 -3
  169. package/bootstrap/services/portal/src/assets/settings.svg +0 -4
  170. package/bootstrap/services/portal/src/assets/shopping-bag.svg +0 -3
  171. package/bootstrap/services/portal/src/assets/user-black.svg +0 -3
  172. package/bootstrap/services/portal/src/assets/user.svg +0 -3
  173. package/bootstrap/services/portal/src/assets/users.svg +0 -3
  174. package/bootstrap/services/portal/src/assets/wallet.svg +0 -3
  175. package/bootstrap/services/portal/src/data/data.js +0 -70
  176. package/bootstrap/services/portal/src/features/attributeFormRow/AttributeFormRow.jsx +0 -32
  177. package/bootstrap/services/portal/src/features/billingShipping/BillingShipping.jsx +0 -160
  178. package/bootstrap/services/portal/src/features/crud/crudEdit.less +0 -230
  179. package/bootstrap/services/portal/src/features/crud/crudList.less +0 -134
  180. package/bootstrap/services/portal/src/features/crud/crudPage.less +0 -31
  181. package/bootstrap/services/portal/src/features/crudContact/CrudContactList.jsx +0 -108
  182. package/bootstrap/services/portal/src/features/crudContact/CrudContactSingle.jsx +0 -243
  183. package/bootstrap/services/portal/src/features/crudOrder/CrudOrderList.jsx +0 -109
  184. package/bootstrap/services/portal/src/features/crudOrder/CrudOrderSingle.jsx +0 -315
  185. package/bootstrap/services/portal/src/features/crudProducts/CrudProductList.jsx +0 -104
  186. package/bootstrap/services/portal/src/features/crudProducts/CrudProductSingle.jsx +0 -388
  187. package/bootstrap/services/portal/src/features/crudRaffles/CrudRafflesList.jsx +0 -104
  188. package/bootstrap/services/portal/src/features/crudRaffles/CrudRafflesSingle.jsx +0 -208
  189. package/bootstrap/services/portal/src/features/crudSubscription/CrudSubscriptionList.jsx +0 -110
  190. package/bootstrap/services/portal/src/features/crudSubscription/CrudSubscriptionSingle.jsx +0 -261
  191. package/bootstrap/services/portal/src/features/crudUser/CrudUserList.jsx +0 -107
  192. package/bootstrap/services/portal/src/features/crudUser/CrudUserSingle.jsx +0 -402
  193. package/bootstrap/services/portal/src/features/inventoryFormRow/InventoryFormRow.jsx +0 -30
  194. package/bootstrap/services/portal/src/features/lineItems/LineItems.jsx +0 -113
  195. package/bootstrap/services/portal/src/features/loginForm/LoginForm.jsx +0 -56
  196. package/bootstrap/services/portal/src/features/loginForm/loginForm.less +0 -56
  197. package/bootstrap/services/portal/src/features/notes/Notes.jsx +0 -18
  198. package/bootstrap/services/portal/src/features/passwordReset/PasswordResetForm.jsx +0 -96
  199. package/bootstrap/services/portal/src/features/passwordReset/PasswordResetRequestForm.jsx +0 -74
  200. package/bootstrap/services/portal/src/features/priceFormRow/PriceFormRow.jsx +0 -102
  201. package/bootstrap/services/portal/src/features/priceFormRow/priceFormRow.less +0 -24
  202. package/bootstrap/services/portal/src/features/raffleEntriesList/RaffleEntriesList.jsx +0 -99
  203. package/bootstrap/services/portal/src/features/raffleProductFormRow/RaffleProductFormRow.jsx +0 -46
  204. package/bootstrap/services/portal/src/features/sidebar/Sidebar.jsx +0 -64
  205. package/bootstrap/services/portal/src/features/sidebar/sidebar.less +0 -49
  206. package/bootstrap/services/portal/src/features/skus/Skus.jsx +0 -109
  207. package/bootstrap/services/portal/src/features/subscriptionSchedule/SubscriptionSchedule.jsx +0 -44
  208. package/bootstrap/services/portal/src/features/taxonomyFormRow/TaxonomyFormRow.jsx +0 -32
  209. package/bootstrap/services/portal/src/features/user/User.jsx +0 -54
  210. package/bootstrap/services/portal/src/features/user/user.less +0 -57
  211. package/bootstrap/services/portal/src/includes/utilities.js +0 -259
  212. package/bootstrap/services/portal/src/index.js +0 -14
  213. package/bootstrap/services/portal/src/layouts/CrudLayout.jsx +0 -50
  214. package/bootstrap/services/portal/src/layouts/LoginLayout.jsx +0 -17
  215. package/bootstrap/services/portal/src/layouts/PortalLayout.jsx +0 -48
  216. package/bootstrap/services/portal/src/layouts/loginLayout.less +0 -33
  217. package/bootstrap/services/portal/src/layouts/portalLayout.less +0 -67
  218. package/bootstrap/services/portal/src/pages/contacts/Contacts.jsx +0 -199
  219. package/bootstrap/services/portal/src/pages/dashboard/Dashboard.jsx +0 -17
  220. package/bootstrap/services/portal/src/pages/integrations/Integrations.jsx +0 -10
  221. package/bootstrap/services/portal/src/pages/login/Login.jsx +0 -15
  222. package/bootstrap/services/portal/src/pages/login/login.less +0 -10
  223. package/bootstrap/services/portal/src/pages/orders/Orders.jsx +0 -199
  224. package/bootstrap/services/portal/src/pages/passwordReset/PasswordResetPage.jsx +0 -15
  225. package/bootstrap/services/portal/src/pages/passwordResetRequest/PasswordResetRequestPage.jsx +0 -15
  226. package/bootstrap/services/portal/src/pages/payments/Payments.jsx +0 -10
  227. package/bootstrap/services/portal/src/pages/portal/Portal.jsx +0 -43
  228. package/bootstrap/services/portal/src/pages/products/Products.jsx +0 -212
  229. package/bootstrap/services/portal/src/pages/raffleEntries/RaffleEntries.jsx +0 -124
  230. package/bootstrap/services/portal/src/pages/raffles/Raffles.jsx +0 -186
  231. package/bootstrap/services/portal/src/pages/reports/Reports.jsx +0 -10
  232. package/bootstrap/services/portal/src/pages/settings/Settings.jsx +0 -10
  233. package/bootstrap/services/portal/src/pages/subscriptions/Subscriptions.jsx +0 -199
  234. package/bootstrap/services/portal/src/pages/users/Users.jsx +0 -193
  235. package/bootstrap/services/portal/src/pages/users/users.less +0 -25
  236. package/bootstrap/services/portal/src/styles/inputs.less +0 -157
  237. package/bootstrap/services/portal/src/styles/main.less +0 -26
  238. package/bootstrap/services/portal/src/ui/collapsible/Collapsible.jsx +0 -97
  239. package/bootstrap/services/portal/src/ui/collapsible/collapsible.less +0 -23
  240. package/bootstrap/services/portal/src/ui/customCheckbox/CustomCheckbox.jsx +0 -17
  241. package/bootstrap/services/portal/src/ui/customCheckbox/customCheckbox.less +0 -42
  242. package/bootstrap/services/portal/src/ui/customMultiSelect/CustomMultiSelect.jsx +0 -63
  243. package/bootstrap/services/portal/src/ui/customMultiSelect/CustomMultiSelectPeriod.jsx +0 -63
  244. package/bootstrap/services/portal/src/ui/goBack/GoBack.jsx +0 -19
  245. package/bootstrap/services/portal/src/ui/loader/Loader.jsx +0 -12
  246. package/bootstrap/services/portal/src/ui/pagination/Pagination.jsx +0 -23
  247. package/bootstrap/services/portal/src/ui/repeater/Repeater.jsx +0 -29
  248. package/bootstrap/services/portal/src/ui/saveButton/SaveButton.jsx +0 -69
  249. package/bootstrap/services/user/src/db/seeders/development/02-portal-admin-user.js +0 -27
  250. package/bootstrap/services/user/src/tests/user.test.js +0 -126
  251. package/templates/service/app.js.hbs +0 -38
  252. package/templates/service/schema/{{serviceName}}.schema.js.hbs +0 -14
  253. /package/bootstrap/services/portal/src/{ui/saveButton/saveButton.less → components/CustomSelect/CustomSelect.less} +0 -0
  254. /package/templates/service/{controllers → src/controllers}/http.controller.js.hbs +0 -0
  255. /package/templates/service/{controllers → src/controllers}/message.controller.js.hbs +0 -0
  256. /package/templates/service/{db → src/mysql.db}/migrations/01-init.js.hbs +0 -0
  257. /package/templates/service/{db → src/mysql.db}/migrations/02-{{lowerCase serviceName}}-service-init.js.hbs +0 -0
  258. /package/templates/service/{policies → src/policies}/{{serviceName}}.policy.js.hbs +0 -0
  259. /package/templates/service/{services/{{serviceName}}.service.js.hbs → src/services/mysql.{{serviceName}}.service.js.hbs} +0 -0
@@ -1,388 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import CustomSelect from '../../ui/customSelect/CustomSelect';
3
- import CustomMultiSelect from '../../ui/customMultiSelect/CustomMultiSelect';
4
- import gnarEngine from '@gnar-engine/js-client';
5
- import SaveButton from '../../ui/saveButton/SaveButton';
6
- import Repeater from '../../ui/repeater/Repeater';
7
- import arrow from '../../assets/arrow.svg';
8
- import { productStatuses, taxClasses, productCategories } from '../../data/data';
9
- import Skus from '../skus/Skus';
10
- import TaxonomyFormRow from '../taxonomyFormRow/TaxonomyFormRow';
11
-
12
-
13
-
14
- const CrudProductSingle = ({product, setProduct, setView, loading, setLoading, refreshSelectedProduct, fetchProducts, setSelectedSingleItemId, formatDate}) => {
15
-
16
- const [formData, setFormData] = useState({
17
- name: '',
18
- description: '',
19
- categories: [],
20
- status: '',
21
- skus: [{}]
22
- });
23
- const [validationErrors, setValidationErrors] = useState([]);
24
- const [selectedAction, setSelectedAction] = useState(null);
25
- const [productStatus, setProductStatus] = useState(null);
26
- const [productTaxClass, setProductTaxClass] = useState(null);
27
- const [prices, setPrices] = useState([]);
28
- const [inventories, setInventories] = useState([]);
29
- const [attributes, setAttributes] = useState([]);
30
- const [selectedCategories, setSelectedCategories] = useState([]);
31
-
32
- // prepare form data for editing existing product
33
- useEffect(() => {
34
- console.log('product:', product);
35
-
36
- if (product && product._id) {
37
- setFormData({
38
- name: product.name || '',
39
- description: product.description || '',
40
- skus: product.skus?.length ? product.skus : [],
41
- });
42
-
43
- // Set product status
44
- const existingStatus = productStatuses.find(status => status.id === product.status);
45
- setProductStatus(existingStatus || null);
46
-
47
- // iterate through each skus and set taxClass
48
- product.skus.forEach(sku => {
49
- const existingTaxClass = taxClasses.find(taxClass => taxClass.id === sku.taxClass);
50
- setProductTaxClass(existingTaxClass || null);
51
- });
52
-
53
- // Set product categories
54
- const newSelectedCategories = [];
55
-
56
- if (Array.isArray(product.categories) && product.categories.length > 0) {
57
- product.categories.forEach(category => {
58
- const selectedCategory = productCategories.find(cat => cat.id === category);
59
- if (selectedCategory) {
60
- newSelectedCategories.push(selectedCategory);
61
- }
62
- });
63
- }
64
-
65
- setSelectedCategories(newSelectedCategories);
66
-
67
- // iterate through each skus and then iterate through each prices
68
- const newPrices = [];
69
- product.skus.forEach(sku => {
70
- if (Array.isArray(sku.prices) && sku.prices.length > 0) {
71
- sku.prices.forEach(price => {
72
- newPrices.push(price);
73
- });
74
- }
75
- });
76
-
77
- setPrices(newPrices);
78
-
79
- // Ensure inventories are set correctly
80
- setInventories(product.inventories || []);
81
-
82
- // Ensure attributes are set correctly
83
- setAttributes(product.attributes || []);
84
-
85
- } else {
86
- // Default values for new products
87
- setProduct(null);
88
- // setFormData({
89
- // name: '',
90
- // description: '',
91
- // categories: [],
92
- // status: '',
93
- // skus: []
94
- // });
95
- // setProductStatus(null);
96
- // setProductTaxClass(null);
97
- // setPrices([]);
98
- // setInventories([]);
99
- // setAttributes([]);
100
- }
101
-
102
- setLoading(null);
103
- }, [product]);
104
-
105
- const handleCategoryChange = (selectedCategory) => {
106
- console.log('Newly selected category:', selectedCategory);
107
-
108
- let newCategories = [...selectedCategories];
109
-
110
- // remove from current category state if it's already in the list
111
- if (newCategories.find(category => category.id === selectedCategory.id)) {
112
- newCategories = newCategories.filter(category => category.id !== selectedCategory.id);
113
- }
114
- // otherwise add to the list
115
- else {
116
- newCategories.push(selectedCategory);
117
- }
118
-
119
- // Update the state
120
- setSelectedCategories(newCategories);
121
-
122
- // Update formData with category IDs
123
- setFormData(prevData => ({
124
- ...prevData,
125
- categories: newCategories.map(category => category.id)
126
- }));
127
- };
128
-
129
- const handleStatusChange = (selectedStatus) => {
130
- setProductStatus(selectedStatus);
131
- setFormData(prevData => ({
132
- ...prevData,
133
- status: selectedStatus ? selectedStatus.id : ''
134
- }));
135
- };
136
-
137
-
138
- // handle form data changes
139
- const handleChange = (e) => {
140
- setValidationErrors([]);
141
- const { name, value } = e.target;
142
-
143
- setFormData(prevData => ({
144
- ...prevData,
145
- [name]: value
146
- }));
147
- };
148
-
149
-
150
- // handle delete user
151
- const handleDelete = async () => {
152
- if (window.confirm('Are you sure you want to delete this product?')) {
153
- try {
154
- setLoading('loading');
155
-
156
- await gnarEngine.products.delete(product._id);
157
-
158
- setLoading('success');
159
- setTimeout(() => {
160
- setLoading(null);
161
- }, 3000);
162
-
163
- refreshSelectedProduct();
164
- setView('list');
165
-
166
- } catch (error) {
167
-
168
- setLoading('error');
169
- console.error('Error deleting product:', error);
170
- }
171
- } else {
172
- console.log('Deletion canceled');
173
- }
174
- };
175
-
176
- const handleSubmit = async (e) => {
177
- e.preventDefault();
178
- setValidationErrors([]);
179
- setLoading('loading');
180
-
181
- try {
182
- if (product) {
183
- // Editing an existing product
184
- await gnarEngine.products.update(product._id, {
185
- ...product,
186
- ...(formData || {})
187
- });
188
-
189
-
190
- setLoading('success');
191
- setTimeout(() => {
192
- setLoading(null);
193
- refreshSelectedProduct();
194
- }, 3000);
195
- } else {
196
- // Creating a new product
197
- const newProduct = await gnarEngine.products.createProducts([{...formData}]);
198
- setLoading('success');
199
- setTimeout(() => {
200
- setLoading(null);
201
- setProduct(newProduct);
202
- }, 3000);
203
- }
204
- } catch (error) {
205
- const errors = [];
206
-
207
- if (error.response?.data?.errors) {
208
- Object.keys(error.response.data.errors).forEach((key) => {
209
- errors.push(error.response.data.errors[key]);
210
- });
211
- } else if (error.response?.data?.message) {
212
- errors.push(error.response.data.message);
213
- }
214
-
215
- setValidationErrors(errors);
216
- console.error('Error saving product:', error);
217
- setLoading('error');
218
- setTimeout(() => {
219
- setLoading(null);
220
- }, 3000);
221
- }
222
- };
223
-
224
-
225
-
226
- const routeKey = 'products';
227
- const handleMenuBtnClick = () => setView({ isBackToList: true });
228
-
229
- // add event listener to sidebar buttons to change view
230
- useEffect(() => {
231
- const sidebarButtons = document.querySelectorAll('.sidebar a[href^="/portal/' + routeKey + '"]');
232
- sidebarButtons.forEach(button => {
233
- // if it doesn't already have an event listener
234
- if (!button.hasEventListener) {
235
- button.addEventListener('click', handleMenuBtnClick);
236
- }
237
- })
238
-
239
- // Cleanup to prevent memory leaks and double bindings
240
- return () => {
241
- sidebarButtons.forEach(button => {
242
- button.removeEventListener('click', handleMenuBtnClick);
243
- });
244
- };
245
- }, []);
246
-
247
- return (
248
- <div className="single-edit product">
249
- {validationErrors.length > 0 &&
250
- <div className="error-messages">
251
- {validationErrors.map((error, index) => {
252
- return <p key={index}>{error}</p>
253
- })}
254
- </div>
255
- }
256
- <div className='single-edit-header'>
257
- <div className='single-edit-header-left'>
258
- {product && product._id &&
259
- <p><strong>Parent Product:&nbsp;</strong>#{product._id}</p>
260
- }
261
- <p>Date Added: {formatDate(product?.createdAt)}</p>
262
- <form onSubmit={handleSubmit}>
263
- <div>
264
- <input
265
- type="text"
266
- name="name"
267
- placeholder='Product Name'
268
- value={formData.name}
269
- onChange={handleChange}
270
- required
271
- />
272
- <CustomSelect
273
- name="status"
274
- placeholder="Status"
275
- options={productStatuses}
276
- labelKey="status"
277
- setSelectedOption={handleStatusChange}
278
- selectedOption={productStatus}
279
- />
280
- </div>
281
- </form>
282
- </div>
283
- <div className='single-edit-header-right'>
284
- <div className="flex-row-buttons-cont">
285
- <button onClick={() => {
286
- setView('list');
287
- setProduct(null);
288
- setSelectedSingleItemId(null);
289
- }} className="secondaryButton">
290
- Back
291
- </button>
292
- <button onClick={handleDelete} className="secondaryButton">Delete</button>
293
- <SaveButton
294
- save={handleSubmit}
295
- loading={loading}
296
- textCreate="Add Product"
297
- textCreateLoading="Saving..."
298
- textCreateSuccess="Saved"
299
- textCreateError="Error"
300
- textUpdate="Save"
301
- textUpdateLoading="Updating..."
302
- textUpdateSuccess="Updated"
303
- textUpdateError="Error"
304
- isUpdating={!!product}
305
- />
306
- </div>
307
- </div>
308
-
309
- </div>
310
-
311
- <div className='card'>
312
- <div className='card-header'>
313
- <h2>Description and Category</h2>
314
- </div>
315
- <div className='card-content'>
316
- <form onSubmit={handleSubmit}>
317
- <div className='form-group'>
318
- <label>Description</label>
319
- <textarea
320
- name="description"
321
- value={formData.description}
322
- onChange={handleChange}
323
- required
324
- />
325
- </div>
326
- <div className='form-group categories'>
327
- <label>Categories</label>
328
- <CustomMultiSelect
329
- name="categories"
330
- placeholder="Select categories"
331
- options={productCategories}
332
- labelKey="category"
333
- setSelectedOption={selected => {
334
- handleCategoryChange(selected);
335
- }}
336
- selectedOptions={selectedCategories}
337
- />
338
- </div>
339
- </form>
340
- </div>
341
- </div>
342
-
343
- <h2>Grouping</h2>
344
- <div className='card'>
345
- <div className='card-header'>
346
- <h2>Taxonomy</h2>
347
- <h2>Terms</h2>
348
- <div></div>
349
- </div>
350
- <div className='card-content'>
351
- <Repeater
352
- items={[product]}
353
- setItems={setProduct}
354
- defaultItem= {{}}
355
- buttonText= "Add grouping"
356
- renderRow= {(item, index, updateItem, remove) => (
357
- <TaxonomyFormRow
358
- key={index}
359
- item={item}
360
- onChange={(field, value) => updateItem({ ...item, [field]: value })}
361
- remove={remove}
362
- />
363
- )}
364
- />
365
- </div>
366
- </div>
367
-
368
- <h2>SKUs</h2>
369
- <Repeater
370
- items={product?.skus ?? [{}]}
371
- setItems={(newSkus) => setProduct({ ...product, skus: newSkus })}
372
- defaultItem={{ sku: "", prices: [{}], taxClass: "" }}
373
- buttonText="Add SKU"
374
- renderRow={(item, index, updateItem, remove) => (
375
- <Skus
376
- key={index}
377
- item={item}
378
- onChange={(field, value) => updateItem({ ...item, [field]: value })}
379
- remove={remove}
380
- />
381
- )}
382
- />
383
-
384
- </div>
385
- );
386
- };
387
-
388
- export default CrudProductSingle;
@@ -1,104 +0,0 @@
1
- import React from 'react';
2
- import CustomCheckbox from '../../ui/customCheckbox/CustomCheckbox';
3
-
4
- const CrudRafflesList = ({ setSelectedSingleItemId, setView, selectedRaffleIds, setSelectedRaffleIds, raffles, message }) => {
5
-
6
- const allSelected = raffles.length > 0 && selectedRaffleIds.size === raffles.length;
7
-
8
- const toggleContactSelection = (raffleId) => {
9
- setSelectedRaffleIds(prev => {
10
- const newSet = new Set(prev);
11
- if (newSet.has(raffleId)) {
12
- newSet.delete(raffleId);
13
- } else {
14
- newSet.add(raffleId);
15
- }
16
- return newSet;
17
- });
18
- };
19
-
20
-
21
- const toggleSelectAll = () => {
22
- if (allSelected) {
23
- setSelectedRaffleIds(new Set());
24
- } else {
25
- setSelectedRaffleIds(new Set(raffles.map(raffle => raffle.id)));
26
- }
27
- };
28
-
29
- const handleEditClick = (raffle) => {
30
- setSelectedSingleItemId(raffle.id);
31
- setView('single');
32
- };
33
-
34
- const columns = [
35
- { columnLabel: 'Raffle', dataKey: 'id' },
36
- { columnLabel: 'Name', dataKey: 'name' },
37
- { columnLabel: 'Date added', dataKey: 'created_at' },
38
- ];
39
-
40
-
41
- return (
42
- <div className="">
43
- <div className='pagination-labels-cont'>
44
- <div className='pagination-count'>
45
- Showing {raffles.length} of {raffles.length} raffle{raffles.length !== 1 ? 's' : ''}
46
- </div>
47
- <div className="pagination-count">
48
- {selectedRaffleIds.size} of {raffles.length} raffle{raffles.length !== 1 ? 's' : ''} selected
49
- </div>
50
- </div>
51
- <div className='crud-list'>
52
- <table className='custom-table'>
53
- <thead>
54
- <tr>
55
- <th className="checkbox">
56
- <CustomCheckbox
57
- name="selectAll"
58
- checked={allSelected}
59
- setChecked={toggleSelectAll}
60
- />
61
- </th>
62
- {columns.map(column => (
63
- <th key={column.columnLabel}>{column.columnLabel}</th>
64
- ))}
65
- </tr>
66
- </thead>
67
-
68
- <tbody>
69
- {message ? (
70
- <tr>
71
- <td colSpan={columns.length + 1}>{message}</td>
72
- </tr>
73
- ) : (
74
- raffles.length > 0 ? (
75
- raffles.map(raffle => (
76
- <tr key={raffle.id} onClick={() => handleEditClick(raffle)}>
77
- <td>
78
- <CustomCheckbox
79
- name={`checkbox-${raffle.id}`}
80
- checked={selectedRaffleIds.has(raffle.id)}
81
- setChecked={() => toggleContactSelection(raffle.id)}
82
- />
83
- </td>
84
- {columns.map(column => (
85
- <td key={column.dataKey}>{raffle[column.dataKey]}</td>
86
- ))}
87
- </tr>
88
- ))
89
- ) : (
90
- <tr>
91
- <td colSpan={columns.length + 1}>No raffles found</td>
92
- </tr>
93
- )
94
- )}
95
- </tbody>
96
- </table>
97
- </div>
98
- </div>
99
-
100
- );
101
-
102
- };
103
-
104
- export default CrudRafflesList;