@gnar-engine/cli 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/assets/gnar-engine-logo-white.svg +9 -0
  2. package/bootstrap/deploy.localdev.yml +51 -0
  3. package/bootstrap/secrets.localdev.yml +27 -0
  4. package/bootstrap/services/agent/Dockerfile +23 -0
  5. package/bootstrap/services/agent/notes.md +28 -0
  6. package/bootstrap/services/agent/package.json +16 -0
  7. package/bootstrap/services/agent/src/app.js +52 -0
  8. package/bootstrap/services/agent/src/commands/agent.handler.js +104 -0
  9. package/bootstrap/services/agent/src/config.js +52 -0
  10. package/bootstrap/services/agent/src/controllers/http.controller.js +44 -0
  11. package/bootstrap/services/agent/src/controllers/message.controller.js +51 -0
  12. package/bootstrap/services/agent/src/db/migrations/01-init.js +50 -0
  13. package/bootstrap/services/agent/src/db/migrations/02-agent-service-init.js +36 -0
  14. package/bootstrap/services/agent/src/policies/agent.policy.js +13 -0
  15. package/bootstrap/services/agent/src/schema/Agent.schema.js +17 -0
  16. package/bootstrap/services/agent/src/services/agent.service.js +259 -0
  17. package/bootstrap/services/agent/src/services/chatgpt.service.js +46 -0
  18. package/bootstrap/services/agent/src/services/manifest.service.js +21 -0
  19. package/bootstrap/services/control/Dockerfile +23 -0
  20. package/bootstrap/services/control/Dockerfile.prod +37 -0
  21. package/bootstrap/services/control/README.md +25 -0
  22. package/bootstrap/services/control/package.json +16 -0
  23. package/bootstrap/services/control/src/app.js +45 -0
  24. package/bootstrap/services/control/src/commands/control.handler.js +231 -0
  25. package/bootstrap/services/control/src/commands/service.handler.js +81 -0
  26. package/bootstrap/services/control/src/commands/task.handler.js +247 -0
  27. package/bootstrap/services/control/src/config.js +55 -0
  28. package/bootstrap/services/control/src/controllers/http.controller.js +228 -0
  29. package/bootstrap/services/control/src/controllers/message.controller.js +40 -0
  30. package/bootstrap/services/control/src/db/migrations/01-init.js +50 -0
  31. package/bootstrap/services/control/src/db/migrations/02-control-service-init.js +60 -0
  32. package/bootstrap/services/control/src/db/migrations/03-alter-tasks.js +29 -0
  33. package/bootstrap/services/control/src/policies/task.policy.js +53 -0
  34. package/bootstrap/services/control/src/schema/control.schema.js +42 -0
  35. package/bootstrap/services/control/src/services/registry.service.js +83 -0
  36. package/bootstrap/services/control/src/services/reset.service.js +28 -0
  37. package/bootstrap/services/control/src/services/task.service.js +153 -0
  38. package/bootstrap/services/control/src/tests/control.test.js +50 -0
  39. package/bootstrap/services/notification/Dockerfile +23 -0
  40. package/bootstrap/services/notification/Dockerfile.prod +37 -0
  41. package/bootstrap/services/notification/README.md +3 -0
  42. package/bootstrap/services/notification/package.json +34 -0
  43. package/bootstrap/services/notification/src/app.js +51 -0
  44. package/bootstrap/services/notification/src/commands/command-bus.js +20 -0
  45. package/bootstrap/services/notification/src/commands/handlers/control.handler.js +18 -0
  46. package/bootstrap/services/notification/src/commands/handlers/notification.handler.js +157 -0
  47. package/bootstrap/services/notification/src/config.js +15 -0
  48. package/bootstrap/services/notification/src/controllers/message.controller.js +82 -0
  49. package/bootstrap/services/notification/src/services/logger.service.js +16 -0
  50. package/bootstrap/services/notification/src/services/ses.service.js +23 -0
  51. package/bootstrap/services/notification/src/templates/admin-order-recieved.hbs +136 -0
  52. package/bootstrap/services/notification/src/templates/admin-subscription-failed.hbs +87 -0
  53. package/bootstrap/services/notification/src/templates/customer-order-recieved.hbs +132 -0
  54. package/bootstrap/services/notification/src/templates/customer-subscription-failed.hbs +77 -0
  55. package/bootstrap/services/notification/src/tests/notification.test.js +0 -0
  56. package/bootstrap/services/portal/Dockerfile +23 -0
  57. package/bootstrap/services/portal/Dockerfile.remote +40 -0
  58. package/bootstrap/services/portal/README.md +22 -0
  59. package/bootstrap/services/portal/nginx.conf +12 -0
  60. package/bootstrap/services/portal/package.json +59 -0
  61. package/bootstrap/services/portal/public/favicon.ico +0 -0
  62. package/bootstrap/services/portal/public/gnar-white.png +0 -0
  63. package/bootstrap/services/portal/public/gnarengine-logo-black.png +0 -0
  64. package/bootstrap/services/portal/public/index.html +43 -0
  65. package/bootstrap/services/portal/public/logo192.png +0 -0
  66. package/bootstrap/services/portal/public/logo512.png +0 -0
  67. package/bootstrap/services/portal/public/manifest.json +25 -0
  68. package/bootstrap/services/portal/public/robots.txt +3 -0
  69. package/bootstrap/services/portal/src/App.js +56 -0
  70. package/bootstrap/services/portal/src/assets/Logo_Anchord_Black.svg +1 -0
  71. package/bootstrap/services/portal/src/assets/Logo_Anchord_Black_Green.svg +1 -0
  72. package/bootstrap/services/portal/src/assets/Logo_Anchord_White_Green.svg +1 -0
  73. package/bootstrap/services/portal/src/assets/activity.svg +3 -0
  74. package/bootstrap/services/portal/src/assets/arrow.svg +3 -0
  75. package/bootstrap/services/portal/src/assets/bin-white.svg +3 -0
  76. package/bootstrap/services/portal/src/assets/bin.svg +3 -0
  77. package/bootstrap/services/portal/src/assets/check.svg +3 -0
  78. package/bootstrap/services/portal/src/assets/chevron.svg +3 -0
  79. package/bootstrap/services/portal/src/assets/contact.svg +3 -0
  80. package/bootstrap/services/portal/src/assets/dots-vertical.svg +5 -0
  81. package/bootstrap/services/portal/src/assets/eye-off.svg +3 -0
  82. package/bootstrap/services/portal/src/assets/eye.svg +4 -0
  83. package/bootstrap/services/portal/src/assets/gnar-engine-black.svg +47 -0
  84. package/bootstrap/services/portal/src/assets/gnar-engine-white.svg +47 -0
  85. package/bootstrap/services/portal/src/assets/gnar_engine.svg +3 -0
  86. package/bootstrap/services/portal/src/assets/gnarengine-logo-black.png +0 -0
  87. package/bootstrap/services/portal/src/assets/home.svg +3 -0
  88. package/bootstrap/services/portal/src/assets/link.svg +3 -0
  89. package/bootstrap/services/portal/src/assets/lock.svg +3 -0
  90. package/bootstrap/services/portal/src/assets/package.svg +4 -0
  91. package/bootstrap/services/portal/src/assets/raffle.svg +3 -0
  92. package/bootstrap/services/portal/src/assets/settings.svg +4 -0
  93. package/bootstrap/services/portal/src/assets/shopping-bag.svg +3 -0
  94. package/bootstrap/services/portal/src/assets/user-black.svg +3 -0
  95. package/bootstrap/services/portal/src/assets/user.svg +3 -0
  96. package/bootstrap/services/portal/src/assets/users.svg +3 -0
  97. package/bootstrap/services/portal/src/assets/wallet.svg +3 -0
  98. package/bootstrap/services/portal/src/css/style.css +1007 -0
  99. package/bootstrap/services/portal/src/data/data.js +70 -0
  100. package/bootstrap/services/portal/src/features/attributeFormRow/AttributeFormRow.jsx +32 -0
  101. package/bootstrap/services/portal/src/features/billingShipping/BillingShipping.jsx +160 -0
  102. package/bootstrap/services/portal/src/features/crud/crudEdit.less +230 -0
  103. package/bootstrap/services/portal/src/features/crud/crudList.less +134 -0
  104. package/bootstrap/services/portal/src/features/crud/crudPage.less +31 -0
  105. package/bootstrap/services/portal/src/features/crudContact/CrudContactList.jsx +108 -0
  106. package/bootstrap/services/portal/src/features/crudContact/CrudContactSingle.jsx +243 -0
  107. package/bootstrap/services/portal/src/features/crudOrder/CrudOrderList.jsx +109 -0
  108. package/bootstrap/services/portal/src/features/crudOrder/CrudOrderSingle.jsx +315 -0
  109. package/bootstrap/services/portal/src/features/crudProducts/CrudProductList.jsx +104 -0
  110. package/bootstrap/services/portal/src/features/crudProducts/CrudProductSingle.jsx +388 -0
  111. package/bootstrap/services/portal/src/features/crudRaffles/CrudRafflesList.jsx +104 -0
  112. package/bootstrap/services/portal/src/features/crudRaffles/CrudRafflesSingle.jsx +208 -0
  113. package/bootstrap/services/portal/src/features/crudSubscription/CrudSubscriptionList.jsx +110 -0
  114. package/bootstrap/services/portal/src/features/crudSubscription/CrudSubscriptionSingle.jsx +261 -0
  115. package/bootstrap/services/portal/src/features/crudUser/CrudUserList.jsx +107 -0
  116. package/bootstrap/services/portal/src/features/crudUser/CrudUserSingle.jsx +402 -0
  117. package/bootstrap/services/portal/src/features/inventoryFormRow/InventoryFormRow.jsx +30 -0
  118. package/bootstrap/services/portal/src/features/lineItems/LineItems.jsx +113 -0
  119. package/bootstrap/services/portal/src/features/loginForm/LoginForm.jsx +56 -0
  120. package/bootstrap/services/portal/src/features/loginForm/loginForm.less +56 -0
  121. package/bootstrap/services/portal/src/features/notes/Notes.jsx +18 -0
  122. package/bootstrap/services/portal/src/features/passwordReset/PasswordResetForm.jsx +96 -0
  123. package/bootstrap/services/portal/src/features/passwordReset/PasswordResetRequestForm.jsx +74 -0
  124. package/bootstrap/services/portal/src/features/priceFormRow/PriceFormRow.jsx +102 -0
  125. package/bootstrap/services/portal/src/features/priceFormRow/priceFormRow.less +24 -0
  126. package/bootstrap/services/portal/src/features/raffleEntriesList/RaffleEntriesList.jsx +99 -0
  127. package/bootstrap/services/portal/src/features/raffleProductFormRow/RaffleProductFormRow.jsx +46 -0
  128. package/bootstrap/services/portal/src/features/sidebar/Sidebar.jsx +64 -0
  129. package/bootstrap/services/portal/src/features/sidebar/sidebar.less +49 -0
  130. package/bootstrap/services/portal/src/features/skus/Skus.jsx +109 -0
  131. package/bootstrap/services/portal/src/features/subscriptionSchedule/SubscriptionSchedule.jsx +44 -0
  132. package/bootstrap/services/portal/src/features/taxonomyFormRow/TaxonomyFormRow.jsx +32 -0
  133. package/bootstrap/services/portal/src/features/user/User.jsx +54 -0
  134. package/bootstrap/services/portal/src/features/user/user.less +57 -0
  135. package/bootstrap/services/portal/src/includes/utilities.js +259 -0
  136. package/bootstrap/services/portal/src/index.js +14 -0
  137. package/bootstrap/services/portal/src/layouts/CrudLayout.jsx +50 -0
  138. package/bootstrap/services/portal/src/layouts/LoginLayout.jsx +17 -0
  139. package/bootstrap/services/portal/src/layouts/PortalLayout.jsx +48 -0
  140. package/bootstrap/services/portal/src/layouts/loginLayout.less +33 -0
  141. package/bootstrap/services/portal/src/layouts/portalLayout.less +67 -0
  142. package/bootstrap/services/portal/src/pages/contacts/Contacts.jsx +199 -0
  143. package/bootstrap/services/portal/src/pages/dashboard/Dashboard.jsx +17 -0
  144. package/bootstrap/services/portal/src/pages/integrations/Integrations.jsx +10 -0
  145. package/bootstrap/services/portal/src/pages/login/Login.jsx +15 -0
  146. package/bootstrap/services/portal/src/pages/login/login.less +10 -0
  147. package/bootstrap/services/portal/src/pages/orders/Orders.jsx +199 -0
  148. package/bootstrap/services/portal/src/pages/passwordReset/PasswordResetPage.jsx +15 -0
  149. package/bootstrap/services/portal/src/pages/passwordResetRequest/PasswordResetRequestPage.jsx +15 -0
  150. package/bootstrap/services/portal/src/pages/payments/Payments.jsx +10 -0
  151. package/bootstrap/services/portal/src/pages/portal/Portal.jsx +43 -0
  152. package/bootstrap/services/portal/src/pages/products/Products.jsx +212 -0
  153. package/bootstrap/services/portal/src/pages/raffleEntries/RaffleEntries.jsx +124 -0
  154. package/bootstrap/services/portal/src/pages/raffles/Raffles.jsx +186 -0
  155. package/bootstrap/services/portal/src/pages/reports/Reports.jsx +10 -0
  156. package/bootstrap/services/portal/src/pages/settings/Settings.jsx +10 -0
  157. package/bootstrap/services/portal/src/pages/subscriptions/Subscriptions.jsx +199 -0
  158. package/bootstrap/services/portal/src/pages/users/Users.jsx +193 -0
  159. package/bootstrap/services/portal/src/pages/users/users.less +25 -0
  160. package/bootstrap/services/portal/src/slices/authSlice.js +71 -0
  161. package/bootstrap/services/portal/src/store/configureStore.js +12 -0
  162. package/bootstrap/services/portal/src/styles/global.less +159 -0
  163. package/bootstrap/services/portal/src/styles/inputs.less +157 -0
  164. package/bootstrap/services/portal/src/styles/main.less +26 -0
  165. package/bootstrap/services/portal/src/ui/collapsible/Collapsible.jsx +97 -0
  166. package/bootstrap/services/portal/src/ui/collapsible/collapsible.less +23 -0
  167. package/bootstrap/services/portal/src/ui/customCheckbox/CustomCheckbox.jsx +17 -0
  168. package/bootstrap/services/portal/src/ui/customCheckbox/customCheckbox.less +42 -0
  169. package/bootstrap/services/portal/src/ui/customMultiSelect/CustomMultiSelect.jsx +63 -0
  170. package/bootstrap/services/portal/src/ui/customMultiSelect/CustomMultiSelectPeriod.jsx +63 -0
  171. package/bootstrap/services/portal/src/ui/customSelect/CustomSelect.jsx +63 -0
  172. package/bootstrap/services/portal/src/ui/customSelect/customSelect.less +92 -0
  173. package/bootstrap/services/portal/src/ui/goBack/GoBack.jsx +19 -0
  174. package/bootstrap/services/portal/src/ui/loader/Loader.jsx +12 -0
  175. package/bootstrap/services/portal/src/ui/pagination/Pagination.jsx +23 -0
  176. package/bootstrap/services/portal/src/ui/repeater/Repeater.jsx +29 -0
  177. package/bootstrap/services/portal/src/ui/saveButton/SaveButton.jsx +69 -0
  178. package/bootstrap/services/portal/src/ui/saveButton/saveButton.less +0 -0
  179. package/bootstrap/services/rabbit-mq/Dockerfile.prod +9 -0
  180. package/bootstrap/services/user/Dockerfile +23 -0
  181. package/bootstrap/services/user/Dockerfile.prod +37 -0
  182. package/bootstrap/services/user/README.md +8 -0
  183. package/bootstrap/services/user/package.json +16 -0
  184. package/bootstrap/services/user/src/app.js +45 -0
  185. package/bootstrap/services/user/src/commands/session.handler.js +23 -0
  186. package/bootstrap/services/user/src/commands/user.handler.js +286 -0
  187. package/bootstrap/services/user/src/config.js +73 -0
  188. package/bootstrap/services/user/src/controllers/http.controller.js +156 -0
  189. package/bootstrap/services/user/src/controllers/message.controller.js +51 -0
  190. package/bootstrap/services/user/src/db/migrations/01-init.js +50 -0
  191. package/bootstrap/services/user/src/db/migrations/02-user-service-init.js +63 -0
  192. package/bootstrap/services/user/src/db/migrations/03-unauth-sessions.js +43 -0
  193. package/bootstrap/services/user/src/db/seeders/development/01-root-user.js +29 -0
  194. package/bootstrap/services/user/src/db/seeders/development/02-portal-admin-user.js +27 -0
  195. package/bootstrap/services/user/src/db/seeders/production/01-root-user.js +29 -0
  196. package/bootstrap/services/user/src/policies/user.policy.js +81 -0
  197. package/bootstrap/services/user/src/schema/user.schema.js +69 -0
  198. package/bootstrap/services/user/src/services/authentication.service.js +127 -0
  199. package/bootstrap/services/user/src/services/session.service.js +58 -0
  200. package/bootstrap/services/user/src/services/user.service.js +130 -0
  201. package/bootstrap/services/user/src/tests/user.test.js +126 -0
  202. package/package.json +3 -7
  203. package/src/agent/agent.client.js +28 -0
  204. package/src/agent/commands.js +48 -0
  205. package/src/cli.js +30 -0
  206. package/src/config.js +8 -0
  207. package/src/control/commands.js +156 -0
  208. package/src/control/control.client.js +127 -0
  209. package/src/dev/commands.js +71 -0
  210. package/src/dev/dev.service.js +320 -0
  211. package/src/engine/infra.js +142 -0
  212. package/src/helpers/helpers.js +63 -0
  213. package/src/profiles/command.js +170 -0
  214. package/src/profiles/profiles.client.js +101 -0
  215. package/src/scaffolder/commands.js +123 -0
  216. package/src/scaffolder/scaffolder.handler.js +252 -0
  217. package/src/services/client.js +174 -0
  218. package/templates/service/Dockerfile.hbs +20 -0
  219. package/templates/service/app.js.hbs +38 -0
  220. package/templates/service/commands/{{serviceName}}.handler.js.hbs +97 -0
  221. package/templates/service/config.js.hbs +48 -0
  222. package/templates/service/controllers/http.controller.js.hbs +87 -0
  223. package/templates/service/controllers/message.controller.js.hbs +51 -0
  224. package/templates/service/db/migrations/01-init.js.hbs +50 -0
  225. package/templates/service/db/migrations/02-{{lowerCase serviceName}}-service-init.js.hbs +23 -0
  226. package/templates/service/package.json.hbs +18 -0
  227. package/templates/service/policies/{{serviceName}}.policy.js.hbs +49 -0
  228. package/templates/service/schema/{{serviceName}}.schema.js.hbs +14 -0
  229. package/templates/service/services/{{serviceName}}.service.js.hbs +32 -0
  230. package/dist/cli.js +0 -18
