From c14ecf1767b59a251fbe4d42c7f52627e518f362 Mon Sep 17 00:00:00 2001 From: andrei Date: Tue, 3 Jun 2025 10:59:10 +0500 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86?= =?UTF-8?q?=D0=B0=20=D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D0=B5?= =?UTF-8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлены функции создания пользователей. Исправлены ошибки при загрузке данных. --- web-app/src/Api/registerApi.js | 20 ++++ web-app/src/Api/rolesApi.js | 18 +++ web-app/src/App/AdminRoute.jsx | 14 +-- web-app/src/Components/Layouts/MainLayout.jsx | 4 +- .../Components/Pages/AdminPage/AdminPage.jsx | 107 +++++++++++++++++- .../CreateUserModalForm.jsx | 82 ++++++++++++++ .../useCreateUserModalForm.js | 24 ++++ .../useCreateUserModalFormUI.js | 47 ++++++++ .../Pages/AdminPage/useAdminPage.js | 22 ++-- .../Pages/AdminPage/useAdminPageUI.js | 46 +++++++- .../CalendarCell/useCalendarCellUI.js | 3 - .../LensIssueFormModal/useLensIssueFormUI.js | 3 +- .../Components/Pages/IssuesPage/useIssues.js | 2 +- .../Components/LensFormModal/useLensFormUI.js | 11 +- .../Components/LensesTab/useLenses.js | 4 +- .../Pages/LoginPage/useLoginPage.js | 2 +- .../Pages/PatientsPage/usePatients.js | 2 +- .../Pages/ProfilePage/useProfilePage.js | 4 +- .../useScheduledAppointmentsViewModalUI.js | 2 +- web-app/src/Redux/Slices/adminSlice.js | 30 +++++ web-app/src/Redux/store.js | 11 ++ 21 files changed, 418 insertions(+), 40 deletions(-) create mode 100644 web-app/src/Api/registerApi.js create mode 100644 web-app/src/Api/rolesApi.js create mode 100644 web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/CreateUserModalForm.jsx create mode 100644 web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/useCreateUserModalForm.js create mode 100644 web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/useCreateUserModalFormUI.js create mode 100644 web-app/src/Redux/Slices/adminSlice.js diff --git a/web-app/src/Api/registerApi.js b/web-app/src/Api/registerApi.js new file mode 100644 index 0000000..ef36a4c --- /dev/null +++ b/web-app/src/Api/registerApi.js @@ -0,0 +1,20 @@ +import {baseQueryWithAuth} from "./baseQuery.js"; +import {createApi} from "@reduxjs/toolkit/query/react"; + + +export const registerApi = createApi({ + reducerPath: 'registerApi', + baseQuery: baseQueryWithAuth, + tagTypes: ['Register'], + endpoints: (builder) => ({ + register: builder.mutation({ + query: (credentials) => ({ + url: '/register/', + method: 'POST', + body: credentials, + }), + }), + }), +}); + +export const {useRegisterMutation} = registerApi; diff --git a/web-app/src/Api/rolesApi.js b/web-app/src/Api/rolesApi.js new file mode 100644 index 0000000..49a0329 --- /dev/null +++ b/web-app/src/Api/rolesApi.js @@ -0,0 +1,18 @@ +import {createApi} from "@reduxjs/toolkit/query/react"; +import {baseQueryWithAuth} from "./baseQuery.js"; + + +export const rolesApi = createApi({ + reducerPath: 'rolesApi', + baseQuery: baseQueryWithAuth, + tagTypes: ['Roles'], + endpoints: (builder) => ({ + getRoles: builder.query({ + query: () => '/roles/', + providesTags: ['Roles'], + refetchOnMountOrArgChange: 5, + }), + }), +}); + +export const {useGetRolesQuery} = rolesApi; \ No newline at end of file diff --git a/web-app/src/App/AdminRoute.jsx b/web-app/src/App/AdminRoute.jsx index a3d4214..2d11f41 100644 --- a/web-app/src/App/AdminRoute.jsx +++ b/web-app/src/App/AdminRoute.jsx @@ -1,7 +1,7 @@ -import { Navigate, Outlet } from "react-router-dom"; +import {Navigate, Outlet} from "react-router-dom"; import {useGetAuthenticatedUserDataQuery} from "../Api/usersApi.js"; import LoadingIndicator from "../Components/Widgets/LoadingIndicator/LoadingIndicator.jsx"; -import {Alert} from "antd"; +import {Result} from "antd"; const AdminRoute = () => { const { @@ -13,22 +13,22 @@ const AdminRoute = () => { }); if (isUserLoading) { - return ; + return ; } if (isUserError) { - return ; + return ; } if (!user) { - return ; + return ; } if (!user.role || user.role.title !== "Администратор") { - return ; + return ; } - return ; + return ; }; export default AdminRoute; \ No newline at end of file diff --git a/web-app/src/Components/Layouts/MainLayout.jsx b/web-app/src/Components/Layouts/MainLayout.jsx index 323f772..4ac17c1 100644 --- a/web-app/src/Components/Layouts/MainLayout.jsx +++ b/web-app/src/Components/Layouts/MainLayout.jsx @@ -1,4 +1,4 @@ -import {Alert, Layout, Menu} from "antd"; +import {Alert, Layout, Menu, Result} from "antd"; import {Outlet} from "react-router-dom"; import { HomeOutlined, @@ -42,7 +42,7 @@ const MainLayout = () => { ); if (mainLayoutData.isUserError) { - return + return } return ( diff --git a/web-app/src/Components/Pages/AdminPage/AdminPage.jsx b/web-app/src/Components/Pages/AdminPage/AdminPage.jsx index 0c7c9da..504e807 100644 --- a/web-app/src/Components/Pages/AdminPage/AdminPage.jsx +++ b/web-app/src/Components/Pages/AdminPage/AdminPage.jsx @@ -1,14 +1,93 @@ -import LoadingIndicator from "../../Widgets/LoadingIndicator/LoadingIndicator.jsx"; -import {Typography} from "antd"; -import useAdminPage from "./useAdminPage.js"; +import {useState} from "react"; +import {Table, Typography, Button, Modal, Form, Input, Select, Alert, Result} from "antd"; import {ControlOutlined} from "@ant-design/icons"; +import LoadingIndicator from "../../Widgets/LoadingIndicator/LoadingIndicator.jsx"; +import useAdminPage from "./useAdminPage.js"; import useAdminPageUI from "./useAdminPageUI.js"; +import CreateUserModalForm from "./Components/CreateUserModalForm/CreateUserModalForm.jsx"; +const {Title} = Typography; +const {Option} = Select; const AdminPage = () => { const adminPageData = useAdminPage(); const adminPageUI = useAdminPageUI(); + const [errorMessage, setErrorMessage] = useState(null); + const columns = [ + { + title: "ID", + dataIndex: "id", + key: "id", + }, + { + title: "Фамилия", + dataIndex: "last_name", + key: "lastName", + sorter: (a, b) => a.last_name.localeCompare(b.last_name), + }, + { + title: "Имя", + dataIndex: "first_name", + key: "firstName", + sorter: (a, b) => a.first_name.localeCompare(b.first_name), + }, + { + title: "Отчество", + dataIndex: "patronymic", + key: "patronymic", + }, + { + title: "Роль", + dataIndex: ["role", "title"], + key: "role", + filters: adminPageData.roles.map(role => ({text: role.title, value: role.title})), + onFilter: (value, record) => record.role.title === value, + }, + { + title: "Действия", + key: "actions", + render: (_, record) => ( + + ), + }, + ]; + + const handleEditSubmit = async (values) => { + try { + await adminPageData.updateUser({ + id: adminPageUI.selectedUser.id, + fullName: values.fullName, + password: values.password || undefined, // Отправляем пароль только если он указан + role: {title: values.role}, + }); + adminPageUI.closeEditModal(); + setErrorMessage(null); + } catch (error) { + setErrorMessage("Ошибка при обновлении пользователя"); + } + }; + + const handleCreateSubmit = async (values) => { + try { + await adminPageData.createUser({ + fullName: values.fullName, + email: values.email, + password: values.password, + role: {title: values.role}, + }); + adminPageUI.closeCreateModal(); + setErrorMessage(null); + } catch (error) { + setErrorMessage("Ошибка при создании пользователя"); + } + }; + + if (adminPageData.isError) { + return + } return (
@@ -16,13 +95,29 @@ const AdminPage = () => { ) : ( <> - + <ControlOutlined/> Панель администратора - </Typography.Title> + + + + + )} - ) + ); }; export default AdminPage; \ No newline at end of file diff --git a/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/CreateUserModalForm.jsx b/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/CreateUserModalForm.jsx new file mode 100644 index 0000000..b103042 --- /dev/null +++ b/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/CreateUserModalForm.jsx @@ -0,0 +1,82 @@ +import {Button, Form, Input, Modal, Select, Tooltip, Typography} from "antd"; +import useCreateUserModalForm from "./useCreateUserModalForm.js"; +import useCreateUserModalFormUI from "./useCreateUserModalFormUI.js"; +import {InfoCircleOutlined} from "@ant-design/icons"; + + +const CreateUserModalForm = () => { + const createUserModalFormData = useCreateUserModalForm(); + const createUserModalFormUI = useCreateUserModalFormUI(createUserModalFormData.registerUser); + + return ( + +
+ + + + + + + + + + + + + + + + + + + + + + + + ({ + validator(_, value) { + if (!value || getFieldValue("password") === value) { + return Promise.resolve(); + } + return Promise.reject(new Error("Пароли не совпадают")); + }, + }),]}> + + + + + + + +
+ ) +}; + +export default CreateUserModalForm; \ No newline at end of file diff --git a/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/useCreateUserModalForm.js b/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/useCreateUserModalForm.js new file mode 100644 index 0000000..72e9558 --- /dev/null +++ b/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/useCreateUserModalForm.js @@ -0,0 +1,24 @@ +import {useGetRolesQuery} from "../../../../../Api/rolesApi.js"; +import {useRegisterMutation} from "../../../../../Api/registerApi.js"; + + +const useCreateUserModalForm = () => { + const { + data: roles = [], + isLoading: isLoadingRoles, + isError: isErrorRoles, + } = useGetRolesQuery(undefined, { + pollingInterval: 60000, + }); + + const [registerUser] = useRegisterMutation(); + + return { + roles, + isLoadingRoles, + isErrorRoles, + registerUser, + }; +}; + +export default useCreateUserModalForm; \ No newline at end of file diff --git a/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/useCreateUserModalFormUI.js b/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/useCreateUserModalFormUI.js new file mode 100644 index 0000000..51c9e26 --- /dev/null +++ b/web-app/src/Components/Pages/AdminPage/Components/CreateUserModalForm/useCreateUserModalFormUI.js @@ -0,0 +1,47 @@ +import {useDispatch, useSelector} from "react-redux"; +import {closeModal} from "../../../../../Redux/Slices/adminSlice.js"; +import {Form, notification} from "antd"; + +const useCreateUserModalFormUI = (registerUser) => { + const dispatch = useDispatch(); + const [form] = Form.useForm(); + + const { + modalVisible, + } = useSelector(state => state.adminUI); + + const handleCancel = () => { + dispatch(closeModal()); + }; + + const handleFinish = async () => { + const values = form.getFieldsValue(); + + try { + console.log(values); + await registerUser(values).unwrap(); + notification.success({ + message: "Пользователь зарегистрирован", + description: "Пользователь успешно зарегистрирован", + placement: "topRight", + }); + form.resetFields(); + handleCancel(); + } catch (error) { + notification.error({ + message: "Ошибка регистрации пользователя", + description: error?.data?.detail || "Не удалось зарегистрировать пользователя", + placement: "topRight", + }); + } + }; + + return { + form, + modalVisible, + handleCancel, + handleFinish, + }; +}; + +export default useCreateUserModalFormUI; \ No newline at end of file diff --git a/web-app/src/Components/Pages/AdminPage/useAdminPage.js b/web-app/src/Components/Pages/AdminPage/useAdminPage.js index 91e9b81..66be414 100644 --- a/web-app/src/Components/Pages/AdminPage/useAdminPage.js +++ b/web-app/src/Components/Pages/AdminPage/useAdminPage.js @@ -1,20 +1,28 @@ import {useGetAllUsersQuery} from "../../../Api/usersApi.js"; - +import {useGetRolesQuery} from "../../../Api/rolesApi.js"; const useAdminPage = () => { - const { - data: users = [], - isLoading, - isError, + data: users = [], isLoading, isError, } = useGetAllUsersQuery(undefined, { pollingInterval: 10000, }); + const {data: roles = [], isLoading: isLoadingRoles, isError: isErrorRoles} = useGetRolesQuery(undefined, { + pollingInterval: 60000, + }); + + // const [updateUser, { isLoading: isUpdating, isError: isUpdateError }] = useUpdateUserMutation(); + // const [createUser, { isLoading: isCreating, isError: isCreateError }] = useCreateUserMutation(); + return { users, - isLoading, - isError, + roles, + isLoading: isLoading || isLoadingRoles, + isError: isError || isErrorRoles, + updateUser: () => { + }, isUpdating: false, isUpdateError: false, createUser: () => { + }, isCreating: false, isCreateError: false, }; }; diff --git a/web-app/src/Components/Pages/AdminPage/useAdminPageUI.js b/web-app/src/Components/Pages/AdminPage/useAdminPageUI.js index 20870b0..3cd8246 100644 --- a/web-app/src/Components/Pages/AdminPage/useAdminPageUI.js +++ b/web-app/src/Components/Pages/AdminPage/useAdminPageUI.js @@ -1,15 +1,57 @@ -import {Grid} from "antd"; - +import {useState} from "react"; +import {Grid, Form} from "antd"; +import {useDispatch} from "react-redux"; +import {openModal} from "../../../Redux/Slices/adminSlice.js"; const {useBreakpoint} = Grid; const useAdminPageUI = () => { + const dispatch = useDispatch(); + const screens = useBreakpoint(); + const [editModalVisible, setEditModalVisible] = useState(false); + const [createModalVisible, setCreateModalVisible] = useState(false); + const [selectedUser, setSelectedUser] = useState(null); + const [editForm] = Form.useForm(); + const [createForm] = Form.useForm(); const containerStyle = {padding: screens.xs ? 16 : 24}; + const openEditModal = (user) => { + setSelectedUser(user); + editForm.setFieldsValue({ + fullName: user.fullName, + role: user.role?.title || "", + }); + setEditModalVisible(true); + }; + + const closeEditModal = () => { + setEditModalVisible(false); + setSelectedUser(null); + editForm.resetFields(); + }; + + const openCreateModal = () => { + dispatch(openModal()); + }; + + const closeCreateModal = () => { + setCreateModalVisible(false); + createForm.resetFields(); + }; + return { containerStyle, + editModalVisible, + createModalVisible, + selectedUser, + editForm, + createForm, + openEditModal, + closeEditModal, + openCreateModal, + closeCreateModal, }; }; diff --git a/web-app/src/Components/Pages/AppointmentsPage/Components/CalendarCell/useCalendarCellUI.js b/web-app/src/Components/Pages/AppointmentsPage/Components/CalendarCell/useCalendarCellUI.js index 7557da1..5321a9a 100644 --- a/web-app/src/Components/Pages/AppointmentsPage/Components/CalendarCell/useCalendarCellUI.js +++ b/web-app/src/Components/Pages/AppointmentsPage/Components/CalendarCell/useCalendarCellUI.js @@ -18,7 +18,6 @@ const useCalendarCellUI = () => { return () => observer.disconnect(); }, []); - // Styles const containerStyle = { height: "100%", cursor: isCompressed ? "pointer" : "default", @@ -61,14 +60,12 @@ const useCalendarCellUI = () => { color: "#1890ff", }; - // Static configuration const labels = { pastAppointment: "Прошедший прием", scheduledAppointment: "Запланированный прием", notSpecified: "Не указан", }; - // Formatting functions const getAppointmentTime = (datetime) => { return datetime ? dayjs(datetime).format("HH:mm") : labels.notSpecified; }; diff --git a/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormUI.js b/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormUI.js index 4474891..83dbab9 100644 --- a/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormUI.js +++ b/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormUI.js @@ -70,10 +70,9 @@ const useLensIssueFormUI = (visible, onCancel, onSubmit, patients, lenses) => { setSelectedLens(null); setIssueDate(dayjs(new Date())); } catch (errorInfo) { - console.error("Validation Failed:", errorInfo); notification.error({ message: "Ошибка валидации", - description: "Проверьте правильность заполнения полей.", + description: errorInfo?.data?.detail || "Проверьте правильность заполнения полей.", placement: "topRight", }); } diff --git a/web-app/src/Components/Pages/IssuesPage/useIssues.js b/web-app/src/Components/Pages/IssuesPage/useIssues.js index d30a946..6479879 100644 --- a/web-app/src/Components/Pages/IssuesPage/useIssues.js +++ b/web-app/src/Components/Pages/IssuesPage/useIssues.js @@ -25,7 +25,7 @@ const useIssues = () => { } catch (error) { notification.error({ message: "Ошибка выдачи линзы", - description: error.data?.message || "Не удалось выдать линзу пациенту.", + description: error?.data?.detail || "Не удалось выдать линзу пациенту.", placement: "topRight", }); } diff --git a/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/useLensFormUI.js b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/useLensFormUI.js index f547eea..ee391ed 100644 --- a/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/useLensFormUI.js +++ b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/useLensFormUI.js @@ -1,5 +1,5 @@ import {useEffect} from "react"; -import {Form} from "antd"; +import {Form, notification} from "antd"; const useLensFormUI = (lensTypes, visible, onCancel, onSubmit, lens) => { @@ -19,7 +19,7 @@ const useLensFormUI = (lensTypes, visible, onCancel, onSubmit, lens) => { const modalStyle = { marginTop: 20, }; - const formItemStyle = { width: "100%" }; + const formItemStyle = {width: "100%"}; const handleOk = async () => { try { @@ -27,6 +27,11 @@ const useLensFormUI = (lensTypes, visible, onCancel, onSubmit, lens) => { onSubmit(values); form.resetFields(); } catch (error) { + notification.error({ + message: "Ошибка", + description: error?.data?.detail || lens ? "Не удалось обновить линзу" : "Не удалось создать линзу", + placement: "topRight", + }); console.log("Validation Failed:", error); } }; @@ -35,7 +40,7 @@ const useLensFormUI = (lensTypes, visible, onCancel, onSubmit, lens) => { form.resetFields(); onCancel(); }; - + return { form, modalStyle, diff --git a/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLenses.js b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLenses.js index a6097cd..f87f931 100644 --- a/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLenses.js +++ b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLenses.js @@ -35,7 +35,7 @@ const useLenses = () => { } catch (error) { notification.error({ message: "Ошибка удаления", - description: error.data?.message || "Не удалось удалить линзу", + description: error?.data?.detail || "Не удалось удалить линзу", placement: "topRight", }); } @@ -63,7 +63,7 @@ const useLenses = () => { } catch (error) { notification.error({ message: "Ошибка", - description: error.data?.message || "Произошла ошибка при сохранении", + description: error?.data?.detail || "Произошла ошибка при сохранении", placement: "topRight", }); } diff --git a/web-app/src/Components/Pages/LoginPage/useLoginPage.js b/web-app/src/Components/Pages/LoginPage/useLoginPage.js index b6d3917..51e6c3b 100644 --- a/web-app/src/Components/Pages/LoginPage/useLoginPage.js +++ b/web-app/src/Components/Pages/LoginPage/useLoginPage.js @@ -17,7 +17,7 @@ const useLoginPage = () => { localStorage.setItem("access_token", token); dispatch(setUser({ token })); } catch (error) { - const errorMessage = error?.data?.message || "Не удалось войти"; + const errorMessage = error?.data?.detail || "Не удалось войти"; dispatch(setError(errorMessage)); notification.error({ message: "Ошибка при входе", diff --git a/web-app/src/Components/Pages/PatientsPage/usePatients.js b/web-app/src/Components/Pages/PatientsPage/usePatients.js index 515f45f..9ffd920 100644 --- a/web-app/src/Components/Pages/PatientsPage/usePatients.js +++ b/web-app/src/Components/Pages/PatientsPage/usePatients.js @@ -22,7 +22,7 @@ const usePatients = () => { } catch (error) { notification.error({ message: "Ошибка удаления", - description: error.data?.message || "Не удалось удалить пациента", + description: error?.data?.detail || "Не удалось удалить пациента", placement: "topRight", }); } diff --git a/web-app/src/Components/Pages/ProfilePage/useProfilePage.js b/web-app/src/Components/Pages/ProfilePage/useProfilePage.js index 6fc0762..77dde89 100644 --- a/web-app/src/Components/Pages/ProfilePage/useProfilePage.js +++ b/web-app/src/Components/Pages/ProfilePage/useProfilePage.js @@ -48,7 +48,7 @@ const useProfilePage = () => { } catch (error) { notification.error({ message: "Ошибка", - description: error?.data?.message || "Не удалось обновить профиль.", + description: error?.data?.detail || "Не удалось обновить профиль.", placement: "topRight", }); } @@ -72,7 +72,7 @@ const useProfilePage = () => { } catch (error) { notification.error({ message: "Ошибка", - description: error?.data?.message || "Не удалось изменить пароль.", + description: error?.data?.detail || "Не удалось изменить пароль.", placement: "topRight", }); } diff --git a/web-app/src/Components/Widgets/ScheduledAppointmentsViewModal/useScheduledAppointmentsViewModalUI.js b/web-app/src/Components/Widgets/ScheduledAppointmentsViewModal/useScheduledAppointmentsViewModalUI.js index df2100f..3c856e6 100644 --- a/web-app/src/Components/Widgets/ScheduledAppointmentsViewModal/useScheduledAppointmentsViewModalUI.js +++ b/web-app/src/Components/Widgets/ScheduledAppointmentsViewModal/useScheduledAppointmentsViewModalUI.js @@ -67,7 +67,7 @@ const useScheduledAppointmentsViewModalUI = (cancelAppointment) => { } catch (error) { notification.error({ message: "Ошибка", - description: error.data?.message || "Не удалось отменить прием.", + description: error?.data?.detail || "Не удалось отменить прием.", placement: "topRight", }); } diff --git a/web-app/src/Redux/Slices/adminSlice.js b/web-app/src/Redux/Slices/adminSlice.js new file mode 100644 index 0000000..47634db --- /dev/null +++ b/web-app/src/Redux/Slices/adminSlice.js @@ -0,0 +1,30 @@ +import {createSlice} from '@reduxjs/toolkit'; + +const initialState = { + modalVisible: false, + selectedUser: null, +}; + +const adminSlice = createSlice({ + name: 'adminUI', + initialState, + reducers: { + setSelectedUser(state, action) { + state.selectedUser = action.payload; + }, + openModal(state) { + state.modalVisible = true; + }, + closeModal(state) { + state.modalVisible = false; + }, + }, +}); + +export const { + openModal, + closeModal, + setSelectedUser, +} = adminSlice.actions; + +export default adminSlice.reducer; \ No newline at end of file diff --git a/web-app/src/Redux/store.js b/web-app/src/Redux/store.js index 9c0d86d..5fcbb47 100644 --- a/web-app/src/Redux/store.js +++ b/web-app/src/Redux/store.js @@ -17,6 +17,9 @@ import {usersApi} from "../Api/usersApi.js"; import usersReducer from "./Slices/usersSlice.js"; import {authApi} from "../Api/authApi.js"; import authReducer from "./Slices/authSlice.js"; +import {rolesApi} from "../Api/rolesApi.js"; +import adminReducer from "./Slices/adminSlice.js"; +import {registerApi} from "../Api/registerApi.js"; export const store = configureStore({ reducer: { @@ -48,6 +51,12 @@ export const store = configureStore({ auth: authReducer, [authApi.reducerPath]: authApi.reducer, + + adminUI: adminReducer, + + [rolesApi.reducerPath]: rolesApi.reducer, + + [registerApi.reducerPath]: registerApi.reducer }, middleware: (getDefaultMiddleware) => ( getDefaultMiddleware().concat( @@ -62,6 +71,8 @@ export const store = configureStore({ appointmentTypesApi.middleware, usersApi.middleware, authApi.middleware, + rolesApi.middleware, + registerApi.middleware, ) ), });