init commit,

This commit is contained in:
louiscklaw
2025-05-28 09:55:51 +08:00
commit efe70ceb69
8042 changed files with 951668 additions and 0 deletions

View 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(),
},
})}
/>
);

View File

@@ -0,0 +1,3 @@
export * from './router-link';
export * from './error-boundary';

View 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} />;
}

View 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';

View 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]);
}

View File

@@ -0,0 +1,10 @@
import { useMemo } from 'react';
import { useLocation } from 'react-router';
// ----------------------------------------------------------------------
export function usePathname() {
const { pathname } = useLocation();
return useMemo(() => pathname, [pathname]);
}

View 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;
}

View 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]);
}

View 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`,
},
},
},
};

View 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],
},
];

View 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],
},
];

View 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 /> },
],
},
],
},
];

View 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 /> },
],
},
];

View 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 /> },
];

View 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 /> },
],
},
],
},
];