auth token

parent 09d90b26
import React from 'react';
import { BrowserRouter, Routes, Route, Outlet } from 'react-router-dom';
import { BrowserRouter, Routes, Route, Navigate, Outlet } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { RootState } from '../src/main';
import Header from './components/Header/Header';
import AuthPage from './pages/AuthPage/AuthPage';
import HomePage from './pages/HomePage/HomePage';
import RequestPage from './pages/RequestPage/RequestPage';
import AddPage from './pages/(crudPages)/AddPage';
import EditPage from './pages/(crudPages)/EditPage';
import 'react-material-symbols/rounded';
import './App.css';
const AuthLayout = () => {
const AuthLayout: React.FC = () => {
return (
<>
<Header />
<Outlet />
</>
)
}
);
};
const App: React.FC = () => {
const token = useSelector((state: RootState) => state.auth.token);
return (
<BrowserRouter>
<Routes>
<Route path="/auth" element={<AuthPage />} />
<Route element={<AuthLayout />} >
<Route path="/" element={<HomePage />} />
<Route path="/add" element={<AddPage />} />
<Route path="/edit/:id" element={<EditPage />} />
<Route path="/requests" element={<RequestPage />} />
</Route>
{!token ? (
<>
<Route path="/auth" element={<AuthPage />} />
<Route path="/*" element={<Navigate to="/auth" />} />
</>
) : (
<Route element={<AuthLayout />}>
<Route path="/" element={<HomePage />} />
<Route path="/add" element={<AddPage />} />
<Route path="/edit/:id" element={<EditPage />} />
<Route path="/requests" element={<RequestPage />} />
<Route path="/*" element={<Navigate to="/" />} />
</Route>
)}
</Routes>
</BrowserRouter>
);
......
import React, { useState } from 'react';
import { MaterialSymbol } from 'react-material-symbols';
import { Link } from 'react-router-dom';
import { Link, useNavigate } from 'react-router-dom';
import { Menu, Button, Drawer } from 'antd';
import { useDispatch } from 'react-redux';
import { clearToken } from '../../store/store';
import type { MenuProps } from 'antd';
import './Header.css';
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuItem[] = [
{ key: '1', icon: <MaterialSymbol icon='list' size={24} color='#fff'/>, label: <Link to="/">Список организаций</Link> },
{ key: '2', icon: <MaterialSymbol icon='developer_guide' size={24} color='#fff'/>, label: <Link to="/">Справочники</Link> },
{ key: '3', icon: <MaterialSymbol icon='info' size={24} color='#fff'/>, label: <Link to="/requests">Информация о запросах</Link> },
{ key: '1', icon: <MaterialSymbol icon='list' size={24} color='#fff' />, label: <Link to="/">Список организаций</Link> },
{ key: '2', icon: <MaterialSymbol icon='developer_guide' size={24} color='#fff' />, label: <Link to="/">Справочники</Link> },
{ key: '3', icon: <MaterialSymbol icon='info' size={24} color='#fff' />, label: <Link to="/requests">Информация о запросах</Link> },
];
const Header: React.FC = () => {
const [openMenu, setOpenMenu] = useState<boolean>(false);
const dispatch = useDispatch();
const navigate = useNavigate();
const handleLogout = () => {
dispatch(clearToken());
navigate('/auth');
};
return (
<header className="header">
<div className="header_left">
<Button
<Button
type='text'
onClick={() => {
setOpenMenu(true);
......@@ -27,20 +36,20 @@ const Header: React.FC = () => {
>
<MaterialSymbol icon='menu' size={24} color='#fff' />
</Button>
<Drawer
open={openMenu}
<Drawer
open={openMenu}
onClose={() => {
setOpenMenu(false);
}}
placement='left'
className='custom-drawer'
title="ЕСУТД"
title="ЕСУТДjh"
>
<Menu
theme='dark'
items={items}
defaultSelectedKeys={['1']}
mode='inline'
<Menu
theme='dark'
items={items}
defaultSelectedKeys={['1']}
mode='inline'
className="menu"
onClick={() => {
setOpenMenu(false)
......@@ -49,11 +58,11 @@ const Header: React.FC = () => {
</Drawer>
<h1 className="header_title">ЕСУТД</h1>
</div>
<Button type='text' className="header_logout">
<Button type='text' className="header_logout" onClick={handleLogout}>
<MaterialSymbol icon='logout' size={24} color='#fff' />
</Button>
</header>
)
}
export default Header
export default Header;
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { RootState } from '../../main'; // Add this import to get the RootState
interface Organization {
id: number;
......@@ -13,16 +14,16 @@ interface Organization {
host: string;
}
export const apiSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({
baseUrl: "/esutd/api/organizations",
prepareHeaders: (headers) => {
const accessToken = `OTA3MTEzNzctYzA3YS00NzRkLTkyNDgtNzk4ZmEzMzViNzlj`;
prepareHeaders: (headers, { getState }) => {
const state = getState() as RootState;
const accessToken = state.auth.token;
if (accessToken) {
headers.set("Authorization", `Bearer Token ${accessToken}`);
headers.set("Authorization", `Bearer ${accessToken}`);
}
headers.set("Accept", "*/*");
......@@ -53,7 +54,7 @@ export const apiSlice = createApi({
method: 'PUT',
body: rest,
}),
invalidatesTags: ["organizations"]
invalidatesTags: ["organizations"],
}),
deleteOrganization: builder.mutation<{ success: boolean; id: number }, number>({
query: (orgId) => ({
......
......@@ -5,6 +5,8 @@ import { Provider } from 'react-redux';
import './index.css';
import store from '../src/store/store.ts';
export type RootState = ReturnType<typeof store.getState>;
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<Provider store={store}>
......
import React from 'react';
import { Input, Typography, Button } from 'antd';
import React, { useState } from 'react';
import { Input, Typography, Button, notification } from 'antd';
import { useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { setToken } from '../../store/store';
import styles from './AuthPage.module.css';
// import { useGetOrganizationsQuery } from '../../features/api/apiSlice';
const AuthPage: React.FC = () => {
const [token, setTokenInput] = useState('');
const navigate = useNavigate();
const dispatch = useDispatch();
const handleLogin = async () => {
try {
const response = await fetch('http://77.243.80.217:8080/esutd/api/organizations/list', {
headers: {
'Authorization': `Bearer ${token}`,
},
});
if (response.status === 200) {
dispatch(setToken(token));
navigate('/');
} else if (response.status === 403) {
notification.error({
message: 'Access Denied',
description: 'You do not have permission to access this resource.',
});
} else {
notification.error({
message: 'Login Failed',
description: 'An error occurred while trying to login.',
});
}
} catch (error) {
notification.error({
message: 'Login Error',
description: 'An error occurred while trying to login.',
});
}
};
return (
<div className={styles.wrapper}>
<div className={styles.form}>
......@@ -10,11 +48,13 @@ const AuthPage: React.FC = () => {
<Input
placeholder="введите токен"
className={styles.input_controller}
value={token}
onChange={(e) => setTokenInput(e.target.value)}
/>
<Button className={styles.form_btn} type="primary">Войти</Button>
<Button className={styles.form_btn} type="primary" onClick={handleLogin}>Войти</Button>
</div>
</div>
);
};
export default AuthPage;
\ No newline at end of file
export default AuthPage;
import { configureStore, Store } from '@reduxjs/toolkit';
import { configureStore, Store, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { apiSlice } from '../features/api/apiSlice';
import mainPaginationReducer from '../features/pagination/mainPagination';
interface AuthState {
token: string | null;
}
const initialState: AuthState = {
token: localStorage.getItem('token'),
};
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
setToken: (state, action: PayloadAction<string>) => {
state.token = action.payload;
localStorage.setItem('token', action.payload);
},
clearToken: (state) => {
state.token = null;
localStorage.removeItem('token');
},
},
});
export const { setToken, clearToken } = authSlice.actions;
const store: Store = configureStore({
reducer: {
auth: authSlice.reducer,
mainPagination: mainPaginationReducer,
[apiSlice.reducerPath]: apiSlice.reducer,
},
......@@ -12,3 +38,4 @@ const store: Store = configureStore({
});
export default store;
......@@ -8,7 +8,7 @@ export default defineConfig({
'/api': {
target: 'http://77.243.80.217:8080',
changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, ''),
rewrite: (path) => path.replace(/^\/api/, ''),
secure: false,
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment