chore: user auth wrapper.

This commit is contained in:
Prateek Shourya 2024-02-15 18:24:01 +05:30
parent 5a6a754a70
commit 5ebd64d729
11 changed files with 188 additions and 106 deletions

View File

@ -1,6 +1,6 @@
// lib // lib
import { ThemeProvider } from "lib/theme-provider"; import AppWrapper from "lib/wrappers/app-wrapper";
import { ToastContextProvider } from "lib/toast-provider"; import { UserAuthWrapper } from "lib/wrappers/user-auth-wrapper";
// components // components
import { InstanceSidebar } from "./sidebar"; import { InstanceSidebar } from "./sidebar";
import { InstanceHeader } from "./header"; import { InstanceHeader } from "./header";
@ -16,19 +16,11 @@ interface RootLayoutProps {
children: React.ReactNode; children: React.ReactNode;
} }
export const RootLayout = async ({ children }: RootLayoutProps) => { export const RootLayout = async ({ children }: RootLayoutProps) => (
const isUserInstanceAdmin = true;
return (
<html lang="en"> <html lang="en">
<body className={`antialiased`}> <body className={`antialiased`}>
{/* <AuthWrapper> */} <AppWrapper>
{/* {isUserInstanceAdmin || true ? ( */} <UserAuthWrapper>
<ThemeProvider
themes={["light", "dark"]}
defaultTheme="system"
enableSystem
>
<ToastContextProvider>
<div className="relative flex h-screen w-full overflow-hidden"> <div className="relative flex h-screen w-full overflow-hidden">
<InstanceSidebar /> <InstanceSidebar />
<main className="relative flex h-full w-full flex-col overflow-hidden bg-custom-background-100"> <main className="relative flex h-full w-full flex-col overflow-hidden bg-custom-background-100">
@ -40,14 +32,10 @@ export const RootLayout = async ({ children }: RootLayoutProps) => {
</div> </div>
</main> </main>
</div> </div>
</ToastContextProvider> </UserAuthWrapper>
</ThemeProvider> </AppWrapper>
{/* ) : (
<div>Login</div>
)} */}
</body> </body>
</html> </html>
); );
};
export default RootLayout; export default RootLayout;

View File

@ -1,41 +1,51 @@
"use client"; "use client";
import useSWR from "swr"; import useSWR from "swr";
import useSWRImmutable from "swr/immutable"; import { observer } from "mobx-react-lite";
// hooks // hooks
import useUser from "hooks/use-user";
import useInstance from "hooks/use-instance"; import useInstance from "hooks/use-instance";
// ui
import { Loader } from "@plane/ui";
// components // components
import { GeneralView } from "components/views"; import { InstanceGeneralForm } from "components/forms";
export default function Home() { const GeneralSettingsPage = observer(() => {
const { // store
// isUserInstanceAdmin, const { instance, instanceAdmins, fetchInstanceInfo, fetchInstanceAdmins } =
fetchCurrentUser, useInstance();
fetchCurrentUserInstanceAdminStatus,
} = useUser();
const { fetchInstanceInfo, fetchInstanceAdmins } = useInstance();
// fetching user information
useSWR("CURRENT_USER_DETAILS", () => fetchCurrentUser(), {
shouldRetryOnError: false,
});
// fetching current user instance admin status
useSWRImmutable(
"CURRENT_USER_INSTANCE_ADMIN_STATUS",
() => fetchCurrentUserInstanceAdminStatus(),
{
shouldRetryOnError: false,
}
);
// fetching instance information // fetching instance information
useSWR("INSTANCE_INFO", () => fetchInstanceInfo()); useSWR("INSTANCE_INFO", () => fetchInstanceInfo());
// fetching instance admins // fetching instance admins
useSWR("INSTANCE_ADMINS", () => fetchInstanceAdmins()); useSWR("INSTANCE_ADMINS", () => fetchInstanceAdmins());
return ( return (
<div className="flex"> <div className="flex h-full w-full flex-col gap-8">
<GeneralView /> <div className="mb-2 border-b border-custom-border-100 pb-3">
<div className="pb-1 text-xl font-medium text-custom-text-100">
ID your instance easily
</div>
<div className="text-sm font-normal text-custom-text-300">
Change the name of your instance and instance admin e-mail addresses.
If you have a paid subscription, you will find your license key here.
</div>
</div>
{instance && instanceAdmins ? (
<InstanceGeneralForm
instance={instance}
instanceAdmins={instanceAdmins}
/>
) : (
<Loader className="space-y-4">
<div className="grid grid-cols-2 gap-x-8 gap-y-4">
<Loader.Item height="50px" />
<Loader.Item height="50px" />
</div>
<Loader.Item height="50px" />
</Loader>
)}
</div> </div>
); );
} });
export default GeneralSettingsPage;

View File

@ -1,38 +0,0 @@
import { observer } from "mobx-react-lite";
// hooks
import useInstance from "hooks/use-instance";
// ui
import { Loader } from "@plane/ui";
// components
import { InstanceGeneralForm } from "components/forms";
export const GeneralView = observer(() => {
const { instance, instanceAdmins } = useInstance();
return (
<div className="flex h-full w-full flex-col gap-8">
<div className="mb-2 border-b border-custom-border-100 pb-3">
<div className="pb-1 text-xl font-medium text-custom-text-100">
ID your instance easily
</div>
<div className="text-sm font-normal text-custom-text-300">
Change the name of your instance and instance admin e-mail addresses.
If you have a paid subscription, you will find your license key here.
</div>
</div>
{instance && instanceAdmins ? (
<InstanceGeneralForm
instance={instance}
instanceAdmins={instanceAdmins}
/>
) : (
<Loader className="space-y-4">
<div className="grid grid-cols-2 gap-x-8 gap-y-4">
<Loader.Item height="50px" />
<Loader.Item height="50px" />
</div>
<Loader.Item height="50px" />
</Loader>
)}
</div>
);
});

View File

@ -1 +0,0 @@
export * from "./general-view";

View File

@ -0,0 +1,8 @@
export const SWR_CONFIG = {
refreshWhenHidden: false,
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnMount: true,
refreshInterval: 600000,
errorRetryCount: 3,
};

View File

@ -0,0 +1,3 @@
export const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL
? process.env.NEXT_PUBLIC_API_BASE_URL
: "";

View File

@ -0,0 +1,53 @@
"use client";
import { FC, ReactNode, useEffect } from "react";
import { observer } from "mobx-react-lite";
import { SWRConfig } from "swr";
// lib
import { ThemeProvider } from "lib/theme-provider";
import { ToastContextProvider } from "lib/toast-provider";
// hooks
import useAppTheme from "hooks/use-theme";
import useUser from "hooks/use-user";
// constants
import { SWR_CONFIG } from "constants/swr-config";
interface IAppWrapper {
children: ReactNode;
}
const AppWrapper: FC<IAppWrapper> = observer(({ children }) => {
// store hooks
const { sidebarCollapsed, toggleSidebar } = useAppTheme();
const { currentUser } = useUser();
/**
* Sidebar collapsed fetching from local storage
*/
useEffect(() => {
const localValue =
localStorage && localStorage.getItem("god_mode_sidebar_collapsed");
const localBoolValue = localValue
? localValue === "true"
? true
: false
: false;
if (localValue && sidebarCollapsed === undefined)
toggleSidebar(localBoolValue);
}, [sidebarCollapsed, currentUser, toggleSidebar]);
return (
<ThemeProvider
themes={["light", "dark"]}
defaultTheme="system"
enableSystem
>
<ToastContextProvider>
<SWRConfig value={SWR_CONFIG}>{children}</SWRConfig>
</ToastContextProvider>
</ThemeProvider>
);
});
export default AppWrapper;

View File

@ -0,0 +1,61 @@
"use client";
import { FC, ReactNode } from "react";
// import { useRouter, usePathname } from "next/navigation";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
import useSWRImmutable from "swr/immutable";
// hooks
import useUser from "hooks/use-user";
// ui
import { Spinner } from "@plane/ui";
export interface IUserAuthWrapper {
children: ReactNode;
}
export const UserAuthWrapper: FC<IUserAuthWrapper> = observer((props) => {
const { children } = props;
// store hooks
const {
currentUser,
currentUserLoader,
currentUserError,
fetchCurrentUser,
fetchCurrentUserInstanceAdminStatus,
} = useUser();
// router
// const router = useRouter();
// const pathname = usePathname();
// fetching user information
useSWR("CURRENT_USER_DETAILS", () => fetchCurrentUser(), {
shouldRetryOnError: false,
});
// fetching current user instance admin status
useSWRImmutable(
"CURRENT_USER_INSTANCE_ADMIN_STATUS",
() => fetchCurrentUserInstanceAdminStatus(),
{
shouldRetryOnError: false,
}
);
if (currentUserLoader && !currentUser && !currentUserError) {
return (
<div className="grid h-screen place-items-center bg-custom-background-100 p-4">
<div className="flex flex-col items-center gap-3 text-center">
<Spinner />
</div>
</div>
);
}
// TODO: Login page
if (currentUserError) {
// router.push(`/?next_path=${pathname}`);
// return null;
return <div>Login Page</div>;
}
return <>{children}</>;
});

View File

@ -8,8 +8,8 @@ import {
IMagicSignInData, IMagicSignInData,
IPasswordSignInData, IPasswordSignInData,
} from "@plane/types"; } from "@plane/types";
// helpers
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ? process.env.NEXT_PUBLIC_API_BASE_URL : ""; import { API_BASE_URL } from "helpers/common.helper";
export class AuthService extends APIService { export class AuthService extends APIService {
constructor() { constructor() {

View File

@ -1,8 +1,8 @@
import { APIService } from "services/api.service"; import { APIService } from "services/api.service";
// types // types
import type { IFormattedInstanceConfiguration, IInstance, IInstanceAdmin, IInstanceConfiguration } from "@plane/types"; import type { IFormattedInstanceConfiguration, IInstance, IInstanceAdmin, IInstanceConfiguration } from "@plane/types";
// helpers
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ? process.env.NEXT_PUBLIC_API_BASE_URL : ""; import { API_BASE_URL } from "helpers/common.helper";
export class InstanceService extends APIService { export class InstanceService extends APIService {
constructor() { constructor() {

View File

@ -2,10 +2,8 @@
import { APIService } from "services/api.service"; import { APIService } from "services/api.service";
// types // types
import type { IUser, IInstanceAdminStatus } from "@plane/types"; import type { IUser, IInstanceAdminStatus } from "@plane/types";
// helpers
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL import { API_BASE_URL } from "helpers/common.helper";
? process.env.NEXT_PUBLIC_API_BASE_URL
: "";
export class UserService extends APIService { export class UserService extends APIService {
constructor() { constructor() {