@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,18 +1,25 @@
1
- import {createSlice, createAsyncThunk, createAction} from '@reduxjs/toolkit';
2
- import { getAuthToken, getAuthUser, setAuthToken, setAuthUser, removeAuthToken, removeAuthUser } from '@gnar-engine/js-client/src/storage';
3
- import gnarEngine from '@gnar-engine/js-client';
1
+ import { createSlice, createAsyncThunk, createAction } from '@reduxjs/toolkit';
2
+ import { getAuthToken, getAuthUser, setAuthToken, setAuthUser, removeAuthToken, removeAuthUser } from '../services/storage.js';
3
+ import { user } from '../services/user.js';
4
4
 
5
5
 
6
- export const login = createAsyncThunk('auth/login', async ({username, password}) => {
7
-
6
+ export const login = createAsyncThunk('auth/login', async ({ username, password }) => {
8
7
  let response;
9
-
10
8
  try {
11
- response = await gnarEngine.user.authenticate(username, password);;
9
+ response = await user.authenticate({ username, password });
12
10
  } catch (error) {
13
11
  response = error.response;
14
12
  }
13
+ return response;
14
+ })
15
15
 
16
+ export const register = createAsyncThunk('auth/register', async (user) => {
17
+ let response;
18
+ try {
19
+ response = await user.createUser(user);
20
+ } catch (error) {
21
+ response = error.response;
22
+ }
16
23
  return response;
17
24
  })
18
25
 
@@ -35,8 +42,9 @@ export const authSlice = createSlice({
35
42
  state.authError = '';
36
43
  })
37
44
  .addCase(login.fulfilled, (state, action) => {
45
+ console.log('login.fulfilled', action.payload);
38
46
  state.authLoading = false;
39
- state.authError = action.payload.data?.error ? action.payload.data.message : '';
47
+ state.authError = action.payload.message ? action.payload.message : '';
40
48
 
41
49
  if (action.payload.token) {
42
50
  state.accessToken = action.payload.token;
@@ -47,10 +55,7 @@ export const authSlice = createSlice({
47
55
  setAuthUser(JSON.stringify(action.payload.user));
48
56
 
49
57
  // redirect to portal
50
- window.location.href= '/portal';
51
- } else {
52
- // Handle error case
53
- console.error('Login failed:', action.payload);
58
+ window.location.href= '/portal/dashboard';
54
59
  }
55
60
  })
56
61
  .addCase(logout, (state, action) => {
@@ -63,9 +68,34 @@ export const authSlice = createSlice({
63
68
  removeAuthUser();
64
69
 
65
70
  // Redirect to login page
66
- window.location.href = '/login';
71
+ window.location.href = '/portal/login';
72
+ })
73
+
74
+ // Register
75
+ .addCase(register.pending, (state, action) => {
76
+ state.status = 'loading';
77
+ })
78
+ .addCase(register.fulfilled, (state, action) => {
79
+ state.status = 'idle';
80
+
81
+ if (action.payload.users && action.payload.users.length > 0) {
82
+ const user = action.payload.users[0];
83
+
84
+ state.logged_in = true;
85
+ state.user = user;
86
+
87
+ // Save user auth details (if needed)
88
+ setAuthUser(JSON.stringify(user));
89
+
90
+ // Redirect to dashboard page
91
+ window.location.href = '/portal/dashboard';
92
+ } else {
93
+ state.logged_in = false;
94
+ state.user = {};
95
+ state.error = 'Registration failed: Invalid response';
96
+ }
67
97
  });
68
98
  }
69
99
  })
70
100
 
71
- export default authSlice;
101
+ export default authSlice;
@@ -1,12 +1,10 @@
1
1
  import { configureStore } from '@reduxjs/toolkit';
2
2
  import authSlice from '../slices/authSlice';
3
3
 
4
-
5
4
  const store = configureStore({
6
-
7
5
  reducer: {
8
6
  auth: authSlice.reducer
9
7
  }
10
8
  })
11
9
 
12
- export default store;
10
+ export default store;
@@ -0,0 +1,57 @@
1
+ .card {
2
+ border: 1px solid #3C3C3C;
3
+ border-radius: 10px;
4
+ margin-bottom: 30px;
5
+ width: 100%;
6
+
7
+ .card-title {
8
+ background: #242424;
9
+ margin: 0px;
10
+ padding: 20px 40px;
11
+ font-size: 16px;
12
+ font-weight: 400;
13
+ border-top-left-radius: 10px;
14
+ border-top-right-radius: 10px;
15
+ overflow: hidden;
16
+ }
17
+
18
+ .card-content {
19
+ padding: 30px 40px;
20
+ }
21
+
22
+ .instruction {
23
+ color: @mid-grey;
24
+ margin-bottom: 30px;
25
+ }
26
+ }
27
+
28
+ .card-columns {
29
+ display: flex;
30
+ flex-wrap: no-wrap;
31
+ gap: 50px;
32
+
33
+ & > .col-66 {
34
+ width: 66%;
35
+ }
36
+
37
+ & > .col-33 {
38
+ width: 33%;
39
+ }
40
+ p {
41
+ margin-top: 0px;
42
+ }
43
+ }
44
+
45
+ .card {
46
+ input[type="text"],
47
+ input[type="password"],
48
+ input[type="email"],
49
+ textarea {
50
+ margin-top: 8px;
51
+ background: @dark-3;
52
+
53
+ &::placeholder {
54
+ color: @light-grey;
55
+ }
56
+ }
57
+ }
@@ -1,29 +1,28 @@
1
1
 
2
2
  /* vars */
3
-
4
- @green-1: #479E78;
5
- @dark-grey-1: #434343;
6
- @mid-grey-1: #73768C;
7
- @orange-1: #E8896D;
8
- @orange-2: #EFA12C;
9
- @dark-1: #3C5063;
10
- @grey-light-1: #F6F8F9;
11
- @grey-mid-1: #E4E4E4;
12
- @grey-dark-1: #B3B3B3;
13
- @white: #FFFFFF;
14
- @red-1: #c73939;
15
- @red-2: #ffeeee;
16
- @green-2: #359E59;
3
+ @dark-1: #242424;
4
+ @dark-2: #2C2C2C;
5
+ @dark-3: #242424;
6
+ @dark-grey: #3C3C3C;
7
+ @mid-grey: #868686;
8
+ @light-grey: #D9D9D9;
9
+ @white: #ffffff;
10
+ @green-main: #47DCA6;
11
+ @error-red: #FF4D4F;
17
12
 
18
13
  @content-width: 1550px;
19
14
 
20
15
  /* Fonts */
21
-
22
16
  // @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
23
17
 
24
- body {
25
- font-family: ubuntu, sans-serif;
26
- color: @dark-1;
18
+ html {
19
+ background: @dark-1;
20
+ }
21
+
22
+ body,
23
+ body * {
24
+ font-family: ubuntu, sans-serif !important;
25
+ color: @white;
27
26
  font-size: 14px;
28
27
  }
29
28
 
@@ -31,11 +30,12 @@ body {
31
30
 
32
31
  h1 {
33
32
  margin-top: 0px;
34
- font-size: 28px;
35
- font-weight: 600;
33
+ margin-bottom: 40px;
34
+ font-size: 18px;
35
+ font-weight: 400;
36
36
  }
37
37
  h2 {
38
- font-size: 15px;
38
+ font-size: 14px;
39
39
  font-weight: 500;
40
40
  }
41
41
  body {
@@ -47,10 +47,12 @@ body {
47
47
  }
48
48
 
49
49
  .separator {
50
+ display: inline-block;
50
51
  margin-top: 20px;
51
52
  margin-bottom: 20px;
52
53
  height: 0px;
53
- border-top: 1px solid @grey-mid-1;
54
+ border-top: 1px solid @dark-grey;
55
+ width: 100%;
54
56
  }
55
57
  .content-wrap {
56
58
  display: flex;
@@ -65,9 +67,9 @@ body {
65
67
  padding-right: 20px;
66
68
  }
67
69
  .instruction {
68
- font-size: 12px;
69
70
  margin-top: 10px;
70
71
  margin-bottom: 10px;
72
+ color: @light-grey;
71
73
  }
72
74
  .flex-row {
73
75
  display: flex;
@@ -121,7 +123,7 @@ body {
121
123
 
122
124
  .button {
123
125
  &.button-loading {
124
- background: @grey-mid-1 !important;
126
+ background: @dark-grey !important;
125
127
  cursor: not-allowed !important;
126
128
 
127
129
  &:disabled {
@@ -131,29 +133,72 @@ body {
131
133
  }
132
134
  }
133
135
 
134
- .card {
135
- background: @white;
136
- border: 1px solid @grey-mid-1;
137
- border-radius: 10px;
138
- margin-top: 20px;
139
- box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
136
+ .text-link {
137
+ color: @light-grey;
138
+ cursor: pointer;
139
+ display: inline-block;
140
+ text-decoration: none;
141
+ font-size: 14px;
140
142
 
141
- .card-header {
142
- width: 100%;
143
- background-color: @dark-grey-1;
144
- color: @white;
145
- border-top-left-radius: 10px;
146
- border-top-right-radius: 10px;
147
- display: flex;
148
- justify-content: space-between;
149
-
150
- h2 {
151
- padding: 20px;
152
- margin: 0px;
143
+ &:hover {
144
+ opacity: 0.8;
145
+ }
146
+ }
147
+
148
+ .input {
149
+ font-size: 12px;
150
+ color: @dark-2;
151
+
152
+ input {
153
+ background: @dark-1 !important;
154
+ color: white;
155
+ padding: 10px;
156
+ padding-left: 48px;
157
+ border-radius: 20px;
158
+ font-size: 14px;
159
+ margin-top: 5px;
160
+ margin-bottom: 5px !important;
161
+ }
162
+
163
+ &.icon {
164
+ background-size: 15px;
165
+ background-repeat: no-repeat;
166
+ background-position: 15px 15px;
167
+
168
+ input {
169
+ padding-left: 50px;
153
170
  }
154
171
  }
172
+ }
173
+
174
+ .single-crud-page {
175
+ .top-bar {
176
+ margin-bottom: 20px;
177
+ }
178
+ .bottom-bar {
179
+ margin-top: 20px;
180
+ margin-bottom: 20px;
181
+ justify-content: flex-end;
182
+ }
183
+ }
184
+
185
+ .error-messages {
186
+ display: flex;
187
+ flex-direction: row;
188
+ justify-content: flex-end;
189
+
190
+ ul {
191
+ list-style: none;
192
+ margin: 0px;
193
+ }
155
194
 
156
- .card-content {
157
- padding: 20px;
195
+ li, a, span, p {
196
+ color: @error-red;
158
197
  }
159
- }
198
+ }
199
+
200
+ .button-group {
201
+ button {
202
+ margin-left: 15px;
203
+ }
204
+ }
@@ -0,0 +1,21 @@
1
+ .icon-dashboard {
2
+ background: url('../assets/icon-home.svg');
3
+ }
4
+ .icon-users {
5
+ background: url('../assets/icon-users.svg');
6
+ }
7
+ .icon-settings {
8
+ background: url('../assets/icon-settings.svg');
9
+ }
10
+ .icon-reports {
11
+ background: url('../assets/icon-reports.svg');
12
+ }
13
+ .icon-agent {
14
+ background: url('../assets/icon-agent.svg');
15
+ }
16
+ .icon-page {
17
+ background: url('../assets/icon-page.svg');
18
+ }
19
+ .icon-delete {
20
+ background: url('../assets/icon-delete.svg');
21
+ }
@@ -0,0 +1,52 @@
1
+ input[type="text"],
2
+ input[type="password"],
3
+ input[type="email"],
4
+ textarea,
5
+ .custom-select .custom-select-input {
6
+ border: 1px solid @dark-grey;
7
+ border-radius: 17px;
8
+ padding: 8px 10px;
9
+ font-size: 14px;
10
+ width: 100%;
11
+ box-sizing: border-box;
12
+ background: none;
13
+ margin-bottom: 25px;
14
+ transition: border-color 0.3s;
15
+
16
+ &::placeholder {
17
+ color: @white;
18
+ }
19
+
20
+ &:focus {
21
+ outline: none;
22
+ border-color: @green-main;
23
+ }
24
+ }
25
+
26
+ button {
27
+ background: @green-main;
28
+ border: 1px solid @green-main;
29
+ border-radius: 17px;
30
+ color: @dark-1;
31
+ padding: 9px 19px;
32
+ min-width: 143px;
33
+ font-weight: 700;
34
+ transition: opacity 0.3s;
35
+
36
+ &[type="submit"] {
37
+ margin-top: 25px;
38
+ margin-bottom: 25px;
39
+ }
40
+
41
+ &:hover {
42
+ opacity: 0.8;
43
+ cursor: pointer;
44
+ }
45
+
46
+ &.secondary-btn {
47
+ background: @dark-2;
48
+ color: @white;
49
+ border: 1px solid @dark-grey;
50
+ }
51
+ }
52
+
@@ -0,0 +1,28 @@
1
+ // GLOBAL
2
+ @import "global.less";
3
+ @import "inputs.less";
4
+ @import "icons.less";
5
+ @import "cards.less";
6
+
7
+ // LAYOUTS
8
+ @import "../layouts/PortalLayout/PortalLayout.less";
9
+
10
+ // COMPONENTS
11
+ @import "../components/Sidebar/Sidebar.less";
12
+ @import "../components/Topbar/Topbar.less";
13
+ @import "../components/UserInfo/UserInfo.less";
14
+ @import "../components/CrudList/CrudList.less";
15
+
16
+ // ELEMENTS
17
+ @import "../elements/Repeater/Repeater.less";
18
+ @import "../elements/CustomSelect/CustomSelect.less";
19
+ @import "../elements/RichTextInput/RichTextInput.less";
20
+ @import "../elements/ImageInput/ImageInput.less";
21
+ @import "../elements/ImageMultiInput/ImageMultiInput.less";
22
+
23
+ // PAGES
24
+ @import "../pages/LoginPage/LoginPage.less";
25
+
26
+ #MagiCSS-bookmarklet span {
27
+ color: black !important;
28
+ }
@@ -0,0 +1,9 @@
1
+
2
+ export const fileToBase64 = (file) => {
3
+ return new Promise((resolve, reject) => {
4
+ const reader = new FileReader();
5
+ reader.onload = () => resolve(reader.result); // returns "data:image/png;base64,..."
6
+ reader.onerror = reject;
7
+ reader.readAsDataURL(file);
8
+ });
9
+ }
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from 'vite'
2
+ import react from '@vitejs/plugin-react'
3
+
4
+ // https://vite.dev/config/
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ server: {
8
+ host: true, // binds to 0.0.0.0
9
+ allowedHosts: ['.localhost', 'portal-service'], // allow extra hosts
10
+ },
11
+ base: '/portal/',
12
+ })
@@ -1,4 +1,4 @@
1
- # Dockerfile for Product Service
1
+ # Dockerfile for User Service
2
2
  FROM node:20-alpine
3
3
 
4
4
  # Set the working directory
@@ -1,4 +1,4 @@
1
- import { message, http, logger, db, registerService, webSockets } from '@gnar-engine/core';
1
+ import { message, http, logger, db, registerService, webSockets, test } from '@gnar-engine/core';
2
2
  import { config } from './config.js';
3
3
  import { messageHandlers } from './controllers/message.controller.js';
4
4
  import { httpController as userPlatformHttpController } from './controllers/http.controller.js';
@@ -40,6 +40,11 @@ export const initService = async () => {
40
40
  await registerService();
41
41
 
42
42
  logger.info('G n a r E n g i n e | User Service initialised successfully.');
43
+
44
+ // Tests
45
+ if (config.environment === 'test' && config.runTests) {
46
+ test.runCommandTests({config});
47
+ }
43
48
  }
44
49
 
45
50
  initService();
@@ -76,7 +76,6 @@ commands.register('userService.getAuthenticatedUser', async ({token}) => {
76
76
  const user_id = await auth.getAuthenticatedUser(token);
77
77
 
78
78
  if (user_id) {
79
- logger.info('Auth user: ' + user_id);
80
79
  const userObj = await user.getById({id: user_id});
81
80
 
82
81
  if (userObj) {
@@ -86,8 +85,6 @@ commands.register('userService.getAuthenticatedUser', async ({token}) => {
86
85
  return userObj;
87
86
  }
88
87
  }
89
-
90
- return;
91
88
  });
92
89
 
93
90
 
@@ -6,12 +6,16 @@ export const config = {
6
6
  // service name
7
7
  serviceName: 'userService',
8
8
 
9
+ // environment
10
+ environment: process.env.USER_NODE_ENV || 'dev',
11
+ runTests: process.env.USER_RUN_TESTS || false,
12
+
9
13
  // microservice | modular-monolith
10
14
  architecture: process.env.GLOBAL_ARCHITECTURE || 'microservice',
11
15
 
12
16
  // web server
13
17
  http: {
14
- allowedOrigins: [],
18
+ allowedOrigins: ['localhost', 'localhost:4003'],
15
19
  allowedMethods: ['GET', 'POST', 'PUT', 'DELETE'],
16
20
  allowedHeaders: ['Content-Type', 'Authorization'],
17
21
  rateLimiting: {
@@ -1,4 +1,5 @@
1
1
  import { config } from '../config.js';
2
+ import { logger } from '@gnar-engine/core';
2
3
 
3
4
 
4
5
  export const authorise = {
@@ -23,6 +24,7 @@ export const authorise = {
23
24
  * Authorise get many users
24
25
  */
25
26
  getMany: async (request, reply) => {
27
+ logger.info('user -' + JSON.stringify(request.user));
26
28
  if (!request.user || request.user.role !== 'service_admin') {
27
29
  reply.code(403).send({error: 'not authorised'});
28
30
  }
@@ -78,4 +80,4 @@ export const authorise = {
78
80
  reply.code(403).send({error: 'not authorised'});
79
81
  }
80
82
  }
81
- }
83
+ }
@@ -0,0 +1,22 @@
1
+ import { commands, logger, test } from '@gnar-engine/core';
2
+
3
+ // Preparation before tests run
4
+ test.prep(async () => {
5
+ if (process.env.NODE_ENV === 'production') {
6
+ throw new Error('Do not run tests in production mode!');
7
+ }
8
+ })
9
+
10
+ // Test create user command
11
+ test.run('Create User Command', async () => {
12
+ const users = await commands.execute('createUsers', [
13
+ {
14
+ email: 'test@gnar.co.uk'
15
+ }
16
+ ]);
17
+
18
+ test.assert(users.length === 1, 'User was not created successfully');
19
+ test.assert(users[0].email === 'test@gnar.co.uk', 'User email does not match');
20
+ });
21
+
22
+
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ TARGET_DIR="$HOME/.gnarengine"
5
+ CLI_DIR="$(pwd)"
6
+
7
+ echo "Installing Gnar Engine CLI from local source for user $USER..."
8
+
9
+ mkdir -p "$TARGET_DIR"
10
+
11
+ # Install dependencies
12
+ cd "$CLI_DIR"
13
+ npm install
14
+
15
+ # Link CLI to custom global folder
16
+ npm link --prefix "$TARGET_DIR"
17
+
18
+ # Bin path for npm link
19
+ BIN_PATH="$TARGET_DIR/bin"
20
+
21
+ # Add to shell PATH if not already present
22
+ for SHELLRC in "$HOME/.bashrc" "$HOME/.zshrc"; do
23
+ [ -f "$SHELLRC" ] || continue
24
+ if ! grep -q "$BIN_PATH" "$SHELLRC"; then
25
+ echo "export PATH=\"$BIN_PATH:\$PATH\"" >>"$SHELLRC"
26
+ echo "Added $BIN_PATH to PATH in $SHELLRC"
27
+ fi
28
+ done
29
+
30
+ echo "Gnar Engine CLI installed! Restart your terminal and run 'gnar --help'"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gnar-engine/cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Gnar Engine Development Framework CLI: Project bootstrap, scaffolder & control plane.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -6,6 +6,7 @@ import { registerDevCommands } from './dev/commands.js';
6
6
  import { registerControlCommands } from './control/commands.js';
7
7
  import { registerScaffolderCommands } from './scaffolder/commands.js';
8
8
  import { registerAgentCommands } from './agent/commands.js';
9
+ import path from 'path';
9
10
 
10
11
  // Create a new program
11
12
  const program = new Command();
@@ -28,3 +29,10 @@ G n a r E n g i n e - A powerful, AI ready microservice framework for modern a
28
29
 
29
30
  // Parse CLI input
30
31
  program.parse(process.argv);
32
+
33
+ // Consts
34
+ export const directories = {
35
+ scaffolderTemplates: path.join(import.meta.dirname, '../templates/service'),
36
+ bootstrap: path.join(import.meta.dirname, '../bootstrap'),
37
+ provisioner: path.join(import.meta.dirname, './provisioner')
38
+ }
package/src/config.js CHANGED
@@ -4,5 +4,6 @@ export const gnarEngineCliConfig = {
4
4
  /**
5
5
  * The path the Gnar Engine service core should be found in the service containers
6
6
  */
7
- corePath: '/usr/gnar_engine/app/gnarengine-service-core'
7
+ corePath: '/usr/gnar_engine/app/node_modules/@gnar-engine/core'
8
+
8
9
  }