diff --git a/frontend/src/Route.tsx b/frontend/src/Route.tsx
index 7726c68..798ca70 100644
--- a/frontend/src/Route.tsx
+++ b/frontend/src/Route.tsx
@@ -1,13 +1,30 @@
-import { Routes, Route, Outlet } from "react-router-dom";
+import { Routes, Route, Outlet, createBrowserRouter, RouterProvider } from "react-router-dom";
import Login from '@/views/Login'
+import Register from '@/views/Register'
+import { ScrollRestoration } from "react-router-dom";
-export function PageRoute() {
+const router = createBrowserRouter([
+ { path: "*", Component: Root },
+]);
+
+function Root() {
return (
<>
}>
} />
+ } />
+
+ >
+ )
+}
+
+
+export function PageRoute() {
+ return (
+ <>
+ ;
>
)
}
diff --git a/frontend/src/apis/apis.ts b/frontend/src/apis/apis.ts
new file mode 100644
index 0000000..d76df1e
--- /dev/null
+++ b/frontend/src/apis/apis.ts
@@ -0,0 +1,21 @@
+interface tokenData {
+ accessToken: string
+ selectedProfile: {
+ name: string
+ }
+}
+
+export async function login(username: string, password: string) {
+ const v = await fetch(import.meta.env.VITE_APIADDR + "/api/yggdrasil/authserver/authenticate", {
+ method: "POST",
+ body: JSON.stringify({
+ "username": username,
+ "password": password,
+ })
+ })
+ const data = await v.json()
+ if (!v.ok) {
+ throw data?.errorMessage
+ }
+ return data as tokenData
+}
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index 095cf67..c65c6fd 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -1,15 +1,12 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
-import { BrowserRouter } from "react-router-dom";
import CssBaseline from '@mui/material/CssBaseline';
ReactDOM.createRoot(document.getElementById('root')!).render(
-
-
)
diff --git a/frontend/src/utils/email.ts b/frontend/src/utils/email.ts
new file mode 100644
index 0000000..2d88b7d
--- /dev/null
+++ b/frontend/src/utils/email.ts
@@ -0,0 +1,3 @@
+export function checkEmail(email: string) {
+ return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email);
+}
\ No newline at end of file
diff --git a/frontend/src/views/Login.tsx b/frontend/src/views/Login.tsx
index 4775e8f..097b400 100644
--- a/frontend/src/views/Login.tsx
+++ b/frontend/src/views/Login.tsx
@@ -15,7 +15,9 @@ import Backdrop from '@mui/material/Backdrop';
import CircularProgress from '@mui/material/CircularProgress';
import { useSetAtom } from 'jotai';
import { token, username } from '@/store/store'
-
+import { login } from '@/apis/apis'
+import { checkEmail } from '@/utils/email'
+import { Link as RouterLink } from "react-router-dom";
function Loading() {
return (
@@ -30,27 +32,6 @@ function Loading() {
)
}
-interface tokenData {
- accessToken: string
- selectedProfile: {
- name: string
- }
-}
-
-async function tologin(username: string, password: string) {
- const v = await fetch(import.meta.env.VITE_APIADDR + "/api/yggdrasil/authserver/authenticate", {
- method: "POST",
- body: JSON.stringify({
- "username": username,
- "password": password,
- })
- })
- const data = await v.json()
- if (!v.ok) {
- throw data?.errorMessage
- }
- return data as tokenData
-}
export default function SignIn() {
@@ -67,13 +48,13 @@ export default function SignIn() {
email: data.get('email')?.toString(),
password: data.get('password')?.toString(),
}
- if (!postData.email?.includes("@")) {
+ if (!checkEmail(postData.email ?? "")) {
setEmailErr("需要为邮箱")
return
}
if (loading) return
setLoading(true)
- tologin(postData.email, postData.password ?? "").
+ login(postData.email!, postData.password ?? "").
then(v => {
if (!v) return
setToken(v.accessToken)
@@ -137,7 +118,7 @@ export default function SignIn() {
-
+
{"注册"}
diff --git a/frontend/src/views/Register.tsx b/frontend/src/views/Register.tsx
new file mode 100644
index 0000000..b58df2d
--- /dev/null
+++ b/frontend/src/views/Register.tsx
@@ -0,0 +1,130 @@
+import * as React from 'react';
+import Avatar from '@mui/material/Avatar';
+import Button from '@mui/material/Button';
+import CssBaseline from '@mui/material/CssBaseline';
+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 { useState } from 'react';
+import { checkEmail } from '@/utils/email';
+import { Link as RouterLink } from "react-router-dom";
+
+
+
+export default function SignUp() {
+ const [emailErr, setEmailErr] = useState("");
+ const [passErr, setpassErr] = useState("");
+
+
+
+ const handleSubmit = (event: React.FormEvent) => {
+ setEmailErr("")
+ setpassErr("")
+ event.preventDefault();
+ const data = new FormData(event.currentTarget);
+ const d = {
+ email: data.get('email')?.toString(),
+ password: data.get('password')?.toString(),
+ password1: data.get('password1')?.toString(),
+ username: data.get("username")?.toString()
+ }
+ if (!checkEmail(d.email ?? "")) {
+ setEmailErr("需要为邮箱")
+ return
+ }
+ if (d.password != d.password1) {
+ setpassErr("密码不一致")
+ return
+ }
+ if (d.password == "") {
+ setpassErr("密码为空")
+ return
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ 注册
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+
+
+
+
+ );
+}
\ No newline at end of file