@digitaldefiance/express-suite-react-components 2.9.7 → 2.9.11

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 (257) hide show
  1. package/package.json +6 -5
  2. package/src/auth/Private.d.ts +6 -0
  3. package/src/auth/Private.d.ts.map +1 -0
  4. package/src/auth/Private.js +14 -0
  5. package/src/auth/PrivateRoute.d.ts +8 -0
  6. package/src/auth/PrivateRoute.d.ts.map +1 -0
  7. package/src/auth/PrivateRoute.js +23 -0
  8. package/src/auth/UnAuth.d.ts +6 -0
  9. package/src/auth/UnAuth.d.ts.map +1 -0
  10. package/src/auth/UnAuth.js +14 -0
  11. package/src/auth/UnAuthRoute.d.ts +8 -0
  12. package/src/auth/UnAuthRoute.d.ts.map +1 -0
  13. package/src/auth/UnAuthRoute.js +22 -0
  14. package/src/auth/{index.ts → index.d.ts} +2 -1
  15. package/src/auth/index.d.ts.map +1 -0
  16. package/src/auth/index.js +10 -0
  17. package/src/components/ApiAccess.d.ts +16 -0
  18. package/src/components/ApiAccess.d.ts.map +1 -0
  19. package/src/components/ApiAccess.js +70 -0
  20. package/src/components/BackupCodeLoginForm.d.ts +43 -0
  21. package/src/components/BackupCodeLoginForm.d.ts.map +1 -0
  22. package/src/components/BackupCodeLoginForm.js +106 -0
  23. package/src/components/BackupCodesForm.d.ts +26 -0
  24. package/src/components/BackupCodesForm.d.ts.map +1 -0
  25. package/src/components/BackupCodesForm.js +108 -0
  26. package/src/components/ChangePasswordForm.d.ts +26 -0
  27. package/src/components/ChangePasswordForm.d.ts.map +1 -0
  28. package/src/components/ChangePasswordForm.js +66 -0
  29. package/src/components/ConfirmationDialog.d.ts +13 -0
  30. package/src/components/ConfirmationDialog.d.ts.map +1 -0
  31. package/src/components/ConfirmationDialog.js +10 -0
  32. package/src/components/CurrencyCodeSelector.d.ts +9 -0
  33. package/src/components/CurrencyCodeSelector.d.ts.map +1 -0
  34. package/src/components/CurrencyCodeSelector.js +31 -0
  35. package/src/components/CurrencyInput.d.ts +13 -0
  36. package/src/components/CurrencyInput.d.ts.map +1 -0
  37. package/src/components/CurrencyInput.js +22 -0
  38. package/src/components/DashboardPage.d.ts +8 -0
  39. package/src/components/DashboardPage.d.ts.map +1 -0
  40. package/src/components/DashboardPage.js +10 -0
  41. package/src/components/DropdownMenu.d.ts +9 -0
  42. package/src/components/DropdownMenu.d.ts.map +1 -0
  43. package/src/components/DropdownMenu.js +56 -0
  44. package/src/components/ExpirationSecondsSelector.d.ts +13 -0
  45. package/src/components/ExpirationSecondsSelector.d.ts.map +1 -0
  46. package/src/components/ExpirationSecondsSelector.js +32 -0
  47. package/src/components/Flag.d.ts +20 -0
  48. package/src/components/Flag.d.ts.map +1 -0
  49. package/src/components/Flag.js +43 -0
  50. package/src/components/ForgotPasswordForm.d.ts +18 -0
  51. package/src/components/ForgotPasswordForm.d.ts.map +1 -0
  52. package/src/components/ForgotPasswordForm.js +54 -0
  53. package/src/components/LoginForm.d.ts +44 -0
  54. package/src/components/LoginForm.d.ts.map +1 -0
  55. package/src/components/LoginForm.js +99 -0
  56. package/src/components/LogoutPage.d.ts +8 -0
  57. package/src/components/LogoutPage.d.ts.map +1 -0
  58. package/src/components/LogoutPage.js +16 -0
  59. package/src/components/RegisterForm.d.ts +54 -0
  60. package/src/components/RegisterForm.d.ts.map +1 -0
  61. package/src/components/RegisterForm.js +105 -0
  62. package/src/components/ResetPasswordForm.d.ts +23 -0
  63. package/src/components/ResetPasswordForm.d.ts.map +1 -0
  64. package/src/components/ResetPasswordForm.js +68 -0
  65. package/src/components/SideMenu.d.ts +8 -0
  66. package/src/components/SideMenu.d.ts.map +1 -0
  67. package/src/components/SideMenu.js +25 -0
  68. package/src/components/SideMenuListItem.d.ts +13 -0
  69. package/src/components/SideMenuListItem.d.ts.map +1 -0
  70. package/src/components/SideMenuListItem.js +44 -0
  71. package/src/components/TopMenu.d.ts +24 -0
  72. package/src/components/TopMenu.d.ts.map +1 -0
  73. package/src/components/TopMenu.js +42 -0
  74. package/src/components/TranslatedTitle.d.ts +7 -0
  75. package/src/components/TranslatedTitle.d.ts.map +1 -0
  76. package/src/components/TranslatedTitle.js +15 -0
  77. package/src/components/UserLanguageSelector.d.ts +4 -0
  78. package/src/components/UserLanguageSelector.d.ts.map +1 -0
  79. package/src/components/UserLanguageSelector.js +31 -0
  80. package/src/components/UserMenu.d.ts +4 -0
  81. package/src/components/UserMenu.d.ts.map +1 -0
  82. package/src/components/UserMenu.js +12 -0
  83. package/src/components/UserSettingsForm.d.ts +56 -0
  84. package/src/components/UserSettingsForm.d.ts.map +1 -0
  85. package/src/components/UserSettingsForm.js +93 -0
  86. package/src/components/VerifyEmailPage.d.ts +23 -0
  87. package/src/components/VerifyEmailPage.d.ts.map +1 -0
  88. package/src/components/VerifyEmailPage.js +61 -0
  89. package/src/components/{index.ts → index.d.ts} +1 -1
  90. package/src/components/index.d.ts.map +1 -0
  91. package/src/components/index.js +28 -0
  92. package/src/contexts/AuthProvider.d.ts +152 -0
  93. package/src/contexts/AuthProvider.d.ts.map +1 -0
  94. package/src/contexts/AuthProvider.js +446 -0
  95. package/src/contexts/I18nProvider.d.ts +16 -0
  96. package/src/contexts/I18nProvider.d.ts.map +1 -0
  97. package/src/contexts/I18nProvider.js +46 -0
  98. package/src/contexts/MenuContext.d.ts +20 -0
  99. package/src/contexts/MenuContext.d.ts.map +1 -0
  100. package/src/contexts/MenuContext.js +244 -0
  101. package/src/contexts/SuiteConfigProvider.d.ts +44 -0
  102. package/src/contexts/SuiteConfigProvider.d.ts.map +1 -0
  103. package/src/contexts/SuiteConfigProvider.js +43 -0
  104. package/src/contexts/ThemeProvider.d.ts +15 -0
  105. package/src/contexts/ThemeProvider.d.ts.map +1 -0
  106. package/src/contexts/ThemeProvider.js +36 -0
  107. package/src/contexts/{index.ts → index.d.ts} +1 -0
  108. package/src/contexts/index.d.ts.map +1 -0
  109. package/src/contexts/index.js +8 -0
  110. package/src/hooks/{index.ts → index.d.ts} +1 -0
  111. package/src/hooks/index.d.ts.map +1 -0
  112. package/src/hooks/index.js +8 -0
  113. package/src/hooks/useBackupCodes.d.ts +15 -0
  114. package/src/hooks/useBackupCodes.d.ts.map +1 -0
  115. package/src/hooks/useBackupCodes.js +70 -0
  116. package/src/hooks/useEmailVerification.d.ts +10 -0
  117. package/src/hooks/useEmailVerification.d.ts.map +1 -0
  118. package/src/hooks/useEmailVerification.js +36 -0
  119. package/src/hooks/useExpiringValue.d.ts +14 -0
  120. package/src/hooks/useExpiringValue.d.ts.map +1 -0
  121. package/src/hooks/useExpiringValue.js +53 -0
  122. package/src/hooks/useLocalStorage.d.ts +2 -0
  123. package/src/hooks/useLocalStorage.d.ts.map +1 -0
  124. package/src/hooks/useLocalStorage.js +15 -0
  125. package/src/hooks/useUserSettings.d.ts +46 -0
  126. package/src/hooks/useUserSettings.d.ts.map +1 -0
  127. package/src/hooks/useUserSettings.js +152 -0
  128. package/src/{index.ts → index.d.ts} +1 -1
  129. package/src/index.d.ts.map +1 -0
  130. package/src/index.js +12 -0
  131. package/src/interfaces/IAppConfig.d.ts +6 -0
  132. package/src/interfaces/IAppConfig.d.ts.map +1 -0
  133. package/src/interfaces/IAppConfig.js +2 -0
  134. package/src/interfaces/IMenuConfig.d.ts +11 -0
  135. package/src/interfaces/IMenuConfig.d.ts.map +1 -0
  136. package/src/interfaces/IMenuConfig.js +2 -0
  137. package/src/interfaces/IMenuOption.d.ts +58 -0
  138. package/src/interfaces/IMenuOption.d.ts.map +1 -0
  139. package/src/interfaces/IMenuOption.js +2 -0
  140. package/src/interfaces/index.d.ts +4 -0
  141. package/src/interfaces/index.d.ts.map +1 -0
  142. package/src/interfaces/index.js +6 -0
  143. package/src/services/__mocks__/authService.d.ts +21 -0
  144. package/src/services/__mocks__/authService.d.ts.map +1 -0
  145. package/src/services/__mocks__/authService.js +15 -0
  146. package/src/services/api.d.ts +3 -0
  147. package/src/services/api.d.ts.map +1 -0
  148. package/src/services/api.js +14 -0
  149. package/src/services/authService.d.ts +72 -0
  150. package/src/services/authService.d.ts.map +1 -0
  151. package/src/services/authService.js +353 -0
  152. package/src/services/authenticatedApi.d.ts +3 -0
  153. package/src/services/authenticatedApi.d.ts.map +1 -0
  154. package/src/services/authenticatedApi.js +18 -0
  155. package/src/services/index.d.ts +4 -0
  156. package/src/services/index.d.ts.map +1 -0
  157. package/src/services/index.js +6 -0
  158. package/src/types/MenuType.d.ts +11 -0
  159. package/src/types/MenuType.d.ts.map +1 -0
  160. package/src/types/MenuType.js +12 -0
  161. package/src/types/expirationSeconds.d.ts +3 -0
  162. package/src/types/expirationSeconds.d.ts.map +1 -0
  163. package/src/types/expirationSeconds.js +17 -0
  164. package/src/types/index.d.ts +2 -0
  165. package/src/types/index.d.ts.map +1 -0
  166. package/src/types/index.js +4 -0
  167. package/src/types/translation.d.ts +10 -0
  168. package/src/types/translation.d.ts.map +1 -0
  169. package/src/types/translation.js +9 -0
  170. package/src/wrappers/BackupCodeLoginWrapper.d.ts +8 -0
  171. package/src/wrappers/BackupCodeLoginWrapper.d.ts.map +1 -0
  172. package/src/wrappers/BackupCodeLoginWrapper.js +21 -0
  173. package/src/wrappers/BackupCodesWrapper.d.ts +7 -0
  174. package/src/wrappers/BackupCodesWrapper.d.ts.map +1 -0
  175. package/src/wrappers/BackupCodesWrapper.js +17 -0
  176. package/src/wrappers/ChangePasswordFormWrapper.d.ts +8 -0
  177. package/src/wrappers/ChangePasswordFormWrapper.d.ts.map +1 -0
  178. package/src/wrappers/ChangePasswordFormWrapper.js +21 -0
  179. package/src/wrappers/LoginFormWrapper.d.ts +9 -0
  180. package/src/wrappers/LoginFormWrapper.d.ts.map +1 -0
  181. package/src/wrappers/LoginFormWrapper.js +43 -0
  182. package/src/wrappers/LogoutPageWrapper.d.ts +9 -0
  183. package/src/wrappers/LogoutPageWrapper.d.ts.map +1 -0
  184. package/src/wrappers/LogoutPageWrapper.js +21 -0
  185. package/src/wrappers/RegisterFormWrapper.d.ts +9 -0
  186. package/src/wrappers/RegisterFormWrapper.d.ts.map +1 -0
  187. package/src/wrappers/RegisterFormWrapper.js +26 -0
  188. package/src/wrappers/UserSettingsFormWrapper.d.ts +8 -0
  189. package/src/wrappers/UserSettingsFormWrapper.d.ts.map +1 -0
  190. package/src/wrappers/UserSettingsFormWrapper.js +24 -0
  191. package/src/wrappers/VerifyEmailPageWrapper.d.ts +8 -0
  192. package/src/wrappers/VerifyEmailPageWrapper.d.ts.map +1 -0
  193. package/src/wrappers/VerifyEmailPageWrapper.js +20 -0
  194. package/src/wrappers/{index.tsx → index.d.ts} +1 -8
  195. package/src/wrappers/index.d.ts.map +1 -0
  196. package/src/wrappers/index.js +20 -0
  197. package/LICENSE +0 -21
  198. package/src/auth/Private.tsx +0 -17
  199. package/src/auth/PrivateRoute.tsx +0 -28
  200. package/src/auth/UnAuth.tsx +0 -16
  201. package/src/auth/UnAuthRoute.tsx +0 -30
  202. package/src/components/ApiAccess.tsx +0 -134
  203. package/src/components/BackupCodeLoginForm.tsx +0 -314
  204. package/src/components/BackupCodesForm.tsx +0 -198
  205. package/src/components/ChangePasswordForm.tsx +0 -182
  206. package/src/components/ConfirmationDialog.tsx +0 -48
  207. package/src/components/CurrencyCodeSelector.tsx +0 -60
  208. package/src/components/CurrencyInput.tsx +0 -80
  209. package/src/components/DashboardPage.tsx +0 -24
  210. package/src/components/DropdownMenu.tsx +0 -92
  211. package/src/components/ExpirationSecondsSelector.tsx +0 -65
  212. package/src/components/Flag.tsx +0 -53
  213. package/src/components/ForgotPasswordForm.tsx +0 -120
  214. package/src/components/LoginForm.tsx +0 -307
  215. package/src/components/LogoutPage.tsx +0 -21
  216. package/src/components/RegisterForm.tsx +0 -354
  217. package/src/components/ResetPasswordForm.tsx +0 -164
  218. package/src/components/SideMenu.tsx +0 -46
  219. package/src/components/SideMenuListItem.tsx +0 -74
  220. package/src/components/TopMenu.tsx +0 -149
  221. package/src/components/TranslatedTitle.tsx +0 -22
  222. package/src/components/UserLanguageSelector.tsx +0 -45
  223. package/src/components/UserMenu.tsx +0 -15
  224. package/src/components/UserSettingsForm.tsx +0 -328
  225. package/src/components/VerifyEmailPage.tsx +0 -133
  226. package/src/contexts/AuthProvider.spec.tsx +0 -1060
  227. package/src/contexts/AuthProvider.tsx +0 -741
  228. package/src/contexts/I18nProvider.tsx +0 -85
  229. package/src/contexts/MenuContext.tsx +0 -310
  230. package/src/contexts/SuiteConfigProvider.tsx +0 -93
  231. package/src/contexts/ThemeProvider.tsx +0 -67
  232. package/src/hooks/useBackupCodes.ts +0 -85
  233. package/src/hooks/useEmailVerification.ts +0 -39
  234. package/src/hooks/useExpiringValue.ts +0 -78
  235. package/src/hooks/useLocalStorage.ts +0 -18
  236. package/src/hooks/useUserSettings.ts +0 -216
  237. package/src/interfaces/IAppConfig.ts +0 -5
  238. package/src/interfaces/IMenuConfig.ts +0 -11
  239. package/src/interfaces/IMenuOption.ts +0 -55
  240. package/src/interfaces/index.ts +0 -3
  241. package/src/services/__mocks__/authService.ts +0 -14
  242. package/src/services/api.ts +0 -13
  243. package/src/services/authService.ts +0 -422
  244. package/src/services/authenticatedApi.ts +0 -17
  245. package/src/services/index.ts +0 -3
  246. package/src/types/MenuType.ts +0 -15
  247. package/src/types/expirationSeconds.ts +0 -18
  248. package/src/types/index.ts +0 -1
  249. package/src/types/translation.ts +0 -20
  250. package/src/wrappers/BackupCodeLoginWrapper.tsx +0 -35
  251. package/src/wrappers/BackupCodesWrapper.tsx +0 -28
  252. package/src/wrappers/ChangePasswordFormWrapper.tsx +0 -31
  253. package/src/wrappers/LoginFormWrapper.tsx +0 -59
  254. package/src/wrappers/LogoutPageWrapper.tsx +0 -30
  255. package/src/wrappers/RegisterFormWrapper.tsx +0 -48
  256. package/src/wrappers/UserSettingsFormWrapper.tsx +0 -39
  257. package/src/wrappers/VerifyEmailPageWrapper.tsx +0 -27
