From c4c68d76be1f43de21370faf098c511b858432c8 Mon Sep 17 00:00:00 2001 From: Arjun <6592213+arkml@users.noreply.github.com> Date: Thu, 5 Feb 2026 23:03:47 +0530 Subject: [PATCH] refactor onboarding: remove welcome screen, streamline model setup, tighten spacing Co-Authored-By: Claude Opus 4.5 --- apps/x/apps/renderer/public/logo-only.png | Bin 0 -> 22928 bytes .../src/components/onboarding-modal.tsx | 211 +++++++----------- 2 files changed, 79 insertions(+), 132 deletions(-) create mode 100644 apps/x/apps/renderer/public/logo-only.png diff --git a/apps/x/apps/renderer/public/logo-only.png b/apps/x/apps/renderer/public/logo-only.png new file mode 100644 index 0000000000000000000000000000000000000000..e2fd6386b98cb11d2ba86fa6114c7e0f09bb65fb GIT binary patch literal 22928 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 literal 0 HcmV?d00001 diff --git a/apps/x/apps/renderer/src/components/onboarding-modal.tsx b/apps/x/apps/renderer/src/components/onboarding-modal.tsx index 2aac98d7..ad0a7da5 100644 --- a/apps/x/apps/renderer/src/components/onboarding-modal.tsx +++ b/apps/x/apps/renderer/src/components/onboarding-modal.tsx @@ -2,7 +2,7 @@ import * as React from "react" import { useState, useEffect, useCallback } from "react" -import { Loader2, Mic, Mail, CheckCircle2, Sailboat, MessageSquare } from "lucide-react" +import { Loader2, Mic, Mail, CheckCircle2, MessageSquare } from "lucide-react" import { Dialog, @@ -38,7 +38,7 @@ interface OnboardingModalProps { onComplete: () => void } -type Step = 0 | 1 | 2 | 3 +type Step = 0 | 1 | 2 type LlmProviderFlavor = "openai" | "anthropic" | "google" | "openrouter" | "aigateway" | "ollama" | "openai-compatible" @@ -68,8 +68,6 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { const [testState, setTestState] = useState<{ status: "idle" | "testing" | "success" | "error"; error?: string }>({ status: "idle", }) - const [savingLlmConfig, setSavingLlmConfig] = useState(false) - // OAuth provider states const [providers, setProviders] = useState([]) const [providersLoading, setProvidersLoading] = useState(true) @@ -268,7 +266,7 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { }, [startSlackConnect]) const handleNext = () => { - if (currentStep < 3) { + if (currentStep < 2) { setCurrentStep((prev) => (prev + 1) as Step) } } @@ -277,24 +275,27 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { onComplete() } - const handleTestConnection = useCallback(async () => { + const handleTestAndSaveLlmConfig = useCallback(async () => { if (!canTest) return setTestState({ status: "testing" }) try { const apiKey = activeConfig.apiKey.trim() || undefined const baseURL = activeConfig.baseURL.trim() || undefined const model = activeConfig.model.trim() - const result = await window.ipc.invoke("models:test", { + const providerConfig = { provider: { flavor: llmProvider, apiKey, baseURL, }, model, - }) + } + const result = await window.ipc.invoke("models:test", providerConfig) if (result.success) { setTestState({ status: "success" }) - toast.success("Connection successful") + // Save and continue + await window.ipc.invoke("models:saveConfig", providerConfig) + handleNext() } else { setTestState({ status: "error", error: result.error }) toast.error(result.error || "Connection test failed") @@ -304,31 +305,7 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { setTestState({ status: "error", error: "Connection test failed" }) toast.error("Connection test failed") } - }, [activeConfig.apiKey, activeConfig.baseURL, activeConfig.model, canTest, llmProvider]) - - const handleSaveLlmConfig = useCallback(async () => { - if (testState.status !== "success") return - setSavingLlmConfig(true) - try { - const apiKey = activeConfig.apiKey.trim() || undefined - const baseURL = activeConfig.baseURL.trim() || undefined - const model = activeConfig.model.trim() - await window.ipc.invoke("models:saveConfig", { - provider: { - flavor: llmProvider, - apiKey, - baseURL, - }, - model, - }) - setSavingLlmConfig(false) - handleNext() - } catch (error) { - console.error("Failed to save LLM config:", error) - toast.error("Failed to save LLM settings") - setSavingLlmConfig(false) - } - }, [activeConfig.apiKey, activeConfig.baseURL, activeConfig.model, handleNext, llmProvider, testState.status]) + }, [activeConfig.apiKey, activeConfig.baseURL, activeConfig.model, canTest, llmProvider, handleNext]) // Check connection status for all providers const refreshAllStatuses = useCallback(async () => { @@ -468,7 +445,7 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { // Step indicator component const StepIndicator = () => (
- {[0, 1, 2, 3].map((step) => ( + {[0, 1, 2].map((step) => (
) - // Step 0: Welcome - const WelcomeStep = () => ( -
-
- -
- - Your AI coworker, with memory - - Rowboat connects to your email, calendar, and meetings to help you stay on top of your work. - - -
-
-
1
-

Syncs with your email, calendar, and meetings

-
-
-
2
-

Remembers the people and context from your conversations

-
-
-
3
-

Helps you follow up and never miss what matters

-
-
- -
- ) - - // Step 1: LLM Setup + // Step 0: LLM Setup const LlmSetupStep = () => { - const providerOptions: Array<{ id: LlmProviderFlavor; name: string; description: string }> = [ + const [showMoreProviders, setShowMoreProviders] = useState(false) + + const primaryProviders: Array<{ id: LlmProviderFlavor; name: string; description: string }> = [ { id: "openai", name: "OpenAI", description: "Use your OpenAI API key" }, { id: "anthropic", name: "Anthropic", description: "Use your Anthropic API key" }, - { id: "google", name: "Google", description: "Use your Google AI Studio key" }, + { id: "google", name: "Gemini", description: "Use your Google AI Studio key" }, + { id: "ollama", name: "Ollama (Local)", description: "Run a local model via Ollama" }, + ] + + const moreProviders: Array<{ id: LlmProviderFlavor; name: string; description: string }> = [ { id: "openrouter", name: "OpenRouter", description: "Access multiple models with one key" }, { id: "aigateway", name: "AI Gateway (Vercel)", description: "Use Vercel's AI Gateway" }, - { id: "ollama", name: "Ollama (Local)", description: "Run a local model via Ollama" }, { id: "openai-compatible", name: "OpenAI-Compatible", description: "Local or hosted OpenAI-compatible API" }, ] + const isMoreProvider = moreProviders.some(p => p.id === llmProvider) + const modelsForProvider = modelsCatalog[llmProvider] || [] const showModelInput = isLocalProvider || modelsForProvider.length === 0 + const renderProviderCard = (provider: { id: LlmProviderFlavor; name: string; description: string }) => ( + + ) + return (
- +
+ Rowboat + Your AI coworker, with memory +
+ Choose your model - - Select your provider and model to power Rowboat’s AI. - -
+
Provider
- {providerOptions.map((provider) => ( - - ))} + {primaryProviders.map(renderProviderCard)}
+ {(showMoreProviders || isMoreProvider) ? ( +
+ {moreProviders.map(renderProviderCard)} +
+ ) : ( + + )}
@@ -750,48 +717,36 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { )}
-
+ {testState.status === "error" && ( +
+ {testState.error || "Connection test failed"} +
+ )} + +
- {testState.status === "success" && ( - Connected - )} - {testState.status === "error" && ( - - {testState.error || "Test failed"} - - )} -
- -
-
) } - // Step 2: Connect Accounts + // Step 1: Connect Accounts const AccountConnectionStep = () => (
Connect Your Accounts - Connect your accounts to start syncing your data. You can always add more later. + Connect your accounts to start syncing your data locally. You can always add more later. @@ -821,13 +776,6 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { {providers.includes('fireflies-ai') && renderOAuthProvider('fireflies-ai', 'Fireflies', , 'AI meeting transcripts')}
- {/* Team Communication Section */} -
-
- Team Communication -
- {renderSlackRow()} -
)}
@@ -843,7 +791,7 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) {
) - // Step 3: Completion + // Step 2: Completion const CompletionStep = () => { const hasConnections = connectedProviders.length > 0 || granolaEnabled || slackConnected @@ -856,7 +804,7 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { You're All Set! {hasConnections ? ( - <>Your workspace will populate over the next ~30 minutes as we sync your data. + <>Give me 30 minutes to build your context graph.
I can still help with other things on your computer. ) : ( <>You can connect your accounts anytime from the sidebar to start syncing data. )} @@ -926,10 +874,9 @@ export function OnboardingModal({ open, onComplete }: OnboardingModalProps) { onEscapeKeyDown={(e) => e.preventDefault()} > - {currentStep === 0 && } - {currentStep === 1 && } - {currentStep === 2 && } - {currentStep === 3 && } + {currentStep === 0 && } + {currentStep === 1 && } + {currentStep === 2 && }