dev: Updating themening worfkflow (#1827)

This commit is contained in:
guru_sainath 2023-08-10 13:03:42 +05:30 committed by GitHub
parent be062ccd34
commit 005b42cb8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 251 additions and 231 deletions

View File

@ -4,17 +4,13 @@ import { useTheme } from "next-themes";
import { useForm } from "react-hook-form";
// hooks
import useUser from "hooks/use-user";
// ui
import { PrimaryButton } from "components/ui";
import { ColorPickerInput } from "components/core";
// services
import userService from "services/user.service";
// helper
import { applyTheme } from "helpers/theme.helper";
// types
import { ICustomTheme } from "types";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
@ -33,11 +29,11 @@ const defaultValues: ICustomTheme = {
theme: "custom",
};
export const CustomThemeSelector: React.FC<Props> = ({ preLoadedData }) => {
export const CustomThemeSelector: React.FC<Props> = observer(({ preLoadedData }) => {
const store: any = useMobxStore();
const { setTheme } = useTheme();
const [darkPalette, setDarkPalette] = useState(false);
const {
register,
formState: { errors, isSubmitting },
@ -48,11 +44,14 @@ export const CustomThemeSelector: React.FC<Props> = ({ preLoadedData }) => {
} = useForm<ICustomTheme>({
defaultValues,
});
useEffect(() => {
reset({
...defaultValues,
...preLoadedData,
});
}, [preLoadedData, reset]);
const { setTheme } = useTheme();
const { mutateUser } = useUser();
const handleFormSubmit = async (formData: ICustomTheme) => {
const handleUpdateTheme = async (formData: any) => {
const payload: ICustomTheme = {
background: formData.background,
text: formData.text,
@ -64,28 +63,14 @@ export const CustomThemeSelector: React.FC<Props> = ({ preLoadedData }) => {
theme: "custom",
};
store.user
.updateCurrentUserSettings({ theme: payload })
.then((response: any) => {
setTheme("custom");
applyTheme(payload.palette, darkPalette);
})
.catch((error: any) => {
console.log("error", error);
});
};
const handleUpdateTheme = async (formData: any) => {
await handleFormSubmit({ ...formData, darkPalette });
return store.user
.updateCurrentUserSettings({ theme: payload })
.then((response: any) => response)
.catch((error: any) => error);
};
useEffect(() => {
reset({
...defaultValues,
...preLoadedData,
});
}, [preLoadedData, reset]);
return (
<form onSubmit={handleSubmit(handleUpdateTheme)}>
<div className="space-y-5">
@ -164,4 +149,4 @@ export const CustomThemeSelector: React.FC<Props> = ({ preLoadedData }) => {
</div>
</form>
);
};
});

View File

@ -1,9 +1,5 @@
import { useState, useEffect } from "react";
// next-themes
import { useTheme } from "next-themes";
// services
import userService from "services/user.service";
// hooks
import useUser from "hooks/use-user";
// constants
@ -13,6 +9,10 @@ import { CustomSelect } from "components/ui";
// types
import { ICustomTheme } from "types";
import { unsetCustomCssVariables } from "helpers/theme.helper";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
type Props = {
setPreLoadedData: React.Dispatch<React.SetStateAction<ICustomTheme | null>>;
@ -20,48 +20,21 @@ type Props = {
setCustomThemeSelectorOptions: React.Dispatch<React.SetStateAction<boolean>>;
};
export const ThemeSwitch: React.FC<Props> = ({
setPreLoadedData,
customThemeSelectorOptions,
setCustomThemeSelectorOptions,
}) => {
const [mounted, setMounted] = useState(false);
const { theme, setTheme } = useTheme();
export const ThemeSwitch: React.FC<Props> = observer(
({ setPreLoadedData, customThemeSelectorOptions, setCustomThemeSelectorOptions }) => {
const store: any = useMobxStore();
const { user, mutateUser } = useUser();
const { theme, setTheme } = useTheme();
const updateUserTheme = (newTheme: string) => {
if (!user) return;
setTheme(newTheme);
mutateUser((prevData) => {
if (!prevData) return prevData;
return {
...prevData,
theme: {
...prevData.theme,
theme: newTheme,
},
return store.user
.updateCurrentUserSettings({ theme: { ...user.theme, theme: newTheme } })
.then((response: any) => response)
.catch((error: any) => error);
};
}, false);
userService.updateUser({
theme: {
...user.theme,
theme: newTheme,
},
});
};
// useEffect only runs on the client, so now we can safely show the UI
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) return null;
const currentThemeObj = THEMES_OBJ.find((t) => t.value === theme);
@ -158,4 +131,5 @@ export const ThemeSwitch: React.FC<Props> = ({
))}
</CustomSelect>
);
};
}
);

View File

@ -1,9 +1,14 @@
import { useEffect } from "react";
// next themes
import { useTheme } from "next-themes";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// theme helpers
import { applyTheme, unsetCustomCssVariables } from "helpers/theme.helper";
const MobxStoreInit = () => {
const store: any = useMobxStore();
const { setTheme } = useTheme();
useEffect(() => {
// sidebar collapsed toggle
@ -21,11 +26,25 @@ const MobxStoreInit = () => {
);
// theme
if (localStorage && localStorage.getItem("theme") && store.theme.theme === null)
store.theme.setTheme(
localStorage.getItem("theme") ? localStorage.getItem("theme") : "system"
);
}, [store?.theme]);
if (store.theme.theme === null && store?.user?.currentUserSettings) {
let currentTheme = localStorage.getItem("theme");
currentTheme = currentTheme ? currentTheme : "system";
// validating the theme and applying for initial state
if (currentTheme) {
setTheme(currentTheme);
store.theme.setTheme({ theme: { theme: currentTheme } });
}
}
}, [store?.theme, store?.user, setTheme]);
useEffect(() => {
// current user
if (store?.user?.currentUser === null) store.user.setCurrentUser();
// current user settings
if (store?.user?.currentUserSettings === null) store.user.setCurrentUserSettings();
}, [store?.user]);
return <></>;
};

View File

@ -1,7 +1,4 @@
import { useEffect, useState } from "react";
// next-themes
import { useTheme } from "next-themes";
// hooks
import useUserAuth from "hooks/use-user-auth";
// layouts
@ -14,37 +11,47 @@ import { Spinner } from "components/ui";
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
// types
import { ICustomTheme } from "types";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// next themes
import { useTheme } from "next-themes";
const ProfilePreferences = () => {
const [customThemeSelectorOptions, setCustomThemeSelectorOptions] = useState(false);
const [preLoadedData, setPreLoadedData] = useState<ICustomTheme | null>(null);
const { theme } = useTheme();
const ProfilePreferences = observer(() => {
const { user: myProfile } = useUserAuth();
const store: any = useMobxStore();
const { theme } = useTheme();
console.log("store", store?.theme?.theme);
console.log("theme", theme);
const [customThemeSelectorOptions, setCustomThemeSelectorOptions] = useState(false);
const [preLoadedData, setPreLoadedData] = useState<ICustomTheme | null>(null);
useEffect(() => {
if (theme === "custom") {
if (myProfile?.theme.palette)
if (store?.user && store?.theme?.theme === "custom") {
const currentTheme = store?.user?.currentUserSettings?.theme;
if (currentTheme.palette)
setPreLoadedData({
background: myProfile.theme.background !== "" ? myProfile.theme.background : "#0d101b",
text: myProfile.theme.text !== "" ? myProfile.theme.text : "#c5c5c5",
primary: myProfile.theme.primary !== "" ? myProfile.theme.primary : "#3f76ff",
background: currentTheme.background !== "" ? currentTheme.background : "#0d101b",
text: currentTheme.text !== "" ? currentTheme.text : "#c5c5c5",
primary: currentTheme.primary !== "" ? currentTheme.primary : "#3f76ff",
sidebarBackground:
myProfile.theme.sidebarBackground !== ""
? myProfile.theme.sidebarBackground
: "#0d101b",
sidebarText: myProfile.theme.sidebarText !== "" ? myProfile.theme.sidebarText : "#c5c5c5",
currentTheme.sidebarBackground !== "" ? currentTheme.sidebarBackground : "#0d101b",
sidebarText: currentTheme.sidebarText !== "" ? currentTheme.sidebarText : "#c5c5c5",
darkPalette: false,
palette:
myProfile.theme.palette !== ",,,,"
? myProfile.theme.palette
currentTheme.palette !== ",,,,"
? currentTheme.palette
: "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
theme: "custom",
});
if (!customThemeSelectorOptions) setCustomThemeSelectorOptions(true);
setCustomThemeSelectorOptions((prevData) => true);
}
}, [myProfile, theme, customThemeSelectorOptions]);
}, [store, store?.theme?.theme]);
return (
<WorkspaceAuthorizationLayout
@ -91,6 +98,6 @@ const ProfilePreferences = () => {
)}
</WorkspaceAuthorizationLayout>
);
};
});
export default ProfilePreferences;

