mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-12 22:42:13 +02:00
refactor: use new layout in dashboard
This commit is contained in:
parent
65a10518d5
commit
ab052bf1f2
1 changed files with 11 additions and 78 deletions
|
|
@ -5,7 +5,7 @@ import { Loader2 } from "lucide-react";
|
||||||
import { useParams, usePathname, useRouter } from "next/navigation";
|
import { useParams, usePathname, useRouter } from "next/navigation";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { myAccessAtom } from "@/atoms/members/members-query.atoms";
|
import { myAccessAtom } from "@/atoms/members/members-query.atoms";
|
||||||
import { updateLLMPreferencesMutationAtom } from "@/atoms/new-llm-config/new-llm-config-mutation.atoms";
|
import { updateLLMPreferencesMutationAtom } from "@/atoms/new-llm-config/new-llm-config-mutation.atoms";
|
||||||
|
|
@ -17,22 +17,18 @@ import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-quer
|
||||||
import { DocumentUploadDialogProvider } from "@/components/assistant-ui/document-upload-popup";
|
import { DocumentUploadDialogProvider } from "@/components/assistant-ui/document-upload-popup";
|
||||||
import { DashboardBreadcrumb } from "@/components/dashboard-breadcrumb";
|
import { DashboardBreadcrumb } from "@/components/dashboard-breadcrumb";
|
||||||
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
|
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
|
||||||
|
import { LayoutDataProvider } from "@/components/layout";
|
||||||
import { OnboardingTour } from "@/components/onboarding-tour";
|
import { OnboardingTour } from "@/components/onboarding-tour";
|
||||||
import { AppSidebarProvider } from "@/components/sidebar/AppSidebarProvider";
|
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Separator } from "@/components/ui/separator";
|
|
||||||
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
|
|
||||||
|
|
||||||
export function DashboardClientLayout({
|
export function DashboardClientLayout({
|
||||||
children,
|
children,
|
||||||
searchSpaceId,
|
searchSpaceId,
|
||||||
navSecondary,
|
|
||||||
navMain,
|
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
searchSpaceId: string;
|
searchSpaceId: string;
|
||||||
navSecondary: any[];
|
navSecondary?: any[];
|
||||||
navMain: any[];
|
navMain?: any[];
|
||||||
}) {
|
}) {
|
||||||
const t = useTranslations("dashboard");
|
const t = useTranslations("dashboard");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
@ -59,50 +55,15 @@ export function DashboardClientLayout({
|
||||||
const [isAutoConfiguring, setIsAutoConfiguring] = useState(false);
|
const [isAutoConfiguring, setIsAutoConfiguring] = useState(false);
|
||||||
const hasAttemptedAutoConfig = useRef(false);
|
const hasAttemptedAutoConfig = useRef(false);
|
||||||
|
|
||||||
// Skip onboarding check if we're already on the onboarding page
|
|
||||||
const isOnboardingPage = pathname?.includes("/onboard");
|
const isOnboardingPage = pathname?.includes("/onboard");
|
||||||
|
|
||||||
// Only owners should see onboarding - invited members use existing config
|
|
||||||
const isOwner = access?.is_owner ?? false;
|
const isOwner = access?.is_owner ?? false;
|
||||||
|
|
||||||
// Translate navigation items
|
|
||||||
const tNavMenu = useTranslations("nav_menu");
|
|
||||||
const translatedNavMain = useMemo(() => {
|
|
||||||
return navMain.map((item) => ({
|
|
||||||
...item,
|
|
||||||
title: tNavMenu(item.title.toLowerCase().replace(/ /g, "_")),
|
|
||||||
items: item.items?.map((subItem: any) => ({
|
|
||||||
...subItem,
|
|
||||||
title: tNavMenu(subItem.title.toLowerCase().replace(/ /g, "_")),
|
|
||||||
})),
|
|
||||||
}));
|
|
||||||
}, [navMain, tNavMenu]);
|
|
||||||
|
|
||||||
const translatedNavSecondary = useMemo(() => {
|
|
||||||
return navSecondary.map((item) => ({
|
|
||||||
...item,
|
|
||||||
title: item.title === "All Search Spaces" ? tNavMenu("all_search_spaces") : item.title,
|
|
||||||
}));
|
|
||||||
}, [navSecondary, tNavMenu]);
|
|
||||||
|
|
||||||
const [open, setOpen] = useState<boolean>(() => {
|
|
||||||
try {
|
|
||||||
const match = document.cookie.match(/(?:^|; )sidebar_state=([^;]+)/);
|
|
||||||
if (match) return match[1] === "true";
|
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Skip check if already on onboarding page
|
|
||||||
if (isOnboardingPage) {
|
if (isOnboardingPage) {
|
||||||
setHasCheckedOnboarding(true);
|
setHasCheckedOnboarding(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for all data to load
|
|
||||||
if (
|
if (
|
||||||
!loading &&
|
!loading &&
|
||||||
!accessLoading &&
|
!accessLoading &&
|
||||||
|
|
@ -112,19 +73,16 @@ export function DashboardClientLayout({
|
||||||
) {
|
) {
|
||||||
const onboardingComplete = isOnboardingComplete();
|
const onboardingComplete = isOnboardingComplete();
|
||||||
|
|
||||||
// If onboarding is complete, nothing to do
|
|
||||||
if (onboardingComplete) {
|
if (onboardingComplete) {
|
||||||
setHasCheckedOnboarding(true);
|
setHasCheckedOnboarding(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only handle onboarding for owners
|
|
||||||
if (!isOwner) {
|
if (!isOwner) {
|
||||||
setHasCheckedOnboarding(true);
|
setHasCheckedOnboarding(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If global configs available, auto-configure without going to onboard page
|
|
||||||
if (globalConfigs.length > 0 && !hasAttemptedAutoConfig.current) {
|
if (globalConfigs.length > 0 && !hasAttemptedAutoConfig.current) {
|
||||||
hasAttemptedAutoConfig.current = true;
|
hasAttemptedAutoConfig.current = true;
|
||||||
setIsAutoConfiguring(true);
|
setIsAutoConfiguring(true);
|
||||||
|
|
@ -149,7 +107,6 @@ export function DashboardClientLayout({
|
||||||
setHasCheckedOnboarding(true);
|
setHasCheckedOnboarding(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Auto-configuration failed:", error);
|
console.error("Auto-configuration failed:", error);
|
||||||
// Fall back to onboard page
|
|
||||||
router.push(`/dashboard/${searchSpaceId}/onboard`);
|
router.push(`/dashboard/${searchSpaceId}/onboard`);
|
||||||
} finally {
|
} finally {
|
||||||
setIsAutoConfiguring(false);
|
setIsAutoConfiguring(false);
|
||||||
|
|
@ -160,7 +117,6 @@ export function DashboardClientLayout({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No global configs - redirect to onboard page
|
|
||||||
router.push(`/dashboard/${searchSpaceId}/onboard`);
|
router.push(`/dashboard/${searchSpaceId}/onboard`);
|
||||||
setHasCheckedOnboarding(true);
|
setHasCheckedOnboarding(true);
|
||||||
}
|
}
|
||||||
|
|
@ -180,7 +136,6 @@ export function DashboardClientLayout({
|
||||||
refetchPreferences,
|
refetchPreferences,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Synchronize active search space and chat IDs with URL
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const activeSeacrhSpaceId =
|
const activeSeacrhSpaceId =
|
||||||
typeof search_space_id === "string"
|
typeof search_space_id === "string"
|
||||||
|
|
@ -192,7 +147,6 @@ export function DashboardClientLayout({
|
||||||
setActiveSearchSpaceIdState(activeSeacrhSpaceId);
|
setActiveSearchSpaceIdState(activeSeacrhSpaceId);
|
||||||
}, [search_space_id, setActiveSearchSpaceIdState]);
|
}, [search_space_id, setActiveSearchSpaceIdState]);
|
||||||
|
|
||||||
// Show loading screen while checking onboarding status or auto-configuring
|
|
||||||
if (
|
if (
|
||||||
(!hasCheckedOnboarding &&
|
(!hasCheckedOnboarding &&
|
||||||
(loading || accessLoading || globalConfigsLoading) &&
|
(loading || accessLoading || globalConfigsLoading) &&
|
||||||
|
|
@ -220,7 +174,6 @@ export function DashboardClientLayout({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show error screen if there's an error loading preferences (but not on onboarding page)
|
|
||||||
if (error && !hasCheckedOnboarding && !isOnboardingPage) {
|
if (error && !hasCheckedOnboarding && !isOnboardingPage) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center min-h-screen space-y-4">
|
<div className="flex flex-col items-center justify-center min-h-screen space-y-4">
|
||||||
|
|
@ -244,33 +197,13 @@ export function DashboardClientLayout({
|
||||||
return (
|
return (
|
||||||
<DocumentUploadDialogProvider>
|
<DocumentUploadDialogProvider>
|
||||||
<OnboardingTour />
|
<OnboardingTour />
|
||||||
<SidebarProvider className="h-full overflow-hidden" open={open} onOpenChange={setOpen}>
|
<LayoutDataProvider
|
||||||
{/* Use AppSidebarProvider which fetches user, search space, and recent chats */}
|
searchSpaceId={searchSpaceId}
|
||||||
<AppSidebarProvider
|
breadcrumb={<DashboardBreadcrumb />}
|
||||||
searchSpaceId={searchSpaceId}
|
languageSwitcher={<LanguageSwitcher />}
|
||||||
navSecondary={translatedNavSecondary}
|
>
|
||||||
navMain={translatedNavMain}
|
{children}
|
||||||
/>
|
</LayoutDataProvider>
|
||||||
<SidebarInset className="h-full ">
|
|
||||||
<main className="flex flex-col h-full">
|
|
||||||
<header className="sticky top-0 flex h-16 shrink-0 items-center gap-2 bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/60 border-b">
|
|
||||||
<div className="flex items-center justify-between w-full gap-2 px-4">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<SidebarTrigger className="-ml-1" />
|
|
||||||
<div className="hidden md:flex items-center gap-2">
|
|
||||||
<Separator orientation="vertical" className="h-6" />
|
|
||||||
<DashboardBreadcrumb />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<LanguageSwitcher />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div className="flex-1 overflow-hidden">{children}</div>
|
|
||||||
</main>
|
|
||||||
</SidebarInset>
|
|
||||||
</SidebarProvider>
|
|
||||||
</DocumentUploadDialogProvider>
|
</DocumentUploadDialogProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue