mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: profile themning
This commit is contained in:
parent
48ad9d5fea
commit
e95cd1e385
20
packages/types/src/users.d.ts
vendored
20
packages/types/src/users.d.ts
vendored
@ -27,7 +27,7 @@ export interface IUser {
|
|||||||
user_timezone: string;
|
user_timezone: string;
|
||||||
username: string;
|
username: string;
|
||||||
last_login_medium: TLoginMediums;
|
last_login_medium: TLoginMediums;
|
||||||
// theme: IUserTheme;
|
theme: IUserTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IUserAccount {
|
export interface IUserAccount {
|
||||||
@ -48,7 +48,7 @@ export type TUserProfile = {
|
|||||||
palette: string | undefined;
|
palette: string | undefined;
|
||||||
primary: string | undefined;
|
primary: string | undefined;
|
||||||
background: string | undefined;
|
background: string | undefined;
|
||||||
darkPalette: string | undefined;
|
darkPalette: boolean | undefined;
|
||||||
sidebarText: string | undefined;
|
sidebarText: string | undefined;
|
||||||
sidebarBackground: string | undefined;
|
sidebarBackground: string | undefined;
|
||||||
};
|
};
|
||||||
@ -80,14 +80,14 @@ export interface IUserSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IUserTheme {
|
export interface IUserTheme {
|
||||||
background: string;
|
text: string | undefined;
|
||||||
text: string;
|
theme: string | undefined;
|
||||||
primary: string;
|
palette: string | undefined;
|
||||||
sidebarBackground: string;
|
primary: string | undefined;
|
||||||
sidebarText: string;
|
background: string | undefined;
|
||||||
darkPalette: boolean;
|
darkPalette: boolean | undefined;
|
||||||
palette: string;
|
sidebarText: string | undefined;
|
||||||
theme: string;
|
sidebarBackground: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IUserLite {
|
export interface IUserLite {
|
||||||
|
@ -4,9 +4,9 @@ import { Controller, useForm } from "react-hook-form";
|
|||||||
// types
|
// types
|
||||||
import { IUserTheme } from "@plane/types";
|
import { IUserTheme } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
import { Button, InputColorPicker } from "@plane/ui";
|
import { Button, InputColorPicker, setPromiseToast } from "@plane/ui";
|
||||||
// hooks
|
// hooks
|
||||||
import { useUser } from "@/hooks/store";
|
import { useUserProfile } from "@/hooks/store";
|
||||||
|
|
||||||
const inputRules = {
|
const inputRules = {
|
||||||
required: "Background color is required",
|
required: "Background color is required",
|
||||||
@ -25,13 +25,9 @@ const inputRules = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CustomThemeSelector: React.FC = observer(() => {
|
export const CustomThemeSelector: React.FC = observer(() => {
|
||||||
const {
|
|
||||||
userProfile: { data: userProfile },
|
|
||||||
} = useUser();
|
|
||||||
|
|
||||||
const userTheme: any = userProfile?.theme;
|
|
||||||
// hooks
|
|
||||||
const { setTheme } = useTheme();
|
const { setTheme } = useTheme();
|
||||||
|
// hooks
|
||||||
|
const { data: userProfile, updateUserTheme } = useUserProfile();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@ -40,17 +36,18 @@ export const CustomThemeSelector: React.FC = observer(() => {
|
|||||||
watch,
|
watch,
|
||||||
} = useForm<IUserTheme>({
|
} = useForm<IUserTheme>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
background: userTheme?.background !== "" ? userTheme?.background : "#0d101b",
|
background: userProfile?.theme?.background !== "" ? userProfile?.theme?.background : "#0d101b",
|
||||||
text: userTheme?.text !== "" ? userTheme?.text : "#c5c5c5",
|
text: userProfile?.theme?.text !== "" ? userProfile?.theme?.text : "#c5c5c5",
|
||||||
primary: userTheme?.primary !== "" ? userTheme?.primary : "#3f76ff",
|
primary: userProfile?.theme?.primary !== "" ? userProfile?.theme?.primary : "#3f76ff",
|
||||||
sidebarBackground: userTheme?.sidebarBackground !== "" ? userTheme?.sidebarBackground : "#0d101b",
|
sidebarBackground:
|
||||||
sidebarText: userTheme?.sidebarText !== "" ? userTheme?.sidebarText : "#c5c5c5",
|
userProfile?.theme?.sidebarBackground !== "" ? userProfile?.theme?.sidebarBackground : "#0d101b",
|
||||||
darkPalette: userTheme?.darkPalette || false,
|
sidebarText: userProfile?.theme?.sidebarText !== "" ? userProfile?.theme?.sidebarText : "#c5c5c5",
|
||||||
palette: userTheme?.palette !== "" ? userTheme?.palette : "",
|
darkPalette: userProfile?.theme?.darkPalette || false,
|
||||||
|
palette: userProfile?.theme?.palette !== "" ? userProfile?.theme?.palette : "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleUpdateTheme = async (formData: any) => {
|
const handleUpdateTheme = async (formData: Partial<IUserTheme>) => {
|
||||||
const payload: IUserTheme = {
|
const payload: IUserTheme = {
|
||||||
background: formData.background,
|
background: formData.background,
|
||||||
text: formData.text,
|
text: formData.text,
|
||||||
@ -61,12 +58,22 @@ export const CustomThemeSelector: React.FC = observer(() => {
|
|||||||
palette: `${formData.background},${formData.text},${formData.primary},${formData.sidebarBackground},${formData.sidebarText}`,
|
palette: `${formData.background},${formData.text},${formData.primary},${formData.sidebarBackground},${formData.sidebarText}`,
|
||||||
theme: "custom",
|
theme: "custom",
|
||||||
};
|
};
|
||||||
|
|
||||||
setTheme("custom");
|
setTheme("custom");
|
||||||
|
|
||||||
console.log(payload);
|
const updateCurrentUserThemePromise = updateUserTheme(payload);
|
||||||
|
setPromiseToast(updateCurrentUserThemePromise, {
|
||||||
|
loading: "Updating theme...",
|
||||||
|
success: {
|
||||||
|
title: "Success!",
|
||||||
|
message: () => "Theme updated successfully!",
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
title: "Error!",
|
||||||
|
message: () => "Failed to Update the theme",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// return updateUserProfile({ theme: payload });
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleValueChange = (val: string | undefined, onChange: any) => {
|
const handleValueChange = (val: string | undefined, onChange: any) => {
|
||||||
|
@ -5,7 +5,7 @@ import { useTheme } from "next-themes";
|
|||||||
// helpers
|
// helpers
|
||||||
import { applyTheme, unsetCustomCssVariables } from "@/helpers/theme.helper";
|
import { applyTheme, unsetCustomCssVariables } from "@/helpers/theme.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useAppRouter, useAppTheme, useUser } from "@/hooks/store";
|
import { useAppRouter, useAppTheme, useUserProfile } from "@/hooks/store";
|
||||||
|
|
||||||
type TStoreWrapper = {
|
type TStoreWrapper = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -20,9 +20,7 @@ const StoreWrapper: FC<TStoreWrapper> = observer((props) => {
|
|||||||
// store hooks
|
// store hooks
|
||||||
const { setQuery } = useAppRouter();
|
const { setQuery } = useAppRouter();
|
||||||
const { sidebarCollapsed, toggleSidebar } = useAppTheme();
|
const { sidebarCollapsed, toggleSidebar } = useAppTheme();
|
||||||
const {
|
const { data: userProfile } = useUserProfile();
|
||||||
userProfile: { data: userProfile },
|
|
||||||
} = useUser();
|
|
||||||
// states
|
// states
|
||||||
const [dom, setDom] = useState<undefined | HTMLElement>();
|
const [dom, setDom] = useState<undefined | HTMLElement>();
|
||||||
|
|
||||||
@ -40,14 +38,19 @@ const StoreWrapper: FC<TStoreWrapper> = observer((props) => {
|
|||||||
* Setting up the theme of the user by fetching it from local storage
|
* Setting up the theme of the user by fetching it from local storage
|
||||||
*/
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!userProfile) return;
|
if (!userProfile?.theme?.theme) return;
|
||||||
if (window) setDom(window.document?.querySelector<HTMLElement>("[data-theme='custom']") || undefined);
|
if (window) setDom(() => window.document?.querySelector<HTMLElement>("[data-theme='custom']") || undefined);
|
||||||
|
|
||||||
setTheme(userProfile?.theme?.theme || "system");
|
setTheme(userProfile?.theme?.theme || "system");
|
||||||
if (userProfile?.theme?.theme === "custom" && userProfile?.theme?.palette && dom)
|
if (userProfile?.theme?.theme === "custom" && userProfile?.theme?.palette && dom)
|
||||||
applyTheme(userProfile?.theme?.palette, false);
|
applyTheme(
|
||||||
|
userProfile?.theme?.palette !== ",,,,"
|
||||||
|
? userProfile?.theme?.palette
|
||||||
|
: "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
|
||||||
|
false
|
||||||
|
);
|
||||||
else unsetCustomCssVariables();
|
else unsetCustomCssVariables();
|
||||||
}, [userProfile, setTheme, dom]);
|
}, [userProfile, userProfile?.theme?.theme, userProfile?.theme?.palette, setTheme, dom]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!router.query) return;
|
if (!router.query) return;
|
||||||
|
@ -2,64 +2,55 @@ import { useEffect, useState, ReactElement } from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
// ui
|
// ui
|
||||||
import {
|
import { Spinner, setPromiseToast } from "@plane/ui";
|
||||||
Spinner,
|
|
||||||
// setPromiseToast
|
|
||||||
} from "@plane/ui";
|
|
||||||
// components
|
// components
|
||||||
import { CustomThemeSelector, ThemeSwitch, PageHead } from "@/components/core";
|
import { CustomThemeSelector, ThemeSwitch, PageHead } from "@/components/core";
|
||||||
// constants
|
// constants
|
||||||
import { I_THEME_OPTION, THEME_OPTIONS } from "@/constants/themes";
|
import { I_THEME_OPTION, THEME_OPTIONS } from "@/constants/themes";
|
||||||
// hooks
|
// hooks
|
||||||
import { useUser } from "@/hooks/store";
|
import { useUserProfile } from "@/hooks/store";
|
||||||
// layouts
|
// layouts
|
||||||
import { ProfilePreferenceSettingsLayout } from "@/layouts/settings-layout/profile/preferences";
|
import { ProfilePreferenceSettingsLayout } from "@/layouts/settings-layout/profile/preferences";
|
||||||
// type
|
// type
|
||||||
import { NextPageWithLayout } from "@/lib/types";
|
import { NextPageWithLayout } from "@/lib/types";
|
||||||
|
|
||||||
const ProfilePreferencesThemePage: NextPageWithLayout = observer(() => {
|
const ProfilePreferencesThemePage: NextPageWithLayout = observer(() => {
|
||||||
|
const { setTheme } = useTheme();
|
||||||
// states
|
// states
|
||||||
const [currentTheme, setCurrentTheme] = useState<I_THEME_OPTION | null>(null);
|
const [currentTheme, setCurrentTheme] = useState<I_THEME_OPTION | null>(null);
|
||||||
// store hooks
|
|
||||||
const {
|
|
||||||
data: currentUser,
|
|
||||||
userProfile: { data: userProfile },
|
|
||||||
} = useUser();
|
|
||||||
// computed
|
|
||||||
const userTheme = userProfile?.theme;
|
|
||||||
// hooks
|
// hooks
|
||||||
const { setTheme } = useTheme();
|
const { data: userProfile, updateUserTheme } = useUserProfile();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (userTheme) {
|
if (userProfile?.theme?.theme) {
|
||||||
const userThemeOption = THEME_OPTIONS.find((t) => t.value === userTheme?.theme);
|
const userThemeOption = THEME_OPTIONS.find((t) => t.value === userProfile?.theme?.theme);
|
||||||
if (userThemeOption) {
|
if (userThemeOption) {
|
||||||
setCurrentTheme(userThemeOption);
|
setCurrentTheme(userThemeOption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [userTheme]);
|
}, [userProfile?.theme?.theme]);
|
||||||
|
|
||||||
const handleThemeChange = (themeOption: I_THEME_OPTION) => {
|
const handleThemeChange = (themeOption: I_THEME_OPTION) => {
|
||||||
setTheme(themeOption.value);
|
setTheme(themeOption.value);
|
||||||
// const updateCurrentUserThemePromise = updateCurrentUserTheme(themeOption.value);
|
const updateCurrentUserThemePromise = updateUserTheme({ theme: themeOption.value });
|
||||||
|
|
||||||
// setPromiseToast(updateCurrentUserThemePromise, {
|
setPromiseToast(updateCurrentUserThemePromise, {
|
||||||
// loading: "Updating theme...",
|
loading: "Updating theme...",
|
||||||
// success: {
|
success: {
|
||||||
// title: "Success!",
|
title: "Success!",
|
||||||
// message: () => "Theme updated successfully!",
|
message: () => "Theme updated successfully!",
|
||||||
// },
|
},
|
||||||
// error: {
|
error: {
|
||||||
// title: "Error!",
|
title: "Error!",
|
||||||
// message: () => "Failed to Update the theme",
|
message: () => "Failed to Update the theme",
|
||||||
// },
|
},
|
||||||
// });
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageHead title="Profile - Theme Prefrence" />
|
<PageHead title="Profile - Theme Prefrence" />
|
||||||
{currentUser ? (
|
{userProfile ? (
|
||||||
<div className="mx-auto mt-10 h-full w-full overflow-y-auto md:px-6 px-4 pb-8 md:mt-14 lg:px-20 vertical-scrollbar scrollbar-md">
|
<div className="mx-auto mt-10 h-full w-full overflow-y-auto md:px-6 px-4 pb-8 md:mt-14 lg:px-20 vertical-scrollbar scrollbar-md">
|
||||||
<div className="flex items-center border-b border-custom-border-100 pb-3.5">
|
<div className="flex items-center border-b border-custom-border-100 pb-3.5">
|
||||||
<h3 className="text-xl font-medium">Preferences</h3>
|
<h3 className="text-xl font-medium">Preferences</h3>
|
||||||
@ -73,7 +64,7 @@ const ProfilePreferencesThemePage: NextPageWithLayout = observer(() => {
|
|||||||
<ThemeSwitch value={currentTheme} onChange={handleThemeChange} />
|
<ThemeSwitch value={currentTheme} onChange={handleThemeChange} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{userTheme?.theme === "custom" && <CustomThemeSelector />}
|
{userProfile?.theme?.theme === "custom" && <CustomThemeSelector />}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="grid h-full w-full place-items-center px-4 sm:px-0">
|
<div className="grid h-full w-full place-items-center px-4 sm:px-0">
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
// mobx
|
|
||||||
import { action, observable, makeObservable } from "mobx";
|
import { action, observable, makeObservable } from "mobx";
|
||||||
// helper
|
// store types
|
||||||
import { applyTheme, unsetCustomCssVariables } from "@/helpers/theme.helper";
|
import { RootStore } from "@/store/root.store";
|
||||||
|
|
||||||
export interface IThemeStore {
|
export interface IThemeStore {
|
||||||
// observables
|
// observables
|
||||||
theme: string | null;
|
|
||||||
sidebarCollapsed: boolean | undefined;
|
sidebarCollapsed: boolean | undefined;
|
||||||
profileSidebarCollapsed: boolean | undefined;
|
profileSidebarCollapsed: boolean | undefined;
|
||||||
workspaceAnalyticsSidebarCollapsed: boolean | undefined;
|
workspaceAnalyticsSidebarCollapsed: boolean | undefined;
|
||||||
issueDetailSidebarCollapsed: boolean | undefined;
|
issueDetailSidebarCollapsed: boolean | undefined;
|
||||||
// actions
|
// actions
|
||||||
toggleSidebar: (collapsed?: boolean) => void;
|
toggleSidebar: (collapsed?: boolean) => void;
|
||||||
setTheme: (theme: any) => void;
|
|
||||||
toggleProfileSidebar: (collapsed?: boolean) => void;
|
toggleProfileSidebar: (collapsed?: boolean) => void;
|
||||||
toggleWorkspaceAnalyticsSidebar: (collapsed?: boolean) => void;
|
toggleWorkspaceAnalyticsSidebar: (collapsed?: boolean) => void;
|
||||||
toggleIssueDetailSidebar: (collapsed?: boolean) => void;
|
toggleIssueDetailSidebar: (collapsed?: boolean) => void;
|
||||||
@ -21,31 +18,23 @@ export interface IThemeStore {
|
|||||||
export class ThemeStore implements IThemeStore {
|
export class ThemeStore implements IThemeStore {
|
||||||
// observables
|
// observables
|
||||||
sidebarCollapsed: boolean | undefined = undefined;
|
sidebarCollapsed: boolean | undefined = undefined;
|
||||||
theme: string | null = null;
|
|
||||||
profileSidebarCollapsed: boolean | undefined = undefined;
|
profileSidebarCollapsed: boolean | undefined = undefined;
|
||||||
workspaceAnalyticsSidebarCollapsed: boolean | undefined = undefined;
|
workspaceAnalyticsSidebarCollapsed: boolean | undefined = undefined;
|
||||||
issueDetailSidebarCollapsed: boolean | undefined = undefined;
|
issueDetailSidebarCollapsed: boolean | undefined = undefined;
|
||||||
// root store
|
|
||||||
rootStore;
|
|
||||||
|
|
||||||
constructor(_rootStore: any | null = null) {
|
constructor(private store: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// observable
|
// observable
|
||||||
sidebarCollapsed: observable.ref,
|
sidebarCollapsed: observable.ref,
|
||||||
theme: observable.ref,
|
|
||||||
profileSidebarCollapsed: observable.ref,
|
profileSidebarCollapsed: observable.ref,
|
||||||
workspaceAnalyticsSidebarCollapsed: observable.ref,
|
workspaceAnalyticsSidebarCollapsed: observable.ref,
|
||||||
issueDetailSidebarCollapsed: observable.ref,
|
issueDetailSidebarCollapsed: observable.ref,
|
||||||
// action
|
// action
|
||||||
toggleSidebar: action,
|
toggleSidebar: action,
|
||||||
setTheme: action,
|
|
||||||
toggleProfileSidebar: action,
|
toggleProfileSidebar: action,
|
||||||
toggleWorkspaceAnalyticsSidebar: action,
|
toggleWorkspaceAnalyticsSidebar: action,
|
||||||
toggleIssueDetailSidebar: action,
|
toggleIssueDetailSidebar: action,
|
||||||
// computed
|
|
||||||
});
|
});
|
||||||
// root store
|
|
||||||
this.rootStore = _rootStore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,30 +84,4 @@ export class ThemeStore implements IThemeStore {
|
|||||||
}
|
}
|
||||||
localStorage.setItem("issue_detail_sidebar_collapsed", this.issueDetailSidebarCollapsed.toString());
|
localStorage.setItem("issue_detail_sidebar_collapsed", this.issueDetailSidebarCollapsed.toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the user theme and applies it to the platform
|
|
||||||
* @param _theme
|
|
||||||
*/
|
|
||||||
setTheme = async (_theme: { theme: any }) => {
|
|
||||||
try {
|
|
||||||
const currentTheme: string = _theme?.theme?.theme?.toString();
|
|
||||||
// updating the local storage theme value
|
|
||||||
localStorage.setItem("theme", currentTheme);
|
|
||||||
// updating the mobx theme value
|
|
||||||
this.theme = currentTheme;
|
|
||||||
// applying the theme to platform if the selected theme is custom
|
|
||||||
if (currentTheme === "custom") {
|
|
||||||
const themeSettings = this.rootStore.user.currentUserSettings || null;
|
|
||||||
applyTheme(
|
|
||||||
themeSettings?.theme?.palette !== ",,,,"
|
|
||||||
? themeSettings?.theme?.palette
|
|
||||||
: "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
|
|
||||||
themeSettings?.theme?.darkPalette
|
|
||||||
);
|
|
||||||
} else unsetCustomCssVariables();
|
|
||||||
} catch (error) {
|
|
||||||
console.error("setting user theme error", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
import set from "lodash/set";
|
import set from "lodash/set";
|
||||||
import { action, makeObservable, observable, runInAction } from "mobx";
|
import { action, makeObservable, observable, runInAction } from "mobx";
|
||||||
// services
|
// services
|
||||||
import { UserService } from "services/user.service";
|
import { UserService } from "services/user.service";
|
||||||
// types
|
// types
|
||||||
import { TUserProfile } from "@plane/types";
|
import { IUserTheme, TUserProfile } from "@plane/types";
|
||||||
|
import { RootStore } from "@/store/root.store";
|
||||||
|
|
||||||
type TError = {
|
type TError = {
|
||||||
status: string;
|
status: string;
|
||||||
@ -20,6 +22,7 @@ export interface IUserProfileStore {
|
|||||||
updateUserProfile: (data: Partial<TUserProfile>) => Promise<TUserProfile | undefined>;
|
updateUserProfile: (data: Partial<TUserProfile>) => Promise<TUserProfile | undefined>;
|
||||||
updateUserOnBoard: () => Promise<TUserProfile | undefined>;
|
updateUserOnBoard: () => Promise<TUserProfile | undefined>;
|
||||||
updateTourCompleted: () => Promise<TUserProfile | undefined>;
|
updateTourCompleted: () => Promise<TUserProfile | undefined>;
|
||||||
|
updateUserTheme: (data: Partial<IUserTheme>) => Promise<TUserProfile | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProfileStore implements IUserProfileStore {
|
export class ProfileStore implements IUserProfileStore {
|
||||||
@ -59,7 +62,7 @@ export class ProfileStore implements IUserProfileStore {
|
|||||||
// services
|
// services
|
||||||
userService: UserService;
|
userService: UserService;
|
||||||
|
|
||||||
constructor() {
|
constructor(public store: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// observables
|
// observables
|
||||||
isLoading: observable.ref,
|
isLoading: observable.ref,
|
||||||
@ -70,6 +73,7 @@ export class ProfileStore implements IUserProfileStore {
|
|||||||
updateUserProfile: action,
|
updateUserProfile: action,
|
||||||
updateUserOnBoard: action,
|
updateUserOnBoard: action,
|
||||||
updateTourCompleted: action,
|
updateTourCompleted: action,
|
||||||
|
updateUserTheme: action,
|
||||||
});
|
});
|
||||||
// services
|
// services
|
||||||
this.userService = new UserService();
|
this.userService = new UserService();
|
||||||
@ -179,4 +183,34 @@ export class ProfileStore implements IUserProfileStore {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description updates the user theme
|
||||||
|
* @returns @returns {Promise<TUserProfile | undefined>}
|
||||||
|
*/
|
||||||
|
updateUserTheme = async (data: Partial<IUserTheme>) => {
|
||||||
|
const currentProfileTheme = cloneDeep(this.data.theme);
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
Object.keys(data).forEach((key: string) => {
|
||||||
|
const userKey: keyof IUserTheme = key as keyof IUserTheme;
|
||||||
|
if (this.data.theme) set(this.data.theme, userKey, data[userKey]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const userProfile = await this.userService.updateCurrentUserProfile({ theme: this.data.theme });
|
||||||
|
return userProfile;
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
Object.keys(data).forEach((key: string) => {
|
||||||
|
const userKey: keyof IUserTheme = key as keyof IUserTheme;
|
||||||
|
if (currentProfileTheme) set(this.data.theme, userKey, currentProfileTheme[userKey]);
|
||||||
|
});
|
||||||
|
this.error = {
|
||||||
|
status: "user-profile-theme-update-error",
|
||||||
|
message: "Failed to update user profile theme",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -2759,7 +2759,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@^18.2.42", "@types/react@^18.2.48":
|
"@types/react@*", "@types/react@18.2.48", "@types/react@^18.2.42", "@types/react@^18.2.48":
|
||||||
version "18.2.48"
|
version "18.2.48"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.48.tgz#11df5664642d0bd879c1f58bc1d37205b064e8f1"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.48.tgz#11df5664642d0bd879c1f58bc1d37205b064e8f1"
|
||||||
integrity sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==
|
integrity sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==
|
||||||
|
Loading…
Reference in New Issue
Block a user