@@ -0,0 +1,315 @@
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, orderStatuses } from '../../data/data';
8
+ import { Link } from "react-router-dom";
9
+ import BillingShipping from "../billingShipping/BillingShipping";
10
+ import LineItems from "../lineItems/LineItems";
11
+
12
+
13
+ const CrudOrderSingle = ({ loading, setLoading, order, setView, refreshSelectedOrder, setOrder, formatDate, setSelectedSingleItemId }) => {
14
+
15
+ const [formData, setFormData] = useState({});
16
+ const [validationErrors, setValidationErrors] = useState([]);
17
+ const [orderType, setOrderType] = useState(null);
18
+ const [orderStatus, setOrderStatus] = useState(null);
19
+ const [notes, setNotes] = useState([]);
20
+
21
+ useEffect(() => {
22
+ if (order && order._id) {
23
+ setFormData(prevFormData => ({
24
+ ...prevFormData,
25
+ userId: order.userId,
26
+ type: order.type,
27
+ status: order.status,
28
+ billingAddress: order.billingAddress,
29
+ shippingAddress: order.shippingAddress,
30
+ lineItems: order.lineItems,
31
+ currency: order.currency,
32
+ subTotal: order.subTotal,
33
+ shipping: order.shipping,
34
+ tax: order.tax,
35
+ total: order.total,
36
+ }));
37
+
38
+ setNotes(order.notes || []);
39
+
40
+ // set order type
41
+ const existingOrderType = orderTypes.find(type => type.id === order.type);
42
+ setOrderType(existingOrderType);
43
+
44
+ // set order status
45
+ const existingOrderStatus = orderStatuses.find(status => status.id === order.status);
46
+ setOrderStatus(existingOrderStatus);
47
+
48
+ } else {
49
+ setFormData({
50
+ ...formData,
51
+ userId: '',
52
+ type: null,
53
+ status: null,
54
+ billingAddress: {
55
+ firstName: '',
56
+ lastName: '',
57
+ addressLine1: '',
58
+ addressLine2: '',
59
+ city: '',
60
+ postcode: '',
61
+ email: '',
62
+ phone: '',
63
+ },
64
+ shippingAddress: {
65
+ firstName: '',
66
+ lastName: '',
67
+ addressLine1: '',
68
+ addressLine2: '',
69
+ city: '',
70
+ postcode: '',
71
+ },
72
+ lineItems: [],
73
+ currency: 'GBP',
74
+ subTotal: 0,
75
+ shipping: 0,
76
+ tax: 0,
77
+ total: 0,
78
+ });
79
+ setNotes([]);
80
+ }
81
+ }, [order]);
82
+
83
+
84
+ const handleSubmit = async (e) => {
85
+ e.preventDefault();
86
+ setLoading('loading');
87
+ setValidationErrors([]);
88
+
89
+ try {
90
+ const updatedOrder = {
91
+ ...formData,
92
+ notes: notes,
93
+ };
94
+
95
+ if (order) {
96
+ const response = await gnarEngine.order.updateOrder(order._id,{
97
+ ...order,
98
+ ...updatedOrder
99
+ });
100
+ console.log('response:', response);
101
+
102
+ setLoading('success');
103
+ setTimeout(() => {
104
+ setLoading(null);
105
+ }, 3000);
106
+
107
+ refreshSelectedOrder();
108
+ } else {
109
+
110
+ const response = await gnarEngine.order.createOrder([updatedOrder]);
111
+ console.log('response:', response);
112
+
113
+ if (response.error) {
114
+ setValidationErrors(response.error);
115
+ } else {
116
+ setOrder(response.order);
117
+ refreshSelectedOrder();
118
+ setView('list');
119
+ }
120
+ }
121
+ }
122
+ catch (error) {
123
+ console.error('Error updating order:', error);
124
+ setValidationErrors(['Error updating order']);
125
+ setTimeout(() => {
126
+ setLoading(null);
127
+ }, 3000);
128
+ }
129
+
130
+
131
+ }
132
+
133
+ // handle delete user
134
+ const handleDelete = async () => {
135
+ if (window.confirm('Are you sure you want to delete this order?')) {
136
+ try {
137
+ setLoading('loading');
138
+
139
+ await gnarEngine.order.delete(order._id);
140
+
141
+ setLoading('success');
142
+ setTimeout(() => {
143
+ setLoading(null);
144
+ }, 3000);
145
+
146
+ refreshSelectedOrder();
147
+ setView('list');
148
+
149
+ } catch (error) {
150
+
151
+ setLoading('error');
152
+ console.error('Error deleting order:', error);
153
+ }
154
+ } else {
155
+ console.log('Deletion canceled');
156
+ }
157
+ };
158
+
159
+ // check order being passed in
160
+ useEffect(() => {
161
+ console.log('order:', order);
162
+ }, [order]);
163
+
164
+
165
+ const handleTypeChange = (selectedOption) => {
166
+ setOrderStatus(selectedOption);
167
+ setFormData({
168
+ ...formData,
169
+ type: selectedOption.id,
170
+ });
171
+ }
172
+
173
+ const handleStatusChange = (selectedOption) => {
174
+ setOrderStatus(selectedOption);
175
+ setFormData({
176
+ ...formData,
177
+ status: selectedOption.id,
178
+ });
179
+ }
180
+
181
+
182
+ return (
183
+
184
+ <div className="single-edit order">
185
+ {validationErrors.length > 0 &&
186
+ <div className="error-messages">
187
+ {validationErrors.map((error, index) => {
188
+ return <p key={index}>{error}</p>
189
+ })}
190
+ </div>
191
+ }
192
+
193
+ <div className='single-edit-header'>
194
+ <div className='single-edit-header-left'>
195
+ <p><strong>{order ? 'Order# ' + order._id : 'Add New Order'}</strong></p>
196
+ <p>Date Added: {formatDate(order?.createdAt)}</p>
197
+ <label>Order Type</label>
198
+ <CustomSelect
199
+ name="type"
200
+ labelKey="type"
201
+ placeholder="Select order type"
202
+ options={orderTypes}
203
+ setSelectedOption={handleTypeChange}
204
+ selectedOption={orderType}
205
+ />
206
+ <label>Order Status</label>
207
+ <CustomSelect
208
+ name="status"
209
+ labelKey="status"
210
+ placeholder="Select order status"
211
+ options={orderStatuses}
212
+ setSelectedOption={handleStatusChange}
213
+ selectedOption={orderStatus}
214
+ />
215
+ <div className="input-cont flex-row flex-row-end">
216
+ <div>
217
+ <label>User ID</label>
218
+ <input
219
+ type="text"
220
+ name="userId"
221
+ placeholder="User ID"
222
+ value={formData.userId}
223
+ onChange={(e) => setFormData({ ...formData, userId: e.target.value })}
224
+ />
225
+ </div>
226
+ <Link to={`/portal/users?view=single&id=${order?.userId}`}>
227
+ <button className="mainButton">View / Edit</button>
228
+ </Link>
229
+ </div>
230
+
231
+ </div>
232
+ <div className='single-edit-header-right'>
233
+ <div className="flex-row-buttons-cont">
234
+ <button onClick={() => {
235
+ setView('list');
236
+ setOrder(null);
237
+ setSelectedSingleItemId(null);
238
+ }} className="secondaryButton">
239
+ Back
240
+ </button>
241
+ <button onClick={handleDelete} className="secondaryButton">Delete</button>
242
+ <SaveButton
243
+ save={handleSubmit}
244
+ loading={loading}
245
+ textCreate="Add Order"
246
+ textCreateLoading="Saving..."
247
+ textCreateSuccess="Saved"
248
+ textCreateError="Error"
249
+ textUpdate="Save"
250
+ textUpdateLoading="Updating..."
251
+ textUpdateSuccess="Updated"
252
+ textUpdateError="Error"
253
+ isUpdating={!!order}
254
+ />
255
+ </div>
256
+ </div>
257
+ </div>
258
+
259
+ <BillingShipping
260
+ order={order}
261
+ />
262
+
263
+ <LineItems
264
+ order={order}
265
+ />
266
+
267
+ <div className="card">
268
+ <div className='card-header'>
269
+ <h2>Order Notes</h2>
270
+ </div>
271
+ <div className='card-content'>
272
+ <div className="order-notes-cont">
273
+ <Repeater
274
+ items={notes}
275
+ setItems={setNotes}
276
+ defaultItem={{ note: '' }}
277
+ renderRow={(item, index, onChange, remove) => (
278
+ <Notes key={index} item={item} onChange={onChange} remove={remove} />
279
+ )}
280
+ buttonText="Add Note"
281
+ />
282
+ </div>
283
+ </div>
284
+ </div>
285
+
286
+ {order && order.subscriptions && (
287
+ <div className="card">
288
+ <div className='card-header'>
289
+ <h2>Subscriptions</h2>
290
+ </div>
291
+ <div className='card-content'>
292
+ {order.subscriptions.length > 0 ? (
293
+ <>
294
+ {order.subscriptions.map((subscription, index) => (
295
+ <div className="subscription-details-cont" key={index}>
296
+ <p><strong>Subscription ID:</strong> {subscription?._id}</p>
297
+ <Link to={`/portal/subscriptions?view=single&id=${subscription._id}`}>
298
+ <button className="secondaryButton">View / Edit</button>
299
+ </Link>
300
+ </div>
301
+ ))}
302
+ </>
303
+ ) : (
304
+ <p>No subscriptions found.</p>
305
+ )}
306
+ </div>
307
+ </div>
308
+ )}
309
+ </div>
310
+
311
+ );
312
+
313
+ };
314
+
315
+ export default CrudOrderSingle;
@@ -0,0 +1,104 @@
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 CrudProductList = ({ setSelectedSingleItemId, setView, selectedProductIds, setSelectedProductIds, products, message }) => {
6
+
7
+ const allSelected = products.length > 0 && selectedProductIds.size === products.length;
8
+
9
+ const toggleProductSelection = (productId) => {
10
+ setSelectedProductIds(prev => {
11
+ const newSet = new Set(prev);
12
+ if (newSet.has(productId)) {
13
+ newSet.delete(productId);
14
+ } else {
15
+ newSet.add(productId);
16
+ }
17
+ return newSet;
18
+ });
19
+ };
20
+
21
+ const toggleSelectAll = () => {
22
+ if (allSelected) {
23
+ setSelectedProductIds(new Set());
24
+ } else {
25
+ setSelectedProductIds(new Set(products.map(product => product.id)));
26
+ }
27
+ };
28
+
29
+ const handleEditClick = (product) => {
30
+ setSelectedSingleItemId(product.id);
31
+ setView('single');
32
+ };
33
+
34
+ const columns = [
35
+ { columnLabel: 'ID', dataKey: 'id' },
36
+ { columnLabel: 'Image', dataKey: 'image' },
37
+ { columnLabel: 'Name', dataKey: 'name' },
38
+ { columnLabel: 'Sku', dataKey: 'sku' },
39
+ { columnLabel: 'Categories', dataKey: 'categories' },
40
+ { columnLabel: 'Date Added', dataKey: 'createdAt' }
41
+ ];
42
+
43
+ return (
44
+ <div className="">
45
+ <div className='pagination-labels-cont'>
46
+ <div className='pagination-count'>
47
+ Showing {products.length} of {products.length} product{products.length !== 1 ? 's' : ''}
48
+ </div>
49
+ <div className="pagination-count">
50
+ {selectedProductIds.size} of {products.length} product{products.length !== 1 ? 's' : ''} selected
51
+ </div>
52
+ </div>
53
+ <div className='crud-list'>
54
+ <table className='custom-table'>
55
+ <thead>
56
+ <tr>
57
+ <th className="checkbox">
58
+ <CustomCheckbox
59
+ name="selectAll"
60
+ checked={allSelected}
61
+ setChecked={toggleSelectAll}
62
+ />
63
+ </th>
64
+ {columns.map(column => (
65
+ <th key={column.columnLabel}>{column.columnLabel}</th>
66
+ ))}
67
+ </tr>
68
+ </thead>
69
+
70
+ <tbody>
71
+ {message ? (
72
+ <tr>
73
+ <td colSpan={columns.length + 1}>{message}</td>
74
+ </tr>
75
+ ) : (
76
+ products.length > 0 ? (
77
+ products.map(product => (
78
+ <tr key={product.id} onClick={() => handleEditClick(product)}>
79
+ <td>
80
+ <CustomCheckbox
81
+ name={`checkbox-${product.id}`}
82
+ checked={selectedProductIds.has(product.id)}
83
+ setChecked={() => toggleProductSelection(product.id)}
84
+ />
85
+ </td>
86
+ {columns.map(column => (
87
+ <td key={column.dataKey}>{product[column.dataKey]}</td>
88
+ ))}
89
+ </tr>
90
+ ))
91
+ ) : (
92
+ <tr>
93
+ <td colSpan={columns.length + 1}>No products found</td>
94
+ </tr>
95
+ )
96
+ )}
97
+ </tbody>
98
+ </table>
99
+ </div>
100
+ </div>
101
+ );
102
+ };
103
+
104
+ export default CrudProductList;