import { useRouter, useSearchParams } from "next/navigation"; import { t } from "@lingui/core/macro"; import { env } from "next-runtime-env"; import { useTheme } from "next-themes"; import { useEffect, useRef, useState } from "react"; import { TbLayoutSidebarLeftCollapse, TbLayoutSidebarLeftExpand, TbLayoutSidebarRightCollapse, TbLayoutSidebarRightExpand, } from "react-icons/tb"; import { authClient } from "@kan/auth/client"; import { useClickOutside } from "~/hooks/useClickOutside"; import { useModal } from "~/providers/modal"; import { usePopup } from "~/providers/popup"; import { useWorkspace, WorkspaceProvider } from "~/providers/workspace"; import { api } from "~/utils/api"; import { ChangePasswordFormConfirmation } from "~/views/settings/components/ChangePasswordConfirmation"; import Button from "./Button"; import Modal from "./modal"; import SideNavigation from "./SideNavigation"; interface DashboardProps { children: React.ReactNode; rightPanel?: React.ReactNode; hasRightPanel?: boolean; } export function getDashboardLayout( page: React.ReactElement, rightPanel?: React.ReactNode, hasRightPanel = false, ) { return ( {page} ); } export default function Dashboard({ children, rightPanel, hasRightPanel = false, }: DashboardProps) { const { resolvedTheme } = useTheme(); const { openModal, closeModal, modalContentType } = useModal(); const { availableWorkspaces, hasLoaded } = useWorkspace(); const { showPopup } = usePopup(); const router = useRouter(); const searchParams = useSearchParams(); const { data: session, isPending: sessionLoading } = authClient.useSession(); const { data: user, isLoading: userLoading } = api.user.getUser.useQuery( undefined, { enabled: !!session?.user, }, ); const [isSideNavOpen, setIsSideNavOpen] = useState(false); const [isRightPanelOpen, setIsRightPanelOpen] = useState(false); const sideNavRef = useRef(null); const rightPanelRef = useRef(null); const sideNavButtonRef = useRef(null); const rightPanelButtonRef = useRef(null); const toggleSideNav = () => { setIsSideNavOpen(!isSideNavOpen); if (!isSideNavOpen) { setIsRightPanelOpen(false); } }; const closeSideNav = () => { setIsSideNavOpen(false); }; const toggleRightPanel = () => { setIsRightPanelOpen(!isRightPanelOpen); if (!isRightPanelOpen) { setIsSideNavOpen(false); } }; useClickOutside(sideNavRef, (event) => { if (sideNavButtonRef.current?.contains(event.target as Node)) { return; } if (isSideNavOpen) { setIsSideNavOpen(false); } }); useClickOutside(rightPanelRef, (event) => { if (rightPanelButtonRef.current?.contains(event.target as Node)) { return; } if (isRightPanelOpen) { setIsRightPanelOpen(false); } }); useEffect(() => { const partnerActivated = searchParams.get("partner_activated"); const partnerError = searchParams.get("partner_error"); if (partnerActivated) { showPopup({ header: t`License activated`, message: t`Your license has been activated successfully.`, icon: "success", }); const params = new URLSearchParams(searchParams.toString()); params.delete("partner_activated"); router.replace(`?${params.toString()}`); } else if (partnerError) { const messages: Record = { invalid_license: t`That license key could not be found. Please contact support.`, license_inactive: t`Your license is not active. Please check your account.`, missing_license: t`No license key was provided. Please try activating again.`, }; showPopup({ header: t`License activation failed`, message: messages[partnerError] ?? t`Something went wrong during license activation.`, icon: "error", }); const params = new URLSearchParams(searchParams.toString()); params.delete("partner_error"); router.replace(`?${params.toString()}`); } }, [searchParams, showPopup, router]); useEffect(() => { if (hasLoaded && availableWorkspaces.length === 0) { if (env("NEXT_PUBLIC_KAN_ENV") === "cloud") { router.push( `/onboarding/select-plan?returnUrl=${encodeURIComponent(window.location.pathname)}`, ); } else { openModal("NEW_WORKSPACE", undefined, undefined, false); } } }, [hasLoaded, availableWorkspaces.length, openModal, router]); useEffect(() => { const isCredentialsEnabled = env("NEXT_PUBLIC_ALLOW_CREDENTIALS")?.toLowerCase() === "true"; if ( !userLoading && user && isCredentialsEnabled && user.hasMagicLinkAccount && !user.hasPassword && !sessionStorage.getItem("set_password_prompted") ) { sessionStorage.setItem("set_password_prompted", "1"); openModal("SET_PASSWORD_PROMPT"); } }, [user, userLoading, openModal]); const isDarkMode = resolvedTheme === "dark"; return ( <> {/* Mobile Header */} {isSideNavOpen ? ( ) : ( )} {hasRightPanel && ( {isRightPanelOpen ? ( ) : ( )} )} {children} {/* Mobile Right Panel */} {hasRightPanel && rightPanel && ( {rightPanel} )} {/* Desktop Right Panel */} {hasRightPanel && rightPanel && ( {rightPanel} )} {user?.hasPassword ? ( {t`Password already set`} {t`Your account already has a password. You can change it from your account settings.`} {t`Close`} ) : ( )} > ); }
{t`Your account already has a password. You can change it from your account settings.`}