finish auth

parent 248c660b
......@@ -18,7 +18,8 @@
"react-material-symbols": "^4.4.0",
"react-redux": "^9.1.2",
"react-router": "^6.25.1",
"react-router-dom": "^6.25.1"
"react-router-dom": "^6.25.1",
"redux-persist": "^6.0.0"
},
"devDependencies": {
"@types/node": "^20.14.12",
......@@ -3908,6 +3909,14 @@
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="
},
"node_modules/redux-persist": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
"integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
"peerDependencies": {
"redux": ">4.0.0"
}
},
"node_modules/redux-thunk": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
......
......@@ -9,7 +9,7 @@ import './Header.css';
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuItem[] = [
const MenuItems: 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> },
......@@ -47,7 +47,7 @@ const Header: React.FC = () => {
>
<Menu
theme='dark'
items={items}
items={MenuItems}
defaultSelectedKeys={['1']}
mode='inline'
className="menu"
......
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { RootState } from '../../main'; // Add this import to get the RootState
import { RootState } from '../../main';
interface Organization {
id: number;
......@@ -33,14 +33,14 @@ export const apiSlice = createApi({
}),
tagTypes: ["organizations"],
endpoints: (builder) => ({
getOrganizations: builder.query<Organization[], void>({
getOrganizations: builder.query<Organization[], void>({ // получить информацию
query: () => '/list',
providesTags: ["organizations"],
providesTags: ["organizations"], // для управления кэшем или инвалидации данных в системе управления состоянием
}),
getOrganization: builder.query<Organization, string>({
query: (orgId) => `/info?id=${orgId}`,
}),
addNewOrganization: builder.mutation<Organization, Partial<Organization>>({
}),
addNewOrganization: builder.mutation<Organization, Partial<Organization>>({ // изменение данных
query: (initialOrg) => ({
url: '/add',
method: 'POST',
......
......@@ -3,14 +3,17 @@ import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import { Provider } from 'react-redux';
import './index.css';
import store from '../src/store/store.ts';
import {store, persistor} from '../src/store/store.ts';
import { PersistGate } from 'redux-persist/integration/react';
export type RootState = ReturnType<typeof store.getState>;
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<Provider store={store}>
<App />
<PersistGate loading={null} persistor={persistor}>
<App/>
</PersistGate>
</Provider>
</React.StrictMode>,
);
......@@ -7,13 +7,13 @@ import styles from './AuthPage.module.css';
// import { useGetOrganizationsQuery } from '../../features/api/apiSlice';
const AuthPage: React.FC = () => {
const [token, setTokenInput] = useState('');
const [token, setTokenInput] = useState<string>('');
const navigate = useNavigate();
const dispatch = useDispatch();
const handleLogin = async () => {
try {
const response = await fetch('http://77.243.80.217:8080/esutd/api/organizations/list', {
const response = await fetch('http://77.243.80.217:8080/esutd/api/organizations/list', { // Get запрос
headers: {
'Authorization': `Bearer ${token}`,
},
......
......@@ -3,6 +3,7 @@ import { useNavigate } from 'react-router';
import { Button, Space, Tag, Modal, message } from 'antd';
import type { TableProps } from 'antd';
import { useDeleteOrganizationMutation } from '../../features/api/apiSlice';
import { getStatusText, getStatusColor } from './utils';
export interface DataType {
id: number;
......@@ -13,24 +14,6 @@ export interface DataType {
host: string;
}
const getStatusText = (status: number) => {
switch (status) {
case 0: return "удален";
case 1: return "заблокирован";
case 2: return "активен";
default: return "неизвестно";
}
}
const getStatusColor = (status: number) => {
switch (status) {
case 0: return 'red';
case 1: return 'orange';
case 2: return 'green';
default: return 'grey';
}
}
export const columns: TableProps<DataType>['columns'] = [
{
title: "ID",
......@@ -107,22 +90,16 @@ export const ActionColumn: React.FC<{ data: DataType }> = ({ data }) => {
return (
<Space>
<Button onClick={handleEditClick} />
<Button onClick={showDeleteModal} />
<Button onClick={handleEditClick}>Изменить</Button>
<Button onClick={showDeleteModal} type="primary" danger>Удалить</Button>
<Modal
open={open}
title={`Вы уверены в том, что хотите удалить ${data.name}?`}
footer={() => (
<div style={{ textAlign: 'start', marginTop: '1rem' }}>
<Button key="submit" type="primary" danger onClick={handleDeleteModalOk} style={{ marginRight: '.5rem' }}>
Удалить
</Button>
<Button key="back" onClick={handleDeleteModalCancel}>
Назад
</Button>
</div>
)}
/>
title={`Вы уверены, что хотите удалить ${data.name}?`}
onOk={handleDeleteModalOk}
onCancel={handleDeleteModalCancel}
>
<p>Подтвердите удаление организации.</p>
</Modal>
</Space>
)
}
export const getStatusText = (status: number) => {
switch (status) {
case 0: return "удален";
case 1: return "заблокирован";
case 2: return "активен";
default: return "неизвестно";
}
}
export const getStatusColor = (status: number) => {
switch (status) {
case 0: return 'red';
case 1: return 'orange';
case 2: return 'green';
default: return 'grey';
}
}
import { configureStore, Store, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { apiSlice } from '../features/api/apiSlice';
import mainPaginationReducer from '../features/pagination/mainPagination';
import storage from 'redux-persist/lib/storage';
import { persistReducer, persistStore } from 'redux-persist';
interface AuthState {
token: string | null;
}
const initialState: AuthState = {
token: localStorage.getItem('token'),
token: null,
};
const authSlice = createSlice({
......@@ -15,27 +16,34 @@ const authSlice = createSlice({
initialState,
reducers: {
setToken: (state, action: PayloadAction<string>) => {
state.token = action.payload;
localStorage.setItem('token', action.payload);
state.token = action.payload;
},
clearToken: (state) => {
state.token = null;
localStorage.removeItem('token');
},
},
});
export const { setToken, clearToken } = authSlice.actions;
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, authSlice.reducer);
const store: Store = configureStore({
reducer: {
auth: authSlice.reducer,
auth: persistedReducer,
mainPagination: mainPaginationReducer,
[apiSlice.reducerPath]: apiSlice.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(apiSlice.middleware),
getDefaultMiddleware({ serializableCheck: false}).concat(apiSlice.middleware),
});
export default store;
const persistor = persistStore(store);
export { store, persistor };
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