View File

@ -22,8 +22,14 @@ import {
import { Spinner } from "components/ui";
// images
import BluePlaneLogoWithoutText from "public/plane-logos/blue-without-text.png";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// next themes
import { useTheme } from "next-themes";
import { ICurrentUserResponse, IUser } from "types";
import { IUser } from "types";
// types
type EmailPasswordFormValues = {
email: string;
@ -31,15 +37,18 @@ type EmailPasswordFormValues = {
medium?: string;
};
const HomePage: NextPage = () => {
const HomePage: NextPage = observer(() => {
const store: any = useMobxStore();
const { setTheme } = useTheme();
const { isLoading, mutateUser } = useUserAuth("sign-in");
const { setToastAlert } = useToast();
const { setTheme } = useTheme();
const changeTheme = (user: IUser) => {
setTheme(user.theme.theme ?? "system");
const handleTheme = (user: IUser) => {
const currentTheme = user.theme.theme ?? "system";
setTheme(currentTheme);
store?.user?.setCurrentUserSettings();
};
const handleGoogleSignIn = async ({ clientId, credential }: any) => {
@ -53,7 +62,7 @@ const HomePage: NextPage = () => {
const response = await authenticationService.socialAuth(socialAuthPayload);
if (response && response?.user) {
mutateUser();
changeTheme(response.user);
handleTheme(response?.user);
}
} else {
throw Error("Cant find credentials");
@ -79,7 +88,7 @@ const HomePage: NextPage = () => {
const response = await authenticationService.socialAuth(socialAuthPayload);
if (response && response?.user) {
mutateUser();
changeTheme(response.user);
handleTheme(response?.user);
}
} else {
throw Error("Cant find credentials");
@ -101,7 +110,7 @@ const HomePage: NextPage = () => {
try {
if (response) {
mutateUser();
changeTheme(response.user);
handleTheme(response?.user);
}
} catch (err: any) {
setToastAlert({
@ -128,7 +137,7 @@ const HomePage: NextPage = () => {
try {
if (response) {
mutateUser();
changeTheme(response.user);
handleTheme(response?.user);
}
} catch (err: any) {
setToastAlert({
@ -140,10 +149,6 @@ const HomePage: NextPage = () => {
}
};
useEffect(() => {
setTheme("system");
}, [setTheme]);
return (
<DefaultLayout>
{isLoading ? (
@ -202,6 +207,6 @@ const HomePage: NextPage = () => {
)}
</DefaultLayout>
);
};
});
export default HomePage;

View File

@ -38,21 +38,24 @@ class ThemeStore {
}
}
setTheme = async (_theme: ICurrentUserSettings) => {
setTheme = async (_theme: { theme: ICurrentUserSettings }) => {
try {
localStorage.setItem("theme", _theme.theme.toString());
this.theme = _theme.theme.toString();
const currentTheme: string = _theme.theme.theme.toString();
if (this.theme === "custom") {
let themeSettings = this.rootStore.user.currentUserSettings || null;
if (themeSettings && themeSettings.theme.palette) {
// 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
themeSettings?.theme?.palette !== ",,,,"
? themeSettings?.theme?.palette
: "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
themeSettings.theme.darkPalette
themeSettings?.theme?.darkPalette
);
}
} else unsetCustomCssVariables();
} catch (error) {
console.error("setting user theme error", error);

View File

@ -1,5 +1,5 @@
// mobx
import { action, observable, computed, makeObservable } from "mobx";
import { action, observable, computed, runInAction, makeObservable } from "mobx";
// services
import UserService from "services/user.service";
// interfaces
@ -31,8 +31,9 @@ class UserStore {
try {
let userResponse: ICurrentUser | null = await UserService.currentUser();
userResponse = userResponse || null;
if (userResponse) {
this.currentUser = {
const userPayload: ICurrentUser = {
id: userResponse?.id,
avatar: userResponse?.avatar,
first_name: userResponse?.first_name,
@ -46,6 +47,9 @@ class UserStore {
is_onboarded: userResponse?.is_onboarded,
role: userResponse?.role,
};
runInAction(() => {
this.currentUser = userPayload;
});
}
} catch (error) {
console.error("Fetching current user error", error);
@ -56,11 +60,15 @@ class UserStore {
try {
let userSettingsResponse: ICurrentUserSettings | null = await UserService.currentUser();
userSettingsResponse = userSettingsResponse || null;
if (userSettingsResponse) {
this.currentUserSettings = {
theme: userSettingsResponse?.theme,
const themePayload = {
theme: { ...userSettingsResponse?.theme },
};
this.rootStore.theme.setTheme();
runInAction(() => {
this.currentUserSettings = themePayload;
this.rootStore.theme.setTheme(themePayload);
});
}
} catch (error) {
console.error("Fetching current user error", error);
@ -71,9 +79,26 @@ class UserStore {
try {
let userResponse: ICurrentUser = await UserService.updateUser(user);
userResponse = userResponse || null;
if (userResponse) {
this.currentUser = userResponse;
return userResponse;
const userPayload: ICurrentUser = {
id: userResponse?.id,
avatar: userResponse?.avatar,
first_name: userResponse?.first_name,
last_name: userResponse?.last_name,
username: userResponse?.username,
email: userResponse?.email,
mobile_number: userResponse?.mobile_number,
is_email_verified: userResponse?.is_email_verified,
is_tour_completed: userResponse?.is_tour_completed,
onboarding_step: userResponse?.onboarding_step,
is_onboarded: userResponse?.is_onboarded,
role: userResponse?.role,
};
runInAction(() => {
this.currentUser = userPayload;
});
return userPayload;
}
} catch (error) {
console.error("Updating user error", error);
@ -86,9 +111,14 @@ class UserStore {
let userSettingsResponse: ICurrentUserSettings = await UserService.updateUser(userTheme);
userSettingsResponse = userSettingsResponse || null;
if (userSettingsResponse) {
this.currentUserSettings = userSettingsResponse;
this.rootStore.theme.setTheme(userTheme);
return userSettingsResponse;
const themePayload = {
theme: { ...userSettingsResponse?.theme },
};
runInAction(() => {
this.currentUserSettings = themePayload;
this.rootStore.theme.setTheme(themePayload);
});
return themePayload;
}
} catch (error) {
console.error("Updating user settings error", error);
@ -97,10 +127,7 @@ class UserStore {
};
// init load
initialLoad() {
this.setCurrentUser();
this.setCurrentUserSettings();
}
initialLoad() {}
}
export default UserStore;