@digitaldefiance/express-suite-react-components 5.0.0 → 5.0.2

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 (312) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -0
  3. package/package.json +3 -4
  4. package/src/auth/AdminRoute.tsx +54 -0
  5. package/src/auth/Private.tsx +17 -0
  6. package/src/auth/PrivateRoute.tsx +28 -0
  7. package/src/auth/UnAuth.tsx +16 -0
  8. package/src/auth/UnAuthRoute.tsx +30 -0
  9. package/src/auth/{index.d.ts → index.ts} +2 -3
  10. package/src/components/ApiAccess.tsx +175 -0
  11. package/src/components/BackupCodeLoginForm.tsx +489 -0
  12. package/src/components/BackupCodesForm.tsx +287 -0
  13. package/src/components/CategoryMenu.tsx +155 -0
  14. package/src/components/ChangePasswordForm.tsx +273 -0
  15. package/src/components/ConfirmationDialog.tsx +48 -0
  16. package/src/components/CurrencyCodeSelector.tsx +60 -0
  17. package/src/components/CurrencyInput.tsx +80 -0
  18. package/src/components/DashboardPage.tsx +24 -0
  19. package/src/components/DropdownMenu.tsx +105 -0
  20. package/src/components/ExpirationSecondsSelector.tsx +60 -0
  21. package/src/components/FakeEmailAdminPanel.tsx +374 -0
  22. package/src/components/Flag.tsx +52 -0
  23. package/src/components/ForgotPasswordForm.tsx +174 -0
  24. package/src/components/LoginForm.tsx +468 -0
  25. package/src/components/LogoutPage.tsx +21 -0
  26. package/src/components/RegisterForm.tsx +1169 -0
  27. package/src/components/ResetPasswordForm.tsx +247 -0
  28. package/src/components/SideMenu.tsx +46 -0
  29. package/src/components/SideMenuListItem.tsx +75 -0
  30. package/src/components/T.tsx +24 -0
  31. package/src/components/TDiv.tsx +26 -0
  32. package/src/components/TImgAlt.tsx +28 -0
  33. package/src/components/TopMenu.tsx +252 -0
  34. package/src/components/TotpSetupForm.tsx +188 -0
  35. package/src/components/TotpVerificationForm.tsx +148 -0
  36. package/src/components/TranslatedTitle.tsx +31 -0
  37. package/src/components/UserLanguageSelector.tsx +45 -0
  38. package/src/components/UserMenu.tsx +15 -0
  39. package/src/components/UserSettingsForm.tsx +904 -0
  40. package/src/components/VerifyEmailPage.tsx +222 -0
  41. package/src/components/__tests__/RegisterForm.totp.spec.tsx +377 -0
  42. package/src/components/__tests__/TotpSetupForm.spec.tsx +258 -0
  43. package/src/components/__tests__/TotpVerificationForm.spec.tsx +259 -0
  44. package/src/components/__tests__/UserSettingsForm.totp.spec.tsx +396 -0
  45. package/src/components/{index.d.ts → index.ts} +1 -1
  46. package/src/contexts/AuthProvider.spec.tsx +1284 -0
  47. package/src/contexts/AuthProvider.tsx +977 -0
  48. package/src/contexts/I18nProvider.tsx +164 -0
  49. package/src/contexts/MenuContext.tsx +426 -0
  50. package/src/contexts/SuiteConfigProvider.tsx +93 -0
  51. package/src/contexts/ThemeProvider.tsx +67 -0
  52. package/src/contexts/{index.d.ts → index.ts} +0 -1
  53. package/src/hooks/{index.d.ts → index.ts} +0 -1
  54. package/src/hooks/useAuthenticatedApi.tsx +67 -0
  55. package/src/hooks/useBackupCodes.ts +105 -0
  56. package/src/hooks/useEmailVerification.ts +54 -0
  57. package/src/hooks/useExpiringValue.ts +78 -0
  58. package/src/hooks/useLocalStorage.ts +18 -0
  59. package/src/hooks/useUserSettings.ts +271 -0
  60. package/src/{index.d.ts → index.ts} +1 -1
  61. package/src/interfaces/IAppConfig.ts +7 -0
  62. package/src/interfaces/ICategoryConfig.ts +41 -0
  63. package/src/interfaces/IMenuConfig.ts +28 -0
  64. package/src/interfaces/IMenuOption.ts +79 -0
  65. package/src/interfaces/{index.d.ts → index.ts} +0 -1
  66. package/src/services/__mocks__/authService.ts +14 -0
  67. package/src/services/__tests__/authService.totp.property.spec.ts +360 -0
  68. package/src/services/__tests__/authService.totp.spec.ts +439 -0
  69. package/src/services/api.ts +13 -0
  70. package/src/services/authService.ts +692 -0
  71. package/src/services/authenticatedApi.ts +17 -0
  72. package/src/services/index.ts +3 -0
  73. package/src/types/MenuType.ts +15 -0
  74. package/src/types/expirationSeconds.ts +18 -0
  75. package/src/types/index.ts +1 -0
  76. package/src/types/translation.ts +20 -0
  77. package/src/wrappers/BackupCodeLoginWrapper.tsx +34 -0
  78. package/src/wrappers/BackupCodesWrapper.tsx +28 -0
  79. package/src/wrappers/ChangePasswordFormWrapper.tsx +34 -0
  80. package/src/wrappers/ForgotPasswordFormWrapper.tsx +45 -0
  81. package/src/wrappers/LoginFormWrapper.tsx +108 -0
  82. package/src/wrappers/LogoutPageWrapper.tsx +30 -0
  83. package/src/wrappers/RegisterFormWrapper.tsx +109 -0
  84. package/src/wrappers/ResetPasswordFormWrapper.tsx +57 -0
  85. package/src/wrappers/UserSettingsFormWrapper.tsx +140 -0
  86. package/src/wrappers/VerifyEmailPageWrapper.tsx +27 -0
  87. package/src/wrappers/__tests__/LoginFormWrapper.totp.spec.tsx +339 -0
  88. package/src/wrappers/{index.d.ts → index.tsx} +10 -1
  89. package/src/auth/AdminRoute.d.ts +0 -8
  90. package/src/auth/AdminRoute.d.ts.map +0 -1
  91. package/src/auth/AdminRoute.js +0 -28
  92. package/src/auth/Private.d.ts +0 -6
  93. package/src/auth/Private.d.ts.map +0 -1
  94. package/src/auth/Private.js +0 -14
  95. package/src/auth/PrivateRoute.d.ts +0 -8
  96. package/src/auth/PrivateRoute.d.ts.map +0 -1
  97. package/src/auth/PrivateRoute.js +0 -23
  98. package/src/auth/UnAuth.d.ts +0 -6
  99. package/src/auth/UnAuth.d.ts.map +0 -1
  100. package/src/auth/UnAuth.js +0 -14
  101. package/src/auth/UnAuthRoute.d.ts +0 -8
  102. package/src/auth/UnAuthRoute.d.ts.map +0 -1
  103. package/src/auth/UnAuthRoute.js +0 -22
  104. package/src/auth/index.d.ts.map +0 -1
  105. package/src/auth/index.js +0 -12
  106. package/src/components/ApiAccess.d.ts +0 -16
  107. package/src/components/ApiAccess.d.ts.map +0 -1
  108. package/src/components/ApiAccess.js +0 -77
  109. package/src/components/BackupCodeLoginForm.d.ts +0 -43
  110. package/src/components/BackupCodeLoginForm.d.ts.map +0 -1
  111. package/src/components/BackupCodeLoginForm.js +0 -139
  112. package/src/components/BackupCodesForm.d.ts +0 -26
  113. package/src/components/BackupCodesForm.d.ts.map +0 -1
  114. package/src/components/BackupCodesForm.js +0 -120
  115. package/src/components/CategoryMenu.d.ts +0 -17
  116. package/src/components/CategoryMenu.d.ts.map +0 -1
  117. package/src/components/CategoryMenu.js +0 -65
  118. package/src/components/ChangePasswordForm.d.ts +0 -26
  119. package/src/components/ChangePasswordForm.d.ts.map +0 -1
  120. package/src/components/ChangePasswordForm.js +0 -78
  121. package/src/components/ConfirmationDialog.d.ts +0 -13
  122. package/src/components/ConfirmationDialog.d.ts.map +0 -1
  123. package/src/components/ConfirmationDialog.js +0 -10
  124. package/src/components/CurrencyCodeSelector.d.ts +0 -9
  125. package/src/components/CurrencyCodeSelector.d.ts.map +0 -1
  126. package/src/components/CurrencyCodeSelector.js +0 -31
  127. package/src/components/CurrencyInput.d.ts +0 -13
  128. package/src/components/CurrencyInput.d.ts.map +0 -1
  129. package/src/components/CurrencyInput.js +0 -22
  130. package/src/components/DashboardPage.d.ts +0 -8
  131. package/src/components/DashboardPage.d.ts.map +0 -1
  132. package/src/components/DashboardPage.js +0 -10
  133. package/src/components/DropdownMenu.d.ts +0 -13
  134. package/src/components/DropdownMenu.d.ts.map +0 -1
  135. package/src/components/DropdownMenu.js +0 -63
  136. package/src/components/ExpirationSecondsSelector.d.ts +0 -13
  137. package/src/components/ExpirationSecondsSelector.d.ts.map +0 -1
  138. package/src/components/ExpirationSecondsSelector.js +0 -32
  139. package/src/components/FakeEmailAdminPanel.d.ts +0 -23
  140. package/src/components/FakeEmailAdminPanel.d.ts.map +0 -1
  141. package/src/components/FakeEmailAdminPanel.js +0 -147
  142. package/src/components/Flag.d.ts +0 -20
  143. package/src/components/Flag.d.ts.map +0 -1
  144. package/src/components/Flag.js +0 -43
  145. package/src/components/ForgotPasswordForm.d.ts +0 -18
  146. package/src/components/ForgotPasswordForm.d.ts.map +0 -1
  147. package/src/components/ForgotPasswordForm.js +0 -61
  148. package/src/components/LoginForm.d.ts +0 -44
  149. package/src/components/LoginForm.d.ts.map +0 -1
  150. package/src/components/LoginForm.js +0 -123
  151. package/src/components/LogoutPage.d.ts +0 -8
  152. package/src/components/LogoutPage.d.ts.map +0 -1
  153. package/src/components/LogoutPage.js +0 -16
  154. package/src/components/RegisterForm.d.ts +0 -100
  155. package/src/components/RegisterForm.d.ts.map +0 -1
  156. package/src/components/RegisterForm.js +0 -306
  157. package/src/components/ResetPasswordForm.d.ts +0 -23
  158. package/src/components/ResetPasswordForm.d.ts.map +0 -1
  159. package/src/components/ResetPasswordForm.js +0 -78
  160. package/src/components/SideMenu.d.ts +0 -8
  161. package/src/components/SideMenu.d.ts.map +0 -1
  162. package/src/components/SideMenu.js +0 -25
  163. package/src/components/SideMenuListItem.d.ts +0 -13
  164. package/src/components/SideMenuListItem.d.ts.map +0 -1
  165. package/src/components/SideMenuListItem.js +0 -44
  166. package/src/components/T.d.ts +0 -7
  167. package/src/components/T.d.ts.map +0 -1
  168. package/src/components/T.js +0 -13
  169. package/src/components/TDiv.d.ts +0 -9
  170. package/src/components/TDiv.d.ts.map +0 -1
  171. package/src/components/TDiv.js +0 -14
  172. package/src/components/TImgAlt.d.ts +0 -10
  173. package/src/components/TImgAlt.d.ts.map +0 -1
  174. package/src/components/TImgAlt.js +0 -14
  175. package/src/components/TopMenu.d.ts +0 -50
  176. package/src/components/TopMenu.d.ts.map +0 -1
  177. package/src/components/TopMenu.js +0 -79
  178. package/src/components/TotpSetupForm.d.ts +0 -24
  179. package/src/components/TotpSetupForm.d.ts.map +0 -1
  180. package/src/components/TotpSetupForm.js +0 -82
  181. package/src/components/TotpVerificationForm.d.ts +0 -23
  182. package/src/components/TotpVerificationForm.d.ts.map +0 -1
  183. package/src/components/TotpVerificationForm.js +0 -66
  184. package/src/components/TranslatedTitle.d.ts +0 -8
  185. package/src/components/TranslatedTitle.d.ts.map +0 -1
  186. package/src/components/TranslatedTitle.js +0 -15
  187. package/src/components/UserLanguageSelector.d.ts +0 -4
  188. package/src/components/UserLanguageSelector.d.ts.map +0 -1
  189. package/src/components/UserLanguageSelector.js +0 -31
  190. package/src/components/UserMenu.d.ts +0 -4
  191. package/src/components/UserMenu.d.ts.map +0 -1
  192. package/src/components/UserMenu.js +0 -12
  193. package/src/components/UserSettingsForm.d.ts +0 -113
  194. package/src/components/UserSettingsForm.d.ts.map +0 -1
  195. package/src/components/UserSettingsForm.js +0 -269
  196. package/src/components/VerifyEmailPage.d.ts +0 -24
  197. package/src/components/VerifyEmailPage.d.ts.map +0 -1
  198. package/src/components/VerifyEmailPage.js +0 -81
  199. package/src/components/index.d.ts.map +0 -1
  200. package/src/components/index.js +0 -35
  201. package/src/contexts/AuthProvider.d.ts +0 -186
  202. package/src/contexts/AuthProvider.d.ts.map +0 -1
  203. package/src/contexts/AuthProvider.js +0 -515
  204. package/src/contexts/I18nProvider.d.ts +0 -27
  205. package/src/contexts/I18nProvider.d.ts.map +0 -1
  206. package/src/contexts/I18nProvider.js +0 -60
  207. package/src/contexts/MenuContext.d.ts +0 -20
  208. package/src/contexts/MenuContext.d.ts.map +0 -1
  209. package/src/contexts/MenuContext.js +0 -275
  210. package/src/contexts/SuiteConfigProvider.d.ts +0 -44
  211. package/src/contexts/SuiteConfigProvider.d.ts.map +0 -1
  212. package/src/contexts/SuiteConfigProvider.js +0 -43
  213. package/src/contexts/ThemeProvider.d.ts +0 -15
  214. package/src/contexts/ThemeProvider.d.ts.map +0 -1
  215. package/src/contexts/ThemeProvider.js +0 -36
  216. package/src/contexts/index.d.ts.map +0 -1
  217. package/src/contexts/index.js +0 -8
  218. package/src/hooks/index.d.ts.map +0 -1
  219. package/src/hooks/index.js +0 -9
  220. package/src/hooks/useAuthenticatedApi.d.ts +0 -34
  221. package/src/hooks/useAuthenticatedApi.d.ts.map +0 -1
  222. package/src/hooks/useAuthenticatedApi.js +0 -46
  223. package/src/hooks/useBackupCodes.d.ts +0 -15
  224. package/src/hooks/useBackupCodes.d.ts.map +0 -1
  225. package/src/hooks/useBackupCodes.js +0 -74
  226. package/src/hooks/useEmailVerification.d.ts +0 -10
  227. package/src/hooks/useEmailVerification.d.ts.map +0 -1
  228. package/src/hooks/useEmailVerification.js +0 -40
  229. package/src/hooks/useExpiringValue.d.ts +0 -14
  230. package/src/hooks/useExpiringValue.d.ts.map +0 -1
  231. package/src/hooks/useExpiringValue.js +0 -53
  232. package/src/hooks/useLocalStorage.d.ts +0 -2
  233. package/src/hooks/useLocalStorage.d.ts.map +0 -1
  234. package/src/hooks/useLocalStorage.js +0 -15
  235. package/src/hooks/useUserSettings.d.ts +0 -48
  236. package/src/hooks/useUserSettings.d.ts.map +0 -1
  237. package/src/hooks/useUserSettings.js +0 -171
  238. package/src/index.d.ts.map +0 -1
  239. package/src/index.js +0 -12
  240. package/src/interfaces/IAppConfig.d.ts +0 -8
  241. package/src/interfaces/IAppConfig.d.ts.map +0 -1
  242. package/src/interfaces/IAppConfig.js +0 -2
  243. package/src/interfaces/ICategoryConfig.d.ts +0 -41
  244. package/src/interfaces/ICategoryConfig.d.ts.map +0 -1
  245. package/src/interfaces/ICategoryConfig.js +0 -2
  246. package/src/interfaces/IMenuConfig.d.ts +0 -28
  247. package/src/interfaces/IMenuConfig.d.ts.map +0 -1
  248. package/src/interfaces/IMenuConfig.js +0 -2
  249. package/src/interfaces/IMenuOption.d.ts +0 -82
  250. package/src/interfaces/IMenuOption.d.ts.map +0 -1
  251. package/src/interfaces/IMenuOption.js +0 -2
  252. package/src/interfaces/index.d.ts.map +0 -1
  253. package/src/interfaces/index.js +0 -7
  254. package/src/services/__mocks__/authService.d.ts +0 -21
  255. package/src/services/__mocks__/authService.d.ts.map +0 -1
  256. package/src/services/__mocks__/authService.js +0 -15
  257. package/src/services/api.d.ts +0 -3
  258. package/src/services/api.d.ts.map +0 -1
  259. package/src/services/api.js +0 -14
  260. package/src/services/authService.d.ts +0 -126
  261. package/src/services/authService.d.ts.map +0 -1
  262. package/src/services/authService.js +0 -471
  263. package/src/services/authenticatedApi.d.ts +0 -3
  264. package/src/services/authenticatedApi.d.ts.map +0 -1
  265. package/src/services/authenticatedApi.js +0 -18
  266. package/src/services/index.d.ts +0 -4
  267. package/src/services/index.d.ts.map +0 -1
  268. package/src/services/index.js +0 -6
  269. package/src/types/MenuType.d.ts +0 -11
  270. package/src/types/MenuType.d.ts.map +0 -1
  271. package/src/types/MenuType.js +0 -12
  272. package/src/types/expirationSeconds.d.ts +0 -3
  273. package/src/types/expirationSeconds.d.ts.map +0 -1
  274. package/src/types/expirationSeconds.js +0 -17
  275. package/src/types/index.d.ts +0 -2
  276. package/src/types/index.d.ts.map +0 -1
  277. package/src/types/index.js +0 -4
  278. package/src/types/translation.d.ts +0 -10
  279. package/src/types/translation.d.ts.map +0 -1
  280. package/src/types/translation.js +0 -9
  281. package/src/wrappers/BackupCodeLoginWrapper.d.ts +0 -8
  282. package/src/wrappers/BackupCodeLoginWrapper.d.ts.map +0 -1
  283. package/src/wrappers/BackupCodeLoginWrapper.js +0 -20
  284. package/src/wrappers/BackupCodesWrapper.d.ts +0 -7
  285. package/src/wrappers/BackupCodesWrapper.d.ts.map +0 -1
  286. package/src/wrappers/BackupCodesWrapper.js +0 -17
  287. package/src/wrappers/ChangePasswordFormWrapper.d.ts +0 -8
  288. package/src/wrappers/ChangePasswordFormWrapper.d.ts.map +0 -1
  289. package/src/wrappers/ChangePasswordFormWrapper.js +0 -21
  290. package/src/wrappers/ForgotPasswordFormWrapper.d.ts +0 -8
  291. package/src/wrappers/ForgotPasswordFormWrapper.d.ts.map +0 -1
  292. package/src/wrappers/ForgotPasswordFormWrapper.js +0 -29
  293. package/src/wrappers/LoginFormWrapper.d.ts +0 -21
  294. package/src/wrappers/LoginFormWrapper.d.ts.map +0 -1
  295. package/src/wrappers/LoginFormWrapper.js +0 -72
  296. package/src/wrappers/LogoutPageWrapper.d.ts +0 -9
  297. package/src/wrappers/LogoutPageWrapper.d.ts.map +0 -1
  298. package/src/wrappers/LogoutPageWrapper.js +0 -21
  299. package/src/wrappers/RegisterFormWrapper.d.ts +0 -20
  300. package/src/wrappers/RegisterFormWrapper.d.ts.map +0 -1
  301. package/src/wrappers/RegisterFormWrapper.js +0 -51
  302. package/src/wrappers/ResetPasswordFormWrapper.d.ts +0 -9
  303. package/src/wrappers/ResetPasswordFormWrapper.d.ts.map +0 -1
  304. package/src/wrappers/ResetPasswordFormWrapper.js +0 -34
  305. package/src/wrappers/UserSettingsFormWrapper.d.ts +0 -29
  306. package/src/wrappers/UserSettingsFormWrapper.d.ts.map +0 -1
  307. package/src/wrappers/UserSettingsFormWrapper.js +0 -95
  308. package/src/wrappers/VerifyEmailPageWrapper.d.ts +0 -8
  309. package/src/wrappers/VerifyEmailPageWrapper.d.ts.map +0 -1
  310. package/src/wrappers/VerifyEmailPageWrapper.js +0 -21
  311. package/src/wrappers/index.d.ts.map +0 -1
  312. package/src/wrappers/index.js +0 -24