@@ -1,164 +0,0 @@
1
- import { Alert, Box, Button, Container, TextField, Typography } from '@mui/material';
2
- import { useFormik } from 'formik';
3
- import { FC, useState } from 'react';
4
- import * as Yup from 'yup';
5
- import { Constants, SuiteCoreComponentId, SuiteCoreStringKey } from '@digitaldefiance/suite-core-lib';
6
- import { useI18n } from '../contexts';
7
-
8
- export interface ResetPasswordFormValues {
9
- password: string;
10
- confirmPassword: string;
11
- }
12
-
13
- export interface ResetPasswordFormProps {
14
- token: string | null;
15
- onSubmit: (token: string, password: string) => Promise<void>;
16
- passwordValidation?: Yup.StringSchema;
17
- confirmPasswordValidation?: Yup.StringSchema;
18
- labels?: {
19
- title?: string;
20
- password?: string;
21
- confirmPassword?: string;
22
- resetButton?: string;
23
- successMessage?: string;
24
- invalidToken?: string;
25
- };
26
- }
27
-
28
- export const ResetPasswordForm: FC<ResetPasswordFormProps> = ({
29
- token,
30
- onSubmit,
31
- passwordValidation,
32
- confirmPasswordValidation,
33
- labels = {},
34
- }) => {
35
- const { t, tComponent } = useI18n();
36
- const [success, setSuccess] = useState(false);
37
- const [apiError, setApiError] = useState<string>('');
38
-
39
- const validation = {
40
- password: passwordValidation || Yup.string()
41
- .min(Constants.PasswordMinLength, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordMinLengthTemplate))
42
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
43
- confirmPassword: confirmPasswordValidation || Yup.string()
44
- .oneOf([Yup.ref('password')], tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordMatch))
45
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
46
- };
47
-
48
- const translatedLabels = {
49
- title: labels.title || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.PasswordReset_Title),
50
- password: labels.password || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_NewPassword),
51
- confirmPassword: labels.confirmPassword || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_ConfirmNewPassword),
52
- resetButton: labels.resetButton || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.PasswordReset_Button),
53
- successMessage: labels.successMessage || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.PasswordReset_Success),
54
- invalidToken: labels.invalidToken || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.ForgotPassword_InvalidToken),
55
- };
56
-
57
- const formik = useFormik<ResetPasswordFormValues>({
58
- initialValues: {
59
- password: '',
60
- confirmPassword: '',
61
- },
62
- validationSchema: Yup.object({
63
- password: validation.password,
64
- confirmPassword: validation.confirmPassword,
65
- }),
66
- onSubmit: async (values) => {
67
- if (!token) {
68
- setApiError(translatedLabels.invalidToken);
69
- return;
70
- }
71
-
72
- try {
73
- await onSubmit(token, values.password);
74
- setSuccess(true);
75
- setApiError('');
76
- } catch (error: any) {
77
- setApiError(error.response?.data?.message || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Error_PasswordChange));
78
- setSuccess(false);
79
- }
80
- },
81
- });
82
-
83
- if (!token) {
84
- return (
85
- <Container maxWidth="sm">
86
- <Alert severity="error" sx={{ mt: 4 }}>
87
- {translatedLabels.invalidToken}
88
- </Alert>
89
- </Container>
90
- );
91
- }
92
-
93
- return (
94
- <Container maxWidth="sm">
95
- <Box
96
- sx={{
97
- mt: 8,
98
- display: 'flex',
99
- flexDirection: 'column',
100
- alignItems: 'center',
101
- }}
102
- >
103
- <Typography variant="h4" component="h1" gutterBottom>
104
- {translatedLabels.title}
105
- </Typography>
106
-
107
- <Box component="form" onSubmit={formik.handleSubmit} sx={{ mt: 1, width: '100%' }}>
108
- <TextField
109
- fullWidth
110
- id="password"
111
- name="password"
112
- label={translatedLabels.password}
113
- type="password"
114
- value={formik.values.password}
115
- onChange={formik.handleChange}
116
- onBlur={formik.handleBlur}
117
- error={Boolean(formik.touched.password && formik.errors.password)}
118
- helperText={formik.touched.password && formik.errors.password}
119
- margin="normal"
120
- />
121
-
122
- <TextField
123
- fullWidth
124
- id="confirmPassword"
125
- name="confirmPassword"
126
- label={translatedLabels.confirmPassword}
127
- type="password"
128
- value={formik.values.confirmPassword}
129
- onChange={formik.handleChange}
130
- onBlur={formik.handleBlur}
131
- error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
132
- helperText={formik.touched.confirmPassword && formik.errors.confirmPassword}
133
- margin="normal"
134
- />
135
-
136
- {apiError && (
137
- <Alert severity="error" sx={{ mt: 2, mb: 2 }}>
138
- {apiError}
139
- </Alert>
140
- )}
141
-
142
- {success && (
143
- <Alert severity="success" sx={{ mt: 2, mb: 2 }}>
144
- {translatedLabels.successMessage}
145
- </Alert>
146
- )}
147
-
148
- <Button
149
- type="submit"
150
- fullWidth
151
- variant="contained"
152
- color="primary"
153
- sx={{ mt: 3, mb: 2 }}
154
- disabled={formik.isSubmitting}
155
- >
156
- {translatedLabels.resetButton}
157
- </Button>
158
- </Box>
159
- </Box>
160
- </Container>
161
- );
162
- };
163
-
164
- export default ResetPasswordForm;
@@ -1,46 +0,0 @@
1
- import { Drawer, List } from '@mui/material';
2
- import { FC } from 'react';
3
- import { useNavigate } from 'react-router-dom';
4
- import { useMenu } from '../contexts/MenuContext';
5
- import { IMenuOption } from '../interfaces/IMenuOption';
6
- import { MenuTypes } from '../types/MenuType';
7
- import { SideMenuListItem } from './SideMenuListItem';
8
-
9
- interface SideMenuProps {
10
- isOpen: boolean;
11
- onClose: () => void;
12
- }
13
-
14
- export const SideMenu: FC<SideMenuProps> = ({ isOpen, onClose }) => {
15
- const { getMenuOptions } = useMenu();
16
- const navigate = useNavigate();
17
-
18
- const menuOptions = getMenuOptions(MenuTypes.SideMenu, true);
19
-
20
- const handleNavigate = (
21
- link: string | Partial<{ pathname: string; state?: unknown }>
22
- ) => {
23
- if (typeof link === 'string') {
24
- navigate(link);
25
- } else if (link.pathname) {
26
- navigate(link.pathname, { state: link.state });
27
- }
28
- };
29
-
30
- return (
31
- <Drawer anchor="left" open={isOpen} onClose={onClose}>
32
- <List>
33
- {menuOptions.map((item: IMenuOption) => (
34
- <SideMenuListItem
35
- key={item.id}
36
- menuItem={item}
37
- onClose={onClose}
38
- onNavigate={handleNavigate}
39
- />
40
- ))}
41
- </List>
42
- </Drawer>
43
- );
44
- };
45
-
46
- export default SideMenu;
@@ -1,74 +0,0 @@
1
- import {
2
- Divider,
3
- ListItemButton,
4
- ListItemIcon,
5
- ListItemText,
6
- } from '@mui/material';
7
- import { FC, useCallback } from 'react';
8
- import { IMenuOption } from '../interfaces';
9
-
10
- export interface SideMenuListItemProps {
11
- menuItem: IMenuOption;
12
- onClose: () => void;
13
- onNavigate?: (
14
- link: string | Partial<{ pathname: string; state?: unknown }>
15
- ) => void;
16
- }
17
-
18
- export const SideMenuListItem: FC<SideMenuListItemProps> = ({
19
- menuItem,
20
- onClose,
21
- onNavigate,
22
- }) => {
23
- const handleMenuItemClick = useCallback(
24
- (option: IMenuOption) => (event: React.MouseEvent<HTMLElement>) => {
25
- event.stopPropagation();
26
- if (option.action) {
27
- option.action();
28
- } else if (option.link !== undefined && onNavigate) {
29
- if (typeof option.link === 'string') {
30
- onNavigate(option.link);
31
- } else if (
32
- typeof option.link === 'object' &&
33
- 'pathname' in option.link &&
34
- option.link.pathname
35
- ) {
36
- onNavigate({
37
- pathname: option.link.pathname,
38
- state: 'state' in option.link ? option.link.state : undefined,
39
- });
40
- }
41
- }
42
- onClose();
43
- },
44
- [onNavigate, onClose]
45
- );
46
-
47
- if (menuItem.divider) {
48
- return <Divider key={menuItem.label} />;
49
- } else if (menuItem.link) {
50
- return (
51
- <ListItemButton key={menuItem.id} onClick={handleMenuItemClick(menuItem)}>
52
- {menuItem.icon && <ListItemIcon>{menuItem.icon}</ListItemIcon>}
53
- <ListItemText primary={menuItem.label} />
54
- </ListItemButton>
55
- );
56
- } else if (menuItem.action) {
57
- const action = menuItem.action;
58
- return (
59
- <ListItemButton
60
- key={menuItem.id}
61
- onClick={async () => {
62
- await action();
63
- onClose();
64
- }}
65
- >
66
- {menuItem.icon && <ListItemIcon>{menuItem.icon}</ListItemIcon>}
67
- <ListItemText primary={menuItem.label} />
68
- </ListItemButton>
69
- );
70
- }
71
- return null;
72
- };
73
-
74
- export default SideMenuListItem;
@@ -1,149 +0,0 @@
1
- import {
2
- SuiteCoreComponentId,
3
- SuiteCoreStringKey,
4
- } from '@digitaldefiance/suite-core-lib';
5
- import MenuIcon from '@mui/icons-material/Menu';
6
- import {
7
- AppBar,
8
- Box,
9
- Button,
10
- IconButton,
11
- Toolbar,
12
- Typography,
13
- } from '@mui/material';
14
- import React, { FC, ReactElement, useContext, useState } from 'react';
15
- import { Link } from 'react-router-dom';
16
- import { AuthContext } from '../contexts/AuthProvider';
17
- import { useI18n } from '../contexts/I18nProvider';
18
- import { useMenu } from '../contexts/MenuContext';
19
- import { MenuType } from '../types/MenuType';
20
- import { DropdownMenu } from './DropdownMenu';
21
- import { SideMenu } from './SideMenu';
22
- import { UserLanguageSelector } from './UserLanguageSelector';
23
- import { UserMenu } from './UserMenu';
24
-
25
- // Extend Window interface for APP_CONFIG
26
- declare global {
27
- interface Window {
28
- APP_CONFIG?: {
29
- hostname: string;
30
- siteTitle: string;
31
- server: string;
32
- [key: string]: unknown;
33
- };
34
- }
35
- }
36
-
37
- export interface AdditionalDropdownMenu {
38
- menuType: MenuType;
39
- menuIcon: ReactElement;
40
- priority?: number;
41
- }
42
-
43
- export interface TopMenuProps {
44
- Logo: React.ReactNode;
45
- additionalMenus?: Array<AdditionalDropdownMenu>;
46
- }
47
-
48
- export const TopMenu: FC<TopMenuProps> = ({ Logo, additionalMenus }) => {
49
- const { isAuthenticated } = useContext(AuthContext);
50
- const { getTopMenus } = useMenu();
51
- const [isSideMenuOpen, setIsSideMenuOpen] = useState(false);
52
-
53
- const handleOpenSideMenu = () => setIsSideMenuOpen(true);
54
- const handleCloseSideMenu = () => setIsSideMenuOpen(false);
55
- const { t, tComponent } = useI18n();
56
- const appConfig = window.APP_CONFIG;
57
- const siteTitle = tComponent<SuiteCoreStringKey>(
58
- SuiteCoreComponentId,
59
- SuiteCoreStringKey.Common_SiteTemplate
60
- );
61
-
62
- return (
63
- <AppBar position="fixed" sx={{ top: 10 }}>
64
- <Toolbar>
65
- <IconButton
66
- size="large"
67
- edge="start"
68
- color="inherit"
69
- aria-label="menu"
70
- sx={{ mr: 2 }}
71
- onClick={handleOpenSideMenu}
72
- >
73
- <MenuIcon />
74
- </IconButton>
75
- <Box
76
- sx={{
77
- height: 40,
78
- width: 40,
79
- marginRight: 2,
80
- display: 'flex',
81
- alignItems: 'center',
82
- }}
83
- >
84
- {Logo}
85
- </Box>
86
- <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
87
- {siteTitle}
88
- </Typography>
89
- <Box sx={{ display: 'flex', alignItems: 'center' }}>
90
- {isAuthenticated ? (
91
- <>
92
- <Button
93
- color="inherit"
94
- // @ts-expect-error - MUI Button with react-router Link has type incompatibility
95
- component={Link}
96
- to="/dashboard"
97
- >
98
- {tComponent<SuiteCoreStringKey>(
99
- SuiteCoreComponentId,
100
- SuiteCoreStringKey.Common_Dashboard
101
- )}
102
- </Button>
103
- {getTopMenus().map((menu, index) =>
104
- menu.isUserMenu ? (
105
- <UserMenu key={`user-menu`} />
106
- ) : (
107
- <DropdownMenu
108
- key={`menu-${index}`}
109
- menuType={menu.menuType}
110
- menuIcon={menu.menuIcon as ReactElement}
111
- />
112
- )
113
- )}
114
- </>
115
- ) : (
116
- <>
117
- <Button
118
- color="inherit"
119
- // @ts-expect-error - MUI Button with react-router Link has type incompatibility
120
- component={Link}
121
- to="/login"
122
- >
123
- {tComponent<SuiteCoreStringKey>(
124
- SuiteCoreComponentId,
125
- SuiteCoreStringKey.Login_LoginButton
126
- )}
127
- </Button>
128
- <Button
129
- color="inherit"
130
- // @ts-expect-error - MUI Button with react-router Link has type incompatibility
131
- component={Link}
132
- to="/register"
133
- >
134
- {tComponent<SuiteCoreStringKey>(
135
- SuiteCoreComponentId,
136
- SuiteCoreStringKey.RegisterButton
137
- )}
138
- </Button>
139
- </>
140
- )}
141
- <UserLanguageSelector />
142
- </Box>
143
- </Toolbar>
144
- <SideMenu isOpen={isSideMenuOpen} onClose={handleCloseSideMenu} />
145
- </AppBar>
146
- );
147
- };
148
-
149
- export default TopMenu;
@@ -1,22 +0,0 @@
1
- // src/app/components/TranslatedTitle.tsx
2
-
3
- import { useEffect } from 'react';
4
- import { useI18n } from '../contexts';
5
- import { SuiteCoreStringKey } from '@digitaldefiance/suite-core-lib';
6
-
7
- interface FCParams<TEnum extends string> {
8
- componentId: string;
9
- stringKey: TEnum;
10
- }
11
-
12
- export const TranslatedTitle = <TEnum extends string>({ componentId, stringKey }: FCParams<TEnum>): null => {
13
- const { tComponent, currentLanguage } = useI18n();
14
-
15
- useEffect(() => {
16
- document.title = tComponent<TEnum>(componentId, stringKey, undefined, currentLanguage);
17
- }, [tComponent, componentId, stringKey, currentLanguage]);
18
-
19
- return null;
20
- };
21
-
22
- export default TranslatedTitle;
@@ -1,45 +0,0 @@
1
- import { LanguageRegistry, LanguageDefinition } from '@digitaldefiance/i18n-lib';
2
- import { Button, Menu, MenuItem } from '@mui/material';
3
- import { FC, MouseEvent, useState, useMemo } from 'react';
4
- import { Flag } from './Flag';
5
- import { useUserSettings } from '../hooks';
6
- import { createAuthenticatedApiClient } from '../services';
7
- import { useAuth, useSuiteConfig } from '../contexts';
8
-
9
- export const UserLanguageSelector: FC = () => {
10
- const { baseUrl } = useSuiteConfig();
11
- const authenticatedApi = useMemo(() => createAuthenticatedApiClient(baseUrl), [baseUrl]);
12
- const { isAuthenticated } = useAuth();
13
- const { currentLanguage, changeLanguage } = useUserSettings({ authenticatedApi, isAuthenticated });
14
- const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
15
-
16
- const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
17
- setAnchorEl(event.currentTarget);
18
- };
19
-
20
- const handleClose = () => {
21
- setAnchorEl(null);
22
- };
23
-
24
- const handleLanguageChange = (newLanguage: string) => {
25
- changeLanguage(newLanguage);
26
- handleClose();
27
- };
28
-
29
- return (
30
- <>
31
- <Button onClick={handleClick}>
32
- <Flag language={currentLanguage} />
33
- </Button>
34
- <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose}>
35
- {Object.values(LanguageRegistry.getAllLanguages()).map((lang: LanguageDefinition) => (
36
- <MenuItem key={lang.code} onClick={() => handleLanguageChange(lang.code)}>
37
- <Flag language={lang.code} sx={{ mr: 1 }} /> {lang.name}
38
- </MenuItem>
39
- ))}
40
- </Menu>
41
- </>
42
- );
43
- };
44
-
45
- export default UserLanguageSelector;
@@ -1,15 +0,0 @@
1
- import { FC } from 'react';
2
- import { AccountCircle } from '@mui/icons-material';
3
- import { MenuTypes } from '../types/MenuType';
4
- import { DropdownMenu } from './DropdownMenu';
5
-
6
- export const UserMenu: FC = () => {
7
- return (
8
- <DropdownMenu
9
- menuType={MenuTypes.UserMenu}
10
- menuIcon={<AccountCircle />}
11
- />
12
- );
13
- };
14
-
15
- export default UserMenu;