diff --git a/frontend/src/components/dashboard/NextStepCard.tsx b/frontend/src/components/dashboard/NextStepCard.tsx index 5d54a266..9b158d5a 100644 --- a/frontend/src/components/dashboard/NextStepCard.tsx +++ b/frontend/src/components/dashboard/NextStepCard.tsx @@ -6,6 +6,7 @@ import type { OnboardingStatus } from '@/api/onboarding' import { useTrialBanner } from '@/hooks/useTrialBanner' import type { TrialBannerStage } from '@/hooks/useTrialBanner' import { useOnboardingStatus } from '@/hooks/useOnboardingStatus' +import { FOCUS_START_SESSION_EVENT } from '@/components/dashboard/StartSessionInput' /** * Next-step card — surfaces the single highest-priority incomplete onboarding @@ -114,9 +115,10 @@ export function pickNextStep( export function NextStepCard() { const status = useOnboardingStatus() const [locallyDismissed, setLocallyDismissed] = useState(false) + const [locallyHidden, setLocallyHidden] = useState(false) const { stage } = useTrialBanner() - if (!status || status.dismissed || locallyDismissed) return null + if (!status || status.dismissed || locallyDismissed || locallyHidden) return null const next = pickNextStep(status, stage) if (!next) return null @@ -154,14 +156,29 @@ export function NextStepCard() {
- - {next.ctaLabel} - - + {next.key === 'ran_session' ? ( + + ) : ( + + {next.ctaLabel} + + + )}
) diff --git a/frontend/src/components/dashboard/SetupChecklist.tsx b/frontend/src/components/dashboard/SetupChecklist.tsx index 7d8677b2..13ddcb1f 100644 --- a/frontend/src/components/dashboard/SetupChecklist.tsx +++ b/frontend/src/components/dashboard/SetupChecklist.tsx @@ -5,6 +5,7 @@ import type { OnboardingStatus } from '@/api/onboarding' import { useTrialBanner } from '@/hooks/useTrialBanner' import type { TrialBannerStage } from '@/hooks/useTrialBanner' import { useOnboardingStatus } from '@/hooks/useOnboardingStatus' +import { FOCUS_START_SESSION_EVENT } from '@/components/dashboard/StartSessionInput' /** * Unified setup checklist — single list (no SOLO/TEAM bifurcation). @@ -112,6 +113,21 @@ export function SetupChecklist() { {item.label} + ) : item.key === 'ran_session' ? ( + ) : ( ([]) const [isDragOver, setIsDragOver] = useState(false) + const [nudge, setNudge] = useState(false) const navigate = useNavigate() + const wrapperRef = useRef(null) const textareaRef = useRef(null) const fileInputRef = useRef(null) const dragCounterRef = useRef(0) useEffect(() => { textareaRef.current?.focus() }, []) + // External "focus me" trigger (e.g. NextStepCard "Start a session" CTA on + // the same page). Scrolls into view, focuses the textarea, and pulses a + // ring so the click feels intentional even when the input was already + // partially visible. + useEffect(() => { + const handler = () => { + wrapperRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }) + textareaRef.current?.focus({ preventScroll: true }) + setNudge(true) + window.setTimeout(() => setNudge(false), 900) + } + window.addEventListener(FOCUS_START_SESSION_EVENT, handler) + return () => window.removeEventListener(FOCUS_START_SESSION_EVENT, handler) + }, []) + // Auto-grow textarea useEffect(() => { const el = textareaRef.current @@ -190,7 +209,8 @@ export function StartSessionInput() { return (
{/* Main input area */}
{/* Drag overlay */} {isDragOver && (