diff --git a/package-lock.json b/package-lock.json index 4ec6fbb..550feb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@testing-library/user-event": "^13.5.0", "axios": "^1.4.0", "hammerjs": "^2.0.8", + "jwt-decode": "^3.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-player": "^2.12.0", @@ -11506,6 +11507,11 @@ "node": ">=4.0" } }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz", diff --git a/package.json b/package.json index eb87ecc..90e98d8 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@testing-library/user-event": "^13.5.0", "axios": "^1.4.0", "hammerjs": "^2.0.8", + "jwt-decode": "^3.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-player": "^2.12.0", diff --git a/src/App.js b/src/App.js index 07c68b2..d424c4d 100644 --- a/src/App.js +++ b/src/App.js @@ -1,20 +1,23 @@ -// App.js -import React from 'react'; +import React, { useState, useEffect } from 'react'; import AppBar from '@mui/material/AppBar'; +import Avatar from '@mui/material/Avatar'; +import Box from '@mui/material/Box'; import IconButton from '@mui/material/IconButton'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; +import ExitToAppIcon from '@mui/icons-material/ExitToApp'; import { Route, Router, Routes } from 'react-router-dom'; import ConfigContext, { config } from './Config'; import LoginForm from './LoginForm'; import Main from './Main'; -import VideoPlayer from './VideoPlayer'; // 导入我们将创建的VideoPlayer组件 +import VideoPlayer from './VideoPlayer'; import { default as VuetifyLogo, default as VuetifyName } from './logo.svg'; import axios from 'axios'; import { useLocation, useNavigate } from 'react-router-dom'; - +import jwtDecode from 'jwt-decode'; + axios.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) { @@ -24,51 +27,69 @@ axios.interceptors.request.use((config) => { }); const App = () => { - const navigate = useNavigate(); // 将 navigate 声明移动到组件内部 + const navigate = useNavigate(); const location = useLocation(); + const [username, setUsername] = useState(''); + + useEffect(() => { + const token = localStorage.getItem('token'); + if (token) { + const decodedToken = jwtDecode(token); + setUsername(decodedToken.username); + } + }, []); + axios.interceptors.response.use( - (response) => { return response; }, - (error) => { - - if (error.response.status === 401) { - sessionStorage.setItem('previousLocation', location.pathname); // 使用 window.location.pathname 获取当前路径 - navigate('/login'); // 使用 window.location.assign() 进行导航 + sessionStorage.setItem('previousLocation', location.pathname); + navigate('/login'); } return Promise.reject(error); } ); + const handleLogout = () => { + localStorage.removeItem('token'); + setUsername(''); + navigate('/login'); + }; + return ( - - - -
- - +
+ + + Vuetify Logo - - Vuetify Name - - - -
- - } /> - } /> - } /> - - + + + {username && ( + + {username.charAt(0).toUpperCase()} + + {username} + + + )} + + + +
+
+
+ + } /> + } /> + } /> +
- ); };