@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,208 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import gnarEngine from '@gnar-engine/js-client';
3
- import SaveButton from "../../ui/saveButton/SaveButton";
4
- import Repeater from "../../ui/repeater/Repeater";
5
- import { raffleStatuses } from "../../data/data";
6
- import bin from '../../assets/bin.svg';
7
- import RaffleProductFormRow from "../raffleProductFormRow/RaffleProductFormRow";
8
- import CustomSelect from "../../ui/customSelect/CustomSelect";
9
-
10
-
11
- const CrudRafflesSingle = ({ loading, setLoading, raffle, setView, refreshSelectedRaffle, setRaffle, formatDate, setSelectedSingleItemId, fetchRaffles }) => {
12
- const initialForm = {
13
- name: '',
14
- status: { id: 'draft', status: 'Draft' }, // default to draft status
15
- description: '',
16
- prizeDescription: '',
17
- raffleProducts: [
18
- { productSku: '', type: '', numEntries: '' }
19
- ]
20
- };
21
-
22
- const [formData, setFormData] = useState(initialForm);
23
- const [validationErrors, setValidationErrors] = useState([]);
24
-
25
- // when raffle prop changes, populate form
26
- useEffect(() => {
27
- const raffleStatus = raffleStatuses.find(status => status.id === (raffle?.status || 'draft'));
28
-
29
- if (raffle && raffle.id) {
30
- setFormData({
31
- name: raffle.name || '',
32
- status: raffleStatus,
33
- description: raffle.description || '',
34
- prizeDescription: raffle.prize_description || '',
35
- raffleProducts: raffle.raffleProducts?.map(p => ({
36
- productSku: p.product_sku || '',
37
- numEntries: p.num_entries?.toString() || '',
38
- type: p.type || 'one-time'
39
- })) || [{ productSku: '', numEntries: '', type: 'one-time' }]
40
- });
41
- } else {
42
- setFormData(initialForm);
43
- }
44
- }, [raffle]);
45
-
46
-
47
- // handle change for text/textarea inputs
48
- const handleFieldChange = (field, value) => {
49
- setFormData({ ...formData, [field]: value });
50
- };
51
-
52
- const handleSubmit = async (e) => {
53
- e.preventDefault();
54
- setLoading('loading');
55
- setValidationErrors([]);
56
-
57
- // prepare payload: convert numEntries to number
58
- const payload = {
59
- name: formData.name,
60
- status: formData.status.id,
61
- description: formData.description,
62
- prizeDescription: formData.prizeDescription,
63
- raffleProducts: formData.raffleProducts.map(p => ({
64
- productSku: p.productSku,
65
- type: p.type,
66
- numEntries: Number(p.numEntries) || 1,
67
- }))
68
- };
69
-
70
-
71
- try {
72
- let response;
73
- if (raffle && raffle.id) {
74
- response = await gnarEngine.raffles.updateRaffle(raffle.id, payload);
75
- } else {
76
- response = await gnarEngine.raffles.createRaffle([payload]);
77
- }
78
-
79
- if (response.error) {
80
- setValidationErrors(response.error);
81
- setLoading('error');
82
- } else {
83
- setLoading('success');
84
- setTimeout(() => {
85
- setLoading(null)
86
- }, 3000);
87
-
88
- if (raffle && raffle.id) {
89
- refreshSelectedRaffle();
90
- } else {
91
- setRaffle(response.raffle);
92
- refreshSelectedRaffle();
93
- await fetchRaffles();
94
- setView('list');
95
- }
96
- }
97
- } catch (error) {
98
- console.error('Error saving raffle:', error);
99
- setValidationErrors(['Error saving raffle']);
100
- setLoading('error');
101
- setTimeout(() => setLoading(null), 3000);
102
- }
103
- };
104
-
105
- const handleDelete = async () => {
106
- if (!raffle?.id)
107
- return;
108
- if (window.confirm('Are you sure you want to delete this raffle?')) {
109
- try {
110
- setLoading('loading');
111
- await gnarEngine.raffles.deleteRaffle(raffle.id);
112
- setLoading('success');
113
- setTimeout(() => {
114
- setLoading(null);
115
- }, 3000);
116
-
117
- refreshSelectedRaffle();
118
- await fetchRaffles();
119
- setView('list');
120
- } catch (error) {
121
- console.error('Error deleting raffle:', error);
122
- setLoading('error');
123
- }
124
- }
125
- };
126
-
127
- return (
128
- <div className="single-edit raffle">
129
- {validationErrors.length > 0 && (
130
- <div className="error-messages">
131
- {validationErrors.map((err, i) => <p key={i}>{err}</p>)}
132
- </div>
133
- )}
134
-
135
- <div className="single-edit-header">
136
- <div className="single-edit-header-left">
137
- <p><strong>{raffle?.id ? `Raffle# ${raffle.id}` : 'Add New Raffle'}</strong></p>
138
- {raffle?.createdAt && <p>Date Added: {formatDate(raffle.createdAt)}</p>}
139
- </div>
140
- <div className="single-edit-header-right flex-row-buttons-cont">
141
- <button type="button" onClick={() => { setView('list'); setRaffle(null); setSelectedSingleItemId(null); }} className="secondaryButton">Back</button>
142
- {raffle?.id && <button type="button" onClick={handleDelete} className="secondaryButton">Delete</button>}
143
- </div>
144
- </div>
145
-
146
- <form onSubmit={handleSubmit} className="form-body">
147
- <div className="form-group">
148
- <label>Name</label>
149
- <input type="text" value={formData.name} onChange={e => handleFieldChange('name', e.target.value)} />
150
- </div>
151
-
152
- <CustomSelect
153
- name="status"
154
- placeholder="Status"
155
- options={raffleStatuses}
156
- labelKey="status"
157
- setSelectedOption={selectedItem => handleFieldChange('status', selectedItem)}
158
- selectedOption={formData.status}
159
- />
160
-
161
- <div className="form-group">
162
- <label>Description</label>
163
- <textarea value={formData.description} onChange={e => handleFieldChange('description', e.target.value)} />
164
- </div>
165
-
166
- <div className="form-group">
167
- <label>Prize Description</label>
168
- <textarea value={formData.prizeDescription} onChange={e => handleFieldChange('prizeDescription', e.target.value)} />
169
- </div>
170
-
171
- </form>
172
-
173
- <Repeater
174
- items={formData.raffleProducts}
175
- setItems={(newItems) => setFormData({ ...formData, raffleProducts: newItems })}
176
- defaultItem={{ productSku: '', type: '', numEntries: 1 }}
177
- buttonText="Add Product"
178
- renderRow={(item, index, updateItem, remove) => (
179
- <RaffleProductFormRow
180
- key={index}
181
- item={item}
182
- onChange={(field, value) => updateItem({ ...item, [field]: value })}
183
- remove={remove}
184
- />
185
- )}
186
- />
187
-
188
-
189
- <div className="form-actions">
190
- <SaveButton
191
- save={handleSubmit}
192
- loading={loading}
193
- textCreate="Add Raffle"
194
- textCreateLoading="Saving..."
195
- textCreateSuccess="Saved"
196
- textCreateError="Error"
197
- textUpdate="Save"
198
- textUpdateLoading="Updating..."
199
- textUpdateSuccess="Updated"
200
- textUpdateError="Error"
201
- isUpdating={!!raffle?.id}
202
- />
203
- </div>
204
- </div>
205
- );
206
- };
207
-
208
- export default CrudRafflesSingle;
@@ -1,110 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import gnarEngine from '@gnar-engine/js-client';
3
- import CustomCheckbox from '../../ui/customCheckbox/CustomCheckbox';
4
-
5
- const CrudSubscriptionList = ({ setSelectedSingleItemId, setView, selectedSubscriptionIds, setSelectedSubscriptionIds, subscriptions, message}) => {
6
-
7
- const allSelected = subscriptions.length > 0 && selectedSubscriptionIds.size === subscriptions.length;
8
-
9
- const toggleContactSelection = (subscriptionId) => {
10
- setSelectedSubscriptionIds(prev => {
11
- const newSet = new Set(prev);
12
- if (newSet.has(subscriptionId)) {
13
- newSet.delete(subscriptionId);
14
- } else {
15
- newSet.add(subscriptionId);
16
- }
17
- return newSet;
18
- });
19
- };
20
-
21
-
22
- const toggleSelectAll = () => {
23
- if (allSelected) {
24
- setSelectedSubscriptionIds(new Set());
25
- } else {
26
- setSelectedSubscriptionIds(new Set(subscriptions.map(subscription => subscription.id)));
27
- }
28
- };
29
-
30
-
31
- const handleEditClick = (product) => {
32
- setSelectedSingleItemId(product.id);
33
- setView('single');
34
- };
35
-
36
- const columns = [
37
- { columnLabel: 'Subscription', dataKey: 'id' },
38
- { columnLabel: 'First Name', dataKey: 'firstName' },
39
- { columnLabel: 'Last Name', dataKey: 'lastName' },
40
- { columnLabel: 'Date', dataKey: 'createdAt' },
41
- { columnLabel: 'Status', dataKey: 'status' },
42
- { columnLabel: 'Total', dataKey: 'total' },
43
- { columnLabel: 'Date added', dataKey: 'createdAt' },
44
- ];
45
-
46
-
47
- return (
48
- <div className="">
49
- <div className='pagination-labels-cont'>
50
- <div className='pagination-count'>
51
- Showing {subscriptions.length} of {subscriptions.length} subscription{subscriptions.length !== 1 ? 's' : ''}
52
- </div>
53
- <div className="pagination-count">
54
- {selectedSubscriptionIds.size} of {subscriptions.length} subscription{subscriptions.length !== 1 ? 's' : ''} selected
55
- </div>
56
- </div>
57
- <div className='crud-list'>
58
- <table className='custom-table'>
59
- <thead>
60
- <tr>
61
- <th className="checkbox">
62
- <CustomCheckbox
63
- name="selectAll"
64
- checked={allSelected}
65
- setChecked={toggleSelectAll}
66
- />
67
- </th>
68
- {columns.map(column => (
69
- <th key={column.columnLabel}>{column.columnLabel}</th>
70
- ))}
71
- </tr>
72
- </thead>
73
-
74
- <tbody>
75
- {message ? (
76
- <tr>
77
- <td colSpan={columns.length + 1}>{message}</td>
78
- </tr>
79
- ) : (
80
- subscriptions.length > 0 ? (
81
- subscriptions.map(order => (
82
- <tr key={order.id} onClick={() => handleEditClick(order)}>
83
- <td>
84
- <CustomCheckbox
85
- name={`checkbox-${order.id}`}
86
- checked={selectedSubscriptionIds.has(order.id)}
87
- setChecked={() => toggleContactSelection(order.id)}
88
- />
89
- </td>
90
- {columns.map(column => (
91
- <td key={column.dataKey}>{order[column.dataKey]}</td>
92
- ))}
93
- </tr>
94
- ))
95
- ) : (
96
- <tr>
97
- <td colSpan={columns.length + 1}>No orders found</td>
98
- </tr>
99
- )
100
- )}
101
- </tbody>
102
- </table>
103
- </div>
104
- </div>
105
-
106
- );
107
-
108
- };
109
-
110
- export default CrudSubscriptionList;
@@ -1,261 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import gnarEngine from '@gnar-engine/js-client';
3
- import SaveButton from "../../ui/saveButton/SaveButton";
4
- import Repeater from "../../ui/repeater/Repeater";
5
- import Notes from "../notes/Notes";
6
- import CustomSelect from "../../ui/customSelect/CustomSelect";
7
- import { orderTypes, subscriptionStatuses } from '../../data/data';
8
- import { Link } from "react-router-dom";
9
- import BillingShipping from "../billingShipping/BillingShipping";
10
- import SubscriptionSchedule from "../subscriptionSchedule/SubscriptionSchedule";
11
- import LineItems from "../lineItems/LineItems";
12
-
13
-
14
- const CrudSubscriptionSingle = ({ loading, setLoading, subscription, setView, refreshSelectedSubscription, setSubscription, fetchSubscriptions, setSelectedSingleItemId, formatDate }) => {
15
-
16
- const [formData, setFormData] = useState({});
17
- const [validationErrors, setValidationErrors] = useState([]);
18
- const [orderType, setOrderType] = useState(null);
19
- const [orderStatus, setOrderStatus] = useState(null);
20
-
21
- useEffect(() => {
22
- if (subscription && subscription._id) {
23
- setFormData({
24
- ...subscription,
25
- });
26
-
27
- // set order type
28
- const existingOrderType = orderTypes.find(type => type.id === subscription.type);
29
- setOrderType(existingOrderType);
30
-
31
- // set order status
32
- const existingSubscriptionStatus = subscriptionStatuses.find(status => status.id === subscription.status);
33
- setOrderStatus(existingSubscriptionStatus);
34
-
35
- } else {
36
- setFormData({
37
- ...formData,
38
- userId: '',
39
- notes: [],
40
- type: null,
41
- status: null,
42
- billingAddress: {
43
- firstName: '',
44
- lastName: '',
45
- addressLine1: '',
46
- addressLine2: '',
47
- city: '',
48
- postcode: '',
49
- email: '',
50
- phone: '',
51
- },
52
- shippingAddress: {
53
- firstName: '',
54
- lastName: '',
55
- addressLine1: '',
56
- addressLine2: '',
57
- city: '',
58
- postcode: '',
59
- },
60
- lineItems: [],
61
- currency: 'GBP',
62
- subTotal: 0,
63
- shipping: 0,
64
- tax: 0,
65
- total: 0,
66
- });
67
- }
68
- }, [subscription]);
69
-
70
-
71
- const handleSubmit = async (e) => {
72
- e.preventDefault();
73
- setLoading('loading');
74
- setValidationErrors([]);
75
-
76
- try {
77
-
78
- // parse ints
79
- formData.retryAttempt = parseInt(formData.retryAttempt) || 0;
80
-
81
- if (subscription) {
82
- const response = await gnarEngine.subscription.updateSubscription(subscription._id, formData);
83
- console.log('response:', response);
84
-
85
- setLoading('success');
86
- setTimeout(() => {
87
- setLoading(null);
88
- fetchSubscriptions();
89
- refreshSelectedSubscription();
90
- }, 3000);
91
-
92
- refreshSelectedSubscription();
93
- } else {
94
-
95
- const response = await gnarEngine.subscription.createSubscription([formData]);
96
- console.log('response:', response);
97
-
98
- if (response.error) {
99
- setValidationErrors(response.error);
100
- } else {
101
- setSubscription(response.subscription);
102
- refreshSelectedSubscription();
103
- setView('list');
104
- }
105
- }
106
- }
107
- catch (error) {
108
- console.error('Error updating subscription:', error);
109
- setValidationErrors(['Error updating subscription']);
110
- setTimeout(() => {
111
- setLoading(null);
112
- }, 3000);
113
- }
114
-
115
-
116
- }
117
-
118
- // handle delete user
119
- const handleDelete = async () => {
120
- if (window.confirm('Are you sure you want to delete this subscription?')) {
121
- try {
122
- setLoading('loading');
123
-
124
- await gnarEngine.subscription.deleteSubscription(subscription._id);
125
-
126
- setLoading('success');
127
- setTimeout(() => {
128
- setLoading(null);
129
- }, 3000);
130
-
131
- refreshSelectedSubscription();
132
- setView('list');
133
-
134
- } catch (error) {
135
-
136
- setLoading('error');
137
- console.error('Error deleting subscription:', subscription);
138
- }
139
- } else {
140
- console.log('Deletion canceled');
141
- }
142
- };
143
-
144
- // check order being passed in
145
- useEffect(() => {
146
- console.log('subscription:', subscription);
147
- }, [subscription]);
148
-
149
-
150
- const handleStatusChange = (selectedOption) => {
151
- setOrderStatus(selectedOption);
152
- setFormData({
153
- ...formData,
154
- status: selectedOption.id,
155
- });
156
- }
157
-
158
-
159
- return (
160
-
161
- <div className="single-edit subscriptions">
162
- {validationErrors.length > 0 &&
163
- <div className="error-messages">
164
- {validationErrors.map((error, index) => {
165
- return <p key={index}>{error}</p>
166
- })}
167
- </div>
168
- }
169
-
170
- <div className='single-edit-header'>
171
- <div className='single-edit-header-left'>
172
- <p><strong>{subscription ? 'Subscription ID# ' + subscription._id : 'Add New Subscription'}</strong></p>
173
- <p>Date Added: {formatDate(subscription?.createdAt)}</p>
174
- <label htmlFor="orderStatus">Order Status</label>
175
- <CustomSelect
176
- name="status"
177
- labelKey="status"
178
- placeholder="Select subscription status"
179
- options={subscriptionStatuses}
180
- setSelectedOption={handleStatusChange}
181
- selectedOption={orderStatus}
182
- />
183
- <div className="input-cont flex-row flex-row-end">
184
- <div>
185
- <label htmlFor="userId">User ID</label>
186
- <input
187
- type="text"
188
- name="userId"
189
- placeholder="User ID"
190
- value={formData.userId}
191
- onChange={(e) => setFormData({ ...formData, userId: e.target.value })}
192
- />
193
- </div>
194
- <Link to={`/portal/users?view=single&id=${subscription?.userId}`}>
195
- <button className="mainButton">View / Edit</button>
196
- </Link>
197
- </div>
198
-
199
- </div>
200
- <div className='single-edit-header-right'>
201
- <div className="flex-row-buttons-cont">
202
- <button onClick={() => {
203
- setView('list');
204
- setSubscription(null);
205
- setSelectedSingleItemId(null);
206
- }} className="secondaryButton">
207
- Back
208
- </button>
209
- <button onClick={handleDelete} className="secondaryButton">Delete</button>
210
- <SaveButton
211
- save={handleSubmit}
212
- loading={loading}
213
- textCreate="Add Subscription"
214
- textCreateLoading="Saving..."
215
- textCreateSuccess="Saved"
216
- textCreateError="Error"
217
- textUpdate="Save"
218
- textUpdateLoading="Updating..."
219
- textUpdateSuccess="Updated"
220
- textUpdateError="Error"
221
- isUpdating={!!subscription}
222
- />
223
- </div>
224
- </div>
225
- </div>
226
-
227
- <BillingShipping
228
- order={subscription}
229
- />
230
-
231
- <SubscriptionSchedule
232
- subscription={subscription}
233
- formData={formData}
234
- onChange={(e) => setFormData({ ...formData, [e.target.name]: e.target.value })}
235
- />
236
-
237
- <LineItems
238
- order={subscription}
239
- />
240
-
241
- <div className="card">
242
- <div className='card-header'>
243
- <h2>Orders</h2>
244
- </div>
245
- <div className='card-content'>
246
- <div className="subscription-details-cont">
247
- <p><strong>Parent Order ID:</strong> {subscription?.originalSubscriptionOrderId}</p>
248
- <Link to={`/portal/orders?view=single&id=${subscription?.originalSubscriptionOrderId}`}>
249
- <button className="secondaryButton">View / Edit</button>
250
- </Link>
251
- </div>
252
- </div>
253
- </div>
254
-
255
- </div>
256
-
257
- );
258
-
259
- };
260
-
261
- export default CrudSubscriptionSingle;
@@ -1,107 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import gnarEngine from '@gnar-engine/js-client';
3
- import dotsVertical from '../../assets/dots-vertical.svg';
4
- import CustomCheckbox from '../../ui/customCheckbox/CustomCheckbox';
5
-
6
- const CrudUserList = ({ setSelectedSingleItemId, setView, selectedUserIds, setSelectedUserIds, users, message }) => {
7
-
8
- const allSelected = users.length > 0 && selectedUserIds.size === users.length;
9
-
10
- const handleEditClick = (user) => {
11
- setSelectedSingleItemId(user.id);
12
- setView('single');
13
- };
14
-
15
- const toggleUserSelection = (userId) => {
16
- setSelectedUserIds(prev => {
17
- const newSet = new Set(prev);
18
- if (newSet.has(userId)) {
19
- newSet.delete(userId);
20
- } else {
21
- newSet.add(userId);
22
- }
23
- return newSet;
24
- });
25
- };
26
-
27
-
28
- const toggleSelectAll = () => {
29
- if (allSelected) {
30
- setSelectedUserIds(new Set());
31
- } else {
32
- setSelectedUserIds(new Set(users.map(user => user.id)));
33
- }
34
- };
35
-
36
-
37
- const columns = [
38
- { columnLabel: 'ID', dataKey: 'id' },
39
- { columnLabel: 'Username', dataKey: 'username' },
40
- { columnLabel: 'Email', dataKey: 'email' },
41
- { columnLabel: 'User Role', dataKey: 'userRole' },
42
- { columnLabel: 'Date Added', dataKey: 'createdAt' }
43
- ];
44
-
45
- return (
46
- <div className="">
47
- <div className='pagination-labels-cont'>
48
- <div className='pagination-count'>
49
- Showing {users.length} of {users.length} user{users.length !== 1 ? 's' : ''}
50
- </div>
51
- <div className="pagination-count">
52
- {selectedUserIds.size} of {users.length} user{users.length !== 1 ? 's' : ''} selected
53
- </div>
54
- </div>
55
-
56
- <div className='crud-list'>
57
- <table className='custom-table'>
58
- <thead>
59
- <tr>
60
- <th className="checkbox">
61
- <CustomCheckbox
62
- name="select-all"
63
- checked={allSelected}
64
- setChecked={toggleSelectAll}
65
- />
66
- </th>
67
- {columns.map(column => (
68
- <th key={column.columnLabel}>{column.columnLabel}</th>
69
- ))}
70
- </tr>
71
- </thead>
72
-
73
- <tbody>
74
- {message ? (
75
- <tr>
76
- <td colSpan={columns.length + 1}>{message}</td>
77
- </tr>
78
- ) : (
79
- users.length > 0 ? (
80
- users.map(user => (
81
- <tr key={user.id} onClick={() => handleEditClick(user)}>
82
- <td onClick={(e) => e.stopPropagation()}>
83
- <CustomCheckbox
84
- name={`checkbox-${user.id}`}
85
- checked={selectedUserIds.has(user.id)}
86
- setChecked={() => toggleUserSelection(user.id)}
87
- />
88
- </td>
89
- {columns.map(column => (
90
- <td key={column.dataKey}>{user[column.dataKey]}</td>
91
- ))}
92
- </tr>
93
- ))
94
- ) : (
95
- <tr>
96
- <td colSpan={columns.length + 1}>No users found</td>
97
- </tr>
98
- )
99
- )}
100
- </tbody>
101
- </table>
102
- </div>
103
- </div>
104
- );
105
- };
106
-
107
- export default CrudUserList;