fix: use getLayout to persist layout state across pages
This commit is contained in:
@@ -10,6 +10,7 @@ import { authClient } from "@kan/auth/client";
|
|||||||
|
|
||||||
import { useClickOutside } from "~/hooks/useClickOutside";
|
import { useClickOutside } from "~/hooks/useClickOutside";
|
||||||
import { useTheme } from "~/providers/theme";
|
import { useTheme } from "~/providers/theme";
|
||||||
|
import { WorkspaceProvider } from "~/providers/workspace";
|
||||||
import SideNavigation from "./SideNavigation";
|
import SideNavigation from "./SideNavigation";
|
||||||
|
|
||||||
interface DashboardProps {
|
interface DashboardProps {
|
||||||
@@ -18,6 +19,20 @@ interface DashboardProps {
|
|||||||
hasRightPanel?: boolean;
|
hasRightPanel?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDashboardLayout(
|
||||||
|
page: React.ReactElement,
|
||||||
|
rightPanel?: React.ReactNode,
|
||||||
|
hasRightPanel = false,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<WorkspaceProvider>
|
||||||
|
<Dashboard rightPanel={rightPanel} hasRightPanel={hasRightPanel}>
|
||||||
|
{page}
|
||||||
|
</Dashboard>
|
||||||
|
</WorkspaceProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function Dashboard({
|
export default function Dashboard({
|
||||||
children,
|
children,
|
||||||
rightPanel,
|
rightPanel,
|
||||||
@@ -26,6 +41,7 @@ export default function Dashboard({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const { data: session, isPending: sessionLoading } = authClient.useSession();
|
const { data: session, isPending: sessionLoading } = authClient.useSession();
|
||||||
|
|
||||||
const [isSideNavOpen, setIsSideNavOpen] = useState(false);
|
const [isSideNavOpen, setIsSideNavOpen] = useState(false);
|
||||||
const [isRightPanelOpen, setIsRightPanelOpen] = useState(false);
|
const [isRightPanelOpen, setIsRightPanelOpen] = useState(false);
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export default function SideNavigation({
|
|||||||
<>
|
<>
|
||||||
<nav
|
<nav
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex h-full flex-col justify-between bg-light-100 pr-3 transition-all duration-300 dark:bg-dark-100",
|
"flex h-full flex-col justify-between bg-light-100 pr-3 dark:bg-dark-100",
|
||||||
isCollapsed ? "w-auto" : "w-64",
|
isCollapsed ? "w-auto" : "w-64",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -96,7 +96,7 @@ export default function SideNavigation({
|
|||||||
<div className="flex h-14 items-center justify-between pb-[18px] pt-1.5">
|
<div className="flex h-14 items-center justify-between pb-[18px] pt-1.5">
|
||||||
{!isCollapsed && (
|
{!isCollapsed && (
|
||||||
<Link href="/" className="block">
|
<Link href="/" className="block">
|
||||||
<h1 className="pl-2 text-lg font-bold tracking-tight text-neutral-700 dark:text-dark-950">
|
<h1 className="pl-2 text-lg font-bold tracking-tight text-neutral-700 dark:text-dark-1000">
|
||||||
kan.bn
|
kan.bn
|
||||||
</h1>
|
</h1>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import "~/styles/globals.css";
|
import "~/styles/globals.css";
|
||||||
import "~/utils/i18n";
|
import "~/utils/i18n";
|
||||||
|
|
||||||
import type { Viewport } from "next";
|
import type { NextPage, Viewport } from "next";
|
||||||
import type { AppType } from "next/app";
|
import type { AppProps, AppType } from "next/app";
|
||||||
|
import type { ReactElement, ReactNode } from "react";
|
||||||
import { Plus_Jakarta_Sans } from "next/font/google";
|
import { Plus_Jakarta_Sans } from "next/font/google";
|
||||||
import Script from "next/script";
|
import Script from "next/script";
|
||||||
import { env } from "next-runtime-env";
|
import { env } from "next-runtime-env";
|
||||||
@@ -34,7 +35,15 @@ export const viewport: Viewport = {
|
|||||||
userScalable: false,
|
userScalable: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const MyApp: AppType = ({ Component, pageProps }) => {
|
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
|
||||||
|
getLayout?: (page: ReactElement) => ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
type AppPropsWithLayout = AppProps & {
|
||||||
|
Component: NextPageWithLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MyApp: AppType = ({ Component, pageProps }: AppPropsWithLayout) => {
|
||||||
const posthogKey = env("NEXT_PUBLIC_POSTHOG_KEY");
|
const posthogKey = env("NEXT_PUBLIC_POSTHOG_KEY");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -50,6 +59,8 @@ const MyApp: AppType = ({ Component, pageProps }) => {
|
|||||||
}
|
}
|
||||||
}, [posthogKey]);
|
}, [posthogKey]);
|
||||||
|
|
||||||
|
const getLayout = Component.getLayout ?? ((page) => page);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<style jsx global>{`
|
<style jsx global>{`
|
||||||
@@ -75,10 +86,10 @@ const MyApp: AppType = ({ Component, pageProps }) => {
|
|||||||
<PopupProvider>
|
<PopupProvider>
|
||||||
{posthogKey ? (
|
{posthogKey ? (
|
||||||
<PostHogProvider client={posthog}>
|
<PostHogProvider client={posthog}>
|
||||||
<Component {...pageProps} />
|
{getLayout(<Component {...pageProps} />)}
|
||||||
</PostHogProvider>
|
</PostHogProvider>
|
||||||
) : (
|
) : (
|
||||||
<Component {...pageProps} />
|
getLayout(<Component {...pageProps} />)
|
||||||
)}
|
)}
|
||||||
</PopupProvider>
|
</PopupProvider>
|
||||||
</ModalProvider>
|
</ModalProvider>
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import { WorkspaceProvider } from "~/providers/workspace";
|
import type { NextPageWithLayout } from "~/pages/_app";
|
||||||
import Dashboard from "~/components/Dashboard";
|
import { getDashboardLayout } from "~/components/Dashboard";
|
||||||
import Popup from "~/components/Popup";
|
import Popup from "~/components/Popup";
|
||||||
import BoardView from "~/views/board";
|
import BoardView from "~/views/board";
|
||||||
|
|
||||||
export default function BoardPage() {
|
const BoardPage: NextPageWithLayout = () => {
|
||||||
return (
|
return (
|
||||||
<WorkspaceProvider>
|
<>
|
||||||
<Dashboard>
|
<BoardView />
|
||||||
<BoardView />
|
|
||||||
</Dashboard>
|
|
||||||
<Popup />
|
<Popup />
|
||||||
</WorkspaceProvider>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
BoardPage.getLayout = (page) => getDashboardLayout(page);
|
||||||
|
|
||||||
|
export default BoardPage;
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import { WorkspaceProvider } from "~/providers/workspace";
|
import type { NextPageWithLayout } from "../_app";
|
||||||
import Dashboard from "~/components/Dashboard";
|
import { getDashboardLayout } from "~/components/Dashboard";
|
||||||
import Popup from "~/components/Popup";
|
import Popup from "~/components/Popup";
|
||||||
import BoardsView from "~/views/boards";
|
import BoardsView from "~/views/boards";
|
||||||
|
|
||||||
export default function BoardsPage() {
|
const BoardsPage: NextPageWithLayout = () => {
|
||||||
return (
|
return (
|
||||||
<WorkspaceProvider>
|
<>
|
||||||
<Dashboard>
|
<BoardsView />
|
||||||
<BoardsView />
|
|
||||||
</Dashboard>
|
|
||||||
<Popup />
|
<Popup />
|
||||||
</WorkspaceProvider>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
BoardsPage.getLayout = (page) => getDashboardLayout(page);
|
||||||
|
|
||||||
|
export default BoardsPage;
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
import Dashboard from "~/components/Dashboard";
|
import type { NextPageWithLayout } from "~/pages/_app";
|
||||||
|
import { getDashboardLayout } from "~/components/Dashboard";
|
||||||
import Popup from "~/components/Popup";
|
import Popup from "~/components/Popup";
|
||||||
import { WorkspaceProvider } from "~/providers/workspace";
|
|
||||||
import CardView, { CardRightPanel } from "~/views/card";
|
import CardView, { CardRightPanel } from "~/views/card";
|
||||||
|
|
||||||
export default function CardPage() {
|
const CardPage: NextPageWithLayout = () => {
|
||||||
return (
|
return (
|
||||||
<WorkspaceProvider>
|
<>
|
||||||
<Dashboard hasRightPanel rightPanel={<CardRightPanel />}>
|
<CardView />
|
||||||
<CardView />
|
|
||||||
</Dashboard>
|
|
||||||
<Popup />
|
<Popup />
|
||||||
</WorkspaceProvider>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
CardPage.getLayout = (page) =>
|
||||||
|
getDashboardLayout(page, <CardRightPanel />, true);
|
||||||
|
|
||||||
|
export default CardPage;
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import { WorkspaceProvider } from "~/providers/workspace";
|
import type { NextPageWithLayout } from "~/pages/_app";
|
||||||
import Dashboard from "~/components/Dashboard";
|
import { getDashboardLayout } from "~/components/Dashboard";
|
||||||
import Popup from "~/components/Popup";
|
import Popup from "~/components/Popup";
|
||||||
import MembersView from "~/views/members";
|
import MembersView from "~/views/members";
|
||||||
|
|
||||||
export default function MembersPage() {
|
const MembersPage: NextPageWithLayout = () => {
|
||||||
return (
|
return (
|
||||||
<WorkspaceProvider>
|
<>
|
||||||
<Dashboard>
|
<MembersView />
|
||||||
<MembersView />
|
|
||||||
</Dashboard>
|
|
||||||
<Popup />
|
<Popup />
|
||||||
</WorkspaceProvider>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
MembersPage.getLayout = (page) => getDashboardLayout(page);
|
||||||
|
|
||||||
|
export default MembersPage;
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import { WorkspaceProvider } from "~/providers/workspace";
|
import type { NextPageWithLayout } from "~/pages/_app";
|
||||||
import Dashboard from "~/components/Dashboard";
|
import { getDashboardLayout } from "~/components/Dashboard";
|
||||||
import SettingsView from "~/views/settings";
|
|
||||||
import Popup from "~/components/Popup";
|
import Popup from "~/components/Popup";
|
||||||
|
import SettingsView from "~/views/settings";
|
||||||
|
|
||||||
export default function SettingsPage() {
|
const SettingsPage: NextPageWithLayout = () => {
|
||||||
return (
|
return (
|
||||||
<WorkspaceProvider>
|
<>
|
||||||
<Dashboard>
|
<SettingsView />
|
||||||
<SettingsView />
|
|
||||||
</Dashboard>
|
|
||||||
<Popup />
|
<Popup />
|
||||||
</WorkspaceProvider>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
SettingsPage.getLayout = (page) => getDashboardLayout(page);
|
||||||
|
|
||||||
|
export default SettingsPage;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export function BoardsList() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid h-fit w-full grid-cols-1 gap-4 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-7">
|
<div className="grid h-fit w-full grid-cols-1 gap-4 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 2xl:grid-cols-7">
|
||||||
{data?.map((board) => (
|
{data?.map((board) => (
|
||||||
<Link key={board.publicId} href={`boards/${board.publicId}`}>
|
<Link key={board.publicId} href={`boards/${board.publicId}`}>
|
||||||
<div className="align-center relative mr-5 flex h-[150px] w-full items-center justify-center rounded-md border border-dashed border-light-400 bg-light-50 shadow-sm hover:bg-light-200 dark:border-dark-600 dark:bg-dark-50 dark:hover:bg-dark-100">
|
<div className="align-center relative mr-5 flex h-[150px] w-full items-center justify-center rounded-md border border-dashed border-light-400 bg-light-50 shadow-sm hover:bg-light-200 dark:border-dark-600 dark:bg-dark-50 dark:hover:bg-dark-100">
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ export default function BoardsPage() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageHead title={t`Boards | ${workspace.name ?? "Workspace"}`} />
|
<PageHead title={t`Boards | ${workspace.name ?? "Workspace"}`} />
|
||||||
<div className="relative m-auto h-full max-w-[1600px] px-5 py-6 md:px-8 md:py-8">
|
<PatternedBackground />
|
||||||
<PatternedBackground />
|
<div className="m-auto h-full max-w-[1200px] p-6 px-5 md:px-28 md:py-12">
|
||||||
<div className="relative z-10 mb-8 flex w-full items-center justify-between">
|
<div className="relative z-10 mb-8 flex w-full items-center justify-between">
|
||||||
<h1 className="font-bold tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
|
<h1 className="font-bold tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
|
||||||
{t`Boards`}
|
{t`Boards`}
|
||||||
|
|||||||
Reference in New Issue
Block a user