diff --git a/surfsense_web/app/(home)/login/GoogleLoginButton.tsx b/surfsense_web/app/(home)/login/GoogleLoginButton.tsx
index 3c8aaeb77..52d79d72b 100644
--- a/surfsense_web/app/(home)/login/GoogleLoginButton.tsx
+++ b/surfsense_web/app/(home)/login/GoogleLoginButton.tsx
@@ -32,10 +32,10 @@ export function GoogleLoginButton() {
-
-
- {t("welcome_back")}
-
+
+ {/*
+ Login
+ */}
{/*
void;
}) {
const t = useTranslations("documents");
+ const router = useRouter();
+ const params = useParams();
+ const searchSpaceId = params.search_space_id;
+
const sorted = React.useMemo(
() => sortDocuments(documents, sortKey, sortDesc),
[documents, sortKey, sortDesc]
@@ -117,10 +122,29 @@ export function DocumentsTableShell({
) : sorted.length === 0 ? (
-
-
-
{t("no_documents")}
-
+
+
+
+
+
+
{t("no_documents")}
+
+ Get started by adding your first data source.
+
+
+ router.push(`/dashboard/${searchSpaceId}/sources/add`)}
+ className="mt-2"
+ >
+
+ Add Sources
+
+
) : (
<>
diff --git a/surfsense_web/app/dashboard/[search_space_id]/layout.tsx b/surfsense_web/app/dashboard/[search_space_id]/layout.tsx
index c014c6f32..ea5dc41e2 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/layout.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/layout.tsx
@@ -28,7 +28,7 @@ export default function DashboardLayout({
const customNavMain = [
{
- title: "Researcher",
+ title: "Chat",
url: `/dashboard/${search_space_id}/researcher`,
icon: "SquareTerminal",
items: [],
diff --git a/surfsense_web/app/dashboard/[search_space_id]/onboard/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/onboard/page.tsx
index bfbae3b99..099909515 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/onboard/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/onboard/page.tsx
@@ -4,17 +4,16 @@ import { ArrowLeft, ArrowRight, Bot, CheckCircle, Sparkles } from "lucide-react"
import { AnimatePresence, motion } from "motion/react";
import { useParams, useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { Logo } from "@/components/Logo";
-import { AddProviderStep } from "@/components/onboard/add-provider-step";
-import { AssignRolesStep } from "@/components/onboard/assign-roles-step";
import { CompletionStep } from "@/components/onboard/completion-step";
+import { SetupLLMStep } from "@/components/onboard/setup-llm-step";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Progress } from "@/components/ui/progress";
import { useGlobalLLMConfigs, useLLMConfigs, useLLMPreferences } from "@/hooks/use-llm-configs";
-const TOTAL_STEPS = 3;
+const TOTAL_STEPS = 2;
const OnboardPage = () => {
const t = useTranslations("onboard");
@@ -33,6 +32,10 @@ const OnboardPage = () => {
const [currentStep, setCurrentStep] = useState(1);
const [hasUserProgressed, setHasUserProgressed] = useState(false);
+ // Track if onboarding was complete on initial mount
+ const wasCompleteOnMount = useRef
(null);
+ const hasCheckedInitialState = useRef(false);
+
// Check if user is authenticated
useEffect(() => {
const token = localStorage.getItem("surfsense_bearer_token");
@@ -42,6 +45,19 @@ const OnboardPage = () => {
}
}, [router]);
+ // Capture onboarding state on first load
+ useEffect(() => {
+ if (
+ !hasCheckedInitialState.current &&
+ !preferencesLoading &&
+ !configsLoading &&
+ !globalConfigsLoading
+ ) {
+ wasCompleteOnMount.current = isOnboardingComplete();
+ hasCheckedInitialState.current = true;
+ }
+ }, [preferencesLoading, configsLoading, globalConfigsLoading, isOnboardingComplete]);
+
// Track if user has progressed beyond step 1
useEffect(() => {
if (currentStep > 1) {
@@ -49,47 +65,42 @@ const OnboardPage = () => {
}
}, [currentStep]);
- // Redirect to dashboard if onboarding is already complete and user hasn't progressed (fresh page load)
- // But only check once to avoid redirect loops
+ // Redirect to dashboard if onboarding was already complete on mount (not during this session)
useEffect(() => {
+ // Only redirect if:
+ // 1. Onboarding was complete when page loaded
+ // 2. User hasn't progressed past step 1
+ // 3. All data is loaded
if (
+ wasCompleteOnMount.current === true &&
+ !hasUserProgressed &&
!preferencesLoading &&
!configsLoading &&
- !globalConfigsLoading &&
- isOnboardingComplete() &&
- !hasUserProgressed
+ !globalConfigsLoading
) {
- // Small delay to ensure the check is stable
+ // Small delay to ensure the check is stable on initial load
const timer = setTimeout(() => {
router.push(`/dashboard/${searchSpaceId}`);
- }, 100);
+ }, 300);
return () => clearTimeout(timer);
}
}, [
+ hasUserProgressed,
preferencesLoading,
configsLoading,
globalConfigsLoading,
- isOnboardingComplete,
- hasUserProgressed,
router,
searchSpaceId,
]);
const progress = (currentStep / TOTAL_STEPS) * 100;
- const stepTitles = [t("add_llm_provider"), t("assign_llm_roles"), t("setup_complete")];
+ const stepTitles = [t("setup_llm_configuration"), t("setup_complete")];
- const stepDescriptions = [
- t("configure_first_provider"),
- t("assign_specific_roles"),
- t("all_set"),
- ];
+ const stepDescriptions = [t("configure_providers_and_assign_roles"), t("all_set")];
- // User can proceed to step 2 if they have either custom configs OR global configs available
+ // User can proceed to step 2 if all roles are assigned
const canProceedToStep2 =
- !configsLoading && !globalConfigsLoading && (llmConfigs.length > 0 || globalConfigs.length > 0);
-
- const canProceedToStep3 =
!preferencesLoading &&
preferences.long_context_llm_id &&
preferences.fast_llm_id &&
@@ -107,10 +118,6 @@ const OnboardPage = () => {
}
};
- const handleComplete = () => {
- router.push(`/dashboard/${searchSpaceId}/documents`);
- };
-
if (configsLoading || preferencesLoading || globalConfigsLoading) {
return (
@@ -192,9 +199,8 @@ const OnboardPage = () => {
- {currentStep === 1 && }
- {currentStep === 2 && }
- {currentStep === 3 && }
+ {currentStep === 1 && }
+ {currentStep === 2 && }
{stepTitles[currentStep - 1]}
@@ -211,19 +217,14 @@ const OnboardPage = () => {
transition={{ duration: 0.3 }}
>
{currentStep === 1 && (
-
- )}
- {currentStep === 2 && (
-
)}
- {currentStep === 3 && }
+ {currentStep === 2 && }
@@ -231,38 +232,24 @@ const OnboardPage = () => {
{/* Navigation */}
-
-
- {t("previous")}
-
-
-
- {currentStep < TOTAL_STEPS && (
+ {currentStep === 1 ? (
+ <>
+
{t("next")}
- )}
-
- {currentStep === TOTAL_STEPS && (
-
- {t("complete_setup")}
-
-
- )}
-
+ >
+ ) : (
+
+
+ {t("previous")}
+
+ )}
diff --git a/surfsense_web/components/chat/ChatPanel/ChatPanelView.tsx b/surfsense_web/components/chat/ChatPanel/ChatPanelView.tsx
index 549f50806..40c2650a5 100644
--- a/surfsense_web/components/chat/ChatPanel/ChatPanelView.tsx
+++ b/surfsense_web/components/chat/ChatPanel/ChatPanelView.tsx
@@ -78,17 +78,11 @@ export function ChatPanelView(props: ChatPanelViewProps) {
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
+ className="relative"
>
- {
- if (e.key === "Enter" || e.key === " ") {
- e.preventDefault();
- handleGeneratePost();
- }
- }}
className={cn(
"relative w-full rounded-2xl p-4 transition-all duration-300 cursor-pointer group overflow-hidden",
"border-2",
@@ -151,9 +145,12 @@ export function ChatPanelView(props: ChatPanelViewProps) {
-