From 1a2dfc692f8b6908287d9d1c2d940143f0b5dfe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E7=A7=8B=E6=97=AD?= Date: Sun, 19 Feb 2023 12:10:20 +0800 Subject: [PATCH] login page --- package.json | 4 +- pnpm-lock.yaml | 67 +++++++++++++++++++++++++++++- src/pages/_app.tsx | 8 +++- src/pages/index.tsx | 4 -- src/pages/login.tsx | 92 +++++++++++++++++++++++++++++++++++++++++ src/utils/validation.ts | 16 +++++++ 6 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 src/pages/login.tsx create mode 100644 src/utils/validation.ts diff --git a/package.json b/package.json index 3e74580..2105e79 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,11 @@ "@mui/icons-material": "^5.11.9", "@mui/material": "^5.11.9", "@next/font": "13.1.6", + "formik": "^2.2.9", "next": "13.1.6", "react": "18.2.0", - "react-dom": "18.2.0" + "react-dom": "18.2.0", + "yup": "^1.0.0" }, "devDependencies": { "@types/node": "18.13.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f91dd89..7634f1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,6 +13,7 @@ specifiers: eslint: ^8.34.0 eslint-config-next: ^13.1.6 eslint-config-prettier: ^8.6.0 + formik: ^2.2.9 husky: ^8.0.0 lint-staged: ^13.1.2 next: 13.1.6 @@ -20,6 +21,7 @@ specifiers: react: 18.2.0 react-dom: 18.2.0 typescript: ^4.9.5 + yup: ^1.0.0 dependencies: '@emotion/react': 11.10.6_pmekkgnqduwlme35zpnqhenc34 @@ -28,9 +30,11 @@ dependencies: '@mui/icons-material': 5.11.9_ofpk46txu7v2f5mzrtv4xsczka '@mui/material': 5.11.9_xqeqsl5kvjjtyxwyi3jhw3yuli '@next/font': 13.1.6 + formik: 2.2.9_react@18.2.0 next: 13.1.6_biqbaboplfbrettd7655fr4n2y react: 18.2.0 react-dom: 18.2.0_react@18.2.0 + yup: 1.0.0 devDependencies: '@types/node': 18.13.0 @@ -1071,6 +1075,11 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /deepmerge/2.2.1: + resolution: {integrity: sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==} + engines: {node: '>=0.10.0'} + dev: false + /define-lazy-prop/2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} @@ -1606,6 +1615,21 @@ packages: is-callable: 1.2.7 dev: true + /formik/2.2.9_react@18.2.0: + resolution: {integrity: sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==} + peerDependencies: + react: '>=16.8.0' + dependencies: + deepmerge: 2.2.1 + hoist-non-react-statics: 3.3.2 + lodash: 4.17.21 + lodash-es: 4.17.21 + react: 18.2.0 + react-fast-compare: 2.0.4 + tiny-warning: 1.0.3 + tslib: 1.14.1 + dev: false + /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -2151,10 +2175,18 @@ packages: p-locate: 5.0.0 dev: true + /lodash-es/4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + /log-update/4.0.0: resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} engines: {node: '>=10'} @@ -2500,6 +2532,10 @@ packages: object-assign: 4.1.1 react-is: 16.13.1 + /property-expr/2.0.5: + resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==} + dev: false + /punycode/2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} @@ -2519,6 +2555,10 @@ packages: scheduler: 0.23.0 dev: false + /react-fast-compare/2.0.4: + resolution: {integrity: sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==} + dev: false + /react-is/16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -2866,6 +2906,10 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true + /tiny-case/1.0.3: + resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + dev: false + /tiny-glob/0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} dependencies: @@ -2873,6 +2917,10 @@ packages: globrex: 0.1.2 dev: true + /tiny-warning/1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + dev: false + /to-fast-properties/2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -2885,6 +2933,10 @@ packages: is-number: 7.0.0 dev: true + /toposort/2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + dev: false + /tsconfig-paths/3.14.1: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} dependencies: @@ -2896,7 +2948,6 @@ packages: /tslib/1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true /tslib/2.5.0: resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} @@ -2928,6 +2979,11 @@ packages: engines: {node: '>=10'} dev: true + /type-fest/2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: false + /typed-array-length/1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: @@ -3041,3 +3097,12 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /yup/1.0.0: + resolution: {integrity: sha512-bRZIyMkoe212ahGJTE32cr2dLkJw53Va+Uw5mzsBKpcef9zCGQ23k/xtpQUfGwdWPKvCIlR8CzFwchs2rm2XpQ==} + dependencies: + property-expr: 2.0.5 + tiny-case: 1.0.3 + toposort: 2.0.2 + type-fest: 2.19.0 + dev: false diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 926739b..cb457e6 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,9 +1,15 @@ import type { AppProps } from 'next/app' +import CssBaseline from '@mui/material/CssBaseline' import '@fontsource/roboto/300.css' import '@fontsource/roboto/400.css' import '@fontsource/roboto/500.css' import '@fontsource/roboto/700.css' export default function App({ Component, pageProps }: AppProps) { - return + return ( + <> + + + + ) } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index be69a8d..39a4136 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,7 +1,3 @@ -import { Inter } from '@next/font/google' - -const inter = Inter({ subsets: ['latin'] }) - export default function Home() { return <>hello world } diff --git a/src/pages/login.tsx b/src/pages/login.tsx new file mode 100644 index 0000000..7be079a --- /dev/null +++ b/src/pages/login.tsx @@ -0,0 +1,92 @@ +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 * as yup from '@/utils/validation' + +export default function SignIn() { + const formik = useFormik({ + initialValues: { + email: '', + password: '', + }, + validateOnChange: false, + validationSchema: yup.object({ + email: yup.emailSchema, + password: yup.passwordSchema, + }), + onSubmit: (values) => { + console.log(JSON.stringify(values, null, 2)) + }, + }) + + return ( + + + + + + + 登录 + + + + + + + + + 忘记密码? + + + + + 注册 + + + + + + + ) +} diff --git a/src/utils/validation.ts b/src/utils/validation.ts new file mode 100644 index 0000000..e925cc1 --- /dev/null +++ b/src/utils/validation.ts @@ -0,0 +1,16 @@ +import * as yup from 'yup' + +export * from 'yup' + +export const emailSchema = yup + .string() + .email('请输入正确的邮箱') + .required('请输入邮箱') + +export const passwordSchema = yup + .string() + .required('请输入密码') + .matches(/^.{8,18}$/, '8~18个字符') + .matches(/^(.*)?\d+(.*)?$/, '至少一个数字') + .matches(/^(?=.*[a-z])(?=.*[A-Z])[^]*$/, '大写字母和小写字母') + .matches(/^[^\s].*[^\s]$/, '首尾字符不能是空格')