diff --git a/apps/app/components/command-palette/change-interface-theme.tsx b/apps/app/components/command-palette/change-interface-theme.tsx index b2b43c6704..b34212b7f9 100644 --- a/apps/app/components/command-palette/change-interface-theme.tsx +++ b/apps/app/components/command-palette/change-interface-theme.tsx @@ -5,6 +5,8 @@ import { Command } from "cmdk"; import { THEMES_OBJ } from "constants/themes"; import { useTheme } from "next-themes"; import { SettingIcon } from "components/icons"; +import userService from "services/user.service"; +import useUser from "hooks/use-user"; type Props = { setIsPaletteOpen: Dispatch>; @@ -12,24 +14,50 @@ type Props = { export const ChangeInterfaceTheme: React.FC = ({ setIsPaletteOpen }) => { const [mounted, setMounted] = useState(false); + const { setTheme } = useTheme(); + const { user, mutateUser } = useUser(); + + const updateUserTheme = (newTheme: string) => { + if (!user) return; + + setTheme(newTheme); + + mutateUser((prevData) => { + if (!prevData) return prevData; + + return { + ...prevData, + theme: { + ...prevData.theme, + theme: newTheme, + }, + }; + }, 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; - } + if (!mounted) return null; return ( <> - {THEMES_OBJ.map((theme) => ( + {THEMES_OBJ.filter((t) => t.value !== "custom").map((theme) => ( { - setTheme(theme.value); + updateUserTheme(theme.value); setIsPaletteOpen(false); }} className="focus:outline-none" diff --git a/apps/app/components/core/theme/custom-theme-selector.tsx b/apps/app/components/core/theme/custom-theme-selector.tsx index 40450ee2c7..668083b590 100644 --- a/apps/app/components/core/theme/custom-theme-selector.tsx +++ b/apps/app/components/core/theme/custom-theme-selector.tsx @@ -28,6 +28,7 @@ const defaultValues: ICustomTheme = { sidebarText: "#c5c5c5", darkPalette: false, palette: "", + theme: "custom", }; export const CustomThemeSelector: React.FC = ({ preLoadedData }) => { @@ -56,6 +57,7 @@ export const CustomThemeSelector: React.FC = ({ preLoadedData }) => { sidebarText: formData.sidebarText, darkPalette: darkPalette, palette: `${formData.background},${formData.text},${formData.primary},${formData.sidebarBackground},${formData.sidebarText}`, + theme: "custom", }; await userService diff --git a/apps/app/components/core/theme/theme-switch.tsx b/apps/app/components/core/theme/theme-switch.tsx index 39b570bc53..8ac950b8ce 100644 --- a/apps/app/components/core/theme/theme-switch.tsx +++ b/apps/app/components/core/theme/theme-switch.tsx @@ -1,142 +1,161 @@ -import { useState, useEffect, Dispatch, SetStateAction } from "react"; +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 import { THEMES_OBJ } from "constants/themes"; // ui import { CustomSelect } from "components/ui"; // types -import { ICustomTheme, IUser } from "types"; +import { ICustomTheme } from "types"; +import { unsetCustomCssVariables } from "helpers/theme.helper"; type Props = { - user: IUser | undefined; - setPreLoadedData: Dispatch>; + setPreLoadedData: React.Dispatch>; customThemeSelectorOptions: boolean; - setCustomThemeSelectorOptions: Dispatch>; + setCustomThemeSelectorOptions: React.Dispatch>; }; export const ThemeSwitch: React.FC = ({ - user, setPreLoadedData, customThemeSelectorOptions, setCustomThemeSelectorOptions, }) => { const [mounted, setMounted] = useState(false); + const { theme, setTheme } = useTheme(); + const { user, mutateUser } = useUser(); + + const updateUserTheme = (newTheme: string) => { + if (!user) return; + + setTheme(newTheme); + + mutateUser((prevData) => { + if (!prevData) return prevData; + + return { + ...prevData, + theme: { + ...prevData.theme, + theme: newTheme, + }, + }; + }, 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; - } + if (!mounted) return null; const currentThemeObj = THEMES_OBJ.find((t) => t.value === theme); return ( - <> - + +
-
-
-
- {currentThemeObj.label} + /> +
- ) : ( - "Select your theme" - ) - } - onChange={({ value, type }: { value: string; type: string }) => { - if (value === "custom") { - if (user?.theme.palette) { - setPreLoadedData({ - background: user.theme.background !== "" ? user.theme.background : "#0d101b", - text: user.theme.text !== "" ? user.theme.text : "#c5c5c5", - primary: user.theme.primary !== "" ? user.theme.primary : "#3f76ff", - sidebarBackground: - user.theme.sidebarBackground !== "" ? user.theme.sidebarBackground : "#0d101b", - sidebarText: user.theme.sidebarText !== "" ? user.theme.sidebarText : "#c5c5c5", - darkPalette: false, - palette: - user.theme.palette !== ",,,," - ? user.theme.palette - : "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5", - }); - } - - if (!customThemeSelectorOptions) setCustomThemeSelectorOptions(true); - } else { - if (customThemeSelectorOptions) setCustomThemeSelectorOptions(false); - - for (let i = 10; i <= 900; i >= 100 ? (i += 100) : (i += 10)) { - document.documentElement.style.removeProperty(`--color-background-${i}`); - document.documentElement.style.removeProperty(`--color-text-${i}`); - document.documentElement.style.removeProperty(`--color-border-${i}`); - document.documentElement.style.removeProperty(`--color-primary-${i}`); - document.documentElement.style.removeProperty(`--color-sidebar-background-${i}`); - document.documentElement.style.removeProperty(`--color-sidebar-text-${i}`); - document.documentElement.style.removeProperty(`--color-sidebar-border-${i}`); - } + {currentThemeObj.label} +
+ ) : ( + "Select your theme" + ) + } + onChange={({ value, type }: { value: string; type: string }) => { + if (value === "custom") { + if (user?.theme.palette) { + setPreLoadedData({ + background: user.theme.background !== "" ? user.theme.background : "#0d101b", + text: user.theme.text !== "" ? user.theme.text : "#c5c5c5", + primary: user.theme.primary !== "" ? user.theme.primary : "#3f76ff", + sidebarBackground: + user.theme.sidebarBackground !== "" ? user.theme.sidebarBackground : "#0d101b", + sidebarText: user.theme.sidebarText !== "" ? user.theme.sidebarText : "#c5c5c5", + darkPalette: false, + palette: + user.theme.palette !== ",,,," + ? user.theme.palette + : "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5", + theme: "custom", + }); } - setTheme(value); - document.documentElement.style.setProperty("color-scheme", type); - }} - input - width="w-full" - position="right" - > - {THEMES_OBJ.map(({ value, label, type, icon }) => ( - -
+ if (!customThemeSelectorOptions) setCustomThemeSelectorOptions(true); + } else { + if (customThemeSelectorOptions) setCustomThemeSelectorOptions(false); + unsetCustomCssVariables(); + } + + updateUserTheme(value); + document.documentElement.style.setProperty("--color-scheme", type); + }} + input + width="w-full" + position="right" + > + {THEMES_OBJ.map(({ value, label, type, icon }) => ( + +
+
-
-
-
- {label} + /> +
- - ))} - - + {label} +
+ + ))} + ); }; diff --git a/apps/app/components/workspace/sidebar-dropdown.tsx b/apps/app/components/workspace/sidebar-dropdown.tsx index 3b9aa97eb9..7a43cfb74b 100644 --- a/apps/app/components/workspace/sidebar-dropdown.tsx +++ b/apps/app/components/workspace/sidebar-dropdown.tsx @@ -3,10 +3,10 @@ import { Fragment } from "react"; import { useRouter } from "next/router"; import Link from "next/link"; -// next-themes -import { useTheme } from "next-themes"; // headless ui import { Menu, Transition } from "@headlessui/react"; +// next-themes +import { useTheme } from "next-themes"; // hooks import useUser from "hooks/use-user"; import useThemeHook from "hooks/use-theme"; @@ -91,7 +91,7 @@ export const WorkspaceSidebarDropdown = () => { .then(() => { mutateUser(undefined); router.push("/"); - setTheme("dark"); + setTheme("system"); }) .catch(() => setToastAlert({ diff --git a/apps/app/constants/themes.ts b/apps/app/constants/themes.ts index 78420843a6..74b74caba8 100644 --- a/apps/app/constants/themes.ts +++ b/apps/app/constants/themes.ts @@ -1,6 +1,16 @@ export const THEMES = ["light", "dark", "light-contrast", "dark-contrast", "custom"]; export const THEMES_OBJ = [ + { + value: "system", + label: "System Preference", + type: "light", + icon: { + border: "#DEE2E6", + color1: "#FAFAFA", + color2: "#3F76FF", + }, + }, { value: "light", label: "Light", diff --git a/apps/app/contexts/theme.context.tsx b/apps/app/contexts/theme.context.tsx index 0f54891253..d338b9b6b8 100644 --- a/apps/app/contexts/theme.context.tsx +++ b/apps/app/contexts/theme.context.tsx @@ -11,7 +11,7 @@ import projectService from "services/project.service"; // fetch-keys import { USER_PROJECT_VIEW } from "constants/fetch-keys"; // helper -import { applyTheme } from "helpers/theme.helper"; +import { applyTheme, unsetCustomCssVariables } from "helpers/theme.helper"; // constants export const themeContext = createContext({} as ContextType); @@ -92,15 +92,18 @@ export const ThemeContextProvider: React.FC<{ children: React.ReactNode }> = ({ useEffect(() => { const theme = localStorage.getItem("theme"); - if (theme && theme === "custom") { - if (user && user.theme.palette) { - applyTheme( - user.theme.palette !== ",,,," - ? user.theme.palette - : "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5", - user.theme.darkPalette - ); - } + + if (theme) { + if (theme === "custom") { + if (user && user.theme.palette) { + applyTheme( + user.theme.palette !== ",,,," + ? user.theme.palette + : "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5", + user.theme.darkPalette + ); + } + } else unsetCustomCssVariables(); } }, [user]); diff --git a/apps/app/helpers/theme.helper.ts b/apps/app/helpers/theme.helper.ts index 993a6b9ea2..8a521bc31c 100644 --- a/apps/app/helpers/theme.helper.ts +++ b/apps/app/helpers/theme.helper.ts @@ -60,6 +60,7 @@ const calculateShades = (hexValue: string): TShades => { }; export const applyTheme = (palette: string, isDarkPalette: boolean) => { + const dom = document?.querySelector("[data-theme='custom']"); // palette: [bg, text, primary, sidebarBg, sidebarText] const values: string[] = palette.split(","); values.push(isDarkPalette ? "dark" : "light"); @@ -79,41 +80,40 @@ export const applyTheme = (palette: string, isDarkPalette: boolean) => { const sidebarBackgroundRgbValues = `${sidebarBackgroundShades[shade].r}, ${sidebarBackgroundShades[shade].g}, ${sidebarBackgroundShades[shade].b}`; const sidebarTextRgbValues = `${sidebarTextShades[shade].r}, ${sidebarTextShades[shade].g}, ${sidebarTextShades[shade].b}`; - document - .querySelector("[data-theme='custom']") - ?.style.setProperty(`--color-background-${shade}`, bgRgbValues); - document - .querySelector("[data-theme='custom']") - ?.style.setProperty(`--color-text-${shade}`, textRgbValues); - document - .querySelector("[data-theme='custom']") - ?.style.setProperty(`--color-primary-${shade}`, primaryRgbValues); - document - .querySelector("[data-theme='custom']") - ?.style.setProperty(`--color-sidebar-background-${shade}`, sidebarBackgroundRgbValues); - document - .querySelector("[data-theme='custom']") - ?.style.setProperty(`--color-sidebar-text-${shade}`, sidebarTextRgbValues); + dom?.style.setProperty(`--color-background-${shade}`, bgRgbValues); + dom?.style.setProperty(`--color-text-${shade}`, textRgbValues); + dom?.style.setProperty(`--color-primary-${shade}`, primaryRgbValues); + dom?.style.setProperty(`--color-sidebar-background-${shade}`, sidebarBackgroundRgbValues); + dom?.style.setProperty(`--color-sidebar-text-${shade}`, sidebarTextRgbValues); if (i >= 100 && i <= 400) { const borderShade = i === 100 ? 70 : i === 200 ? 80 : i === 300 ? 90 : 100; - document - .querySelector("[data-theme='custom']") - ?.style.setProperty( - `--color-border-${shade}`, - `${bgShades[borderShade].r}, ${bgShades[borderShade].g}, ${bgShades[borderShade].b}` - ); - document - .querySelector("[data-theme='custom']") - ?.style.setProperty( - `--color-sidebar-border-${shade}`, - `${sidebarBackgroundShades[borderShade].r}, ${sidebarBackgroundShades[borderShade].g}, ${sidebarBackgroundShades[borderShade].b}` - ); + dom?.style.setProperty( + `--color-border-${shade}`, + `${bgShades[borderShade].r}, ${bgShades[borderShade].g}, ${bgShades[borderShade].b}` + ); + dom?.style.setProperty( + `--color-sidebar-border-${shade}`, + `${sidebarBackgroundShades[borderShade].r}, ${sidebarBackgroundShades[borderShade].g}, ${sidebarBackgroundShades[borderShade].b}` + ); } } - document - .querySelector("[data-theme='custom']") - ?.style.setProperty("--color-scheme", values[5]); + dom?.style.setProperty("--color-scheme", values[5]); +}; + +export const unsetCustomCssVariables = () => { + for (let i = 10; i <= 900; i >= 100 ? (i += 100) : (i += 10)) { + const dom = document.querySelector("[data-theme='custom']"); + + dom?.style.removeProperty(`--color-background-${i}`); + dom?.style.removeProperty(`--color-text-${i}`); + dom?.style.removeProperty(`--color-border-${i}`); + dom?.style.removeProperty(`--color-primary-${i}`); + dom?.style.removeProperty(`--color-sidebar-background-${i}`); + dom?.style.removeProperty(`--color-sidebar-text-${i}`); + dom?.style.removeProperty(`--color-sidebar-border-${i}`); + dom?.style.removeProperty("--color-scheme"); + } }; diff --git a/apps/app/pages/[workspaceSlug]/me/profile/preferences.tsx b/apps/app/pages/[workspaceSlug]/me/profile/preferences.tsx index 605131aa4b..61e743fc3a 100644 --- a/apps/app/pages/[workspaceSlug]/me/profile/preferences.tsx +++ b/apps/app/pages/[workspaceSlug]/me/profile/preferences.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from "react"; -import { useTheme } from "next-themes"; +// next-themes +import { useTheme } from "next-themes"; // hooks import useUserAuth from "hooks/use-user-auth"; // layouts @@ -15,11 +16,13 @@ import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; import { ICustomTheme } from "types"; const ProfilePreferences = () => { - const { user: myProfile } = useUserAuth(); - const { theme } = useTheme(); const [customThemeSelectorOptions, setCustomThemeSelectorOptions] = useState(false); const [preLoadedData, setPreLoadedData] = useState(null); + const { theme } = useTheme(); + + const { user: myProfile } = useUserAuth(); + useEffect(() => { if (theme === "custom") { if (myProfile?.theme.palette) @@ -37,6 +40,7 @@ const ProfilePreferences = () => { myProfile.theme.palette !== ",,,," ? myProfile.theme.palette : "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5", + theme: "custom", }); if (!customThemeSelectorOptions) setCustomThemeSelectorOptions(true); } @@ -71,7 +75,6 @@ const ProfilePreferences = () => {
- + diff --git a/apps/app/pages/colors.tsx b/apps/app/pages/colors.tsx deleted file mode 100644 index d52e2cf41c..0000000000 --- a/apps/app/pages/colors.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import React from "react"; - -// layouts -import DefaultLayout from "layouts/default-layout"; -import { UserAuthorizationLayout } from "layouts/auth-layout/user-authorization-wrapper"; -// types -import type { NextPage } from "next"; - -const Colors: NextPage = () => ( - - -
-
- Primary: -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Background: -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Text: -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sidebar Background: -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sidebar Text: -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -); - -export default Colors; diff --git a/apps/app/pages/index.tsx b/apps/app/pages/index.tsx index 6cef211c03..f9e4d98440 100644 --- a/apps/app/pages/index.tsx +++ b/apps/app/pages/index.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect } from "react"; import Image from "next/image"; @@ -22,6 +22,8 @@ import { import { Spinner } from "components/ui"; // images import BluePlaneLogoWithoutText from "public/plane-logos/blue-without-text.png"; +import { useTheme } from "next-themes"; +import { ICurrentUserResponse, IUser } from "types"; // types type EmailPasswordFormValues = { email: string; @@ -34,6 +36,12 @@ const HomePage: NextPage = () => { const { setToastAlert } = useToast(); + const { setTheme } = useTheme(); + + const changeTheme = (user: IUser) => { + setTheme(user.theme.theme ?? "system"); + }; + const handleGoogleSignIn = async ({ clientId, credential }: any) => { try { if (clientId && credential) { @@ -43,7 +51,10 @@ const HomePage: NextPage = () => { clientId, }; const response = await authenticationService.socialAuth(socialAuthPayload); - if (response && response?.user) mutateUser(); + if (response && response?.user) { + mutateUser(); + changeTheme(response.user); + } } else { throw Error("Cant find credentials"); } @@ -66,7 +77,10 @@ const HomePage: NextPage = () => { clientId: process.env.NEXT_PUBLIC_GITHUB_ID, }; const response = await authenticationService.socialAuth(socialAuthPayload); - if (response && response?.user) mutateUser(); + if (response && response?.user) { + mutateUser(); + changeTheme(response.user); + } } else { throw Error("Cant find credentials"); } @@ -85,7 +99,10 @@ const HomePage: NextPage = () => { .emailLogin(formData) .then((response) => { try { - if (response) mutateUser(); + if (response) { + mutateUser(); + changeTheme(response.user); + } } catch (err: any) { setToastAlert({ type: "error", @@ -109,7 +126,10 @@ const HomePage: NextPage = () => { const handleEmailCodeSignIn = async (response: any) => { try { - if (response) mutateUser(); + if (response) { + mutateUser(); + changeTheme(response.user); + } } catch (err: any) { setToastAlert({ type: "error", @@ -120,6 +140,10 @@ const HomePage: NextPage = () => { } }; + useEffect(() => { + setTheme("system"); + }, [setTheme]); + return ( {isLoading ? ( diff --git a/apps/app/pages/magic-sign-in.tsx b/apps/app/pages/magic-sign-in.tsx index c959764a2f..7de298d392 100644 --- a/apps/app/pages/magic-sign-in.tsx +++ b/apps/app/pages/magic-sign-in.tsx @@ -1,6 +1,9 @@ import React, { useState, useEffect } from "react"; -// next imports + import { useRouter } from "next/router"; + +// next-themes +import { useTheme } from "next-themes"; // layouts import DefaultLayout from "layouts/default-layout"; // services @@ -17,11 +20,17 @@ const MagicSignIn: NextPage = () => { const { setToastAlert } = useToast(); - const { user, isLoading, mutateUser } = useUserAuth("sign-in"); + const { setTheme } = useTheme(); + + const { mutateUser } = useUserAuth("sign-in"); const [isSigningIn, setIsSigningIn] = useState(false); const [errorSigningIn, setErrorSignIn] = useState(); + useEffect(() => { + setTheme("system"); + }, [setTheme]); + useEffect(() => { setIsSigningIn(() => false); setErrorSignIn(() => undefined); diff --git a/apps/app/pages/onboarding.tsx b/apps/app/pages/onboarding.tsx index 217584dd0f..51148b19e3 100644 --- a/apps/app/pages/onboarding.tsx +++ b/apps/app/pages/onboarding.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from "react"; -import Router from "next/router"; import Image from "next/image"; import useSWR, { mutate } from "swr"; @@ -32,7 +31,7 @@ import { CURRENT_USER, USER_WORKSPACE_INVITATIONS } from "constants/fetch-keys"; const Onboarding: NextPage = () => { const [step, setStep] = useState(null); - const { theme } = useTheme(); + const { theme, setTheme } = useTheme(); const { user, isLoading: userLoading } = useUserAuth("onboarding"); @@ -117,6 +116,10 @@ const Onboarding: NextPage = () => { await userService.updateUserOnBoard({ userRole: user.role }, user); }; + useEffect(() => { + setTheme("system"); + }, [setTheme]); + useEffect(() => { const handleStepChange = async () => { if (!user || !invitations) return; diff --git a/apps/app/pages/reset-password.tsx b/apps/app/pages/reset-password.tsx index c25974cb94..fa17d2333e 100644 --- a/apps/app/pages/reset-password.tsx +++ b/apps/app/pages/reset-password.tsx @@ -3,6 +3,8 @@ import React, { useEffect, useState } from "react"; import { useRouter } from "next/router"; import Image from "next/image"; +// next-themes +import { useTheme } from "next-themes"; // react-hook-form import { useForm } from "react-hook-form"; // hooks @@ -31,6 +33,8 @@ const ResetPasswordPage: NextPage = () => { const { setToastAlert } = useToast(); + const { setTheme } = useTheme(); + const { register, handleSubmit, @@ -76,6 +80,10 @@ const ResetPasswordPage: NextPage = () => { ); }; + useEffect(() => { + setTheme("system"); + }, [setTheme]); + useEffect(() => { if (parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0")) router.push("/"); else setIsLoading(false); diff --git a/apps/app/pages/sign-up.tsx b/apps/app/pages/sign-up.tsx index fe8960d736..72a391ea46 100644 --- a/apps/app/pages/sign-up.tsx +++ b/apps/app/pages/sign-up.tsx @@ -3,6 +3,8 @@ import React, { useEffect, useState } from "react"; import Image from "next/image"; import { useRouter } from "next/router"; +// next-themes +import { useTheme } from "next-themes"; // services import authenticationService from "services/authentication.service"; // hooks @@ -31,6 +33,8 @@ const SignUp: NextPage = () => { const { setToastAlert } = useToast(); + const { setTheme } = useTheme(); + const { mutateUser } = useUserAuth("sign-in"); const handleSignUp = async (formData: EmailPasswordFormValues) => { @@ -62,6 +66,10 @@ const SignUp: NextPage = () => { ); }; + useEffect(() => { + setTheme("system"); + }, [setTheme]); + useEffect(() => { if (parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0")) router.push("/"); else setIsLoading(false); diff --git a/apps/app/services/authentication.service.ts b/apps/app/services/authentication.service.ts index 86f55e3298..e4a33bff8a 100644 --- a/apps/app/services/authentication.service.ts +++ b/apps/app/services/authentication.service.ts @@ -1,5 +1,6 @@ // services import APIService from "services/api.service"; +import { ICurrentUserResponse } from "types"; const { NEXT_PUBLIC_API_BASE_URL } = process.env; @@ -32,7 +33,11 @@ class AuthService extends APIService { }); } - async socialAuth(data: any) { + async socialAuth(data: any): Promise<{ + access_token: string; + refresh_toke: string; + user: ICurrentUserResponse; + }> { return this.post("/api/social-auth/", data, { headers: {} }) .then((response) => { this.setAccessToken(response?.data?.access_token); diff --git a/apps/app/types/users.d.ts b/apps/app/types/users.d.ts index 3151345e09..ec77df2429 100644 --- a/apps/app/types/users.d.ts +++ b/apps/app/types/users.d.ts @@ -46,6 +46,7 @@ export interface ICustomTheme { sidebarText: string; darkPalette: boolean; palette: string; + theme: string; } export interface ICurrentUserResponse extends IUser {