diff --git a/surfsense_web/app/dashboard/page.tsx b/surfsense_web/app/dashboard/page.tsx index e241428d1..d343a28e3 100644 --- a/surfsense_web/app/dashboard/page.tsx +++ b/surfsense_web/app/dashboard/page.tsx @@ -7,7 +7,11 @@ import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; -import { deleteSearchSpaceMutationAtom } from "@/atoms/search-spaces/search-space-mutation.atoms"; +import { useEffect, useRef, useState } from "react"; +import { + createSearchSpaceMutationAtom, + deleteSearchSpaceMutationAtom, +} from "@/atoms/search-spaces/search-space-mutation.atoms"; import { searchSpacesAtom } from "@/atoms/search-spaces/search-space-query.atoms"; import { currentUserAtom } from "@/atoms/user/user-query.atoms"; import { Logo } from "@/components/Logo"; @@ -129,6 +133,11 @@ const ErrorScreen = ({ message }: { message: string }) => { const DashboardPage = () => { const t = useTranslations("dashboard"); const tCommon = useTranslations("common"); + const router = useRouter(); + + // State for auto-creating search space + const [isAutoCreating, setIsAutoCreating] = useState(false); + const hasAttemptedAutoCreate = useRef(false); // Animation variants const containerVariants: Variants = { @@ -161,9 +170,42 @@ const DashboardPage = () => { refetch: refreshSearchSpaces, } = useAtomValue(searchSpacesAtom); const { mutateAsync: deleteSearchSpace } = useAtomValue(deleteSearchSpaceMutationAtom); + const { mutateAsync: createSearchSpace } = useAtomValue(createSearchSpaceMutationAtom); const { data: user, isPending: isLoadingUser, error: userError } = useAtomValue(currentUserAtom); + // Auto-redirect to chat or auto-create search space + useEffect(() => { + const handleAutoRedirect = async () => { + // Don't run if still loading or already attempted + if (loading || hasAttemptedAutoCreate.current) return; + + // If user has search spaces, redirect to the first one's chat + if (searchSpaces.length > 0) { + router.replace(`/dashboard/${searchSpaces[0].id}/new-chat`); + return; + } + + // If no search spaces exist (edge case for users who registered before this feature), + // auto-create one and redirect + hasAttemptedAutoCreate.current = true; + setIsAutoCreating(true); + + try { + const newSearchSpace = await createSearchSpace({ + name: "My Search Space", + description: "Your personal search space", + }); + router.replace(`/dashboard/${newSearchSpace.id}/new-chat`); + } catch (err) { + console.error("Failed to auto-create search space:", err); + setIsAutoCreating(false); + } + }; + + handleAutoRedirect(); + }, [loading, searchSpaces, router, createSearchSpace]); + // Create user object for UserDropdown const customUser = { name: user?.email ? user.email.split("@")[0] : "User", @@ -173,7 +215,8 @@ const DashboardPage = () => { avatar: "/icon-128.png", // Default avatar }; - if (loading) return ; + // Show loading while loading, auto-redirecting, or auto-creating + if (loading || isAutoCreating || (searchSpaces.length > 0 && !error)) return ; if (error) return ; const handleDeleteSearchSpace = async (id: number) => {