@dashadmin/dash-app-common 1.3.25 → 1.3.28
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.
- package/README.md +35 -0
- package/dist/DashApp.js +176 -1
- package/dist/DashAppLoader.js +348 -3
- package/dist/DashDefaultResources.js +10 -1
- package/dist/components/DashDefaultPrivateApp.js +150 -1
- package/dist/components/DashDefaultPrivateResources.js +10 -1
- package/dist/components/DashDefaultPublicApp.js +20 -1
- package/dist/components/DashResourceLoader.js +245 -1
- package/dist/defaults/extensions/bootstrap/DashDefaultErrorBoundary.js +78 -1
- package/dist/defaults/extensions/bootstrap/dashDefaultInitializeApp.js +59 -1
- package/dist/defaults/extensions/bootstrap/index.js +24 -1
- package/dist/defaults/extensions/components/DashDefaultLoader.js +43 -2
- package/dist/defaults/extensions/components/dashDefaultAutoAdminComponents.js +67 -1
- package/dist/defaults/extensions/components/dashDefaultNotification.js +28 -1
- package/dist/defaults/extensions/components/dashDefaultStaticComponents.js +15 -1
- package/dist/defaults/extensions/components/index.js +13 -1
- package/dist/defaults/extensions/electron/dashDefaultIpcListeners.js +38 -1
- package/dist/defaults/extensions/electron/index.js +5 -1
- package/dist/defaults/extensions/hooks/index.js +12 -1
- package/dist/defaults/extensions/hooks/useDashDefaultLazyAutoAdminComponents.js +17 -1
- package/dist/defaults/extensions/hooks/useDashDefaultLazyI18nProvider.js +51 -1
- package/dist/defaults/extensions/hooks/useDashDefaultLazyResources.js +19 -1
- package/dist/defaults/extensions/hooks/useDashDefaultMountTracker.js +22 -1
- package/dist/defaults/extensions/hooks/useDashDefaultRoutePath.js +17 -1
- package/dist/defaults/extensions/i18n/dashDefaultI18nProvider.js +44 -1
- package/dist/defaults/extensions/i18n/dashDefaultTranslations.js +87 -1
- package/dist/defaults/extensions/i18n/index.js +24 -1
- package/dist/defaults/extensions/index.js +190 -1
- package/dist/defaults/extensions/layout/dashDefaultDomainAppLayout.js +58 -1
- package/dist/defaults/extensions/layout/index.js +12 -1
- package/dist/defaults/extensions/managers/DashDefaultWSMessagesManager.js +84 -1
- package/dist/defaults/extensions/managers/index.js +5 -1
- package/dist/defaults/extensions/providers/dashDefaultAuthProvider.js +220 -1
- package/dist/defaults/extensions/providers/dashDefaultDataProvider.js +395 -1
- package/dist/defaults/extensions/providers/index.js +24 -1
- package/dist/defaults/extensions/router/DashDefaultLanding.js +46 -1
- package/dist/defaults/extensions/router/dashDefaultPrivateRoutes.js +38 -1
- package/dist/defaults/extensions/router/dashDefaultPublicRoutes.js +65 -1
- package/dist/defaults/extensions/router/dashDefaultRouter.js +39 -1
- package/dist/defaults/extensions/router/dashDefaultSharedRoutes.js +40 -1
- package/dist/defaults/extensions/router/index.js +12 -1
- package/dist/defaults/extensions/state/dashDefaultAppCommon.js +57 -1
- package/dist/defaults/extensions/state/dashDefaultAppSettings.js +38 -1
- package/dist/defaults/extensions/state/dashDefaultInitialAppState.js +31 -1
- package/dist/defaults/extensions/state/dashDefaultLayoutSettings.js +48 -1
- package/dist/defaults/extensions/state/dashDefaultQueryClient.js +58 -1
- package/dist/defaults/extensions/state/dashDefaultResourcesIcons.js +24 -1
- package/dist/defaults/extensions/state/index.js +29 -1
- package/dist/defaults/extensions/styles/index.js +2 -1
- package/dist/defaults/extensions/theme/dashDefaultThemeOptions.js +74 -1
- package/dist/defaults/extensions/theme/index.js +6 -1
- package/dist/defaults/extensions/utils/IPCMessageBrokerContext.js +12 -1
- package/dist/defaults/extensions/utils/dashDefaultAuthProviderUtils.js +29 -1
- package/dist/defaults/extensions/utils/dashDefaultDataProviderUtils.js +37 -1
- package/dist/defaults/extensions/utils/dashDefaultNotificationsProcessor.js +149 -1
- package/dist/defaults/extensions/utils/index.js +44 -1
- package/dist/defaults/filters/demo/dashDefaultDemoFilters.js +36 -1
- package/dist/defaults/filters/demo/index.js +4 -1
- package/dist/defaults/filters/index.js +5 -1
- package/dist/defaults/index.js +14 -1
- package/dist/defaults/pages/Account/DashDefaultRegister.js +282 -1
- package/dist/defaults/pages/Account/DashDefaultSignUp.js +420 -1
- package/dist/defaults/pages/Account/DashDefaultSignUpSuccess.js +101 -1
- package/dist/defaults/pages/Account/index.js +8 -1
- package/dist/defaults/pages/DashDefaultLogin.js +218 -1
- package/dist/defaults/pages/Misc/DashDefaultNotFound.js +74 -1
- package/dist/defaults/pages/Misc/DashDefaultServerError.js +79 -1
- package/dist/defaults/pages/Misc/DashDefaultUnauthorized.js +90 -1
- package/dist/defaults/pages/Misc/index.js +8 -1
- package/dist/defaults/pages/Static/DashDefaultPrivacyPage.js +48 -1
- package/dist/defaults/pages/Static/DashDefaultStaticPage.js +55 -1
- package/dist/defaults/pages/Static/DashDefaultTermsPage.js +52 -1
- package/dist/defaults/pages/Static/index.js +8 -1
- package/dist/defaults/pages/index.js +25 -1
- package/dist/defaults/schemas/dashDefaultSchema.js +14 -1
- package/dist/defaults/schemas/demo/dashDefaultTodoSchema.js +24 -1
- package/dist/defaults/schemas/demo/index.js +4 -1
- package/dist/defaults/schemas/index.js +7 -1
- package/dist/filters/demo/todoFilters.js +36 -1
- package/dist/index.js +56 -5975
- package/dist/resources/demo/todoResource.js +58 -1
- package/dist/schemas/defaultSchema.js +14 -1
- package/dist/schemas/demo/todoSchema.js +24 -1
- package/package.json +132 -77
- package/src/DashApp.tsx +294 -0
- package/src/DashAppLoader.tsx +717 -0
- package/src/DashDefaultResources.tsx +10 -0
- package/src/components/DashDefaultPrivateApp.tsx +358 -0
- package/src/components/DashDefaultPrivateResources.tsx +10 -0
- package/src/components/DashDefaultPublicApp.tsx +40 -0
- package/src/components/DashResourceLoader.tsx +564 -0
- package/src/defaults/extensions/bootstrap/DashDefaultErrorBoundary.tsx +113 -0
- package/src/defaults/extensions/bootstrap/dashDefaultInitializeApp.ts +81 -0
- package/src/defaults/extensions/bootstrap/index.ts +32 -0
- package/src/defaults/extensions/components/DashDefaultLoader.tsx +59 -0
- package/src/defaults/extensions/components/dashDefaultAutoAdminComponents.tsx +49 -0
- package/src/defaults/extensions/components/dashDefaultNotification.tsx +37 -0
- package/src/defaults/extensions/components/dashDefaultStaticComponents.tsx +34 -0
- package/src/defaults/extensions/components/index.ts +17 -0
- package/src/defaults/extensions/electron/dashDefaultIpcListeners.ts +62 -0
- package/src/defaults/extensions/electron/index.ts +7 -0
- package/src/defaults/extensions/hooks/index.ts +11 -0
- package/src/defaults/extensions/hooks/useDashDefaultLazyAutoAdminComponents.ts +25 -0
- package/src/defaults/extensions/hooks/useDashDefaultLazyI18nProvider.ts +38 -0
- package/src/defaults/extensions/hooks/useDashDefaultLazyResources.ts +29 -0
- package/src/defaults/extensions/hooks/useDashDefaultMountTracker.ts +28 -0
- package/src/defaults/extensions/hooks/useDashDefaultRoutePath.ts +27 -0
- package/src/defaults/extensions/i18n/dashDefaultI18nProvider.ts +66 -0
- package/src/defaults/extensions/i18n/dashDefaultTranslations.ts +82 -0
- package/src/defaults/extensions/i18n/index.ts +22 -0
- package/src/defaults/extensions/index.ts +177 -0
- package/src/defaults/extensions/layout/dashDefaultDomainAppLayout.tsx +126 -0
- package/src/defaults/extensions/layout/index.ts +12 -0
- package/src/defaults/extensions/managers/DashDefaultWSMessagesManager.tsx +99 -0
- package/src/defaults/extensions/managers/index.ts +7 -0
- package/src/defaults/extensions/providers/dashDefaultAuthProvider.ts +256 -0
- package/src/defaults/extensions/providers/dashDefaultDataProvider.ts +513 -0
- package/src/defaults/extensions/providers/index.ts +25 -0
- package/src/defaults/extensions/router/DashDefaultLanding.tsx +51 -0
- package/src/defaults/extensions/router/dashDefaultPrivateRoutes.tsx +50 -0
- package/src/defaults/extensions/router/dashDefaultPublicRoutes.tsx +86 -0
- package/src/defaults/extensions/router/dashDefaultRouter.tsx +54 -0
- package/src/defaults/extensions/router/dashDefaultSharedRoutes.tsx +56 -0
- package/src/defaults/extensions/router/index.ts +13 -0
- package/src/defaults/extensions/state/dashDefaultAppCommon.ts +54 -0
- package/src/defaults/extensions/state/dashDefaultAppSettings.ts +29 -0
- package/src/defaults/extensions/state/dashDefaultInitialAppState.ts +75 -0
- package/src/defaults/extensions/state/dashDefaultLayoutSettings.ts +59 -0
- package/src/defaults/extensions/state/dashDefaultQueryClient.ts +59 -0
- package/src/defaults/extensions/state/dashDefaultResourcesIcons.tsx +23 -0
- package/src/defaults/extensions/state/index.ts +29 -0
- package/src/defaults/extensions/styles/index.ts +17 -0
- package/src/defaults/extensions/theme/dashDefaultThemeOptions.ts +89 -0
- package/src/defaults/extensions/theme/index.ts +7 -0
- package/src/defaults/extensions/utils/IPCMessageBrokerContext.tsx +22 -0
- package/src/defaults/extensions/utils/dashDefaultAuthProviderUtils.ts +36 -0
- package/src/defaults/extensions/utils/dashDefaultDataProviderUtils.ts +46 -0
- package/src/defaults/extensions/utils/dashDefaultNotificationsProcessor.tsx +208 -0
- package/src/defaults/extensions/utils/index.ts +42 -0
- package/src/defaults/filters/demo/dashDefaultDemoFilters.tsx +50 -0
- package/src/defaults/filters/demo/index.ts +6 -0
- package/src/defaults/filters/index.ts +11 -0
- package/src/defaults/index.ts +27 -0
- package/src/defaults/pages/Account/DashDefaultRegister.tsx +281 -0
- package/src/defaults/pages/Account/DashDefaultSignUp.tsx +492 -0
- package/src/defaults/pages/Account/DashDefaultSignUpSuccess.tsx +113 -0
- package/src/defaults/pages/Account/index.ts +8 -0
- package/src/defaults/pages/DashDefaultLogin.tsx +224 -0
- package/src/defaults/pages/Misc/DashDefaultNotFound.tsx +96 -0
- package/src/defaults/pages/Misc/DashDefaultServerError.tsx +102 -0
- package/src/defaults/pages/Misc/DashDefaultUnauthorized.tsx +116 -0
- package/src/defaults/pages/Misc/index.ts +8 -0
- package/src/defaults/pages/Static/DashDefaultPrivacyPage.tsx +85 -0
- package/src/defaults/pages/Static/DashDefaultStaticPage.tsx +75 -0
- package/src/defaults/pages/Static/DashDefaultTermsPage.tsx +69 -0
- package/src/defaults/pages/Static/index.ts +8 -0
- package/src/defaults/pages/index.ts +28 -0
- package/src/defaults/schemas/dashDefaultSchema.tsx +25 -0
- package/src/defaults/schemas/demo/dashDefaultTodoSchema.tsx +39 -0
- package/src/defaults/schemas/demo/index.ts +6 -0
- package/src/defaults/schemas/index.ts +14 -0
- package/src/filters/demo/todoFilters.tsx +39 -0
- package/src/index.ts +131 -0
- package/src/resources/demo/todoResource.tsx +68 -0
- package/src/schemas/defaultSchema.tsx +14 -0
- package/src/schemas/demo/todoSchema.tsx +27 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { useForm } from 'react-hook-form';
|
|
3
|
+
import { Button as LoadingButton } from "@mui/material";
|
|
4
|
+
import Button from '@mui/material/Button';
|
|
5
|
+
import Link from '@mui/material/Link';
|
|
6
|
+
import Alert from '@mui/material/Alert';
|
|
7
|
+
import Box from '@mui/material/Box';
|
|
8
|
+
import { IconButton, InputAdornment, TextField } from '@mui/material';
|
|
9
|
+
import { useNavigate } from 'react-router';
|
|
10
|
+
import VisibilityOff from '@mui/icons-material/VisibilityOff';
|
|
11
|
+
import Visibility from '@mui/icons-material/Visibility';
|
|
12
|
+
|
|
13
|
+
// Import FullLayoutMarkup - this doesn't need react-admin context
|
|
14
|
+
import FullLayoutMarkup from 'dash-admin/src/default-theme/FullLayoutMarkup';
|
|
15
|
+
import { AuthPersistenceService } from 'dash-auth';
|
|
16
|
+
// Import the singleton instance
|
|
17
|
+
import authService from 'dash-admin/src/contexts/auth/DASHAuthenticationService';
|
|
18
|
+
import { dashStorage } from 'dash-utils';
|
|
19
|
+
|
|
20
|
+
const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
21
|
+
|
|
22
|
+
interface LoginFormData {
|
|
23
|
+
email: string;
|
|
24
|
+
password: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const LoginPage: React.FC = () => {
|
|
28
|
+
const navigate = useNavigate();
|
|
29
|
+
|
|
30
|
+
const validateEmail = (value: string) => {
|
|
31
|
+
return EMAIL_REGEX.test(value);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Check authentication status WITHOUT react-admin hooks
|
|
35
|
+
const [loggedIn, setLoggedIn] = useState(() => {
|
|
36
|
+
const isValidAuth = AuthPersistenceService.isAuthValid();
|
|
37
|
+
const storageAuthenticated = JSON.parse(dashStorage.getItem('authenticated') || 'false');
|
|
38
|
+
return isValidAuth && storageAuthenticated;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const [loginLoading, setLoginLoading] = useState(false);
|
|
42
|
+
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
|
43
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
44
|
+
|
|
45
|
+
const form = useForm<LoginFormData>();
|
|
46
|
+
const {
|
|
47
|
+
register,
|
|
48
|
+
handleSubmit,
|
|
49
|
+
formState: { errors },
|
|
50
|
+
} = form;
|
|
51
|
+
|
|
52
|
+
// Re-check auth status on mount
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
const isValidAuth = AuthPersistenceService.isAuthValid();
|
|
55
|
+
const storageAuthenticated = JSON.parse(dashStorage.getItem('authenticated') || 'false');
|
|
56
|
+
|
|
57
|
+
if (isValidAuth && storageAuthenticated) {
|
|
58
|
+
console.log('User is already authenticated');
|
|
59
|
+
setLoggedIn(true);
|
|
60
|
+
} else {
|
|
61
|
+
console.log('User is not authenticated');
|
|
62
|
+
setLoggedIn(false);
|
|
63
|
+
}
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
66
|
+
const handleClickShowPassword = () => setShowPassword((show) => !show);
|
|
67
|
+
|
|
68
|
+
const handleMouseDownPassword = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
async function onSubmit(data: LoginFormData) {
|
|
73
|
+
const password = data.password;
|
|
74
|
+
setLoginLoading(true);
|
|
75
|
+
setErrorMessage(null);
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
console.log('Attempting login with DASHAuthenticationService...');
|
|
79
|
+
const response = await authService.login({
|
|
80
|
+
username: data.email,
|
|
81
|
+
password,
|
|
82
|
+
redirect: window.location.pathname
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
console.log('Login response:', response);
|
|
86
|
+
|
|
87
|
+
if (!response.success) {
|
|
88
|
+
throw new Error(response.error || 'Login failed');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.log('Login successful!');
|
|
92
|
+
setLoginLoading(false);
|
|
93
|
+
setLoggedIn(true);
|
|
94
|
+
|
|
95
|
+
// Navigate to redirect URL or home
|
|
96
|
+
if (response.redirectAfterLogin) {
|
|
97
|
+
console.log('Redirecting to:', response.redirectAfterLogin);
|
|
98
|
+
navigate(response.redirectAfterLogin);
|
|
99
|
+
} else {
|
|
100
|
+
navigate('/');
|
|
101
|
+
}
|
|
102
|
+
} catch (error: any) {
|
|
103
|
+
console.error('Login error:', error);
|
|
104
|
+
setLoginLoading(false);
|
|
105
|
+
|
|
106
|
+
let eMessage = 'Credenciales inválidas';
|
|
107
|
+
if (error?.response?.data?.message) {
|
|
108
|
+
eMessage = error.response.data.message;
|
|
109
|
+
} else if (error?.error) {
|
|
110
|
+
eMessage = error.error;
|
|
111
|
+
} else if (error?.message) {
|
|
112
|
+
eMessage = error.message;
|
|
113
|
+
}
|
|
114
|
+
setErrorMessage(eMessage);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const horizontal_logo = AuthPersistenceService.getTenantImages()?.horizontal_logo?.original;
|
|
119
|
+
const banner = AuthPersistenceService.getTenantImages()?.banner?.original;
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<FullLayoutMarkup
|
|
123
|
+
logo={horizontal_logo}
|
|
124
|
+
loginBackground={banner}
|
|
125
|
+
>
|
|
126
|
+
<>
|
|
127
|
+
{!loggedIn ? (
|
|
128
|
+
<form
|
|
129
|
+
onSubmit={handleSubmit(onSubmit)}
|
|
130
|
+
className='dash-app-login-form'
|
|
131
|
+
>
|
|
132
|
+
{/*<h1 className='dash-app-login-form-title'>
|
|
133
|
+
Ingresar
|
|
134
|
+
</h1>*/}
|
|
135
|
+
|
|
136
|
+
<div className='dash-app-form-item'>
|
|
137
|
+
<TextField
|
|
138
|
+
label='Email'
|
|
139
|
+
placeholder='Email'
|
|
140
|
+
required
|
|
141
|
+
{...register('email', { validate: validateEmail })}
|
|
142
|
+
className='dash-app-form-item-input'
|
|
143
|
+
/>
|
|
144
|
+
{errors.email && (
|
|
145
|
+
<span style={{ color: 'red' }}>
|
|
146
|
+
{errors.email.message ? String(errors.email.message) : "Email inválido"}
|
|
147
|
+
</span>
|
|
148
|
+
)}
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<div className='dash-app-form-item'>
|
|
152
|
+
<TextField
|
|
153
|
+
label='Contraseña'
|
|
154
|
+
placeholder='Contraseña'
|
|
155
|
+
{...register('password')}
|
|
156
|
+
className='dash-app-form-item-input'
|
|
157
|
+
InputProps={{
|
|
158
|
+
autoComplete: 'password',
|
|
159
|
+
type: showPassword ? 'text' : 'password',
|
|
160
|
+
endAdornment: (
|
|
161
|
+
<InputAdornment position='end'>
|
|
162
|
+
<IconButton
|
|
163
|
+
aria-label='toggle password visibility'
|
|
164
|
+
onClick={handleClickShowPassword}
|
|
165
|
+
onMouseDown={handleMouseDownPassword}
|
|
166
|
+
edge='end'
|
|
167
|
+
>
|
|
168
|
+
{showPassword ? <VisibilityOff /> : <Visibility />}
|
|
169
|
+
</IconButton>
|
|
170
|
+
</InputAdornment>
|
|
171
|
+
),
|
|
172
|
+
}}
|
|
173
|
+
/>
|
|
174
|
+
{errors.password && (
|
|
175
|
+
<span style={{ color: 'red' }}>
|
|
176
|
+
{errors.password.message ? String(errors.password.message) : "Contraseña Inválida"}
|
|
177
|
+
</span>
|
|
178
|
+
)}
|
|
179
|
+
|
|
180
|
+
<Link
|
|
181
|
+
className='link link--secondary'
|
|
182
|
+
style={{ marginLeft: 'auto' }}
|
|
183
|
+
href='/reset-password'
|
|
184
|
+
>
|
|
185
|
+
Resetear contraseña
|
|
186
|
+
</Link>
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
{errorMessage && (
|
|
190
|
+
<Box sx={{ mb: 2 }}>
|
|
191
|
+
<Alert severity="error" variant="filled">
|
|
192
|
+
{errorMessage}
|
|
193
|
+
</Alert>
|
|
194
|
+
</Box>
|
|
195
|
+
)}
|
|
196
|
+
|
|
197
|
+
<div className='dash-app-form-item mt-1'>
|
|
198
|
+
<LoadingButton
|
|
199
|
+
style={{ marginBottom: '21px' }}
|
|
200
|
+
className='submit'
|
|
201
|
+
type='submit'
|
|
202
|
+
disabled={loginLoading}
|
|
203
|
+
variant='contained'
|
|
204
|
+
>
|
|
205
|
+
{loginLoading ? 'Cargando...' : 'Ingresar'}
|
|
206
|
+
</LoadingButton>
|
|
207
|
+
</div>
|
|
208
|
+
</form>
|
|
209
|
+
) : (
|
|
210
|
+
<>
|
|
211
|
+
<div className='dash-app-form-item'>
|
|
212
|
+
Ya se encuentra logueado
|
|
213
|
+
</div>
|
|
214
|
+
<Button onClick={() => navigate('/')}>
|
|
215
|
+
Ir al Home
|
|
216
|
+
</Button>
|
|
217
|
+
</>
|
|
218
|
+
)}
|
|
219
|
+
</>
|
|
220
|
+
</FullLayoutMarkup>
|
|
221
|
+
);
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export default LoginPage;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Not Found Page (404)
|
|
3
|
+
*
|
|
4
|
+
* Page displayed when a route is not found.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { useNavigate } from 'react-router-dom';
|
|
8
|
+
import {
|
|
9
|
+
Box,
|
|
10
|
+
Typography,
|
|
11
|
+
Button,
|
|
12
|
+
Container,
|
|
13
|
+
Paper
|
|
14
|
+
} from '@mui/material';
|
|
15
|
+
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
|
|
16
|
+
import HomeIcon from '@mui/icons-material/Home';
|
|
17
|
+
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
18
|
+
|
|
19
|
+
interface DefaultNotFoundProps {
|
|
20
|
+
title?: string;
|
|
21
|
+
message?: string;
|
|
22
|
+
showHomeButton?: boolean;
|
|
23
|
+
showBackButton?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const DefaultNotFound: React.FC<DefaultNotFoundProps> = ({
|
|
27
|
+
title = 'Page Not Found',
|
|
28
|
+
message = 'The page you are looking for does not exist or has been moved.',
|
|
29
|
+
showHomeButton = true,
|
|
30
|
+
showBackButton = true,
|
|
31
|
+
}) => {
|
|
32
|
+
const navigate = useNavigate();
|
|
33
|
+
|
|
34
|
+
const handleGoBack = () => {
|
|
35
|
+
navigate(-1);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const handleGoHome = () => {
|
|
39
|
+
navigate('/');
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Container maxWidth="sm">
|
|
44
|
+
<Paper
|
|
45
|
+
elevation={0}
|
|
46
|
+
sx={{
|
|
47
|
+
p: 4,
|
|
48
|
+
textAlign: 'center',
|
|
49
|
+
mt: 8
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
<ErrorOutlineIcon
|
|
53
|
+
color="warning"
|
|
54
|
+
sx={{ fontSize: 100, mb: 3 }}
|
|
55
|
+
/>
|
|
56
|
+
|
|
57
|
+
<Typography variant="h1" component="h1" sx={{ fontWeight: 'bold', mb: 2 }}>
|
|
58
|
+
404
|
|
59
|
+
</Typography>
|
|
60
|
+
|
|
61
|
+
<Typography variant="h5" component="h2" gutterBottom>
|
|
62
|
+
{title}
|
|
63
|
+
</Typography>
|
|
64
|
+
|
|
65
|
+
<Typography variant="body1" color="textSecondary" paragraph>
|
|
66
|
+
{message}
|
|
67
|
+
</Typography>
|
|
68
|
+
|
|
69
|
+
<Box sx={{ mt: 4, display: 'flex', justifyContent: 'center', gap: 2, flexWrap: 'wrap' }}>
|
|
70
|
+
{showBackButton && (
|
|
71
|
+
<Button
|
|
72
|
+
variant="outlined"
|
|
73
|
+
startIcon={<ArrowBackIcon />}
|
|
74
|
+
onClick={handleGoBack}
|
|
75
|
+
>
|
|
76
|
+
Go Back
|
|
77
|
+
</Button>
|
|
78
|
+
)}
|
|
79
|
+
|
|
80
|
+
{showHomeButton && (
|
|
81
|
+
<Button
|
|
82
|
+
variant="contained"
|
|
83
|
+
color="primary"
|
|
84
|
+
startIcon={<HomeIcon />}
|
|
85
|
+
onClick={handleGoHome}
|
|
86
|
+
>
|
|
87
|
+
Go to Home
|
|
88
|
+
</Button>
|
|
89
|
+
)}
|
|
90
|
+
</Box>
|
|
91
|
+
</Paper>
|
|
92
|
+
</Container>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export default DefaultNotFound;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Server Error Page (500)
|
|
3
|
+
*
|
|
4
|
+
* Page displayed when a server error occurs.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { useNavigate } from 'react-router-dom';
|
|
8
|
+
import {
|
|
9
|
+
Box,
|
|
10
|
+
Typography,
|
|
11
|
+
Button,
|
|
12
|
+
Container,
|
|
13
|
+
Paper
|
|
14
|
+
} from '@mui/material';
|
|
15
|
+
import ReportProblemIcon from '@mui/icons-material/ReportProblem';
|
|
16
|
+
import HomeIcon from '@mui/icons-material/Home';
|
|
17
|
+
import RefreshIcon from '@mui/icons-material/Refresh';
|
|
18
|
+
|
|
19
|
+
interface DefaultServerErrorProps {
|
|
20
|
+
title?: string;
|
|
21
|
+
message?: string;
|
|
22
|
+
showHomeButton?: boolean;
|
|
23
|
+
showRetryButton?: boolean;
|
|
24
|
+
onRetry?: () => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const DefaultServerError: React.FC<DefaultServerErrorProps> = ({
|
|
28
|
+
title = 'Server Error',
|
|
29
|
+
message = 'Something went wrong on our end. Please try again later.',
|
|
30
|
+
showHomeButton = true,
|
|
31
|
+
showRetryButton = true,
|
|
32
|
+
onRetry,
|
|
33
|
+
}) => {
|
|
34
|
+
const navigate = useNavigate();
|
|
35
|
+
|
|
36
|
+
const handleRetry = () => {
|
|
37
|
+
if (onRetry) {
|
|
38
|
+
onRetry();
|
|
39
|
+
} else {
|
|
40
|
+
window.location.reload();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const handleGoHome = () => {
|
|
45
|
+
navigate('/');
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Container maxWidth="sm">
|
|
50
|
+
<Paper
|
|
51
|
+
elevation={0}
|
|
52
|
+
sx={{
|
|
53
|
+
p: 4,
|
|
54
|
+
textAlign: 'center',
|
|
55
|
+
mt: 8
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
<ReportProblemIcon
|
|
59
|
+
color="error"
|
|
60
|
+
sx={{ fontSize: 100, mb: 3 }}
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
<Typography variant="h1" component="h1" sx={{ fontWeight: 'bold', mb: 2 }}>
|
|
64
|
+
500
|
|
65
|
+
</Typography>
|
|
66
|
+
|
|
67
|
+
<Typography variant="h5" component="h2" gutterBottom>
|
|
68
|
+
{title}
|
|
69
|
+
</Typography>
|
|
70
|
+
|
|
71
|
+
<Typography variant="body1" color="textSecondary" paragraph>
|
|
72
|
+
{message}
|
|
73
|
+
</Typography>
|
|
74
|
+
|
|
75
|
+
<Box sx={{ mt: 4, display: 'flex', justifyContent: 'center', gap: 2, flexWrap: 'wrap' }}>
|
|
76
|
+
{showRetryButton && (
|
|
77
|
+
<Button
|
|
78
|
+
variant="contained"
|
|
79
|
+
color="primary"
|
|
80
|
+
startIcon={<RefreshIcon />}
|
|
81
|
+
onClick={handleRetry}
|
|
82
|
+
>
|
|
83
|
+
Try Again
|
|
84
|
+
</Button>
|
|
85
|
+
)}
|
|
86
|
+
|
|
87
|
+
{showHomeButton && (
|
|
88
|
+
<Button
|
|
89
|
+
variant="outlined"
|
|
90
|
+
startIcon={<HomeIcon />}
|
|
91
|
+
onClick={handleGoHome}
|
|
92
|
+
>
|
|
93
|
+
Go to Home
|
|
94
|
+
</Button>
|
|
95
|
+
)}
|
|
96
|
+
</Box>
|
|
97
|
+
</Paper>
|
|
98
|
+
</Container>
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export default DefaultServerError;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Unauthorized Page (403)
|
|
3
|
+
*
|
|
4
|
+
* Page displayed when a user lacks permission to access a resource.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { useNavigate } from 'react-router-dom';
|
|
8
|
+
import {
|
|
9
|
+
Box,
|
|
10
|
+
Typography,
|
|
11
|
+
Button,
|
|
12
|
+
Container,
|
|
13
|
+
Paper
|
|
14
|
+
} from '@mui/material';
|
|
15
|
+
import LockIcon from '@mui/icons-material/Lock';
|
|
16
|
+
import HomeIcon from '@mui/icons-material/Home';
|
|
17
|
+
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
18
|
+
import LoginIcon from '@mui/icons-material/Login';
|
|
19
|
+
|
|
20
|
+
interface DefaultUnauthorizedProps {
|
|
21
|
+
title?: string;
|
|
22
|
+
message?: string;
|
|
23
|
+
showHomeButton?: boolean;
|
|
24
|
+
showBackButton?: boolean;
|
|
25
|
+
showLoginButton?: boolean;
|
|
26
|
+
isLoggedIn?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const DefaultUnauthorized: React.FC<DefaultUnauthorizedProps> = ({
|
|
30
|
+
title = 'Access Denied',
|
|
31
|
+
message = 'You do not have permission to access this page.',
|
|
32
|
+
showHomeButton = true,
|
|
33
|
+
showBackButton = true,
|
|
34
|
+
showLoginButton = true,
|
|
35
|
+
isLoggedIn = false,
|
|
36
|
+
}) => {
|
|
37
|
+
const navigate = useNavigate();
|
|
38
|
+
|
|
39
|
+
const handleGoBack = () => {
|
|
40
|
+
navigate(-1);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const handleGoHome = () => {
|
|
44
|
+
navigate('/');
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleGoLogin = () => {
|
|
48
|
+
navigate('/login');
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<Container maxWidth="sm">
|
|
53
|
+
<Paper
|
|
54
|
+
elevation={0}
|
|
55
|
+
sx={{
|
|
56
|
+
p: 4,
|
|
57
|
+
textAlign: 'center',
|
|
58
|
+
mt: 8
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
<LockIcon
|
|
62
|
+
color="error"
|
|
63
|
+
sx={{ fontSize: 100, mb: 3 }}
|
|
64
|
+
/>
|
|
65
|
+
|
|
66
|
+
<Typography variant="h1" component="h1" sx={{ fontWeight: 'bold', mb: 2 }}>
|
|
67
|
+
403
|
|
68
|
+
</Typography>
|
|
69
|
+
|
|
70
|
+
<Typography variant="h5" component="h2" gutterBottom>
|
|
71
|
+
{title}
|
|
72
|
+
</Typography>
|
|
73
|
+
|
|
74
|
+
<Typography variant="body1" color="textSecondary" paragraph>
|
|
75
|
+
{message}
|
|
76
|
+
</Typography>
|
|
77
|
+
|
|
78
|
+
<Box sx={{ mt: 4, display: 'flex', justifyContent: 'center', gap: 2, flexWrap: 'wrap' }}>
|
|
79
|
+
{showBackButton && (
|
|
80
|
+
<Button
|
|
81
|
+
variant="outlined"
|
|
82
|
+
startIcon={<ArrowBackIcon />}
|
|
83
|
+
onClick={handleGoBack}
|
|
84
|
+
>
|
|
85
|
+
Go Back
|
|
86
|
+
</Button>
|
|
87
|
+
)}
|
|
88
|
+
|
|
89
|
+
{showHomeButton && (
|
|
90
|
+
<Button
|
|
91
|
+
variant="contained"
|
|
92
|
+
color="primary"
|
|
93
|
+
startIcon={<HomeIcon />}
|
|
94
|
+
onClick={handleGoHome}
|
|
95
|
+
>
|
|
96
|
+
Go to Home
|
|
97
|
+
</Button>
|
|
98
|
+
)}
|
|
99
|
+
|
|
100
|
+
{showLoginButton && !isLoggedIn && (
|
|
101
|
+
<Button
|
|
102
|
+
variant="outlined"
|
|
103
|
+
color="primary"
|
|
104
|
+
startIcon={<LoginIcon />}
|
|
105
|
+
onClick={handleGoLogin}
|
|
106
|
+
>
|
|
107
|
+
Login
|
|
108
|
+
</Button>
|
|
109
|
+
)}
|
|
110
|
+
</Box>
|
|
111
|
+
</Paper>
|
|
112
|
+
</Container>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export default DefaultUnauthorized;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Misc Pages Module
|
|
3
|
+
*
|
|
4
|
+
* Exports all default miscellaneous pages (error pages, etc).
|
|
5
|
+
*/
|
|
6
|
+
export { default as DashDefaultNotFound } from './DashDefaultNotFound';
|
|
7
|
+
export { default as DashDefaultUnauthorized } from './DashDefaultUnauthorized';
|
|
8
|
+
export { default as DashDefaultServerError } from './DashDefaultServerError';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Privacy Policy Page
|
|
3
|
+
*
|
|
4
|
+
* Privacy policy page template.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import DashDefaultStaticPage from './DashDefaultStaticPage';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
interface DefaultPrivacyPageProps {
|
|
11
|
+
companyName?: string;
|
|
12
|
+
effectiveDate?: string;
|
|
13
|
+
contactEmail?: string;
|
|
14
|
+
content?: string | React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const DefaultPrivacyPage: React.FC<DefaultPrivacyPageProps> = ({
|
|
18
|
+
companyName = 'Our Company',
|
|
19
|
+
effectiveDate = new Date().toLocaleDateString(),
|
|
20
|
+
contactEmail = 'privacy@example.com',
|
|
21
|
+
content,
|
|
22
|
+
}) => {
|
|
23
|
+
const defaultContent = (
|
|
24
|
+
<div>
|
|
25
|
+
<p><strong>Effective Date:</strong> {effectiveDate}</p>
|
|
26
|
+
|
|
27
|
+
<h2>1. Information We Collect</h2>
|
|
28
|
+
<p>
|
|
29
|
+
We collect information you provide directly to us, such as when you create an
|
|
30
|
+
account, make a purchase, or contact us for support.
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
<h2>2. How We Use Your Information</h2>
|
|
34
|
+
<p>
|
|
35
|
+
We use the information we collect to provide, maintain, and improve our services,
|
|
36
|
+
process transactions, and send you technical notices and support messages.
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
<h2>3. Information Sharing</h2>
|
|
40
|
+
<p>
|
|
41
|
+
We do not share your personal information with third parties except as described
|
|
42
|
+
in this privacy policy or with your consent.
|
|
43
|
+
</p>
|
|
44
|
+
|
|
45
|
+
<h2>4. Data Security</h2>
|
|
46
|
+
<p>
|
|
47
|
+
We take reasonable measures to help protect information about you from loss, theft,
|
|
48
|
+
misuse, unauthorized access, disclosure, alteration, and destruction.
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<h2>5. Your Rights</h2>
|
|
52
|
+
<p>
|
|
53
|
+
You have the right to access, correct, or delete your personal information.
|
|
54
|
+
You may also have the right to restrict or object to certain processing of your data.
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
<h2>6. Cookies</h2>
|
|
58
|
+
<p>
|
|
59
|
+
We use cookies and similar tracking technologies to track activity on our service
|
|
60
|
+
and hold certain information to improve and analyze our service.
|
|
61
|
+
</p>
|
|
62
|
+
|
|
63
|
+
<h2>7. Changes to This Policy</h2>
|
|
64
|
+
<p>
|
|
65
|
+
We may update this privacy policy from time to time. We will notify you of any
|
|
66
|
+
changes by posting the new privacy policy on this page.
|
|
67
|
+
</p>
|
|
68
|
+
|
|
69
|
+
<h2>8. Contact Us</h2>
|
|
70
|
+
<p>
|
|
71
|
+
If you have any questions about this Privacy Policy, please contact us at{' '}
|
|
72
|
+
<a href={`mailto:${contactEmail}`}>{contactEmail}</a>.
|
|
73
|
+
</p>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<DashDefaultStaticPage
|
|
79
|
+
title="Privacy Policy"
|
|
80
|
+
content={content || defaultContent}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export default DefaultPrivacyPage;
|