fetcing apiSlice

parent 15c2b0eb
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
interface Organization { interface Organization {
id: number | string; id: number;
bin: string; bin: string;
organization_code: string; code: string;
organization_name: string; name: string;
status: string; status: number;
created: string;
deleted: null;
login: string;
password: string;
host: string; host: string;
} }
export const apiSlice = createApi({ export const apiSlice = createApi({
reducerPath: 'api', reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: "https://669f8d88b132e2c136fe5106.mockapi.io/api/v1" }), baseQuery: fetchBaseQuery({
tagTypes: ["organizations"], // Определяет типы тегов для инвалидации кэша или инвалидации данных, связанных с конкретными запросами или мутациями. baseUrl: "/esutd/api/organizations",
prepareHeaders: (headers, { getState }) => {
const accessToken = `OTA3MTEzNzctYzA3YS00NzRkLTkyNDgtNzk4ZmEzMzViNzlj`;
if (accessToken) {
headers.set("Authorization", `Bearer Token ${accessToken}`);
}
headers.set("Accept", "*/*");
return headers;
},
}),
tagTypes: ["organizations"],
endpoints: (builder) => ({ endpoints: (builder) => ({
getOrganizations: builder.query<Organization[], void>({ getOrganizations: builder.query<Organization[], void>({
query: () => '/organizations', query: () => '/list',
providesTags: ["organizations"], // Определяет теги, которые будут инвалидированы при получении данных, чтобы обновить кэш, связанный с этими данными. providesTags: ["organizations"],
}), }),
getOrganization: builder.query<Organization, string>({ getOrganization: builder.query<Organization, string>({
query: (orgId) => `/organizations/${orgId}`, query: (orgId) => `/info?id=${orgId}`,
}), }),
addNewOrganization: builder.mutation<Organization, Partial<Organization>>({ addNewOrganization: builder.mutation<Organization, Partial<Organization>>({
query: (initialOrg) => ({ query: (initialOrg) => ({
url: '/organizations', url: '/add',
method: 'POST', method: 'POST',
body: initialOrg, body: initialOrg,
}), }),
invalidatesTags: ["organizations"], // при успешном выполнении этой мутации необходимо инвалидировать теги, связанные с организациями, чтобы обновить кэш. invalidatesTags: ["organizations"],
}), }),
editOrganization: builder.mutation<Organization, Partial<Organization>>({ editOrganization: builder.mutation<Organization, Partial<Organization>>({
query: ({ id, ...rest }) => ({ query: ({ id, ...rest }) => ({
url: `/organizations/${id}`, url: `/edit?id=${id}`,
method: 'PUT', method: 'PUT',
body: rest, body: rest,
}), }),
...@@ -38,7 +56,7 @@ export const apiSlice = createApi({ ...@@ -38,7 +56,7 @@ export const apiSlice = createApi({
}), }),
deleteOrganization: builder.mutation<{ success: boolean; id: number }, number>({ deleteOrganization: builder.mutation<{ success: boolean; id: number }, number>({
query: (orgId) => ({ query: (orgId) => ({
url: `/organizations/${orgId}`, url: `/delete?id=${orgId}`,
method: 'DELETE', method: 'DELETE',
}), }),
invalidatesTags: ["organizations"], invalidatesTags: ["organizations"],
......
import React from 'react' import React from 'react';
import ReactDOM from 'react-dom/client' import ReactDOM from 'react-dom/client';
import App from './App.tsx' import App from './App.tsx';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import './index.css' import './index.css';
import store from '../src/store/store.ts'; import store from '../src/store/store.ts';
ReactDOM.createRoot(document.getElementById('root')!).render( ReactDOM.createRoot(document.getElementById('root')!).render(
...@@ -11,4 +11,4 @@ ReactDOM.createRoot(document.getElementById('root')!).render( ...@@ -11,4 +11,4 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
<App /> <App />
</Provider> </Provider>
</React.StrictMode>, </React.StrictMode>,
) );
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useNavigate } from 'react-router'; import { useNavigate } from 'react-router';
import { MaterialSymbol } from 'react-material-symbols';
import { Button, Space, Tag, Modal, message } from 'antd'; import { Button, Space, Tag, Modal, message } from 'antd';
import type { TableProps } from 'antd'; import type { TableProps } from 'antd';
import './Homepage.css';
import { useDeleteOrganizationMutation } from '../../features/api/apiSlice'; import { useDeleteOrganizationMutation } from '../../features/api/apiSlice';
export interface DataType { export interface DataType {
id: string | number; id: number;
bin: string; bin: string;
organization_code: string; code: string;
organization_name: string; name: string;
status: string; status: number;
host: string; 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'] = [ export const columns: TableProps<DataType>['columns'] = [
{ {
title: "ID", title: "ID",
...@@ -28,12 +44,12 @@ export const columns: TableProps<DataType>['columns'] = [ ...@@ -28,12 +44,12 @@ export const columns: TableProps<DataType>['columns'] = [
}, },
{ {
title: "Код организации", title: "Код организации",
dataIndex: "organization_code", dataIndex: "code",
key: "code" key: "code"
}, },
{ {
title: "Наименование организации", title: "Наименование организации",
dataIndex: "organization_name", dataIndex: "name",
key: "name" key: "name"
}, },
{ {
...@@ -45,16 +61,11 @@ export const columns: TableProps<DataType>['columns'] = [ ...@@ -45,16 +61,11 @@ export const columns: TableProps<DataType>['columns'] = [
title: "Статус", title: "Статус",
dataIndex: "status", dataIndex: "status",
key: "status", key: "status",
render: (_, record) => { render: (_, record) => (
const color = record.status === '0' ? 'red' : record.status === '1' ? 'processing' : 'green'; <Tag color={getStatusColor(record.status)} style={{ fontSize: '14px' }}>
return ( {getStatusText(record.status)}
<p> </Tag>
<Tag color={color} style={{ fontSize: '14px' }}> )
{record.status === '0' ? 'удален' : record.status === '1' ? 'заблокирован' : 'активен'}
</Tag>
</p>
)
}
}, },
{ {
title: "Действия", title: "Действия",
...@@ -78,7 +89,7 @@ export const ActionColumn: React.FC<{ data: DataType }> = ({ data }) => { ...@@ -78,7 +89,7 @@ export const ActionColumn: React.FC<{ data: DataType }> = ({ data }) => {
const handleDeleteModalOk = async () => { const handleDeleteModalOk = async () => {
try { try {
await deleteOrganization(Number(data.id)).unwrap(); await deleteOrganization(data.id).unwrap();
message.success('Организация успешно удалена!'); message.success('Организация успешно удалена!');
setOpen(false); setOpen(false);
} catch (err) { } catch (err) {
...@@ -91,16 +102,16 @@ export const ActionColumn: React.FC<{ data: DataType }> = ({ data }) => { ...@@ -91,16 +102,16 @@ export const ActionColumn: React.FC<{ data: DataType }> = ({ data }) => {
}; };
const handleEditClick = () => { const handleEditClick = () => {
navigate(`/edit/${data.id.toString()}`); navigate(`/edit/${data.id}`);
} }
return ( return (
<Space> <Space>
<Button onClick={handleEditClick} icon={<MaterialSymbol icon='visibility' size={22} />} /> <Button onClick={handleEditClick} />
<Button onClick={showDeleteModal} icon={<MaterialSymbol icon='delete' size={22} />} /> <Button onClick={showDeleteModal} />
<Modal <Modal
open={open} open={open}
title={`Вы уверены в том, что хотите удалить ${data.organization_name}?`} title={`Вы уверены в том, что хотите удалить ${data.name}?`}
footer={() => ( footer={() => (
<div style={{ textAlign: 'start', marginTop: '1rem' }}> <div style={{ textAlign: 'start', marginTop: '1rem' }}>
<Button key="submit" type="primary" danger onClick={handleDeleteModalOk} style={{ marginRight: '.5rem' }}> <Button key="submit" type="primary" danger onClick={handleDeleteModalOk} style={{ marginRight: '.5rem' }}>
...@@ -114,4 +125,4 @@ export const ActionColumn: React.FC<{ data: DataType }> = ({ data }) => { ...@@ -114,4 +125,4 @@ export const ActionColumn: React.FC<{ data: DataType }> = ({ data }) => {
/> />
</Space> </Space>
) )
} }
\ No newline at end of file
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { useNavigate } from 'react-router'; import { useNavigate } from 'react-router';
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import { MaterialSymbol } from 'react-material-symbols';
import { Button, Pagination, Spin, Table } from 'antd'; import { Button, Pagination, Spin, Table } from 'antd';
import { useGetOrganizationsQuery, } from '../../features/api/apiSlice'; import { useGetOrganizationsQuery } from '../../features/api/apiSlice';
import { setCurrentPage, setTotalOrgNumber } from '../../features/pagination/mainPagination'; import { setCurrentPage, setTotalOrgNumber } from '../../features/pagination/mainPagination';
import { DataType, columns } from './Columns'; import { DataType, columns } from './Columns';
import './Homepage.css'; import './Homepage.css';
...@@ -42,7 +41,16 @@ const HomePage: React.FC = () => { ...@@ -42,7 +41,16 @@ const HomePage: React.FC = () => {
if (isLoading) { if (isLoading) {
table = <Spin /> table = <Spin />
} else if (isSuccess) { } else if (isSuccess) {
const dataSource = orgs.map((org) => ({ ...org, key: org.id })); const dataSource = orgs.map((org) => ({
id: org.id,
bin: org.bin,
code: org.code,
name: org.name,
host: org.host,
status: org.status,
key: org.id
}));
table = <Table dataSource={paginatedData(dataSource)} columns={columns} pagination={false} /> table = <Table dataSource={paginatedData(dataSource)} columns={columns} pagination={false} />
} else if (isError) { } else if (isError) {
table = <div>{error.toString()}</div> table = <div>{error.toString()}</div>
...@@ -58,7 +66,7 @@ const HomePage: React.FC = () => { ...@@ -58,7 +66,7 @@ const HomePage: React.FC = () => {
<div className="container"> <div className="container">
<section className='section'> <section className='section'>
<div className="add"> <div className="add">
<Button icon={<MaterialSymbol icon='add_circle' size={20} color='#0E2B52' />} className='add_title' onClick={handleAddClick}> <Button className='add_title' onClick={handleAddClick}>
Добавить Добавить
</Button> </Button>
</div> </div>
......
...@@ -9,6 +9,6 @@ const store: Store = configureStore({ ...@@ -9,6 +9,6 @@ const store: Store = configureStore({
}, },
middleware: (getDefaultMiddleware) => middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(apiSlice.middleware), getDefaultMiddleware().concat(apiSlice.middleware),
}) });
export default store; export default store;
\ No newline at end of file
import { defineConfig } from 'vite' import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
}) server: {
proxy: {
'/api': {
target: 'http://77.243.80.217:8080',
changeOrigin: true,
// 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