diff --git a/src/core/components/AppRoutes/index.tsx b/src/core/components/AppRoutes/index.tsx
index ec3c6a4..a2f22c6 100644
--- a/src/core/components/AppRoutes/index.tsx
+++ b/src/core/components/AppRoutes/index.tsx
@@ -12,8 +12,8 @@ import PageNotFound from "../../../features/PageNotFound";
import LessonPage from "../../../features/Lessons/LessonPage";
import LessonPageEditor from "../../../features/Lessons/LessonPageEditor";
import TeamCreateUser from "features/Team/CreateUser";
-import AccountSettings from "features/AccountSettings";
import Board from "features/Board";
+import UserProfile from "features/UserProfile";
export default function AppRoutes() {
return (
@@ -94,7 +94,7 @@ export default function AppRoutes() {
path={Constants.ROUTE_PATHS.ACCOUNT_SETTINGS}
element={
-
+
}
/>
diff --git a/src/core/services/userProfile.ts b/src/core/services/userProfile.ts
new file mode 100644
index 0000000..79aa09f
--- /dev/null
+++ b/src/core/services/userProfile.ts
@@ -0,0 +1,18 @@
+import { createApi } from "@reduxjs/toolkit/query/react";
+import { baseQueryWithErrorHandling } from "core/helper/api";
+import { UserProfile } from "core/types/userProfile";
+
+export const userProfileApi = createApi({
+ reducerPath: "userProfileApi",
+ baseQuery: baseQueryWithErrorHandling,
+ endpoints: (builder) => ({
+ getUserProfile: builder.query({
+ query: () => ({
+ url: "user/profile",
+ method: "GET",
+ }),
+ }),
+ }),
+});
+
+export const { useGetUserProfileQuery } = userProfileApi;
diff --git a/src/core/services/websocketService.ts b/src/core/services/websocketService.ts
index 1719850..cad25e9 100644
--- a/src/core/services/websocketService.ts
+++ b/src/core/services/websocketService.ts
@@ -33,6 +33,7 @@ import {
deleteTeamMember,
updateTeamMemberRole,
} from "features/Team/teamSlice";
+import { setProfilePictureUrl } from "features/UserProfile/userProfileSlice";
interface WebSocketMessage {
Cmd: number;
@@ -276,6 +277,9 @@ export function WebSocketMessageHandler(
);
}
break;
+ case WebSocketReceivedMessagesCmds.UserProfilePictureUpdated:
+ dispatch(setProfilePictureUrl(Body));
+ break;
default:
console.error("Unknown message type:", Cmd);
}
diff --git a/src/core/store/store.tsx b/src/core/store/store.tsx
index 89f601b..6c5a7b5 100644
--- a/src/core/store/store.tsx
+++ b/src/core/store/store.tsx
@@ -8,6 +8,8 @@ import { organizationApi } from "core/services/organization";
import { teamSlice } from "features/Team/teamSlice";
import { lessonsSlice } from "features/Lessons/lessonsSlice";
import { lessonPageSlice } from "features/Lessons/LessonPage/lessonPageSlice";
+import { userProfileApi } from "core/services/userProfile";
+import { userProfileSlice } from "features/UserProfile/userProfileSlice";
const makeStore = (/* preloadedState */) => {
const store = configureStore({
@@ -21,12 +23,15 @@ const makeStore = (/* preloadedState */) => {
[lessonPageSlice.reducerPath]: lessonPageSlice.reducer,
[organizationApi.reducerPath]: organizationApi.reducer,
[teamSlice.reducerPath]: teamSlice.reducer,
+ [userProfileApi.reducerPath]: userProfileApi.reducer,
+ [userProfileSlice.reducerPath]: userProfileSlice.reducer,
},
// preloadedState,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(
lessonsApi.middleware,
- organizationApi.middleware
+ organizationApi.middleware,
+ userProfileApi.middleware
),
});
diff --git a/src/core/types/userProfile.ts b/src/core/types/userProfile.ts
new file mode 100644
index 0000000..1bde012
--- /dev/null
+++ b/src/core/types/userProfile.ts
@@ -0,0 +1,7 @@
+export interface UserProfile {
+ ProfilePictureUrl: string;
+ FirstName: string;
+ LastName: string;
+ Email: string;
+ RoleId: string;
+}
diff --git a/src/core/utils/utils.ts b/src/core/utils/utils.ts
index bce0439..5cb1f4c 100644
--- a/src/core/utils/utils.ts
+++ b/src/core/utils/utils.ts
@@ -18,7 +18,7 @@ export const Constants = {
ORGANIZATION_TEAM_CREATE_USER: "/team/create-user",
ORGANIZATION_ROLES: "/roles",
ORGANIZATION_SETTINGS: "/settings",
- ACCOUNT_SETTINGS: "/account",
+ ACCOUNT_SETTINGS: "/user-profile",
WHATS_NEW: "/whats-new",
SUGGEST_FEATURE: "/suggest-feature",
CONTACT_SUPPORT: "/contact-support",
diff --git a/src/core/utils/webSocket.ts b/src/core/utils/webSocket.ts
index 9a33933..8839833 100644
--- a/src/core/utils/webSocket.ts
+++ b/src/core/utils/webSocket.ts
@@ -19,6 +19,7 @@ enum WebSocketReceivedMessagesCmds {
LessonContentUpdated = 14,
LessonContentUpdatedPosition = 15,
LessonContentFileUpdated = 16,
+ UserProfilePictureUpdated = 17,
}
export { WebSocketSendMessagesCmds, WebSocketReceivedMessagesCmds };
diff --git a/src/features/AccountSettings/index.tsx b/src/features/AccountSettings/index.tsx
deleted file mode 100644
index 7be651f..0000000
--- a/src/features/AccountSettings/index.tsx
+++ /dev/null
@@ -1,164 +0,0 @@
-import {
- Avatar,
- Button,
- Card,
- Descriptions,
- Divider,
- Flex,
- Form,
- Input,
- Typography,
-} from "antd";
-import HeaderBar from "../../core/components/Header";
-import MyBanner from "../../shared/components/MyBanner";
-import { MyContainer } from "../../shared/components/MyContainer";
-import { SaveOutlined } from "@ant-design/icons";
-import MyUpload from "shared/components/MyUpload";
-import { Constants } from "core/utils/utils";
-import ColorPicker from "antd/es/color-picker";
-import MyMiddleCard from "shared/components/MyMiddleCard";
-import Meta from "antd/es/card/Meta";
-
-export default function AccountSettings({ isAdmin }: { isAdmin?: boolean }) {
- function AdminWrapper({ children }: { children: React.ReactNode }) {
- if (!isAdmin) {
- return <>{children}>;
- }
-
- return (
-
- );
- }
-
- function TextItem({ value, name }: { value: string; name: string }) {
- if (!isAdmin) {
- return <>{value}>;
- }
-
- return (
-
-
-
- );
- }
-
- return (
- <>
- }
- />
-
-
-
-
-
- }
- title="Jorg Kreith"
- description="Lead"
- />
-
- {/*
-
-
-
-
- First name
- Jorg
-
-
- Email
- julian@xx.com
-
-
-
-
- Last name
- Kreth
-
-
-
- */}
-
-
- ,
- },
- {
- key: "2",
- label: "Last name",
- children: ,
- },
- {
- key: "3",
- label: "Email",
- children: ,
- },
- ]}
- />
-
-
-
-
- >
- );
-}
-
-/*
-// TODO: sessions table
-
-
-
- // Todoo
-
-*/
-
-function TitleText({ children }: { children: React.ReactNode }) {
- return (
-
- {children}
-
- );
-}
-
-function ValueText({ children }: { children: React.ReactNode }) {
- return {children};
-}
diff --git a/src/features/PageNotFound/index.tsx b/src/features/PageNotFound/index.tsx
index b749b15..21a3b6e 100644
--- a/src/features/PageNotFound/index.tsx
+++ b/src/features/PageNotFound/index.tsx
@@ -1,7 +1,21 @@
+import { Button, Result } from "antd";
+import { Constants } from "core/utils/utils";
+import { Link } from "react-router-dom";
+import { MyCenteredContainer } from "shared/components/MyContainer";
+
export default function PageNotFound() {
return (
- <>
- PageNotFound
- >
+
+
+
+
+ }
+ />
+
);
-}
\ No newline at end of file
+}
diff --git a/src/features/Settings/index.tsx b/src/features/Settings/index.tsx
index 1437c8c..351abe5 100644
--- a/src/features/Settings/index.tsx
+++ b/src/features/Settings/index.tsx
@@ -199,7 +199,7 @@ function MediaCard({
}}
>
{children}>;
+ }
+
+ return (
+
+ );
+ }
+
+ function TextItem({ value, name }: { value: string; name: string }) {
+ if (!isAdmin) {
+ return <>{value}>;
+ }
+
+ return (
+
+
+
+ );
+ }
+
+ useEffect(() => {
+ if (!data) return;
+
+ dispatch(setProfilePictureUrl(data.ProfilePictureUrl));
+ dispatch(setFirstName(data.FirstName));
+ dispatch(setLastName(data.LastName));
+ dispatch(setEmail(data.Email));
+ dispatch(setRoleId(data.RoleId));
+ }, [data]);
+
+ useEffect(() => {
+ addWebSocketReconnectListener(refetch);
+
+ return () => removeWebSocketReconnectListener(refetch);
+ }, []);
+
+ return (
+ <>
+ }
+ />
+
+
+ {error ? (
+
+ ) : (
+
+
+ {
+ if (info.file.status === "done") {
+ success("Profile picture updated successfully");
+
+ dispatch(setProfilePictureUrl(info.file.response.Data));
+ }
+ }}
+ imgCropProps={{
+ aspect: 1 / 1,
+ children: <>>,
+ }}
+ >
+ {dataProfilePictureUrl === "" ? (
+
+ {dataFirstName.charAt(0).toUpperCase()}
+
+ ) : (
+
+ )}
+
+ }
+ title={`${dataFirstName} ${dataLastName}`}
+ description={tmpRoleNames[dataRoleId]}
+ />
+
+
+
+
+
+ ),
+ },
+ {
+ key: "2",
+ label: "Last name",
+ children: (
+
+ ),
+ },
+ {
+ key: "3",
+ label: "Email",
+ children: ,
+ },
+ ]}
+ />
+
+
+
+ )}
+
+ >
+ );
+}
+
+/*
+// TODO: sessions table
+
+
+
+ // Todoo
+
+*/
+
+function TitleText({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+
+function ValueText({ children }: { children: React.ReactNode }) {
+ return {children};
+}
diff --git a/src/features/UserProfile/userProfileSlice.ts b/src/features/UserProfile/userProfileSlice.ts
new file mode 100644
index 0000000..1a991b9
--- /dev/null
+++ b/src/features/UserProfile/userProfileSlice.ts
@@ -0,0 +1,47 @@
+import { createSlice } from "@reduxjs/toolkit";
+
+export const userProfileSlice = createSlice({
+ name: "userProfile",
+ initialState: {
+ profilePictureUrl: "",
+ firstName: "",
+ lastName: "",
+ email: "",
+ roleId: "",
+ },
+ reducers: {
+ setProfilePictureUrl: (state, action) => {
+ state.profilePictureUrl = action.payload;
+ },
+ setFirstName: (state, action) => {
+ state.firstName = action.payload;
+ },
+ setLastName: (state, action) => {
+ state.lastName = action.payload;
+ },
+ setEmail: (state, action) => {
+ state.email = action.payload;
+ },
+ setRoleId: (state, action) => {
+ state.roleId = action.payload;
+ },
+ },
+ selectors: {
+ profilePictureUrl: (state) => state.profilePictureUrl,
+ firstName: (state) => state.firstName,
+ lastName: (state) => state.lastName,
+ email: (state) => state.email,
+ roleId: (state) => state.roleId,
+ },
+});
+
+export const {
+ setEmail,
+ setFirstName,
+ setLastName,
+ setProfilePictureUrl,
+ setRoleId,
+} = userProfileSlice.actions;
+
+export const { profilePictureUrl, firstName, lastName, email, roleId } =
+ userProfileSlice.selectors;
diff --git a/src/shared/components/MyUpload/index.tsx b/src/shared/components/MyUpload/index.tsx
index e99fa34..03a60bd 100644
--- a/src/shared/components/MyUpload/index.tsx
+++ b/src/shared/components/MyUpload/index.tsx
@@ -42,29 +42,39 @@ export default function MyUpload({
? accept.join(",")
: (accept as string);
- const MyUpload = () => (
- {
- if (onChange) onChange(info);
- }}
- beforeUpload={beforeUpload}
- >
- {children}
-
- );
-
if (fileType === "video") {
- return ;
+ return (
+ {
+ if (onChange) onChange(info);
+ }}
+ beforeUpload={beforeUpload}
+ >
+ {children}
+
+ );
}
return (
-
+ {
+ if (onChange) onChange(info);
+ }}
+ beforeUpload={beforeUpload}
+ >
+ {children}
+
);
}