register page

This commit is contained in:
秦秋旭 2023-02-20 17:32:14 +08:00
parent 257800f5d9
commit b95a99aaff
4 changed files with 137 additions and 5 deletions

View File

@ -2,10 +2,15 @@ import axios from '@/utils/axios'
export interface LoginInputDto { export interface LoginInputDto {
email: string email: string
/** @minLength 8 */
password: string password: string
} }
export interface CreateUserDto {
email: string
password: string
username?: string
}
export interface Token { export interface Token {
accessToken: string accessToken: string
refreshToken: string refreshToken: string
@ -15,6 +20,10 @@ export interface TokenRefreshPayload {
refreshToken: string refreshToken: string
} }
export async function register(data: CreateUserDto) {
return axios.post<Token>('/api/auth/register', data)
}
export async function login(data: LoginInputDto) { export async function login(data: LoginInputDto) {
return axios.post<Token>('/api/auth/login', data) return axios.post<Token>('/api/auth/login', data)
} }

View File

@ -1,15 +1,40 @@
import { forwardRef } from 'react'
import type { AppProps } from 'next/app' import type { AppProps } from 'next/app'
import CssBaseline from '@mui/material/CssBaseline' import CssBaseline from '@mui/material/CssBaseline'
import NextLink, { type LinkProps as NextLinkProps } from 'next/link'
import { LinkProps } from '@mui/material/Link'
import { ThemeProvider, createTheme } from '@mui/material'
import '@fontsource/roboto/300.css' import '@fontsource/roboto/300.css'
import '@fontsource/roboto/400.css' import '@fontsource/roboto/400.css'
import '@fontsource/roboto/500.css' import '@fontsource/roboto/500.css'
import '@fontsource/roboto/700.css' import '@fontsource/roboto/700.css'
const NextMuiLink = forwardRef<HTMLAnchorElement, NextLinkProps>(
function NextMuiLink(props, ref) {
return <NextLink ref={ref} {...props} />
},
)
const theme = createTheme({
components: {
MuiLink: {
defaultProps: {
component: NextMuiLink,
} as LinkProps,
},
MuiButtonBase: {
defaultProps: {
LinkComponent: NextMuiLink,
},
},
},
})
export default function App({ Component, pageProps }: AppProps) { export default function App({ Component, pageProps }: AppProps) {
return ( return (
<> <ThemeProvider theme={theme}>
<CssBaseline /> <CssBaseline />
<Component {...pageProps} /> <Component {...pageProps} />
</> </ThemeProvider>
) )
} }

View File

@ -12,7 +12,7 @@ import { useRouter } from 'next/router'
import * as yup from '@/utils/validation' import * as yup from '@/utils/validation'
import * as api from '@/api' import * as api from '@/api'
export default function SignIn() { export default function Login() {
const router = useRouter() const router = useRouter()
const formik = useFormik({ const formik = useFormik({
@ -23,7 +23,7 @@ export default function SignIn() {
validateOnChange: false, validateOnChange: false,
validationSchema: yup.object({ validationSchema: yup.object({
email: yup.emailSchema, email: yup.emailSchema,
password: yup.passwordSchema, // password: yup.passwordSchema,
}), }),
onSubmit: async (values) => { onSubmit: async (values) => {
const res = await api.auth.login(values) const res = await api.auth.login(values)
@ -57,6 +57,7 @@ export default function SignIn() {
> >
<TextField <TextField
{...formik.getFieldProps('email')} {...formik.getFieldProps('email')}
required
error={formik.touched.email && !!formik.errors.email} error={formik.touched.email && !!formik.errors.email}
helperText={(formik.touched.email && formik.errors.email) || ' '} helperText={(formik.touched.email && formik.errors.email) || ' '}
fullWidth fullWidth
@ -67,6 +68,7 @@ export default function SignIn() {
/> />
<TextField <TextField
{...formik.getFieldProps('password')} {...formik.getFieldProps('password')}
required
error={formik.touched.password && !!formik.errors.password} error={formik.touched.password && !!formik.errors.password}
helperText={ helperText={
(formik.touched.password && formik.errors.password) || ' ' (formik.touched.password && formik.errors.password) || ' '

96
src/pages/register.tsx Normal file
View File

@ -0,0 +1,96 @@
import Avatar from '@mui/material/Avatar'
import Button from '@mui/material/Button'
import TextField from '@mui/material/TextField'
import Link from '@mui/material/Link'
import Grid from '@mui/material/Grid'
import Box from '@mui/material/Box'
import LockOutlinedIcon from '@mui/icons-material/LockOutlined'
import Typography from '@mui/material/Typography'
import Container from '@mui/material/Container'
import { useFormik } from 'formik'
import { useRouter } from 'next/router'
import * as yup from '@/utils/validation'
import * as api from '@/api'
export default function Register() {
const router = useRouter()
const formik = useFormik({
initialValues: {
email: '',
password: '',
},
validateOnChange: false,
validationSchema: yup.object({
email: yup.emailSchema,
password: yup.passwordSchema,
}),
onSubmit: async (values) => {
const res = await api.auth.register(values)
localStorage.setItem('accessToken', res.data.accessToken)
localStorage.setItem('refreshToken', res.data.refreshToken)
router.push('/')
},
})
return (
<Container component="main" maxWidth="xs">
<Box
sx={{
marginTop: '20vh',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
</Typography>
<Box
component="form"
onSubmit={formik.handleSubmit}
noValidate
sx={{ mt: 1 }}
>
<TextField
{...formik.getFieldProps('email')}
required
error={formik.touched.email && !!formik.errors.email}
helperText={(formik.touched.email && formik.errors.email) || ' '}
fullWidth
label="邮箱"
autoComplete="email"
autoFocus
sx={{ mt: 1 }}
/>
<TextField
{...formik.getFieldProps('password')}
required
error={formik.touched.password && !!formik.errors.password}
helperText={
(formik.touched.password && formik.errors.password) || ' '
}
fullWidth
label="密码"
type="password"
autoComplete="current-password"
sx={{ mt: 1 }}
/>
<Button type="submit" fullWidth variant="contained" sx={{ mt: 1 }}>
</Button>
<Grid container justifyContent="flex-end" sx={{ mt: 2 }}>
<Grid item>
<Link href="/login" variant="body2">
</Link>
</Grid>
</Grid>
</Box>
</Box>
</Container>
)
}