update,
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useMemo } from 'react';
|
||||
import { endpoints, fetcher } from 'src/lib/axios';
|
||||
import { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IPostItem } from 'src/types/blog';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR from 'swr';
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { useMemo } from 'react';
|
||||
import axios, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axios, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { ICalendarEvent } from 'src/types/calendar';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { keyBy } from 'es-toolkit';
|
||||
import { useMemo } from 'react';
|
||||
import axios, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axios, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IChatConversation, IChatMessage, IChatParticipant } from 'src/types/chat';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// src/actions/invoice.ts
|
||||
import { useMemo } from 'react';
|
||||
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axiosInstance, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IInvoiceItem, SaveInvoiceData } from 'src/types/invoice';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR from 'swr';
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import type { UniqueIdentifier } from '@dnd-kit/core';
|
||||
import { startTransition, useMemo } from 'react';
|
||||
import axios, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axios, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IKanban, IKanbanColumn, IKanbanTask } from 'src/types/kanban';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { keyBy } from 'es-toolkit';
|
||||
import { useMemo } from 'react';
|
||||
import { endpoints, fetcher } from 'src/lib/axios';
|
||||
import { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IMail, IMailLabel } from 'src/types/mail';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR from 'swr';
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// src/actions/order.ts
|
||||
import { useMemo } from 'react';
|
||||
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axiosInstance, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IOrderItem } from 'src/types/order';
|
||||
import type { IProductItem } from 'src/types/product';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// src/actions/party-event.ts
|
||||
//
|
||||
import { useMemo } from 'react';
|
||||
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axiosInstance, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IPartyEventItem } from 'src/types/party-event';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// src/actions/party-order.ts
|
||||
//
|
||||
import { useMemo } from 'react';
|
||||
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axiosInstance, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IPartyOrderItem } from 'src/types/party-order';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// src/actions/party-user1.ts
|
||||
//
|
||||
import { useMemo } from 'react';
|
||||
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axiosInstance, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IPartyUserItem } from 'src/types/party-user';
|
||||
import type { IProductItem } from 'src/types/product';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// src/actions/product.ts
|
||||
//
|
||||
import { useMemo } from 'react';
|
||||
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axiosInstance, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IProductItem } from 'src/types/product';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { useMemo } from 'react';
|
||||
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import axiosInstance, { fetcher } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { IProductItem } from 'src/types/product';
|
||||
import { IUserItem } from 'src/types/user';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import axios, { endpoints } from 'src/lib/axios';
|
||||
import axios from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import { JWT_STORAGE_KEY } from './constant';
|
||||
import { setSession } from './utils';
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { useSetState } from 'minimal-shared/hooks';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import axios, { endpoints } from 'src/lib/axios';
|
||||
import axios from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import type { AuthState } from '../../types';
|
||||
import { AuthContext } from '../auth-context';
|
||||
import { JWT_STORAGE_KEY } from './constant';
|
||||
|
@@ -0,0 +1,2 @@
|
||||
export const ERR_ACCESS_TOKEN_NOT_FOUND = `Access token not found in response`;
|
||||
export const ACCESS_TOKEN_NOT_FOUND_IN_RESPONSE = 'Access token not found in response';
|
85
03_source/frontend/src/auth/context/party-user-jwt/action.ts
Normal file
85
03_source/frontend/src/auth/context/party-user-jwt/action.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import axios from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import { JWT_STORAGE_KEY } from './constant';
|
||||
import { ACCESS_TOKEN_NOT_FOUND_IN_RESPONSE, ERR_ACCESS_TOKEN_NOT_FOUND } from './ERRORS';
|
||||
import { setSession } from './utils';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export type SignInParams = {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
export type SignUpParams = {
|
||||
email: string;
|
||||
password: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
};
|
||||
|
||||
/** **************************************
|
||||
* Sign in
|
||||
*************************************** */
|
||||
export const signInWithPassword = async ({ email, password }: SignInParams): Promise<void> => {
|
||||
try {
|
||||
const params = { email, password };
|
||||
|
||||
const res = await axios.post(endpoints.partyUserAuth.signIn, params);
|
||||
|
||||
const { accessToken } = res.data;
|
||||
|
||||
if (!accessToken) {
|
||||
throw new Error(ERR_ACCESS_TOKEN_NOT_FOUND);
|
||||
}
|
||||
|
||||
setSession(accessToken);
|
||||
} catch (error) {
|
||||
console.error('Error during sign in:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/** **************************************
|
||||
* Sign up
|
||||
*************************************** */
|
||||
export const signUp = async ({
|
||||
email,
|
||||
password,
|
||||
firstName,
|
||||
lastName,
|
||||
}: SignUpParams): Promise<void> => {
|
||||
const params = {
|
||||
email,
|
||||
password,
|
||||
firstName,
|
||||
lastName,
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await axios.post(endpoints.auth.signUp, params);
|
||||
|
||||
const { accessToken } = res.data;
|
||||
|
||||
if (!accessToken) {
|
||||
throw new Error(ACCESS_TOKEN_NOT_FOUND_IN_RESPONSE);
|
||||
}
|
||||
|
||||
sessionStorage.setItem(JWT_STORAGE_KEY, accessToken);
|
||||
} catch (error) {
|
||||
console.error('Error during sign up:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/** **************************************
|
||||
* Sign out
|
||||
*************************************** */
|
||||
export const signOut = async (): Promise<void> => {
|
||||
try {
|
||||
await setSession(null);
|
||||
} catch (error) {
|
||||
console.error('Error during sign out:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
@@ -0,0 +1 @@
|
||||
export const JWT_STORAGE_KEY = 'jwt_access_token';
|
@@ -0,0 +1,7 @@
|
||||
export * from './utils';
|
||||
|
||||
export * from './action';
|
||||
|
||||
export * from './constant';
|
||||
|
||||
// export * from './auth-provider';
|
94
03_source/frontend/src/auth/context/party-user-jwt/utils.ts
Normal file
94
03_source/frontend/src/auth/context/party-user-jwt/utils.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import axios from 'src/lib/axios';
|
||||
import { paths } from 'src/routes/paths';
|
||||
import { JWT_STORAGE_KEY } from './constant';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function jwtDecode(token: string) {
|
||||
try {
|
||||
if (!token) return null;
|
||||
|
||||
const parts = token.split('.');
|
||||
if (parts.length < 2) {
|
||||
throw new Error('Invalid token!');
|
||||
}
|
||||
|
||||
const base64Url = parts[1];
|
||||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||
const decoded = JSON.parse(atob(base64));
|
||||
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
console.error('Error decoding token:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function isValidToken(accessToken: string) {
|
||||
if (!accessToken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const decoded = jwtDecode(accessToken);
|
||||
|
||||
if (!decoded || !('exp' in decoded)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const currentTime = Date.now() / 1000;
|
||||
|
||||
return decoded.exp > currentTime;
|
||||
} catch (error) {
|
||||
console.error('Error during token validation:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function tokenExpired(exp: number) {
|
||||
const currentTime = Date.now();
|
||||
const timeLeft = exp * 1000 - currentTime;
|
||||
|
||||
setTimeout(() => {
|
||||
try {
|
||||
alert('Token expired!');
|
||||
sessionStorage.removeItem(JWT_STORAGE_KEY);
|
||||
window.location.href = paths.auth.jwt.signIn;
|
||||
} catch (error) {
|
||||
console.error('Error during token expiration:', error);
|
||||
throw error;
|
||||
}
|
||||
}, timeLeft);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const INVALID_ACCESS_TOKEN = 'Invalid access token!';
|
||||
|
||||
export async function setSession(accessToken: string | null) {
|
||||
try {
|
||||
if (accessToken) {
|
||||
sessionStorage.setItem(JWT_STORAGE_KEY, accessToken);
|
||||
|
||||
axios.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
|
||||
|
||||
const decodedToken = jwtDecode(accessToken); // ~3 days by minimals server
|
||||
|
||||
if (decodedToken && 'exp' in decodedToken) {
|
||||
tokenExpired(decodedToken.exp);
|
||||
} else {
|
||||
throw new Error(INVALID_ACCESS_TOKEN);
|
||||
}
|
||||
} else {
|
||||
sessionStorage.removeItem(JWT_STORAGE_KEY);
|
||||
delete axios.defaults.headers.common.Authorization;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during set session:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
3
03_source/frontend/src/auth/view/party-user-jwt/index.ts
Normal file
3
03_source/frontend/src/auth/view/party-user-jwt/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './jwt-sign-in-view';
|
||||
|
||||
export * from './jwt-sign-up-view';
|
@@ -0,0 +1,167 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import Alert from '@mui/material/Alert';
|
||||
import Box from '@mui/material/Box';
|
||||
import Button from '@mui/material/Button';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import InputAdornment from '@mui/material/InputAdornment';
|
||||
import Link from '@mui/material/Link';
|
||||
import { useBoolean } from 'minimal-shared/hooks';
|
||||
import React, { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Field, Form } from 'src/components/hook-form';
|
||||
import { Iconify } from 'src/components/iconify';
|
||||
import { RouterLink } from 'src/routes/components';
|
||||
import { useRouter } from 'src/routes/hooks';
|
||||
import { paths } from 'src/routes/paths';
|
||||
import { z as zod } from 'zod';
|
||||
import { FormHead } from '../../components/form-head';
|
||||
import { signInWithPassword } from '../../context/party-user-jwt';
|
||||
import { useAuthContext } from '../../hooks';
|
||||
import { getErrorMessage } from '../../utils';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function JwtSignInView(): React.JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const showPassword = useBoolean();
|
||||
|
||||
const { checkUserSession } = useAuthContext();
|
||||
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
|
||||
type SignInSchemaType = zod.infer<typeof SignInSchema>;
|
||||
|
||||
const EMAIL_IS_REQUIRED = 'Email is required!';
|
||||
const EMAIL_MUST_BE_A_VALID_EMAIL_ADDRESS = 'Email must be a valid email address!';
|
||||
const PASSWORD_IS_REQUIRED = 'Password is required!';
|
||||
const PASSWORD_MUST_BE_AT_LEAST_6_CHARACTERS = 'Password must be at least 6 characters!';
|
||||
|
||||
const SignInSchema = zod.object({
|
||||
email: zod
|
||||
.string()
|
||||
.min(1, { message: EMAIL_IS_REQUIRED })
|
||||
.email({ message: EMAIL_MUST_BE_A_VALID_EMAIL_ADDRESS }),
|
||||
password: zod
|
||||
.string()
|
||||
.min(1, { message: PASSWORD_IS_REQUIRED })
|
||||
.min(6, { message: PASSWORD_MUST_BE_AT_LEAST_6_CHARACTERS }),
|
||||
});
|
||||
|
||||
const defaultValues: SignInSchemaType = {
|
||||
email: 'party_user0@prisma.io',
|
||||
password: 'Aa12345678',
|
||||
};
|
||||
|
||||
const methods = useForm<SignInSchemaType>({
|
||||
resolver: zodResolver(SignInSchema),
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
formState: { isSubmitting },
|
||||
} = methods;
|
||||
|
||||
const onSubmit = handleSubmit(async (data) => {
|
||||
try {
|
||||
await signInWithPassword({ email: data.email, password: data.password });
|
||||
await checkUserSession?.();
|
||||
|
||||
router.refresh();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
const feedbackMessage = getErrorMessage(error);
|
||||
setErrorMessage(feedbackMessage);
|
||||
}
|
||||
});
|
||||
|
||||
const renderForm = () => (
|
||||
<Box sx={{ gap: 3, display: 'flex', flexDirection: 'column' }}>
|
||||
<Field.Text name="email" label="Email address" slotProps={{ inputLabel: { shrink: true } }} />
|
||||
|
||||
<Box sx={{ gap: 1.5, display: 'flex', flexDirection: 'column' }}>
|
||||
<Link
|
||||
component={RouterLink}
|
||||
href="#"
|
||||
variant="body2"
|
||||
color="inherit"
|
||||
sx={{ alignSelf: 'flex-end' }}
|
||||
>
|
||||
Forgot password?
|
||||
</Link>
|
||||
|
||||
<Field.Text
|
||||
name="password"
|
||||
label="Password"
|
||||
placeholder="6+ characters"
|
||||
type={showPassword.value ? 'text' : 'password'}
|
||||
slotProps={{
|
||||
inputLabel: { shrink: true },
|
||||
input: {
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<IconButton onClick={showPassword.onToggle} edge="end">
|
||||
<Iconify
|
||||
icon={showPassword.value ? 'solar:eye-bold' : 'solar:eye-closed-bold'}
|
||||
/>
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Button
|
||||
fullWidth
|
||||
color="inherit"
|
||||
size="large"
|
||||
type="submit"
|
||||
variant="contained"
|
||||
loading={isSubmitting}
|
||||
loadingIndicator="Sign in..."
|
||||
>
|
||||
{t('sign-in')}
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormHead
|
||||
title="Sign in to your account"
|
||||
description={
|
||||
<>
|
||||
{`Don’t have an account? `}
|
||||
<Link component={RouterLink} href={paths.partyUserAuth.jwt.signUp} variant="subtitle2">
|
||||
{t('get-started')}
|
||||
</Link>
|
||||
</>
|
||||
}
|
||||
sx={{ textAlign: { xs: 'center', md: 'left' } }}
|
||||
/>
|
||||
|
||||
<Alert severity="info" sx={{ mb: 3 }}>
|
||||
Use <strong>{defaultValues.email}</strong>
|
||||
{' with password '}
|
||||
<strong>{defaultValues.password}</strong>
|
||||
</Alert>
|
||||
|
||||
{!!errorMessage && (
|
||||
<Alert severity="error" sx={{ mb: 3 }}>
|
||||
{errorMessage}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Form methods={methods} onSubmit={onSubmit}>
|
||||
{renderForm()}
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,166 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import Alert from '@mui/material/Alert';
|
||||
import Box from '@mui/material/Box';
|
||||
import Button from '@mui/material/Button';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import InputAdornment from '@mui/material/InputAdornment';
|
||||
import Link from '@mui/material/Link';
|
||||
import { useBoolean } from 'minimal-shared/hooks';
|
||||
import { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Field, Form } from 'src/components/hook-form';
|
||||
import { Iconify } from 'src/components/iconify';
|
||||
import { RouterLink } from 'src/routes/components';
|
||||
import { useRouter } from 'src/routes/hooks';
|
||||
import { paths } from 'src/routes/paths';
|
||||
import { z as zod } from 'zod';
|
||||
import { FormHead } from '../../components/form-head';
|
||||
import { SignUpTerms } from '../../components/sign-up-terms';
|
||||
import { signUp } from '../../context/jwt';
|
||||
import { useAuthContext } from '../../hooks';
|
||||
import { getErrorMessage } from '../../utils';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export type SignUpSchemaType = zod.infer<typeof SignUpSchema>;
|
||||
|
||||
export const SignUpSchema = zod.object({
|
||||
firstName: zod.string().min(1, { message: 'First name is required!' }),
|
||||
lastName: zod.string().min(1, { message: 'Last name is required!' }),
|
||||
email: zod
|
||||
.string()
|
||||
.min(1, { message: 'Email is required!' })
|
||||
.email({ message: 'Email must be a valid email address!' }),
|
||||
password: zod
|
||||
.string()
|
||||
.min(1, { message: 'Password is required!' })
|
||||
.min(6, { message: 'Password must be at least 6 characters!' }),
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function JwtSignUpView() {
|
||||
const router = useRouter();
|
||||
|
||||
const showPassword = useBoolean();
|
||||
|
||||
const { checkUserSession } = useAuthContext();
|
||||
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
|
||||
const defaultValues: SignUpSchemaType = {
|
||||
firstName: 'Hello',
|
||||
lastName: 'Friend',
|
||||
email: 'hello@gmail.com',
|
||||
password: '@2Minimal',
|
||||
};
|
||||
|
||||
const methods = useForm<SignUpSchemaType>({
|
||||
resolver: zodResolver(SignUpSchema),
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
formState: { isSubmitting },
|
||||
} = methods;
|
||||
|
||||
const onSubmit = handleSubmit(async (data) => {
|
||||
try {
|
||||
await signUp({
|
||||
email: data.email,
|
||||
password: data.password,
|
||||
firstName: data.firstName,
|
||||
lastName: data.lastName,
|
||||
});
|
||||
await checkUserSession?.();
|
||||
|
||||
router.refresh();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
const feedbackMessage = getErrorMessage(error);
|
||||
setErrorMessage(feedbackMessage);
|
||||
}
|
||||
});
|
||||
|
||||
const renderForm = () => (
|
||||
<Box sx={{ gap: 3, display: 'flex', flexDirection: 'column' }}>
|
||||
<Box
|
||||
sx={{ display: 'flex', gap: { xs: 3, sm: 2 }, flexDirection: { xs: 'column', sm: 'row' } }}
|
||||
>
|
||||
<Field.Text
|
||||
name="firstName"
|
||||
label="First name"
|
||||
slotProps={{ inputLabel: { shrink: true } }}
|
||||
/>
|
||||
<Field.Text
|
||||
name="lastName"
|
||||
label="Last name"
|
||||
slotProps={{ inputLabel: { shrink: true } }}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Field.Text name="email" label="Email address" slotProps={{ inputLabel: { shrink: true } }} />
|
||||
|
||||
<Field.Text
|
||||
name="password"
|
||||
label="Password"
|
||||
placeholder="6+ characters"
|
||||
type={showPassword.value ? 'text' : 'password'}
|
||||
slotProps={{
|
||||
inputLabel: { shrink: true },
|
||||
input: {
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<IconButton onClick={showPassword.onToggle} edge="end">
|
||||
<Iconify icon={showPassword.value ? 'solar:eye-bold' : 'solar:eye-closed-bold'} />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
fullWidth
|
||||
color="inherit"
|
||||
size="large"
|
||||
type="submit"
|
||||
variant="contained"
|
||||
loading={isSubmitting}
|
||||
loadingIndicator="Create account..."
|
||||
>
|
||||
Create account
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormHead
|
||||
title="Hi New party user, Get started absolutely free "
|
||||
description={
|
||||
<>
|
||||
{`Already have an account? `}
|
||||
<Link component={RouterLink} href={paths.auth.jwt.signIn} variant="subtitle2">
|
||||
Get started
|
||||
</Link>
|
||||
</>
|
||||
}
|
||||
sx={{ textAlign: { xs: 'center', md: 'left' } }}
|
||||
/>
|
||||
|
||||
{!!errorMessage && (
|
||||
<Alert severity="error" sx={{ mb: 3 }}>
|
||||
{errorMessage}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Form methods={methods} onSubmit={onSubmit}>
|
||||
{renderForm()}
|
||||
</Form>
|
||||
|
||||
<SignUpTerms />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { AmplifyResetPasswordView } from 'src/auth/view/amplify';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Reset password | Amplify - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<AmplifyResetPasswordView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { AmplifySignInView } from 'src/auth/view/amplify';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign in | Amplify - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<AmplifySignInView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { AmplifySignUpView } from 'src/auth/view/amplify';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign up | Amplify - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<AmplifySignUpView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { AmplifyUpdatePasswordView } from 'src/auth/view/amplify';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Update password | Amplify - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<AmplifyUpdatePasswordView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { AmplifyVerifyView } from 'src/auth/view/amplify';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Verify | Amplify - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<AmplifyVerifyView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
import { SplashScreen } from 'src/components/loading-screen';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export default function CallbackPage() {
|
||||
return <SplashScreen />;
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { Auth0SignInView } from 'src/auth/view/auth0';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign in | Auth0 - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<Auth0SignInView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { FirebaseResetPasswordView } from 'src/auth/view/firebase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Reset password | Firebase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<FirebaseResetPasswordView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { FirebaseSignInView } from 'src/auth/view/firebase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign in | Firebase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<FirebaseSignInView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { FirebaseSignUpView } from 'src/auth/view/firebase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign up | Firebase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<FirebaseSignUpView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { FirebaseVerifyView } from 'src/auth/view/firebase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Verify | Firebase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<FirebaseVerifyView />
|
||||
</>
|
||||
);
|
||||
}
|
16
03_source/frontend/src/pages/party-user-auth/jwt/sign-in.tsx
Normal file
16
03_source/frontend/src/pages/party-user-auth/jwt/sign-in.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import { JwtSignInView } from 'src/auth/view/party-user-jwt';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign in | Jwt - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<JwtSignInView />
|
||||
</>
|
||||
);
|
||||
}
|
16
03_source/frontend/src/pages/party-user-auth/jwt/sign-up.tsx
Normal file
16
03_source/frontend/src/pages/party-user-auth/jwt/sign-up.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import { JwtSignUpView } from 'src/auth/view/party-user-jwt';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign up | Jwt - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<JwtSignUpView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { SupabaseResetPasswordView } from 'src/auth/view/supabase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Reset password | Supabase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<SupabaseResetPasswordView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { SupabaseSignInView } from 'src/auth/view/supabase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign in | Supabase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<SupabaseSignInView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { SupabaseSignUpView } from 'src/auth/view/supabase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Sign up | Supabase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<SupabaseSignUpView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { SupabaseUpdatePasswordView } from 'src/auth/view/supabase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Update password | Supabase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<SupabaseUpdatePasswordView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import { SupabaseVerifyView } from 'src/auth/view/supabase';
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const metadata = { title: `Verify | Supabase - ${CONFIG.appName}` };
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<title>{metadata.title}</title>
|
||||
|
||||
<SupabaseVerifyView />
|
||||
</>
|
||||
);
|
||||
}
|
@@ -10,6 +10,8 @@ const ROOTS = {
|
||||
AUTH: '/auth',
|
||||
AUTH_DEMO: '/auth-demo',
|
||||
DASHBOARD: '/dashboard',
|
||||
//
|
||||
PARTY_USER_AUTH: '/party-user-auth',
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -207,4 +209,32 @@ export const paths = {
|
||||
demo: { edit: `${ROOTS.DASHBOARD}/party-user/${MOCK_ID}/edit` },
|
||||
},
|
||||
},
|
||||
partyUserAuth: {
|
||||
jwt: {
|
||||
signIn: `${ROOTS.PARTY_USER_AUTH}/jwt/sign-in`,
|
||||
signUp: `${ROOTS.PARTY_USER_AUTH}/jwt/sign-up`,
|
||||
},
|
||||
//
|
||||
// amplify: {
|
||||
// signIn: `${ROOTS.PARTY_USER_AUTH}/amplify/sign-in`,
|
||||
// verify: `${ROOTS.PARTY_USER_AUTH}/amplify/verify`,
|
||||
// signUp: `${ROOTS.PARTY_USER_AUTH}/amplify/sign-up`,
|
||||
// updatePassword: `${ROOTS.PARTY_USER_AUTH}/amplify/update-password`,
|
||||
// resetPassword: `${ROOTS.PARTY_USER_AUTH}/amplify/reset-password`,
|
||||
// },
|
||||
// firebase: {
|
||||
// signIn: `${ROOTS.PARTY_USER_AUTH}/firebase/sign-in`,
|
||||
// verify: `${ROOTS.PARTY_USER_AUTH}/firebase/verify`,
|
||||
// signUp: `${ROOTS.PARTY_USER_AUTH}/firebase/sign-up`,
|
||||
// resetPassword: `${ROOTS.PARTY_USER_AUTH}/firebase/reset-password`,
|
||||
// },
|
||||
// auth0: { signIn: `${ROOTS.PARTY_USER_AUTH}/auth0/sign-in` },
|
||||
// supabase: {
|
||||
// signIn: `${ROOTS.PARTY_USER_AUTH}/supabase/sign-in`,
|
||||
// verify: `${ROOTS.PARTY_USER_AUTH}/supabase/verify`,
|
||||
// signUp: `${ROOTS.PARTY_USER_AUTH}/supabase/sign-up`,
|
||||
// updatePassword: `${ROOTS.PARTY_USER_AUTH}/supabase/update-password`,
|
||||
// resetPassword: `${ROOTS.PARTY_USER_AUTH}/supabase/reset-password`,
|
||||
// },
|
||||
},
|
||||
};
|
||||
|
@@ -9,6 +9,7 @@ import { authDemoRoutes } from './auth-demo';
|
||||
import { componentsRoutes } from './components';
|
||||
import { dashboardRoutes } from './dashboard';
|
||||
import { mainRoutes } from './main';
|
||||
import { partyUserAuthRoutes } from './party-user-auth';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@@ -48,6 +49,9 @@ export const routesSection: RouteObject[] = [
|
||||
// Components
|
||||
...componentsRoutes,
|
||||
|
||||
// party-user-auth
|
||||
...partyUserAuthRoutes,
|
||||
|
||||
// No match
|
||||
{ path: '*', element: <Page404 /> },
|
||||
];
|
||||
|
282
03_source/frontend/src/routes/sections/party-user-auth.tsx
Normal file
282
03_source/frontend/src/routes/sections/party-user-auth.tsx
Normal file
@@ -0,0 +1,282 @@
|
||||
import { lazy, Suspense } from 'react';
|
||||
import type { RouteObject } from 'react-router';
|
||||
import { Outlet } from 'react-router';
|
||||
import { GuestGuard } from 'src/auth/guard';
|
||||
import { SplashScreen } from 'src/components/loading-screen';
|
||||
import { AuthSplitLayout } from 'src/layouts/auth-split';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/** **************************************
|
||||
* Jwt
|
||||
*************************************** */
|
||||
const Jwt = {
|
||||
SignInPage: lazy(() => import('src/pages/party-user-auth/jwt/sign-in')),
|
||||
SignUpPage: lazy(() => import('src/pages/party-user-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 partyUserAuthRoutes: RouteObject[] = [
|
||||
{
|
||||
path: 'party-user-auth',
|
||||
element: (
|
||||
<Suspense fallback={<SplashScreen />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
),
|
||||
children: [authJwt, authAmplify, authFirebase, authAuth0, authSupabase],
|
||||
},
|
||||
];
|
@@ -83,6 +83,44 @@ export function OverviewAppView() {
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid size={{ xs: 12, md: 4 }}>
|
||||
<AppWidgetSummary
|
||||
title="Total party-events"
|
||||
percent={-0.1}
|
||||
total={4}
|
||||
chart={{
|
||||
colors: [theme.palette.error.main],
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
|
||||
series: [],
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid size={{ xs: 12, md: 4 }}>
|
||||
<AppWidgetSummary
|
||||
title="Total party-events"
|
||||
percent={-0.1}
|
||||
total={5}
|
||||
chart={{
|
||||
colors: [theme.palette.error.main],
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
|
||||
series: [],
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid size={{ xs: 12, md: 4 }}>
|
||||
<AppWidgetSummary
|
||||
title="Total party-events"
|
||||
percent={-0.1}
|
||||
total={6}
|
||||
chart={{
|
||||
colors: [theme.palette.error.main],
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
|
||||
series: [],
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
|
||||
<AppCurrentDownload
|
||||
title="Current download"
|
||||
|
@@ -36,7 +36,7 @@ import { EmptyContent } from 'src/components/empty-content';
|
||||
import { Iconify } from 'src/components/iconify';
|
||||
import { toast } from 'src/components/snackbar';
|
||||
import { DashboardContent } from 'src/layouts/dashboard';
|
||||
import { endpoints } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import { RouterLink } from 'src/routes/components';
|
||||
import { paths } from 'src/routes/paths';
|
||||
import type { IPartyEventItem, IProductTableFilters } from 'src/types/party-event';
|
||||
|
@@ -35,7 +35,7 @@ import { EmptyContent } from 'src/components/empty-content';
|
||||
import { Iconify } from 'src/components/iconify';
|
||||
import { toast } from 'src/components/snackbar';
|
||||
import { DashboardContent } from 'src/layouts/dashboard';
|
||||
import { endpoints } from 'src/lib/axios';
|
||||
import { endpoints } from 'src/lib/endpoints';
|
||||
import { RouterLink } from 'src/routes/components';
|
||||
import { paths } from 'src/routes/paths';
|
||||
import type { IProductItem, IProductTableFilters } from 'src/types/product';
|
||||
|
Reference in New Issue
Block a user