diff --git a/space/app/page.tsx b/space/app/page.tsx
index e1522b14b..d03300a25 100644
--- a/space/app/page.tsx
+++ b/space/app/page.tsx
@@ -1,7 +1,5 @@
"use client";
-import { observer } from "mobx-react-lite";
-import useSWR from "swr";
// components
import { UserLoggedIn } from "@/components/account";
import { LogoSpinner } from "@/components/common";
@@ -9,15 +7,8 @@ import { AuthView } from "@/components/views";
// hooks
import { useUser } from "@/hooks/store";
-function HomePage() {
- const { data: currentUser, fetchCurrentUser, isAuthenticated, isLoading } = useUser();
-
- useSWR("CURRENT_USER", () => fetchCurrentUser(), {
- errorRetryCount: 0,
- revalidateIfStale: false,
- revalidateOnFocus: false,
- refreshWhenHidden: false,
- });
+export default function HomePage() {
+ const { data: currentUser, isAuthenticated, isLoading } = useUser();
if (isLoading) return
;
@@ -25,5 +16,3 @@ function HomePage() {
return
;
}
-
-export default observer(HomePage);
diff --git a/space/components/account/auth-forms/auth-root.tsx b/space/components/account/auth-forms/auth-root.tsx
index 273e5bbd5..5be59c5b6 100644
--- a/space/components/account/auth-forms/auth-root.tsx
+++ b/space/components/account/auth-forms/auth-root.tsx
@@ -43,7 +43,7 @@ export const AuthRoot: FC = observer(() => {
const [errorInfo, setErrorInfo] = useState
(undefined);
const [isPasswordAutoset, setIsPasswordAutoset] = useState(true);
// hooks
- const { instance } = useInstance();
+ const { config } = useInstance();
useEffect(() => {
if (error_code) {
@@ -67,11 +67,10 @@ export const AuthRoot: FC = observer(() => {
}
}, [error_code]);
- const isSMTPConfigured = instance?.config?.is_smtp_configured || false;
- const isMagicLoginEnabled = instance?.config?.is_magic_login_enabled || false;
- const isEmailPasswordEnabled = instance?.config?.is_email_password_enabled || false;
- const isOAuthEnabled =
- (instance?.config && (instance?.config?.is_google_enabled || instance?.config?.is_github_enabled)) || false;
+ const isSMTPConfigured = config?.is_smtp_configured || false;
+ const isMagicLoginEnabled = config?.is_magic_login_enabled || false;
+ const isEmailPasswordEnabled = config?.is_email_password_enabled || false;
+ const isOAuthEnabled = (config && (config?.is_google_enabled || config?.is_github_enabled)) || false;
// submit handler- email verification
const handleEmailVerification = async (data: IEmailCheckData) => {
diff --git a/space/components/account/oauth/oauth-options.tsx b/space/components/account/oauth/oauth-options.tsx
index 779f53925..011c7f189 100644
--- a/space/components/account/oauth/oauth-options.tsx
+++ b/space/components/account/oauth/oauth-options.tsx
@@ -6,7 +6,7 @@ import { useInstance } from "@/hooks/store";
export const OAuthOptions: React.FC = observer(() => {
// hooks
- const { instance } = useInstance();
+ const { config } = useInstance();
return (
<>
@@ -16,12 +16,12 @@ export const OAuthOptions: React.FC = observer(() => {
- {instance?.config?.is_google_enabled && (
+ {config?.is_google_enabled && (
)}
- {instance?.config?.is_github_enabled &&
}
+ {config?.is_github_enabled &&
}
>
);
diff --git a/space/hooks/store/use-instance.ts b/space/hooks/store/use-instance.ts
index 62aa0baae..455bc5ca0 100644
--- a/space/hooks/store/use-instance.ts
+++ b/space/hooks/store/use-instance.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
// lib
-import { StoreContext } from "@/lib/app-providers";
+import { StoreContext } from "@/lib/store-provider";
// store
import { IInstanceStore } from "@/store/instance.store";
diff --git a/space/hooks/store/use-issue-details.tsx b/space/hooks/store/use-issue-details.tsx
index 56ee48627..fc708fdbd 100644
--- a/space/hooks/store/use-issue-details.tsx
+++ b/space/hooks/store/use-issue-details.tsx
@@ -1,6 +1,6 @@
import { useContext } from "react";
// lib
-import { StoreContext } from "@/lib/app-providers";
+import { StoreContext } from "@/lib/store-provider";
// store
import { IIssueDetailStore } from "@/store/issue-detail.store";
diff --git a/space/hooks/store/use-issue-filter.ts b/space/hooks/store/use-issue-filter.ts
index a80d9761b..c35b01c64 100644
--- a/space/hooks/store/use-issue-filter.ts
+++ b/space/hooks/store/use-issue-filter.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
// lib
-import { StoreContext } from "@/lib/app-providers";
+import { StoreContext } from "@/lib/store-provider";
// store
import { IIssueFilterStore } from "@/store/issue-filters.store";
diff --git a/space/hooks/store/use-issue.ts b/space/hooks/store/use-issue.ts
index 8ccd95ac4..641f05acf 100644
--- a/space/hooks/store/use-issue.ts
+++ b/space/hooks/store/use-issue.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
// lib
-import { StoreContext } from "@/lib/app-providers";
+import { StoreContext } from "@/lib/store-provider";
// store
import { IIssueStore } from "@/store/issue.store";
diff --git a/space/hooks/store/use-project.ts b/space/hooks/store/use-project.ts
index 0bc7d8f8a..cd3e28958 100644
--- a/space/hooks/store/use-project.ts
+++ b/space/hooks/store/use-project.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
// lib
-import { StoreContext } from "@/lib/app-providers";
+import { StoreContext } from "@/lib/store-provider";
// store
import { IProjectStore } from "@/store/project.store";
diff --git a/space/hooks/store/use-user-profile.ts b/space/hooks/store/use-user-profile.ts
index 042f16c0d..253fec5d6 100644
--- a/space/hooks/store/use-user-profile.ts
+++ b/space/hooks/store/use-user-profile.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
// lib
-import { StoreContext } from "@/lib/app-providers";
+import { StoreContext } from "@/lib/store-provider";
// store
import { IProfileStore } from "@/store/profile.store";
diff --git a/space/hooks/store/use-user.ts b/space/hooks/store/use-user.ts
index c935946f8..7d48e5c7f 100644
--- a/space/hooks/store/use-user.ts
+++ b/space/hooks/store/use-user.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
// lib
-import { StoreContext } from "@/lib/app-providers";
+import { StoreContext } from "@/lib/store-provider";
// store
import { IUserStore } from "@/store/user.store";
diff --git a/space/lib/instance-provider.tsx b/space/lib/instance-provider.tsx
new file mode 100644
index 000000000..032bc5ae9
--- /dev/null
+++ b/space/lib/instance-provider.tsx
@@ -0,0 +1,63 @@
+"use client";
+
+import { ReactNode } from "react";
+import { observer } from "mobx-react-lite";
+import Image from "next/image";
+import { useTheme } from "next-themes";
+import useSWR from "swr";
+// components
+import { LogoSpinner } from "@/components/common";
+import { InstanceFailureView } from "@/components/instance";
+// hooks
+import { useInstance, useUser } from "@/hooks/store";
+// assets
+import PlaneBackgroundPatternDark from "public/auth/background-pattern-dark.svg";
+import PlaneBackgroundPattern from "public/auth/background-pattern.svg";
+import BluePlaneLogoWithoutText from "public/plane-logos/blue-without-text.png";
+
+export const InstanceProvider = observer(({ children }: { children: ReactNode }) => {
+ const { fetchInstanceInfo, instance, error } = useInstance();
+ const { fetchCurrentUser } = useUser();
+ const { resolvedTheme } = useTheme();
+
+ const patternBackground = resolvedTheme === "dark" ? PlaneBackgroundPatternDark : PlaneBackgroundPattern;
+
+ useSWR("INSTANCE_INFO", () => fetchInstanceInfo(), {
+ revalidateOnFocus: false,
+ revalidateIfStale: false,
+ errorRetryCount: 0,
+ });
+ useSWR("CURRENT_USER", () => fetchCurrentUser());
+
+ if (!instance && !error)
+ return (
+
+
+
+ );
+
+ if (error) {
+ return (
+
+ );
+ }
+
+ return <>{children}>;
+});
diff --git a/space/lib/app-providers.tsx b/space/lib/store-provider.tsx
similarity index 84%
rename from space/lib/app-providers.tsx
rename to space/lib/store-provider.tsx
index 389d68ab2..b77a981f8 100644
--- a/space/lib/app-providers.tsx
+++ b/space/lib/store-provider.tsx
@@ -23,12 +23,13 @@ function initializeStore(initialData = {}) {
return singletonRootStore;
}
-export type AppProviderProps = {
+export type StoreProviderProps = {
children: ReactNode;
- initialState: any;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ initialState?: any;
};
-export const AppProvider = ({ children, initialState = {} }: AppProviderProps) => {
+export const StoreProvider = ({ children, initialState = {} }: StoreProviderProps) => {
const store = initializeStore(initialState);
return (
diff --git a/space/lib/user-provider.tsx b/space/lib/user-provider.tsx
new file mode 100644
index 000000000..1ac1c786c
--- /dev/null
+++ b/space/lib/user-provider.tsx
@@ -0,0 +1,12 @@
+import { ReactNode } from "react";
+import { observer } from "mobx-react-lite";
+import useSWR from "swr";
+import { useUser } from "@/hooks/store";
+
+export const UserProvider = observer(({ children }: { children: ReactNode }) => {
+ const { fetchCurrentUser } = useUser();
+
+ useSWR("CURRENT_USER", () => fetchCurrentUser());
+
+ return <>{children}>;
+});
diff --git a/space/lib/wrappers/auth-wrapper.tsx b/space/lib/wrappers/auth-wrapper.tsx
deleted file mode 100644
index 840ce4ba2..000000000
--- a/space/lib/wrappers/auth-wrapper.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import { FC, ReactNode } from "react";
-import { observer } from "mobx-react-lite";
-import { useRouter } from "next/navigation";
-import useSWR from "swr";
-import { Spinner } from "@plane/ui";
-// helpers
-import { EPageTypes } from "@/helpers/authentication.helper";
-// hooks
-import { useUser, useUserProfile } from "@/hooks/store";
-
-type TAuthWrapper = {
- children: ReactNode;
- pageType?: EPageTypes;
-};
-
-export const AuthWrapper: FC = observer((props) => {
- const router = useRouter();
- const { children, pageType = EPageTypes.AUTHENTICATED } = props;
- // hooks
- const { isLoading, data: currentUser, fetchCurrentUser } = useUser();
- const { data: currentUserProfile } = useUserProfile();
-
- const { isLoading: isSWRLoading } = useSWR("INSTANCE_INFORMATION", () => fetchCurrentUser(), {
- revalidateOnFocus: false,
- });
-
- if (isSWRLoading || isLoading)
- return (
-
-
-
- );
-
- if (pageType === EPageTypes.PUBLIC) return <>{children}>;
-
- if (pageType === EPageTypes.INIT) {
- if (!currentUser?.id) return <>{children}>;
- else {
- if (
- currentUserProfile &&
- currentUserProfile?.id &&
- Boolean(currentUserProfile?.onboarding_step?.profile_complete)
- )
- return <>{children}>;
- else {
- router.push(`/onboarding`);
- return <>>;
- }
- }
- }
-
- if (pageType === EPageTypes.NON_AUTHENTICATED) {
- if (!currentUser?.id) return <>{children}>;
- else {
- if (currentUserProfile?.id && currentUserProfile?.onboarding_step?.profile_complete) {
- router.push(`/`);
- return <>>;
- } else {
- router.push(`/onboarding`);
- return <>>;
- }
- }
- }
-
- if (pageType === EPageTypes.ONBOARDING) {
- if (!currentUser?.id) {
- router.push(`/`);
- return <>>;
- } else {
- if (currentUserProfile?.id && currentUserProfile?.onboarding_step?.profile_complete) {
- router.push(`/`);
- return <>>;
- } else return <>{children}>;
- }
- }
-
- if (pageType === EPageTypes.AUTHENTICATED) {
- if (!currentUser?.id) return <>{children}>;
- else {
- if (currentUserProfile?.id && currentUserProfile?.onboarding_step?.profile_complete) return <>{children}>;
- else {
- router.push(`/onboarding`);
- return <>>;
- }
- }
- }
-
- return <>{children}>;
-});
diff --git a/space/lib/wrappers/index.ts b/space/lib/wrappers/index.ts
deleted file mode 100644
index d40c4c886..000000000
--- a/space/lib/wrappers/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./auth-wrapper";
diff --git a/space/services/instance.service.ts b/space/services/instance.service.ts
index 7744f1f65..a11599b0c 100644
--- a/space/services/instance.service.ts
+++ b/space/services/instance.service.ts
@@ -1,5 +1,5 @@
// types
-import type { IInstance } from "@plane/types";
+import type { IInstanceInfo } from "@plane/types";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
// services
@@ -10,7 +10,7 @@ export class InstanceService extends APIService {
super(API_BASE_URL);
}
- async getInstanceInfo(): Promise {
+ async getInstanceInfo(): Promise {
return this.get("/api/instances/")
.then((response) => response.data)
.catch((error) => {
diff --git a/space/store/instance.store.ts b/space/store/instance.store.ts
index 98bb4cfe0..d2e6918a3 100644
--- a/space/store/instance.store.ts
+++ b/space/store/instance.store.ts
@@ -1,7 +1,7 @@
import set from "lodash/set";
import { observable, action, makeObservable, runInAction } from "mobx";
// types
-import { IInstance } from "@plane/types";
+import { IInstance, IInstanceConfig } from "@plane/types";
// services
import { InstanceService } from "@/services/instance.service";
// store types
@@ -20,6 +20,7 @@ export interface IInstanceStore {
// observables
isLoading: boolean;
instance: IInstance | undefined;
+ config: IInstanceConfig | undefined;
error: TError | undefined;
// action
fetchInstanceInfo: () => Promise;
@@ -29,6 +30,7 @@ export interface IInstanceStore {
export class InstanceStore implements IInstanceStore {
isLoading: boolean = true;
instance: IInstance | undefined = undefined;
+ config: IInstanceConfig | undefined = undefined;
error: TError | undefined = undefined;
// services
instanceService;
@@ -38,6 +40,7 @@ export class InstanceStore implements IInstanceStore {
// observable
isLoading: observable.ref,
instance: observable,
+ config: observable,
error: observable,
// actions
fetchInstanceInfo: action,
@@ -56,10 +59,11 @@ export class InstanceStore implements IInstanceStore {
try {
this.isLoading = true;
this.error = undefined;
- const instance = await this.instanceService.getInstanceInfo();
+ const instanceInfo = await this.instanceService.getInstanceInfo();
runInAction(() => {
this.isLoading = false;
- this.instance = instance;
+ this.instance = instanceInfo.instance;
+ this.config = instanceInfo.config;
});
} catch (error) {
runInAction(() => {
diff --git a/web/components/account/auth-forms/auth-root.tsx b/web/components/account/auth-forms/auth-root.tsx
index 8b9df7632..4e4d6be24 100644
--- a/web/components/account/auth-forms/auth-root.tsx
+++ b/web/components/account/auth-forms/auth-root.tsx
@@ -44,7 +44,7 @@ export const AuthRoot: FC = observer((props) => {
const [errorInfo, setErrorInfo] = useState(undefined);
const [isPasswordAutoset, setIsPasswordAutoset] = useState(true);
// hooks
- const { instance } = useInstance();
+ const { config } = useInstance();
useEffect(() => {
if (error_code) {
@@ -68,9 +68,9 @@ export const AuthRoot: FC = observer((props) => {
}
}, [error_code, authMode]);
- const isSMTPConfigured = instance?.config?.is_smtp_configured || false;
- const isMagicLoginEnabled = instance?.config?.is_magic_login_enabled || false;
- const isEmailPasswordEnabled = instance?.config?.is_email_password_enabled || false;
+ const isSMTPConfigured = config?.is_smtp_configured || false;
+ const isMagicLoginEnabled = config?.is_magic_login_enabled || false;
+ const isEmailPasswordEnabled = config?.is_email_password_enabled || false;
// submit handler- email verification
const handleEmailVerification = async (data: IEmailCheckData) => {
diff --git a/web/components/account/oauth/oauth-options.tsx b/web/components/account/oauth/oauth-options.tsx
index 960b48adf..8541def90 100644
--- a/web/components/account/oauth/oauth-options.tsx
+++ b/web/components/account/oauth/oauth-options.tsx
@@ -11,10 +11,9 @@ type TOAuthOptionProps = {
export const OAuthOptions: React.FC = observer((props) => {
const { isSignUp = false } = props;
// hooks
- const { instance } = useInstance();
+ const { config } = useInstance();
- const isOAuthEnabled =
- (instance?.config && (instance?.config?.is_google_enabled || instance?.config?.is_github_enabled)) || false;
+ const isOAuthEnabled = (config && (config?.is_google_enabled || config?.is_github_enabled)) || false;
if (!isOAuthEnabled) return null;
@@ -28,12 +27,12 @@ export const OAuthOptions: React.FC = observer((props) => {