'use client' // React Imports import { useState } from 'react' // Next Imports import Link from 'next/link' import { useParams, useRouter, useSearchParams } from 'next/navigation' // MUI Imports import useMediaQuery from '@mui/material/useMediaQuery' import { styled, useTheme } from '@mui/material/styles' import Typography from '@mui/material/Typography' import IconButton from '@mui/material/IconButton' import InputAdornment from '@mui/material/InputAdornment' import Checkbox from '@mui/material/Checkbox' import Button from '@mui/material/Button' import FormControlLabel from '@mui/material/FormControlLabel' import Divider from '@mui/material/Divider' import Alert from '@mui/material/Alert' // Third-party Imports import { Controller, useForm } from 'react-hook-form' import { valibotResolver } from '@hookform/resolvers/valibot' import { email, object, minLength, string, pipe, nonEmpty } from 'valibot' import type { SubmitHandler } from 'react-hook-form' import type { InferInput } from 'valibot' import classnames from 'classnames' // Type Imports import type { SystemMode } from '@core/types' import type { Locale } from '@/configs/i18n' // Component Imports import Logo from '@components/layout/shared/Logo' import CustomTextField from '@core/components/mui/TextField' // Config Imports import themeConfig from '@configs/themeConfig' // Hook Imports import { useImageVariant } from '@core/hooks/useImageVariant' import { useSettings } from '@core/hooks/useSettings' // Util Imports import { getLocalizedUrl } from '@/utils/i18n' import { useAuthMutation } from '../services/mutations/auth' // Styled Custom Components const LoginIllustration = styled('img')(({ theme }) => ({ zIndex: 2, blockSize: 'auto', maxBlockSize: 680, maxInlineSize: '100%', margin: theme.spacing(12), [theme.breakpoints.down(1536)]: { maxBlockSize: 550 }, [theme.breakpoints.down('lg')]: { maxBlockSize: 450 } })) const MaskImg = styled('img')({ blockSize: 'auto', maxBlockSize: 355, inlineSize: '100%', position: 'absolute', insetBlockEnd: 0, zIndex: -1 }) type ErrorType = { message: string[] } type FormData = InferInput const schema = object({ email: pipe(string(), minLength(1, 'This field is required'), email('Email is invalid')), password: pipe( string(), nonEmpty('This field is required'), minLength(5, 'Password must be at least 5 characters long') ) }) const Login = ({ mode }: { mode: SystemMode }) => { // States const [isPasswordShown, setIsPasswordShown] = useState(false) const [errorState, setErrorState] = useState(null) const { login } = useAuthMutation() // Vars const darkImg = '/images/pages/auth-mask-dark.png' const lightImg = '/images/pages/auth-mask-light.png' const darkIllustration = '/images/illustrations/auth/v2-login-dark.png' const lightIllustration = '/images/illustrations/auth/v2-login-light.png' const borderedDarkIllustration = '/images/illustrations/auth/v2-login-dark-border.png' const borderedLightIllustration = '/images/illustrations/auth/v2-login-light-border.png' // Hooks const router = useRouter() const searchParams = useSearchParams() const { lang: locale } = useParams() const { settings } = useSettings() const theme = useTheme() const hidden = useMediaQuery(theme.breakpoints.down('md')) const authBackground = useImageVariant(mode, lightImg, darkImg) const { control, handleSubmit, formState: { errors } } = useForm({ resolver: valibotResolver(schema), defaultValues: { email: 'guapatlu@jambi.com', password: '12345678' } }) const characterIllustration = useImageVariant( mode, lightIllustration, darkIllustration, borderedLightIllustration, borderedDarkIllustration ) const handleClickShowPassword = () => setIsPasswordShown(show => !show) const onSubmit: SubmitHandler = async (data: FormData) => { login.mutate(data) const redirectURL = searchParams.get('redirectTo') ?? '/' router.replace(getLocalizedUrl(redirectURL, locale as Locale)) } return (
{!hidden && }
{`Welcome to ${themeConfig.templateName}! 馃憢馃徎`} Please sign-in to your account and start the adventure
Email: admin@vuexy.com / Pass:{' '} admin
{}} onSubmit={handleSubmit(onSubmit)} className='flex flex-col gap-6' > ( { field.onChange(e.target.value) errorState !== null && setErrorState(null) }} {...((errors.email || errorState !== null) && { error: true, helperText: errors?.email?.message || errorState?.message[0] })} /> )} /> ( { field.onChange(e.target.value) errorState !== null && setErrorState(null) }} slotProps={{ input: { endAdornment: ( e.preventDefault()} > ) } }} {...(errors.password && { error: true, helperText: errors.password.message })} /> )} />
} label='Remember me' /> Forgot password?
New on our platform? Create an account
or
) } export default Login