@@ -0,0 +1,48 @@
1
+ import {
2
+ Button,
3
+ Dialog,
4
+ DialogActions,
5
+ DialogContent,
6
+ DialogContentText,
7
+ DialogTitle,
8
+ } from '@mui/material';
9
+ import React from 'react';
10
+
11
+ export interface ConfirmationDialogProps {
12
+ open: boolean;
13
+ title: string;
14
+ message: string;
15
+ confirmText?: string;
16
+ cancelText?: string;
17
+ onConfirm: () => void;
18
+ onCancel: () => void;
19
+ }
20
+
21
+ export const ConfirmationDialog: React.FC<ConfirmationDialogProps> = ({
22
+ open,
23
+ title,
24
+ message,
25
+ confirmText = 'Confirm',
26
+ cancelText = 'Cancel',
27
+ onConfirm,
28
+ onCancel,
29
+ }) => {
30
+ return (
31
+ <Dialog open={open} onClose={onCancel}>
32
+ <DialogTitle>{title}</DialogTitle>
33
+ <DialogContent>
34
+ <DialogContentText>{message}</DialogContentText>
35
+ </DialogContent>
36
+ <DialogActions>
37
+ <Button onClick={onCancel} color="primary">
38
+ {cancelText}
39
+ </Button>
40
+ <Button onClick={onConfirm} color="primary">
41
+ {confirmText}
42
+ </Button>
43
+ </DialogActions>
44
+ </Dialog>
45
+ );
46
+ };
47
+
48
+ export default ConfirmationDialog;
@@ -0,0 +1,60 @@
1
+ import { CurrencyCode } from '@digitaldefiance/i18n-lib';
2
+ import { MenuItem, TextField } from '@mui/material';
3
+ import { Field, FieldProps } from 'formik';
4
+ import { ChangeEvent, FC } from 'react';
5
+
6
+ export interface CurrencyCodeSelectorProps {
7
+ name: string;
8
+ label: string;
9
+ onCurrencyChange?: (code: string) => void;
10
+ }
11
+
12
+ export const CurrencyCodeSelector: FC<CurrencyCodeSelectorProps> = ({
13
+ name,
14
+ label,
15
+ onCurrencyChange,
16
+ }) => {
17
+ return (
18
+ <Field name={name}>
19
+ {({ field, form }: FieldProps) => (
20
+ <TextField
21
+ select
22
+ fullWidth
23
+ label={label}
24
+ {...field}
25
+ onChange={(event: ChangeEvent<HTMLInputElement>) => {
26
+ const selectedCode = event.target.value;
27
+ form.setFieldValue(name, selectedCode);
28
+ onCurrencyChange?.(selectedCode);
29
+ }}
30
+ error={form.touched[name] && Boolean(form.errors[name])}
31
+ helperText={form.touched[name] && (form.errors[name] as string)}
32
+ sx={{
33
+ '& .MuiSelect-select': {
34
+ paddingRight: '32px',
35
+ },
36
+ '& .MuiOutlinedInput-root': {
37
+ '& fieldset': {
38
+ borderColor: 'rgba(0, 0, 0, 0.23)',
39
+ },
40
+ '&:hover fieldset': {
41
+ borderColor: 'rgba(0, 0, 0, 0.87)',
42
+ },
43
+ '&.Mui-focused fieldset': {
44
+ borderColor: 'primary.main',
45
+ },
46
+ },
47
+ }}
48
+ >
49
+ {CurrencyCode.getAll().map((code: string) => (
50
+ <MenuItem key={code} value={code}>
51
+ {code}
52
+ </MenuItem>
53
+ ))}
54
+ </TextField>
55
+ )}
56
+ </Field>
57
+ );
58
+ };
59
+
60
+ export default CurrencyCodeSelector;
@@ -0,0 +1,80 @@
1
+ import { TextField } from '@mui/material';
2
+ import { NumericFormat } from 'react-number-format';
3
+ import { getCurrencyFormat } from '@digitaldefiance/i18n-lib';
4
+
5
+ export interface CurrencyInputProps {
6
+ value: number;
7
+ onChange: (value: number) => void;
8
+ currencyCode?: string;
9
+ locale?: string;
10
+ label: string;
11
+ error?: boolean;
12
+ helperText?: string;
13
+ name: string;
14
+ }
15
+
16
+ export const CurrencyInput: React.FC<CurrencyInputProps> = ({
17
+ value,
18
+ onChange,
19
+ currencyCode = 'USD',
20
+ locale = 'en-US',
21
+ label,
22
+ error,
23
+ helperText,
24
+ name,
25
+ }) => {
26
+ const format = getCurrencyFormat(locale, currencyCode);
27
+
28
+ if (format.position === 'infix') {
29
+ const [whole, decimal] = value.toString().split('.');
30
+ const displayValue = `${whole}${format.symbol}${format.decimalSeparator}${
31
+ decimal || '00'
32
+ }`;
33
+
34
+ return (
35
+ <NumericFormat
36
+ customInput={TextField}
37
+ fullWidth
38
+ margin="normal"
39
+ label={label}
40
+ value={displayValue}
41
+ thousandSeparator={format.groupSeparator}
42
+ decimalSeparator={format.decimalSeparator}
43
+ decimalScale={2}
44
+ fixedDecimalScale
45
+ valueIsNumericString
46
+ onValueChange={(values) => {
47
+ onChange(values.floatValue || 0);
48
+ }}
49
+ error={error}
50
+ helperText={helperText}
51
+ name={name}
52
+ />
53
+ );
54
+ }
55
+
56
+ return (
57
+ <NumericFormat
58
+ customInput={TextField}
59
+ fullWidth
60
+ margin="normal"
61
+ label={label}
62
+ value={value}
63
+ thousandSeparator={format.groupSeparator}
64
+ decimalSeparator={format.decimalSeparator}
65
+ decimalScale={2}
66
+ fixedDecimalScale
67
+ prefix={format.position === 'prefix' ? format.symbol + ' ' : undefined}
68
+ suffix={format.position === 'postfix' ? ' ' + format.symbol : undefined}
69
+ valueIsNumericString
70
+ onValueChange={(values) => {
71
+ onChange(values.floatValue || 0);
72
+ }}
73
+ error={error}
74
+ helperText={helperText}
75
+ name={name}
76
+ />
77
+ );
78
+ };
79
+
80
+ export default CurrencyInput;
@@ -0,0 +1,24 @@
1
+ import { Box, Container, Typography } from '@mui/material';
2
+ import { FC, ReactNode } from 'react';
3
+
4
+ export interface DashboardPageProps {
5
+ title?: string;
6
+ children?: ReactNode;
7
+ }
8
+
9
+ export const DashboardPage: FC<DashboardPageProps> = ({ title = 'Dashboard', children }) => {
10
+ return (
11
+ <Container maxWidth="md">
12
+ <Box my={4}>
13
+ <Typography variant="h4" component="h1" gutterBottom align="center">
14
+ {title}
15
+ </Typography>
16
+ <Box display="flex" justifyContent="center" mt={3}>
17
+ {children}
18
+ </Box>
19
+ </Box>
20
+ </Container>
21
+ );
22
+ };
23
+
24
+ export default DashboardPage;
@@ -0,0 +1,105 @@
1
+ import { Box, Fade, IconButton, Menu, MenuItem } from '@mui/material';
2
+ import { FC, MouseEvent, ReactElement, useCallback, useState } from 'react';
3
+ import { useNavigate } from 'react-router';
4
+ import { MenuType } from '../types/MenuType';
5
+ import { IMenuOption } from '../interfaces/IMenuOption';
6
+ import { useMenu } from '../contexts/MenuContext';
7
+
8
+ interface DropdownMenuProps {
9
+ menuType: MenuType;
10
+ menuIcon: ReactElement;
11
+ /** When true, the entire icon button is hidden if there are no menu options. Defaults to false. */
12
+ hideWhenEmpty?: boolean;
13
+ /** Optional callback invoked when the icon button is clicked. When provided alongside menu options, the action fires first and the dropdown still opens. When there are no menu options, only the action fires. */
14
+ action?: () => void;
15
+ }
16
+
17
+ export const DropdownMenu: FC<DropdownMenuProps> = ({ menuType, menuIcon, hideWhenEmpty = false, action }) => {
18
+ const { getMenuOptions } = useMenu();
19
+ const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
20
+ const navigate = useNavigate();
21
+ const handleClose = useCallback(() => {
22
+ setAnchorEl(null);
23
+ }, []);
24
+ const handleMenuItemClick = useCallback(
25
+ (option: IMenuOption) => (event: React.MouseEvent<HTMLElement>) => {
26
+ event.stopPropagation();
27
+ if (option.action) {
28
+ option.action();
29
+ } else if (option.link !== undefined) {
30
+ if (
31
+ typeof option.link === 'object' &&
32
+ 'pathname' in option.link &&
33
+ 'state' in option.link
34
+ ) {
35
+ navigate(option.link.pathname, { state: option.link.state });
36
+ } else {
37
+ navigate(option.link);
38
+ }
39
+ }
40
+ handleClose(); // Call handleClose after handling the click
41
+ },
42
+ [navigate, handleClose], // Add handleClose to the dependency array
43
+ );
44
+
45
+ const menuItems = getMenuOptions(menuType, false);
46
+ const hasItems = menuItems.length > 0;
47
+
48
+ const handleClick = useCallback((event: MouseEvent<HTMLElement>) => {
49
+ if (action) {
50
+ action();
51
+ }
52
+ if (hasItems) {
53
+ setAnchorEl(event.currentTarget);
54
+ }
55
+ }, [action, hasItems]);
56
+
57
+ if (!hasItems && hideWhenEmpty) {
58
+ return null;
59
+ }
60
+
61
+ return (
62
+ <Box>
63
+ <IconButton color="inherit" onClick={(hasItems || action) ? handleClick : undefined}>
64
+ {menuIcon}
65
+ </IconButton>
66
+ {hasItems && (
67
+ <Menu
68
+ anchorEl={anchorEl}
69
+ open={Boolean(anchorEl)}
70
+ onClose={handleClose}
71
+ TransitionComponent={Fade}
72
+ sx={{
73
+ '& .MuiPopover-paper': {
74
+ opacity: 0.5,
75
+ overflow: 'visible',
76
+ },
77
+ }}
78
+ >
79
+ {menuItems.map((option) => (
80
+ <MenuItem
81
+ key={option.id}
82
+ component="li"
83
+ onClick={handleMenuItemClick(option)}
84
+ sx={{
85
+ display: 'flex',
86
+ alignItems: 'center',
87
+ '& > svg': {
88
+ marginRight: 2,
89
+ width: 24,
90
+ height: 24,
91
+ },
92
+ ...option.additionalSx
93
+ }}
94
+ >
95
+ {option.icon}
96
+ {option.label}
97
+ </MenuItem>
98
+ ))}
99
+ </Menu>
100
+ )}
101
+ </Box>
102
+ );
103
+ };
104
+
105
+ export default DropdownMenu;
@@ -0,0 +1,60 @@
1
+ import { MenuItem, TextField } from '@mui/material';
2
+ import { FormikProps } from 'formik';
3
+ import { ChangeEvent, FC } from 'react';
4
+
5
+ export interface ExpirationSecondsSelectorProps<T = Record<string, unknown>> {
6
+ name: string;
7
+ label: string;
8
+ formik: FormikProps<T>;
9
+ optionValues: number[];
10
+ optionNames: string[];
11
+ onChange?: (value: number) => void;
12
+ }
13
+
14
+ export const ExpirationSecondsSelector: FC<
15
+ ExpirationSecondsSelectorProps<Record<string, unknown>>
16
+ > = ({ name, label, formik, optionValues, optionNames, onChange }) => {
17
+ return (
18
+ <TextField
19
+ select
20
+ fullWidth
21
+ label={label}
22
+ name={name}
23
+ value={formik.values[name] ?? ''}
24
+ onChange={(event: ChangeEvent<HTMLInputElement>) => {
25
+ const selectedValue = event.target.value;
26
+ formik.setFieldValue(name, selectedValue);
27
+ if (onChange) {
28
+ onChange(parseInt(selectedValue));
29
+ }
30
+ }}
31
+ error={formik.touched[name] && Boolean(formik.errors[name])}
32
+ helperText={formik.touched[name] && (formik.errors[name] as string)}
33
+ sx={{
34
+ mt: 1,
35
+ '& .MuiSelect-select': {
36
+ paddingRight: '32px',
37
+ },
38
+ '& .MuiOutlinedInput-root': {
39
+ '& fieldset': {
40
+ borderColor: 'rgba(0, 0, 0, 0.23)',
41
+ },
42
+ '&:hover fieldset': {
43
+ borderColor: 'rgba(0, 0, 0, 0.87)',
44
+ },
45
+ '&.Mui-focused fieldset': {
46
+ borderColor: 'primary.main',
47
+ },
48
+ },
49
+ }}
50
+ >
51
+ {optionNames.map((name: string, index: number) => (
52
+ <MenuItem key={name} value={optionValues[index]}>
53
+ {name}
54
+ </MenuItem>
55
+ ))}
56
+ </TextField>
57
+ );
58
+ };
59
+
60
+ export default ExpirationSecondsSelector;