init commit,
This commit is contained in:
168
03_source/frontend/src/routes/components/error-boundary.tsx
Normal file
168
03_source/frontend/src/routes/components/error-boundary.tsx
Normal file
@@ -0,0 +1,168 @@
|
||||
import type { Theme, CSSObject } from '@mui/material/styles';
|
||||
|
||||
import { useRouteError, isRouteErrorResponse } from 'react-router';
|
||||
|
||||
import GlobalStyles from '@mui/material/GlobalStyles';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function ErrorBoundary() {
|
||||
const error = useRouteError();
|
||||
|
||||
return (
|
||||
<>
|
||||
{inputGlobalStyles()}
|
||||
|
||||
<div className={errorBoundaryClasses.root}>
|
||||
<div className={errorBoundaryClasses.container}>{renderErrorMessage(error)}</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function parseStackTrace(stack?: string) {
|
||||
if (!stack) return { filePath: null, functionName: null };
|
||||
|
||||
const filePathMatch = stack.match(/\/src\/[^?]+/);
|
||||
const functionNameMatch = stack.match(/at (\S+)/);
|
||||
|
||||
return {
|
||||
filePath: filePathMatch ? filePathMatch[0] : null,
|
||||
functionName: functionNameMatch ? functionNameMatch[1] : null,
|
||||
};
|
||||
}
|
||||
|
||||
function renderErrorMessage(error: any) {
|
||||
if (isRouteErrorResponse(error)) {
|
||||
return (
|
||||
<>
|
||||
<h1 className={errorBoundaryClasses.title}>
|
||||
{error.status}: {error.statusText}
|
||||
</h1>
|
||||
<p className={errorBoundaryClasses.message}>{error.data}</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (error instanceof Error) {
|
||||
const { filePath, functionName } = parseStackTrace(error.stack);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className={errorBoundaryClasses.title}>Unexpected Application Error!</h1>
|
||||
<p className={errorBoundaryClasses.message}>
|
||||
{error.name}: {error.message}
|
||||
</p>
|
||||
<pre className={errorBoundaryClasses.details}>{error.stack}</pre>
|
||||
{(filePath || functionName) && (
|
||||
<p className={errorBoundaryClasses.filePath}>
|
||||
{filePath} ({functionName})
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return <h1 className={errorBoundaryClasses.title}>Unknown Error</h1>;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const errorBoundaryClasses = {
|
||||
root: 'error-boundary-root',
|
||||
container: 'error-boundary-container',
|
||||
title: 'error-boundary-title',
|
||||
details: 'error-boundary-details',
|
||||
message: 'error-boundary-message',
|
||||
filePath: 'error-boundary-file-path',
|
||||
};
|
||||
|
||||
const cssVars: CSSObject = {
|
||||
'--info-color': '#2dd9da',
|
||||
'--warning-color': '#e2aa53',
|
||||
'--error-color': '#ff5555',
|
||||
'--error-background': '#2a1e1e',
|
||||
'--details-background': '#111111',
|
||||
'--root-background': '#2c2c2e',
|
||||
'--container-background': '#1c1c1e',
|
||||
'--font-stack-monospace':
|
||||
'"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',
|
||||
'--font-stack-sans':
|
||||
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',
|
||||
};
|
||||
|
||||
const rootStyles = (): CSSObject => ({
|
||||
display: 'flex',
|
||||
flex: '1 1 auto',
|
||||
alignItems: 'center',
|
||||
padding: '10vh 15px 0',
|
||||
flexDirection: 'column',
|
||||
fontFamily: 'var(--font-stack-sans)',
|
||||
});
|
||||
|
||||
const contentStyles = (): CSSObject => ({
|
||||
gap: 24,
|
||||
padding: 20,
|
||||
width: '100%',
|
||||
maxWidth: 960,
|
||||
display: 'flex',
|
||||
borderRadius: 8,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: 'var(--container-background)',
|
||||
});
|
||||
|
||||
const titleStyles = (theme: Theme): CSSObject => ({
|
||||
margin: 0,
|
||||
lineHeight: 1.2,
|
||||
fontSize: theme.typography.pxToRem(20),
|
||||
fontWeight: theme.typography.fontWeightBold,
|
||||
});
|
||||
|
||||
const messageStyles = (theme: Theme): CSSObject => ({
|
||||
margin: 0,
|
||||
lineHeight: 1.5,
|
||||
padding: '12px 16px',
|
||||
whiteSpace: 'pre-wrap',
|
||||
color: 'var(--error-color)',
|
||||
fontSize: theme.typography.pxToRem(14),
|
||||
fontFamily: 'var(--font-stack-monospace)',
|
||||
backgroundColor: 'var(--error-background)',
|
||||
borderLeft: '2px solid var(--error-color)',
|
||||
fontWeight: theme.typography.fontWeightBold,
|
||||
});
|
||||
|
||||
const detailsStyles = (): CSSObject => ({
|
||||
margin: 0,
|
||||
padding: 16,
|
||||
lineHeight: 1.5,
|
||||
overflow: 'auto',
|
||||
borderRadius: 'inherit',
|
||||
color: 'var(--warning-color)',
|
||||
backgroundColor: 'var(--details-background)',
|
||||
});
|
||||
|
||||
const filePathStyles = (): CSSObject => ({
|
||||
marginTop: 0,
|
||||
color: 'var(--info-color)',
|
||||
});
|
||||
|
||||
const inputGlobalStyles = () => (
|
||||
<GlobalStyles
|
||||
styles={(theme) => ({
|
||||
body: {
|
||||
...cssVars,
|
||||
margin: 0,
|
||||
color: 'white',
|
||||
backgroundColor: 'var(--root-background)',
|
||||
[`& .${errorBoundaryClasses.root}`]: rootStyles(),
|
||||
[`& .${errorBoundaryClasses.container}`]: contentStyles(),
|
||||
[`& .${errorBoundaryClasses.title}`]: titleStyles(theme),
|
||||
[`& .${errorBoundaryClasses.message}`]: messageStyles(theme),
|
||||
[`& .${errorBoundaryClasses.filePath}`]: filePathStyles(),
|
||||
[`& .${errorBoundaryClasses.details}`]: detailsStyles(),
|
||||
},
|
||||
})}
|
||||
/>
|
||||
);
|
3
03_source/frontend/src/routes/components/index.ts
Normal file
3
03_source/frontend/src/routes/components/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './router-link';
|
||||
|
||||
export * from './error-boundary';
|
14
03_source/frontend/src/routes/components/router-link.tsx
Normal file
14
03_source/frontend/src/routes/components/router-link.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { LinkProps } from 'react-router';
|
||||
|
||||
import { Link } from 'react-router';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
interface RouterLinkProps extends Omit<LinkProps, 'to'> {
|
||||
href: string;
|
||||
ref?: React.RefObject<HTMLAnchorElement | null>;
|
||||
}
|
||||
|
||||
export function RouterLink({ href, ref, ...other }: RouterLinkProps) {
|
||||
return <Link ref={ref} to={href} {...other} />;
|
||||
}
|
7
03_source/frontend/src/routes/hooks/index.ts
Normal file
7
03_source/frontend/src/routes/hooks/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export { useParams } from './use-params';
|
||||
|
||||
export { useRouter } from './use-router';
|
||||
|
||||
export { usePathname } from './use-pathname';
|
||||
|
||||
export { useSearchParams } from './use-search-params';
|
10
03_source/frontend/src/routes/hooks/use-params.ts
Normal file
10
03_source/frontend/src/routes/hooks/use-params.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useParams as _useParams } from 'react-router';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function useParams() {
|
||||
const params = _useParams();
|
||||
|
||||
return useMemo(() => params, [params]);
|
||||
}
|
10
03_source/frontend/src/routes/hooks/use-pathname.ts
Normal file
10
03_source/frontend/src/routes/hooks/use-pathname.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useLocation } from 'react-router';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function usePathname() {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
return useMemo(() => pathname, [pathname]);
|
||||
}
|
21
03_source/frontend/src/routes/hooks/use-router.ts
Normal file
21
03_source/frontend/src/routes/hooks/use-router.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function useRouter() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const router = useMemo(
|
||||
() => ({
|
||||
back: () => navigate(-1),
|
||||
forward: () => navigate(1),
|
||||
refresh: () => navigate(0),
|
||||
push: (href: string) => navigate(href),
|
||||
replace: (href: string) => navigate(href, { replace: true }),
|
||||
}),
|
||||
[navigate]
|
||||
);
|
||||
|
||||
return router;
|
||||
}
|
10
03_source/frontend/src/routes/hooks/use-search-params.ts
Normal file
10
03_source/frontend/src/routes/hooks/use-search-params.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useSearchParams as _useSearchParams } from 'react-router';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function useSearchParams() {
|
||||
const [searchParams] = _useSearchParams();
|
||||
|
||||
return useMemo(() => searchParams, [searchParams]);
|
||||
}
|
176
03_source/frontend/src/routes/paths.ts
Normal file
176
03_source/frontend/src/routes/paths.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import { kebabCase } from 'es-toolkit';
|
||||
|
||||
import { _id, _postTitles } from 'src/_mock/assets';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const MOCK_ID = _id[1];
|
||||
const MOCK_TITLE = _postTitles[2];
|
||||
|
||||
const ROOTS = {
|
||||
AUTH: '/auth',
|
||||
AUTH_DEMO: '/auth-demo',
|
||||
DASHBOARD: '/dashboard',
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export const paths = {
|
||||
comingSoon: '/coming-soon',
|
||||
maintenance: '/maintenance',
|
||||
pricing: '/pricing',
|
||||
payment: '/payment',
|
||||
about: '/about-us',
|
||||
contact: '/contact-us',
|
||||
faqs: '/faqs',
|
||||
page403: '/error/403',
|
||||
page404: '/error/404',
|
||||
page500: '/error/500',
|
||||
components: '/components',
|
||||
docs: 'https://docs.minimals.cc/',
|
||||
changelog: 'https://docs.minimals.cc/changelog/',
|
||||
zoneStore: 'https://mui.com/store/items/zone-landing-page/',
|
||||
minimalStore: 'https://mui.com/store/items/minimal-dashboard/',
|
||||
freeUI: 'https://mui.com/store/items/minimal-dashboard-free/',
|
||||
figmaUrl: 'https://www.figma.com/design/oAxS3CUFO0ou7rH2lTS8oI/%5BPreview%5D-Minimal-Web.v7.0.0',
|
||||
product: {
|
||||
root: `/product`,
|
||||
checkout: `/product/checkout`,
|
||||
details: (id: string) => `/product/${id}`,
|
||||
demo: { details: `/product/${MOCK_ID}` },
|
||||
},
|
||||
post: {
|
||||
root: `/post`,
|
||||
details: (title: string) => `/post/${kebabCase(title)}`,
|
||||
demo: { details: `/post/${kebabCase(MOCK_TITLE)}` },
|
||||
},
|
||||
// AUTH
|
||||
auth: {
|
||||
amplify: {
|
||||
signIn: `${ROOTS.AUTH}/amplify/sign-in`,
|
||||
verify: `${ROOTS.AUTH}/amplify/verify`,
|
||||
signUp: `${ROOTS.AUTH}/amplify/sign-up`,
|
||||
updatePassword: `${ROOTS.AUTH}/amplify/update-password`,
|
||||
resetPassword: `${ROOTS.AUTH}/amplify/reset-password`,
|
||||
},
|
||||
jwt: {
|
||||
signIn: `${ROOTS.AUTH}/jwt/sign-in`,
|
||||
signUp: `${ROOTS.AUTH}/jwt/sign-up`,
|
||||
},
|
||||
firebase: {
|
||||
signIn: `${ROOTS.AUTH}/firebase/sign-in`,
|
||||
verify: `${ROOTS.AUTH}/firebase/verify`,
|
||||
signUp: `${ROOTS.AUTH}/firebase/sign-up`,
|
||||
resetPassword: `${ROOTS.AUTH}/firebase/reset-password`,
|
||||
},
|
||||
auth0: { signIn: `${ROOTS.AUTH}/auth0/sign-in` },
|
||||
supabase: {
|
||||
signIn: `${ROOTS.AUTH}/supabase/sign-in`,
|
||||
verify: `${ROOTS.AUTH}/supabase/verify`,
|
||||
signUp: `${ROOTS.AUTH}/supabase/sign-up`,
|
||||
updatePassword: `${ROOTS.AUTH}/supabase/update-password`,
|
||||
resetPassword: `${ROOTS.AUTH}/supabase/reset-password`,
|
||||
},
|
||||
},
|
||||
authDemo: {
|
||||
split: {
|
||||
signIn: `${ROOTS.AUTH_DEMO}/split/sign-in`,
|
||||
signUp: `${ROOTS.AUTH_DEMO}/split/sign-up`,
|
||||
resetPassword: `${ROOTS.AUTH_DEMO}/split/reset-password`,
|
||||
updatePassword: `${ROOTS.AUTH_DEMO}/split/update-password`,
|
||||
verify: `${ROOTS.AUTH_DEMO}/split/verify`,
|
||||
},
|
||||
centered: {
|
||||
signIn: `${ROOTS.AUTH_DEMO}/centered/sign-in`,
|
||||
signUp: `${ROOTS.AUTH_DEMO}/centered/sign-up`,
|
||||
resetPassword: `${ROOTS.AUTH_DEMO}/centered/reset-password`,
|
||||
updatePassword: `${ROOTS.AUTH_DEMO}/centered/update-password`,
|
||||
verify: `${ROOTS.AUTH_DEMO}/centered/verify`,
|
||||
},
|
||||
},
|
||||
// DASHBOARD
|
||||
dashboard: {
|
||||
root: ROOTS.DASHBOARD,
|
||||
mail: `${ROOTS.DASHBOARD}/mail`,
|
||||
chat: `${ROOTS.DASHBOARD}/chat`,
|
||||
blank: `${ROOTS.DASHBOARD}/blank`,
|
||||
kanban: `${ROOTS.DASHBOARD}/kanban`,
|
||||
calendar: `${ROOTS.DASHBOARD}/calendar`,
|
||||
fileManager: `${ROOTS.DASHBOARD}/file-manager`,
|
||||
permission: `${ROOTS.DASHBOARD}/permission`,
|
||||
general: {
|
||||
app: `${ROOTS.DASHBOARD}/app`,
|
||||
ecommerce: `${ROOTS.DASHBOARD}/ecommerce`,
|
||||
analytics: `${ROOTS.DASHBOARD}/analytics`,
|
||||
banking: `${ROOTS.DASHBOARD}/banking`,
|
||||
booking: `${ROOTS.DASHBOARD}/booking`,
|
||||
file: `${ROOTS.DASHBOARD}/file`,
|
||||
course: `${ROOTS.DASHBOARD}/course`,
|
||||
},
|
||||
user: {
|
||||
root: `${ROOTS.DASHBOARD}/user`,
|
||||
new: `${ROOTS.DASHBOARD}/user/new`,
|
||||
list: `${ROOTS.DASHBOARD}/user/list`,
|
||||
cards: `${ROOTS.DASHBOARD}/user/cards`,
|
||||
profile: `${ROOTS.DASHBOARD}/user/profile`,
|
||||
account: `${ROOTS.DASHBOARD}/user/account`,
|
||||
edit: (id: string) => `${ROOTS.DASHBOARD}/user/${id}/edit`,
|
||||
demo: { edit: `${ROOTS.DASHBOARD}/user/${MOCK_ID}/edit` },
|
||||
},
|
||||
product: {
|
||||
root: `${ROOTS.DASHBOARD}/product`,
|
||||
new: `${ROOTS.DASHBOARD}/product/new`,
|
||||
details: (id: string) => `${ROOTS.DASHBOARD}/product/${id}`,
|
||||
edit: (id: string) => `${ROOTS.DASHBOARD}/product/${id}/edit`,
|
||||
demo: {
|
||||
details: `${ROOTS.DASHBOARD}/product/${MOCK_ID}`,
|
||||
edit: `${ROOTS.DASHBOARD}/product/${MOCK_ID}/edit`,
|
||||
},
|
||||
},
|
||||
invoice: {
|
||||
root: `${ROOTS.DASHBOARD}/invoice`,
|
||||
new: `${ROOTS.DASHBOARD}/invoice/new`,
|
||||
details: (id: string) => `${ROOTS.DASHBOARD}/invoice/${id}`,
|
||||
edit: (id: string) => `${ROOTS.DASHBOARD}/invoice/${id}/edit`,
|
||||
demo: {
|
||||
details: `${ROOTS.DASHBOARD}/invoice/${MOCK_ID}`,
|
||||
edit: `${ROOTS.DASHBOARD}/invoice/${MOCK_ID}/edit`,
|
||||
},
|
||||
},
|
||||
post: {
|
||||
root: `${ROOTS.DASHBOARD}/post`,
|
||||
new: `${ROOTS.DASHBOARD}/post/new`,
|
||||
details: (title: string) => `${ROOTS.DASHBOARD}/post/${kebabCase(title)}`,
|
||||
edit: (title: string) => `${ROOTS.DASHBOARD}/post/${kebabCase(title)}/edit`,
|
||||
demo: {
|
||||
details: `${ROOTS.DASHBOARD}/post/${kebabCase(MOCK_TITLE)}`,
|
||||
edit: `${ROOTS.DASHBOARD}/post/${kebabCase(MOCK_TITLE)}/edit`,
|
||||
},
|
||||
},
|
||||
order: {
|
||||
root: `${ROOTS.DASHBOARD}/order`,
|
||||
details: (id: string) => `${ROOTS.DASHBOARD}/order/${id}`,
|
||||
demo: { details: `${ROOTS.DASHBOARD}/order/${MOCK_ID}` },
|
||||
},
|
||||
job: {
|
||||
root: `${ROOTS.DASHBOARD}/job`,
|
||||
new: `${ROOTS.DASHBOARD}/job/new`,
|
||||
details: (id: string) => `${ROOTS.DASHBOARD}/job/${id}`,
|
||||
edit: (id: string) => `${ROOTS.DASHBOARD}/job/${id}/edit`,
|
||||
demo: {
|
||||
details: `${ROOTS.DASHBOARD}/job/${MOCK_ID}`,
|
||||
edit: `${ROOTS.DASHBOARD}/job/${MOCK_ID}/edit`,
|
||||
},
|
||||
},
|
||||
tour: {
|
||||
root: `${ROOTS.DASHBOARD}/tour`,
|
||||
new: `${ROOTS.DASHBOARD}/tour/new`,
|
||||
details: (id: string) => `${ROOTS.DASHBOARD}/tour/${id}`,
|
||||
edit: (id: string) => `${ROOTS.DASHBOARD}/tour/${id}/edit`,
|
||||
demo: {
|
||||
details: `${ROOTS.DASHBOARD}/tour/${MOCK_ID}`,
|
||||
edit: `${ROOTS.DASHBOARD}/tour/${MOCK_ID}/edit`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
113
03_source/frontend/src/routes/sections/auth-demo.tsx
Normal file
113
03_source/frontend/src/routes/sections/auth-demo.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
import type { RouteObject } from 'react-router';
|
||||
|
||||
import { Outlet } from 'react-router';
|
||||
import { lazy, Suspense } from 'react';
|
||||
|
||||
import { AuthSplitLayout } from 'src/layouts/auth-split';
|
||||
import { AuthCenteredLayout } from 'src/layouts/auth-centered';
|
||||
|
||||
import { SplashScreen } from 'src/components/loading-screen';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/** **************************************
|
||||
* Split layout
|
||||
*************************************** */
|
||||
const SplitLayout = {
|
||||
SignInPage: lazy(() => import('src/pages/auth-demo/split/sign-in')),
|
||||
SignUpPage: lazy(() => import('src/pages/auth-demo/split/sign-up')),
|
||||
VerifyPage: lazy(() => import('src/pages/auth-demo/split/verify')),
|
||||
ResetPasswordPage: lazy(() => import('src/pages/auth-demo/split/reset-password')),
|
||||
UpdatePasswordPage: lazy(() => import('src/pages/auth-demo/split/update-password')),
|
||||
};
|
||||
|
||||
const authSplit = {
|
||||
path: 'split',
|
||||
children: [
|
||||
{
|
||||
path: 'sign-in',
|
||||
element: (
|
||||
<AuthSplitLayout
|
||||
slotProps={{
|
||||
section: { title: 'Hi, Welcome back' },
|
||||
}}
|
||||
>
|
||||
<SplitLayout.SignInPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'sign-up',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<SplitLayout.SignUpPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'verify',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<SplitLayout.VerifyPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'reset-password',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<SplitLayout.ResetPasswordPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'update-password',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<SplitLayout.UpdatePasswordPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/** **************************************
|
||||
* Centered layout
|
||||
*************************************** */
|
||||
const CenteredLayout = {
|
||||
SignInPage: lazy(() => import('src/pages/auth-demo/centered/sign-in')),
|
||||
SignUpPage: lazy(() => import('src/pages/auth-demo/centered/sign-up')),
|
||||
VerifyPage: lazy(() => import('src/pages/auth-demo/centered/verify')),
|
||||
ResetPasswordPage: lazy(() => import('src/pages/auth-demo/centered/reset-password')),
|
||||
UpdatePasswordPage: lazy(() => import('src/pages/auth-demo/centered/update-password')),
|
||||
};
|
||||
|
||||
const authCentered = {
|
||||
path: 'centered',
|
||||
element: (
|
||||
<AuthCenteredLayout>
|
||||
<Outlet />
|
||||
</AuthCenteredLayout>
|
||||
),
|
||||
children: [
|
||||
{ path: 'sign-in', element: <CenteredLayout.SignInPage /> },
|
||||
{ path: 'sign-up', element: <CenteredLayout.SignUpPage /> },
|
||||
{ path: 'verify', element: <CenteredLayout.VerifyPage /> },
|
||||
{ path: 'reset-password', element: <CenteredLayout.ResetPasswordPage /> },
|
||||
{ path: 'update-password', element: <CenteredLayout.UpdatePasswordPage /> },
|
||||
],
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export const authDemoRoutes: RouteObject[] = [
|
||||
{
|
||||
path: 'auth-demo',
|
||||
element: (
|
||||
<Suspense fallback={<SplashScreen />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
),
|
||||
children: [authSplit, authCentered],
|
||||
},
|
||||
];
|
286
03_source/frontend/src/routes/sections/auth.tsx
Normal file
286
03_source/frontend/src/routes/sections/auth.tsx
Normal file
@@ -0,0 +1,286 @@
|
||||
import type { RouteObject } from 'react-router';
|
||||
|
||||
import { Outlet } from 'react-router';
|
||||
import { lazy, Suspense } from 'react';
|
||||
|
||||
import { AuthSplitLayout } from 'src/layouts/auth-split';
|
||||
|
||||
import { SplashScreen } from 'src/components/loading-screen';
|
||||
|
||||
import { GuestGuard } from 'src/auth/guard';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/** **************************************
|
||||
* Jwt
|
||||
*************************************** */
|
||||
const Jwt = {
|
||||
SignInPage: lazy(() => import('src/pages/auth/jwt/sign-in')),
|
||||
SignUpPage: lazy(() => import('src/pages/auth/jwt/sign-up')),
|
||||
};
|
||||
|
||||
const authJwt = {
|
||||
path: 'jwt',
|
||||
children: [
|
||||
{
|
||||
path: 'sign-in',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout
|
||||
slotProps={{
|
||||
section: { title: 'Hi, Welcome back' },
|
||||
}}
|
||||
>
|
||||
<Jwt.SignInPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'sign-up',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout>
|
||||
<Jwt.SignUpPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/** **************************************
|
||||
* Amplify
|
||||
*************************************** */
|
||||
const Amplify = {
|
||||
SignInPage: lazy(() => import('src/pages/auth/amplify/sign-in')),
|
||||
SignUpPage: lazy(() => import('src/pages/auth/amplify/sign-up')),
|
||||
VerifyPage: lazy(() => import('src/pages/auth/amplify/verify')),
|
||||
UpdatePasswordPage: lazy(() => import('src/pages/auth/amplify/update-password')),
|
||||
ResetPasswordPage: lazy(() => import('src/pages/auth/amplify/reset-password')),
|
||||
};
|
||||
|
||||
const authAmplify = {
|
||||
path: 'amplify',
|
||||
children: [
|
||||
{
|
||||
path: 'sign-in',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout
|
||||
slotProps={{
|
||||
section: { title: 'Hi, Welcome back' },
|
||||
}}
|
||||
>
|
||||
<Amplify.SignInPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'sign-up',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout>
|
||||
<Amplify.SignUpPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'verify',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<Amplify.VerifyPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'reset-password',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<Amplify.ResetPasswordPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'update-password',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<Amplify.UpdatePasswordPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/** **************************************
|
||||
* Firebase
|
||||
*************************************** */
|
||||
const Firebase = {
|
||||
SignInPage: lazy(() => import('src/pages/auth/firebase/sign-in')),
|
||||
SignUpPage: lazy(() => import('src/pages/auth/firebase/sign-up')),
|
||||
VerifyPage: lazy(() => import('src/pages/auth/firebase/verify')),
|
||||
ResetPasswordPage: lazy(() => import('src/pages/auth/firebase/reset-password')),
|
||||
};
|
||||
|
||||
const authFirebase = {
|
||||
path: 'firebase',
|
||||
children: [
|
||||
{
|
||||
path: 'sign-in',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout
|
||||
slotProps={{
|
||||
section: { title: 'Hi, Welcome back' },
|
||||
}}
|
||||
>
|
||||
<Firebase.SignInPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'sign-up',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout>
|
||||
<Firebase.SignUpPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'verify',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<Firebase.VerifyPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'reset-password',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<Firebase.ResetPasswordPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/** **************************************
|
||||
* Auth0
|
||||
*************************************** */
|
||||
const Auth0 = {
|
||||
SignInPage: lazy(() => import('src/pages/auth/auth0/sign-in')),
|
||||
CallbackPage: lazy(() => import('src/pages/auth/auth0/callback')),
|
||||
};
|
||||
|
||||
const authAuth0 = {
|
||||
path: 'auth0',
|
||||
children: [
|
||||
{
|
||||
path: 'sign-in',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout
|
||||
slotProps={{
|
||||
section: { title: 'Hi, Welcome back' },
|
||||
}}
|
||||
>
|
||||
<Auth0.SignInPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'callback',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<Auth0.CallbackPage />
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/** **************************************
|
||||
* Supabase
|
||||
*************************************** */
|
||||
const Supabase = {
|
||||
SignInPage: lazy(() => import('src/pages/auth/supabase/sign-in')),
|
||||
SignUpPage: lazy(() => import('src/pages/auth/supabase/sign-up')),
|
||||
VerifyPage: lazy(() => import('src/pages/auth/supabase/verify')),
|
||||
UpdatePasswordPage: lazy(() => import('src/pages/auth/supabase/update-password')),
|
||||
ResetPasswordPage: lazy(() => import('src/pages/auth/supabase/reset-password')),
|
||||
};
|
||||
|
||||
const authSupabase = {
|
||||
path: 'supabase',
|
||||
children: [
|
||||
{
|
||||
path: 'sign-in',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout
|
||||
slotProps={{
|
||||
section: { title: 'Hi, Welcome back' },
|
||||
}}
|
||||
>
|
||||
<Supabase.SignInPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'sign-up',
|
||||
element: (
|
||||
<GuestGuard>
|
||||
<AuthSplitLayout>
|
||||
<Supabase.SignUpPage />
|
||||
</AuthSplitLayout>
|
||||
</GuestGuard>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'verify',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<Supabase.VerifyPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'reset-password',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<Supabase.ResetPasswordPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'update-password',
|
||||
element: (
|
||||
<AuthSplitLayout>
|
||||
<Supabase.UpdatePasswordPage />
|
||||
</AuthSplitLayout>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export const authRoutes: RouteObject[] = [
|
||||
{
|
||||
path: 'auth',
|
||||
element: (
|
||||
<Suspense fallback={<SplashScreen />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
),
|
||||
children: [authJwt, authAmplify, authFirebase, authAuth0, authSupabase],
|
||||
},
|
||||
];
|
169
03_source/frontend/src/routes/sections/components.tsx
Normal file
169
03_source/frontend/src/routes/sections/components.tsx
Normal file
@@ -0,0 +1,169 @@
|
||||
import type { RouteObject } from 'react-router';
|
||||
|
||||
import { lazy, Suspense } from 'react';
|
||||
import { Outlet, Navigate } from 'react-router';
|
||||
|
||||
import { MainLayout } from 'src/layouts/main';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const IndexPage = lazy(() => import('src/pages/components'));
|
||||
|
||||
// Foundation
|
||||
const GridPage = lazy(() => import('src/pages/components/foundation/grid'));
|
||||
const IconsPage = lazy(() => import('src/pages/components/foundation/icons'));
|
||||
const IconsIconifyPage = lazy(() => import('src/pages/components/foundation/icons/iconify'));
|
||||
const ColorsPage = lazy(() => import('src/pages/components/foundation/colors'));
|
||||
const ShadowsPage = lazy(() => import('src/pages/components/foundation/shadows'));
|
||||
const TypographyPage = lazy(() => import('src/pages/components/foundation/typography'));
|
||||
|
||||
// MUI components
|
||||
const ChipPage = lazy(() => import('src/pages/components/mui/chip'));
|
||||
const ListPage = lazy(() => import('src/pages/components/mui/list'));
|
||||
const MenuPage = lazy(() => import('src/pages/components/mui/menu'));
|
||||
const TabsPage = lazy(() => import('src/pages/components/mui/tabs'));
|
||||
const AlertPage = lazy(() => import('src/pages/components/mui/alert'));
|
||||
const BadgePage = lazy(() => import('src/pages/components/mui/badge'));
|
||||
const TablePage = lazy(() => import('src/pages/components/mui/table'));
|
||||
const AvatarPage = lazy(() => import('src/pages/components/mui/avatar'));
|
||||
const DialogPage = lazy(() => import('src/pages/components/mui/dialog'));
|
||||
const RatingPage = lazy(() => import('src/pages/components/mui/rating'));
|
||||
const SliderPage = lazy(() => import('src/pages/components/mui/slider'));
|
||||
const SwitchPage = lazy(() => import('src/pages/components/mui/switch'));
|
||||
const DrawerPage = lazy(() => import('src/pages/components/mui/drawer'));
|
||||
const ButtonsPage = lazy(() => import('src/pages/components/mui/buttons'));
|
||||
const PopoverPage = lazy(() => import('src/pages/components/mui/popover'));
|
||||
const StepperPage = lazy(() => import('src/pages/components/mui/stepper'));
|
||||
const TooltipPage = lazy(() => import('src/pages/components/mui/tooltip'));
|
||||
const CheckboxPage = lazy(() => import('src/pages/components/mui/checkbox'));
|
||||
const ProgressPage = lazy(() => import('src/pages/components/mui/progress'));
|
||||
const TimelinePage = lazy(() => import('src/pages/components/mui/timeline'));
|
||||
const AccordionPage = lazy(() => import('src/pages/components/mui/accordion'));
|
||||
const TextFieldPage = lazy(() => import('src/pages/components/mui/textfield'));
|
||||
const PaginationPage = lazy(() => import('src/pages/components/mui/pagination'));
|
||||
const BreadcrumbsPage = lazy(() => import('src/pages/components/mui/breadcrumbs'));
|
||||
const AutocompletePage = lazy(() => import('src/pages/components/mui/autocomplete'));
|
||||
const RadioButtonsPage = lazy(() => import('src/pages/components/mui/radio-button'));
|
||||
const TransferListPage = lazy(() => import('src/pages/components/mui/transfer-list'));
|
||||
// MUI X
|
||||
const TreeViewPage = lazy(() => import('src/pages/components/mui/tree-view'));
|
||||
const DataGridPage = lazy(() => import('src/pages/components/mui/data-grid'));
|
||||
const DatePickersPage = lazy(() => import('src/pages/components/mui/date-pickers'));
|
||||
|
||||
// Extra components
|
||||
const MapPage = lazy(() => import('src/pages/components/extra/map'));
|
||||
const DndPage = lazy(() => import('src/pages/components/extra/dnd'));
|
||||
const ChartPage = lazy(() => import('src/pages/components/extra/chart'));
|
||||
const ImagePage = lazy(() => import('src/pages/components/extra/image'));
|
||||
const LabelPage = lazy(() => import('src/pages/components/extra/label'));
|
||||
const LayoutPage = lazy(() => import('src/pages/components/extra/layout'));
|
||||
const EditorPage = lazy(() => import('src/pages/components/extra/editor'));
|
||||
const UploadPage = lazy(() => import('src/pages/components/extra/upload'));
|
||||
const AnimatePage = lazy(() => import('src/pages/components/extra/animate'));
|
||||
const ScrollbarPage = lazy(() => import('src/pages/components/extra/scroll'));
|
||||
const LightboxPage = lazy(() => import('src/pages/components/extra/lightbox'));
|
||||
const SnackbarPage = lazy(() => import('src/pages/components/extra/snackbar'));
|
||||
const MarkdownPage = lazy(() => import('src/pages/components/extra/markdown'));
|
||||
const CarouselsPage = lazy(() => import('src/pages/components/extra/carousel'));
|
||||
const MegaMenuPage = lazy(() => import('src/pages/components/extra/mega-menu'));
|
||||
const UtilitiesPage = lazy(() => import('src/pages/components/extra/utilities'));
|
||||
const FormWizardPage = lazy(() => import('src/pages/components/extra/form-wizard'));
|
||||
const OrgChartPage = lazy(() => import('src/pages/components/extra/organization-chart'));
|
||||
const MultiLanguagePage = lazy(() => import('src/pages/components/extra/multi-language'));
|
||||
const NavigationBarPage = lazy(() => import('src/pages/components/extra/navigation-bar'));
|
||||
const FormValidationPage = lazy(() => import('src/pages/components/extra/form-validation'));
|
||||
const ScrollProgressPage = lazy(() => import('src/pages/components/extra/scroll-progress'));
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export const componentsRoutes: RouteObject[] = [
|
||||
{
|
||||
path: 'components',
|
||||
element: (
|
||||
<Suspense>
|
||||
<MainLayout>
|
||||
<Outlet />
|
||||
</MainLayout>
|
||||
</Suspense>
|
||||
),
|
||||
children: [
|
||||
{ index: true, element: <IndexPage /> },
|
||||
{
|
||||
path: 'foundation',
|
||||
children: [
|
||||
{ index: true, element: <Navigate to="/components/foundation/colors" replace /> },
|
||||
{ path: 'grid', element: <GridPage /> },
|
||||
{ path: 'icons', element: <IconsPage /> },
|
||||
{ path: 'icons/iconify', element: <IconsIconifyPage /> },
|
||||
{ path: 'colors', element: <ColorsPage /> },
|
||||
{ path: 'shadows', element: <ShadowsPage /> },
|
||||
{ path: 'typography', element: <TypographyPage /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'mui',
|
||||
children: [
|
||||
{ index: true, element: <Navigate to="/components/mui/accordion" replace /> },
|
||||
{ path: 'chip', element: <ChipPage /> },
|
||||
{ path: 'list', element: <ListPage /> },
|
||||
{ path: 'menu', element: <MenuPage /> },
|
||||
{ path: 'tabs', element: <TabsPage /> },
|
||||
{ path: 'alert', element: <AlertPage /> },
|
||||
{ path: 'badge', element: <BadgePage /> },
|
||||
{ path: 'table', element: <TablePage /> },
|
||||
{ path: 'avatar', element: <AvatarPage /> },
|
||||
{ path: 'dialog', element: <DialogPage /> },
|
||||
{ path: 'rating', element: <RatingPage /> },
|
||||
{ path: 'slider', element: <SliderPage /> },
|
||||
{ path: 'switch', element: <SwitchPage /> },
|
||||
{ path: 'drawer', element: <DrawerPage /> },
|
||||
{ path: 'buttons', element: <ButtonsPage /> },
|
||||
{ path: 'popover', element: <PopoverPage /> },
|
||||
{ path: 'stepper', element: <StepperPage /> },
|
||||
{ path: 'tooltip', element: <TooltipPage /> },
|
||||
{ path: 'checkbox', element: <CheckboxPage /> },
|
||||
{ path: 'progress', element: <ProgressPage /> },
|
||||
{ path: 'timeline', element: <TimelinePage /> },
|
||||
{ path: 'data-grid', element: <DataGridPage /> },
|
||||
{ path: 'tree-view', element: <TreeViewPage /> },
|
||||
{ path: 'accordion', element: <AccordionPage /> },
|
||||
{ path: 'textfield', element: <TextFieldPage /> },
|
||||
{ path: 'pagination', element: <PaginationPage /> },
|
||||
{ path: 'breadcrumbs', element: <BreadcrumbsPage /> },
|
||||
{ path: 'date-pickers', element: <DatePickersPage /> },
|
||||
{ path: 'autocomplete', element: <AutocompletePage /> },
|
||||
{ path: 'radio-button', element: <RadioButtonsPage /> },
|
||||
{ path: 'transfer-list', element: <TransferListPage /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'extra',
|
||||
children: [
|
||||
{ index: true, element: <Navigate to="/components/extra/animate" replace /> },
|
||||
{ path: 'map', element: <MapPage /> },
|
||||
{ path: 'dnd', element: <DndPage /> },
|
||||
{ path: 'chart', element: <ChartPage /> },
|
||||
{ path: 'image', element: <ImagePage /> },
|
||||
{ path: 'label', element: <LabelPage /> },
|
||||
{ path: 'layout', element: <LayoutPage /> },
|
||||
{ path: 'editor', element: <EditorPage /> },
|
||||
{ path: 'upload', element: <UploadPage /> },
|
||||
{ path: 'animate', element: <AnimatePage /> },
|
||||
{ path: 'scroll', element: <ScrollbarPage /> },
|
||||
{ path: 'lightbox', element: <LightboxPage /> },
|
||||
{ path: 'snackbar', element: <SnackbarPage /> },
|
||||
{ path: 'markdown', element: <MarkdownPage /> },
|
||||
{ path: 'carousel', element: <CarouselsPage /> },
|
||||
{ path: 'mega-menu', element: <MegaMenuPage /> },
|
||||
{ path: 'utilities', element: <UtilitiesPage /> },
|
||||
{ path: 'form-wizard', element: <FormWizardPage /> },
|
||||
{ path: 'organization-chart', element: <OrgChartPage /> },
|
||||
{ path: 'multi-language', element: <MultiLanguagePage /> },
|
||||
{ path: 'navigation-bar', element: <NavigationBarPage /> },
|
||||
{ path: 'form-validation', element: <FormValidationPage /> },
|
||||
{ path: 'scroll-progress', element: <ScrollProgressPage /> },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
209
03_source/frontend/src/routes/sections/dashboard.tsx
Normal file
209
03_source/frontend/src/routes/sections/dashboard.tsx
Normal file
@@ -0,0 +1,209 @@
|
||||
import type { RouteObject } from 'react-router';
|
||||
|
||||
import { Outlet } from 'react-router';
|
||||
import { lazy, Suspense } from 'react';
|
||||
|
||||
import { CONFIG } from 'src/global-config';
|
||||
import { DashboardLayout } from 'src/layouts/dashboard';
|
||||
|
||||
import { LoadingScreen } from 'src/components/loading-screen';
|
||||
|
||||
import { AccountLayout } from 'src/sections/account/account-layout';
|
||||
|
||||
import { AuthGuard } from 'src/auth/guard';
|
||||
|
||||
import { usePathname } from '../hooks';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// Overview
|
||||
const IndexPage = lazy(() => import('src/pages/dashboard'));
|
||||
const OverviewEcommercePage = lazy(() => import('src/pages/dashboard/ecommerce'));
|
||||
const OverviewAnalyticsPage = lazy(() => import('src/pages/dashboard/analytics'));
|
||||
const OverviewBankingPage = lazy(() => import('src/pages/dashboard/banking'));
|
||||
const OverviewBookingPage = lazy(() => import('src/pages/dashboard/booking'));
|
||||
const OverviewFilePage = lazy(() => import('src/pages/dashboard/file'));
|
||||
const OverviewCoursePage = lazy(() => import('src/pages/dashboard/course'));
|
||||
// Product
|
||||
const ProductDetailsPage = lazy(() => import('src/pages/dashboard/product/details'));
|
||||
const ProductListPage = lazy(() => import('src/pages/dashboard/product/list'));
|
||||
const ProductCreatePage = lazy(() => import('src/pages/dashboard/product/new'));
|
||||
const ProductEditPage = lazy(() => import('src/pages/dashboard/product/edit'));
|
||||
// Order
|
||||
const OrderListPage = lazy(() => import('src/pages/dashboard/order/list'));
|
||||
const OrderDetailsPage = lazy(() => import('src/pages/dashboard/order/details'));
|
||||
// Invoice
|
||||
const InvoiceListPage = lazy(() => import('src/pages/dashboard/invoice/list'));
|
||||
const InvoiceDetailsPage = lazy(() => import('src/pages/dashboard/invoice/details'));
|
||||
const InvoiceCreatePage = lazy(() => import('src/pages/dashboard/invoice/new'));
|
||||
const InvoiceEditPage = lazy(() => import('src/pages/dashboard/invoice/edit'));
|
||||
// User
|
||||
const UserProfilePage = lazy(() => import('src/pages/dashboard/user/profile'));
|
||||
const UserCardsPage = lazy(() => import('src/pages/dashboard/user/cards'));
|
||||
const UserListPage = lazy(() => import('src/pages/dashboard/user/list'));
|
||||
const UserCreatePage = lazy(() => import('src/pages/dashboard/user/new'));
|
||||
const UserEditPage = lazy(() => import('src/pages/dashboard/user/edit'));
|
||||
// Account
|
||||
const AccountGeneralPage = lazy(() => import('src/pages/dashboard/user/account/general'));
|
||||
const AccountBillingPage = lazy(() => import('src/pages/dashboard/user/account/billing'));
|
||||
const AccountSocialsPage = lazy(() => import('src/pages/dashboard/user/account/socials'));
|
||||
const AccountNotificationsPage = lazy(
|
||||
() => import('src/pages/dashboard/user/account/notifications')
|
||||
);
|
||||
const AccountChangePasswordPage = lazy(
|
||||
() => import('src/pages/dashboard/user/account/change-password')
|
||||
);
|
||||
// Blog
|
||||
const BlogPostsPage = lazy(() => import('src/pages/dashboard/post/list'));
|
||||
const BlogPostPage = lazy(() => import('src/pages/dashboard/post/details'));
|
||||
const BlogNewPostPage = lazy(() => import('src/pages/dashboard/post/new'));
|
||||
const BlogEditPostPage = lazy(() => import('src/pages/dashboard/post/edit'));
|
||||
// Job
|
||||
const JobDetailsPage = lazy(() => import('src/pages/dashboard/job/details'));
|
||||
const JobListPage = lazy(() => import('src/pages/dashboard/job/list'));
|
||||
const JobCreatePage = lazy(() => import('src/pages/dashboard/job/new'));
|
||||
const JobEditPage = lazy(() => import('src/pages/dashboard/job/edit'));
|
||||
// Tour
|
||||
const TourDetailsPage = lazy(() => import('src/pages/dashboard/tour/details'));
|
||||
const TourListPage = lazy(() => import('src/pages/dashboard/tour/list'));
|
||||
const TourCreatePage = lazy(() => import('src/pages/dashboard/tour/new'));
|
||||
const TourEditPage = lazy(() => import('src/pages/dashboard/tour/edit'));
|
||||
// File manager
|
||||
const FileManagerPage = lazy(() => import('src/pages/dashboard/file-manager'));
|
||||
// App
|
||||
const ChatPage = lazy(() => import('src/pages/dashboard/chat'));
|
||||
const MailPage = lazy(() => import('src/pages/dashboard/mail'));
|
||||
const CalendarPage = lazy(() => import('src/pages/dashboard/calendar'));
|
||||
const KanbanPage = lazy(() => import('src/pages/dashboard/kanban'));
|
||||
// Test render page by role
|
||||
const PermissionDeniedPage = lazy(() => import('src/pages/dashboard/permission'));
|
||||
// Blank page
|
||||
const ParamsPage = lazy(() => import('src/pages/dashboard/params'));
|
||||
const BlankPage = lazy(() => import('src/pages/dashboard/blank'));
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function SuspenseOutlet() {
|
||||
const pathname = usePathname();
|
||||
return (
|
||||
<Suspense key={pathname} fallback={<LoadingScreen />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
const dashboardLayout = () => (
|
||||
<DashboardLayout>
|
||||
<SuspenseOutlet />
|
||||
</DashboardLayout>
|
||||
);
|
||||
|
||||
const accountLayout = () => (
|
||||
<AccountLayout>
|
||||
<SuspenseOutlet />
|
||||
</AccountLayout>
|
||||
);
|
||||
|
||||
export const dashboardRoutes: RouteObject[] = [
|
||||
{
|
||||
path: 'dashboard',
|
||||
element: CONFIG.auth.skip ? dashboardLayout() : <AuthGuard>{dashboardLayout()}</AuthGuard>,
|
||||
children: [
|
||||
{ index: true, element: <IndexPage /> },
|
||||
{ path: 'ecommerce', element: <OverviewEcommercePage /> },
|
||||
{ path: 'analytics', element: <OverviewAnalyticsPage /> },
|
||||
{ path: 'banking', element: <OverviewBankingPage /> },
|
||||
{ path: 'booking', element: <OverviewBookingPage /> },
|
||||
{ path: 'file', element: <OverviewFilePage /> },
|
||||
{ path: 'course', element: <OverviewCoursePage /> },
|
||||
{
|
||||
path: 'user',
|
||||
children: [
|
||||
{ index: true, element: <UserProfilePage /> },
|
||||
{ path: 'profile', element: <UserProfilePage /> },
|
||||
{ path: 'cards', element: <UserCardsPage /> },
|
||||
{ path: 'list', element: <UserListPage /> },
|
||||
{ path: 'new', element: <UserCreatePage /> },
|
||||
{ path: ':id/edit', element: <UserEditPage /> },
|
||||
{
|
||||
path: 'account',
|
||||
element: accountLayout(),
|
||||
children: [
|
||||
{ index: true, element: <AccountGeneralPage /> },
|
||||
{ path: 'billing', element: <AccountBillingPage /> },
|
||||
{ path: 'notifications', element: <AccountNotificationsPage /> },
|
||||
{ path: 'socials', element: <AccountSocialsPage /> },
|
||||
{ path: 'change-password', element: <AccountChangePasswordPage /> },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'product',
|
||||
children: [
|
||||
{ index: true, element: <ProductListPage /> },
|
||||
{ path: 'list', element: <ProductListPage /> },
|
||||
{ path: ':id', element: <ProductDetailsPage /> },
|
||||
{ path: 'new', element: <ProductCreatePage /> },
|
||||
{ path: ':id/edit', element: <ProductEditPage /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'order',
|
||||
children: [
|
||||
{ index: true, element: <OrderListPage /> },
|
||||
{ path: 'list', element: <OrderListPage /> },
|
||||
{ path: ':id', element: <OrderDetailsPage /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'invoice',
|
||||
children: [
|
||||
{ index: true, element: <InvoiceListPage /> },
|
||||
{ path: 'list', element: <InvoiceListPage /> },
|
||||
{ path: ':id', element: <InvoiceDetailsPage /> },
|
||||
{ path: ':id/edit', element: <InvoiceEditPage /> },
|
||||
{ path: 'new', element: <InvoiceCreatePage /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'post',
|
||||
children: [
|
||||
{ index: true, element: <BlogPostsPage /> },
|
||||
{ path: 'list', element: <BlogPostsPage /> },
|
||||
{ path: ':title', element: <BlogPostPage /> },
|
||||
{ path: ':title/edit', element: <BlogEditPostPage /> },
|
||||
{ path: 'new', element: <BlogNewPostPage /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'job',
|
||||
children: [
|
||||
{ index: true, element: <JobListPage /> },
|
||||
{ path: 'list', element: <JobListPage /> },
|
||||
{ path: ':id', element: <JobDetailsPage /> },
|
||||
{ path: 'new', element: <JobCreatePage /> },
|
||||
{ path: ':id/edit', element: <JobEditPage /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'tour',
|
||||
children: [
|
||||
{ index: true, element: <TourListPage /> },
|
||||
{ path: 'list', element: <TourListPage /> },
|
||||
{ path: ':id', element: <TourDetailsPage /> },
|
||||
{ path: 'new', element: <TourCreatePage /> },
|
||||
{ path: ':id/edit', element: <TourEditPage /> },
|
||||
],
|
||||
},
|
||||
{ path: 'file-manager', element: <FileManagerPage /> },
|
||||
{ path: 'mail', element: <MailPage /> },
|
||||
{ path: 'chat', element: <ChatPage /> },
|
||||
{ path: 'calendar', element: <CalendarPage /> },
|
||||
{ path: 'kanban', element: <KanbanPage /> },
|
||||
{ path: 'permission', element: <PermissionDeniedPage /> },
|
||||
{ path: 'params', element: <ParamsPage /> },
|
||||
{ path: 'blank', element: <BlankPage /> },
|
||||
],
|
||||
},
|
||||
];
|
55
03_source/frontend/src/routes/sections/index.tsx
Normal file
55
03_source/frontend/src/routes/sections/index.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { RouteObject } from 'react-router';
|
||||
|
||||
import { lazy, Suspense } from 'react';
|
||||
|
||||
import { MainLayout } from 'src/layouts/main';
|
||||
|
||||
import { SplashScreen } from 'src/components/loading-screen';
|
||||
|
||||
import { authRoutes } from './auth';
|
||||
import { mainRoutes } from './main';
|
||||
import { authDemoRoutes } from './auth-demo';
|
||||
import { dashboardRoutes } from './dashboard';
|
||||
import { componentsRoutes } from './components';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const HomePage = lazy(() => import('src/pages/home'));
|
||||
const Page404 = lazy(() => import('src/pages/error/404'));
|
||||
|
||||
export const routesSection: RouteObject[] = [
|
||||
{
|
||||
path: '/',
|
||||
/**
|
||||
* @skip homepage
|
||||
* import { Navigate } from "react-router";
|
||||
* import { CONFIG } from 'src/global-config';
|
||||
*
|
||||
* element: <Navigate to={CONFIG.auth.redirectPath} replace />,
|
||||
* and remove the element below:
|
||||
*/
|
||||
element: (
|
||||
<Suspense fallback={<SplashScreen />}>
|
||||
<MainLayout>
|
||||
<HomePage />
|
||||
</MainLayout>
|
||||
</Suspense>
|
||||
),
|
||||
},
|
||||
|
||||
// Auth
|
||||
...authRoutes,
|
||||
...authDemoRoutes,
|
||||
|
||||
// Dashboard
|
||||
...dashboardRoutes,
|
||||
|
||||
// Main
|
||||
...mainRoutes,
|
||||
|
||||
// Components
|
||||
...componentsRoutes,
|
||||
|
||||
// No match
|
||||
{ path: '*', element: <Page404 /> },
|
||||
];
|
116
03_source/frontend/src/routes/sections/main.tsx
Normal file
116
03_source/frontend/src/routes/sections/main.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import type { RouteObject } from 'react-router';
|
||||
|
||||
import { Outlet } from 'react-router';
|
||||
import { lazy, Suspense } from 'react';
|
||||
|
||||
import { MainLayout } from 'src/layouts/main';
|
||||
import { SimpleLayout } from 'src/layouts/simple';
|
||||
|
||||
import { SplashScreen } from 'src/components/loading-screen';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const FaqsPage = lazy(() => import('src/pages/faqs'));
|
||||
const AboutPage = lazy(() => import('src/pages/about-us'));
|
||||
const ContactPage = lazy(() => import('src/pages/contact-us'));
|
||||
const PricingPage = lazy(() => import('src/pages/pricing'));
|
||||
const PaymentPage = lazy(() => import('src/pages/payment'));
|
||||
const ComingSoonPage = lazy(() => import('src/pages/coming-soon'));
|
||||
const MaintenancePage = lazy(() => import('src/pages/maintenance'));
|
||||
// Product
|
||||
const ProductListPage = lazy(() => import('src/pages/product/list'));
|
||||
const ProductDetailsPage = lazy(() => import('src/pages/product/details'));
|
||||
const ProductCheckoutPage = lazy(() => import('src/pages/product/checkout'));
|
||||
// Blog
|
||||
const PostListPage = lazy(() => import('src/pages/post/list'));
|
||||
const PostDetailsPage = lazy(() => import('src/pages/post/details'));
|
||||
// Error
|
||||
const Page500 = lazy(() => import('src/pages/error/500'));
|
||||
const Page403 = lazy(() => import('src/pages/error/403'));
|
||||
const Page404 = lazy(() => import('src/pages/error/404'));
|
||||
// Blank
|
||||
const BlankPage = lazy(() => import('src/pages/blank'));
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export const mainRoutes: RouteObject[] = [
|
||||
{
|
||||
element: (
|
||||
<Suspense fallback={<SplashScreen />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
),
|
||||
children: [
|
||||
{
|
||||
element: (
|
||||
<MainLayout>
|
||||
<Outlet />
|
||||
</MainLayout>
|
||||
),
|
||||
children: [
|
||||
{ path: 'about-us', element: <AboutPage /> },
|
||||
{ path: 'contact-us', element: <ContactPage /> },
|
||||
{ path: 'faqs', element: <FaqsPage /> },
|
||||
{ path: 'blank', element: <BlankPage /> },
|
||||
{
|
||||
path: 'product',
|
||||
children: [
|
||||
{ index: true, element: <ProductListPage /> },
|
||||
{ path: 'list', element: <ProductListPage /> },
|
||||
{ path: ':id', element: <ProductDetailsPage /> },
|
||||
{ path: 'checkout', element: <ProductCheckoutPage /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'post',
|
||||
children: [
|
||||
{ index: true, element: <PostListPage /> },
|
||||
{ path: 'list', element: <PostListPage /> },
|
||||
{ path: ':title', element: <PostDetailsPage /> },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'pricing',
|
||||
element: (
|
||||
<SimpleLayout>
|
||||
<PricingPage />
|
||||
</SimpleLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'payment',
|
||||
element: (
|
||||
<SimpleLayout>
|
||||
<PaymentPage />
|
||||
</SimpleLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'coming-soon',
|
||||
element: (
|
||||
<SimpleLayout slotProps={{ content: { compact: true } }}>
|
||||
<ComingSoonPage />
|
||||
</SimpleLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'maintenance',
|
||||
element: (
|
||||
<SimpleLayout slotProps={{ content: { compact: true } }}>
|
||||
<MaintenancePage />
|
||||
</SimpleLayout>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'error',
|
||||
children: [
|
||||
{ path: '500', element: <Page500 /> },
|
||||
{ path: '404', element: <Page404 /> },
|
||||
{ path: '403', element: <Page403 /> },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
Reference in New Issue
Block a user