refactor: use new layout in dashboard

This commit is contained in:
CREDO23 2026-01-08 19:11:07 +02:00
parent 65a10518d5
commit ab052bf1f2

View file

@ -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>
); );
} }