diff --git a/web-app/src/Api/usersApi.js b/web-app/src/Api/usersApi.js
index 22a80c2..51d249d 100644
--- a/web-app/src/Api/usersApi.js
+++ b/web-app/src/Api/usersApi.js
@@ -19,7 +19,19 @@ export const usersApi = createApi({
body: data,
}),
}),
+ updateUser: builder.mutation({
+ query: ({userId, ...data}) => ({
+ url: `/users/${userId}/`,
+ method: "PUT",
+ body: data,
+ }),
+ invalidatesTags: ['User']
+ }),
}),
});
-export const {useGetAuthenticatedUserDataQuery} = usersApi;
\ No newline at end of file
+export const {
+ useGetAuthenticatedUserDataQuery,
+ useChangePasswordMutation,
+ useUpdateUserMutation,
+} = usersApi;
\ No newline at end of file
diff --git a/web-app/src/App/App.jsx b/web-app/src/App/App.jsx
index a33bec5..c9f1a63 100644
--- a/web-app/src/App/App.jsx
+++ b/web-app/src/App/App.jsx
@@ -1,22 +1,38 @@
import {BrowserRouter as Router} from "react-router-dom";
import AppRouter from "./AppRouter.jsx";
import "/src/Styles/app.css";
-import {Provider} from "react-redux";
-import store from "../Redux/store.js";
+import {useDispatch, useSelector} from "react-redux";
import dayjs from "dayjs";
import locale from 'antd/locale/ru_RU';
import {ConfigProvider} from "antd";
+import {useEffect} from "react";
+import {checkAuth} from "../Redux/Slices/authSlice.js";
+import LoadingIndicator from "../Components/Widgets/LoadingIndicator/LoadingIndicator.jsx";
+import ErrorBoundary from "./ErrorBoundary.jsx";
dayjs.locale('ru');
-const App = () => (
-
+const App = () => {
+ const dispatch = useDispatch();
+ const {isLoading} = useSelector((state) => state.auth);
+
+ useEffect(() => {
+ dispatch(checkAuth());
+ }, [dispatch]);
+
+ if (isLoading) {
+ return ;
+ }
+
+ return (
-
+
+
+
-
-);
+ );
+};
export default App;
diff --git a/web-app/src/App/PrivateRoute.jsx b/web-app/src/App/PrivateRoute.jsx
index e45c724..e0a2f51 100644
--- a/web-app/src/App/PrivateRoute.jsx
+++ b/web-app/src/App/PrivateRoute.jsx
@@ -1,14 +1,14 @@
-import { Navigate, Outlet } from "react-router-dom";
-import { useSelector } from "react-redux";
+import {Navigate, Outlet} from "react-router-dom";
+import {useSelector} from "react-redux";
const PrivateRoute = () => {
- const { user } = useSelector((state) => state.auth);
+ const {user} = useSelector((state) => state.auth);
if (!user) {
- return ;
+ return ;
}
- return ;
+ return ;
};
export default PrivateRoute;
\ No newline at end of file
diff --git a/web-app/src/App/main.jsx b/web-app/src/App/main.jsx
index 74ce178..3eb55c8 100644
--- a/web-app/src/App/main.jsx
+++ b/web-app/src/App/main.jsx
@@ -1,9 +1,13 @@
import {StrictMode} from 'react'
import {createRoot} from 'react-dom/client'
import App from './App.jsx'
+import store from "../Redux/store.js";
+import {Provider} from "react-redux";
createRoot(document.getElementById('root')).render(
-
+
+
+
)
diff --git a/web-app/src/Components/Pages/HomePage/useHomePageUI.js b/web-app/src/Components/Pages/HomePage/useHomePageUI.js
index d4767df..1e50cc5 100644
--- a/web-app/src/Components/Pages/HomePage/useHomePageUI.js
+++ b/web-app/src/Components/Pages/HomePage/useHomePageUI.js
@@ -1,5 +1,5 @@
import { Grid } from "antd";
-import { useMemo } from "react";
+import {useEffect, useMemo} from "react";
import dayjs from "dayjs";
import isBetween from "dayjs/plugin/isBetween";
import {useSelector} from "react-redux"; // Import isBetween plugin
@@ -18,6 +18,10 @@ const useHomePageUI = (appointments, scheduledAppointments, patients) => {
const buttonStyle = { width: screens.xs ? "100%" : "auto" };
const chartContainerStyle = { padding: 16, background: "#fff", borderRadius: 4 };
+ useEffect(() => {
+ document.title = "Главная страница";
+ }, []);
+
const todayEvents = useMemo(() => {
return [...appointments, ...scheduledAppointments].filter((event) =>
dayjs(event.appointment_datetime || event.scheduled_datetime).isSame(dayjs(), "day")
diff --git a/web-app/src/Components/Pages/ProfilePage/ProfilePage.jsx b/web-app/src/Components/Pages/ProfilePage/ProfilePage.jsx
index d7f5e01..0abce05 100644
--- a/web-app/src/Components/Pages/ProfilePage/ProfilePage.jsx
+++ b/web-app/src/Components/Pages/ProfilePage/ProfilePage.jsx
@@ -1,16 +1,32 @@
-import { Button, Card, Col, Form, Input, Modal, Row, Space, Typography, Result } from "antd";
-import { EditOutlined } from "@ant-design/icons";
+import {Button, Card, Col, Form, Input, Modal, Row, Space, Typography, Result} from "antd";
+import {EditOutlined} from "@ant-design/icons";
import LoadingIndicator from "../../Widgets/LoadingIndicator/LoadingIndicator.jsx";
import useProfilePage from "./useProfilePage.js";
import useProfilePageUI from "./useProfilePageUI.js";
-import { useSelector } from "react-redux";
+import {useSelector} from "react-redux";
const ProfilePage = () => {
- const { userData, isLoading, isError, isUpdating, handleEditProfile, handleCancelEdit, handleSubmitProfile, handleSubmitPassword } = useProfilePage();
- const { containerStyle, cardStyle, buttonStyle, formStyle, profileFormRules, passwordFormRules, isMobile } = useProfilePageUI();
+ const {
+ userData,
+ isLoading,
+ isError,
+ isUpdating,
+ handleEditProfile,
+ handleCancelEdit,
+ handleSubmitProfile,
+ handleSubmitPassword
+ } = useProfilePage();
+ const {
+ containerStyle,
+ cardStyle,
+ buttonStyle,
+ formStyle,
+ profileFormRules,
+ passwordFormRules,
+ profileForm,
+ passwordForm
+ } = useProfilePageUI();
const editProfileModalVisible = useSelector((state) => state.usersUI.editProfileModalVisible);
- const [profileForm] = Form.useForm();
- const [passwordForm] = Form.useForm();
if (isError) {
return (
@@ -25,7 +41,7 @@ const ProfilePage = () => {
return (
{isLoading ? (
-
+
) : (
<>
Профиль
@@ -50,9 +66,9 @@ const ProfilePage = () => {
}
+ icon={}
onClick={handleEditProfile}
- style={{ ...buttonStyle, marginTop: 16 }}
+ style={{...buttonStyle, marginTop: 16}}
>
Редактировать
@@ -77,16 +93,16 @@ const ProfilePage = () => {
style={formStyle}
>
-
+
-
+
-
+
-
+
@@ -105,14 +121,16 @@ const ProfilePage = () => {
style={formStyle}
>
Смена пароля
-
-
+
+
-
+
-
-
+
+
diff --git a/web-app/src/Components/Pages/ProfilePage/useProfilePage.js b/web-app/src/Components/Pages/ProfilePage/useProfilePage.js
index 24f5f1d..6fc0762 100644
--- a/web-app/src/Components/Pages/ProfilePage/useProfilePage.js
+++ b/web-app/src/Components/Pages/ProfilePage/useProfilePage.js
@@ -1,7 +1,11 @@
-import { useGetAuthenticatedUserDataQuery } from "../../../Api/usersApi.js";
-import { useDispatch } from "react-redux";
-import { openEditProfileModal, closeEditProfileModal } from "../../../Redux/Slices/usersSlice.js";
-import { notification } from "antd";
+import {
+ useChangePasswordMutation,
+ useGetAuthenticatedUserDataQuery,
+ useUpdateUserMutation
+} from "../../../Api/usersApi.js";
+import {useDispatch} from "react-redux";
+import {openEditProfileModal, closeEditProfileModal} from "../../../Redux/Slices/usersSlice.js";
+import {notification} from "antd";
const useProfilePage = () => {
const dispatch = useDispatch();
@@ -14,14 +18,9 @@ const useProfilePage = () => {
pollingInterval: 20000,
});
- // const [updateUserProfile, { isLoading: isUpdatingProfile }] = useUpdateUserProfileMutation();
- const updateUserProfile = () => {};
- const isUpdatingProfile = false;
- const isErrorUpdatingProfile = false;
+ const [updateUserProfile, {isLoading: isUpdatingProfile}] = useUpdateUserMutation();
- // const [changePassword, { isLoading: isChangingPassword }] = useChangePasswordMutation();
- const changePassword = () => {};
- const isChangingPassword = false;
+ const [changePassword, {isLoading: isChangingPassword}] = useChangePasswordMutation();
const handleEditProfile = () => {
dispatch(openEditProfileModal());
@@ -37,8 +36,9 @@ const useProfilePage = () => {
first_name: values.first_name,
last_name: values.last_name,
patronymic: values.patronymic || null,
+ login: userData.login,
};
- await updateUserProfile(profileData).unwrap();
+ await updateUserProfile({userId: userData.id, ...profileData}).unwrap();
notification.success({
message: "Успех",
description: "Профиль успешно обновлен.",
@@ -60,6 +60,7 @@ const useProfilePage = () => {
current_password: values.current_password,
new_password: values.new_password,
confirm_password: values.confirm_password,
+ user_id: userData.id,
};
await changePassword(passwordData).unwrap();
notification.success({
diff --git a/web-app/src/Components/Pages/ProfilePage/useProfilePageUI.js b/web-app/src/Components/Pages/ProfilePage/useProfilePageUI.js
index 61c5eb3..0421ed0 100644
--- a/web-app/src/Components/Pages/ProfilePage/useProfilePageUI.js
+++ b/web-app/src/Components/Pages/ProfilePage/useProfilePageUI.js
@@ -1,4 +1,4 @@
-import { Grid } from "antd";
+import {Form, Grid} from "antd";
const { useBreakpoint } = Grid;
@@ -10,6 +10,9 @@ const useProfilePageUI = () => {
const buttonStyle = { width: screens.xs ? "100%" : "auto" };
const formStyle = { maxWidth: 600 };
+ const [profileForm] = Form.useForm();
+ const [passwordForm] = Form.useForm();
+
const profileFormRules = {
first_name: [
{ required: true, message: "Пожалуйста, введите имя" },
@@ -56,6 +59,8 @@ const useProfilePageUI = () => {
formStyle,
profileFormRules,
passwordFormRules,
+ profileForm,
+ passwordForm,
isMobile: screens.xs,
};
};