From 88f9fb20ef31a580516e434fc2cc77aa0c566962 Mon Sep 17 00:00:00 2001 From: Vorflux AI Date: Fri, 1 May 2026 19:22:22 +0000 Subject: [PATCH] fix: redirect new users to onboarding from plugin connect page New users arriving at /auth/connect (e.g. from OpenCode CLI) had no organization yet, causing the 'Approve Connection' button to silently fail. The handleConnect guard 'if (!session || !org) return' would fire with no feedback, leading to rage-clicking. Changes: - Detect logged-in users with no org on the connect page and redirect them to onboarding, stashing the connect URL in sessionStorage. - After onboarding completes (skip or finish), redirect back to the connect page so the plugin auth flow finishes automatically. - Show an error message instead of silently returning when session/org is missing and the user clicks 'Approve Connection'. - Wait for full auth state before showing the connect card. - Extract PENDING_CONNECT_URL_KEY and consumePendingConnectUrl() to a shared constants file with 7 unit tests. --- apps/web/app/(app)/onboarding/page.tsx | 12 ++- apps/web/app/auth/connect/page.tsx | 45 ++++++++-- apps/web/components/initial-header.tsx | 4 +- apps/web/lib/__tests__/constants.test.ts | 106 +++++++++++++++++++++++ apps/web/lib/constants.ts | 28 ++++++ 5 files changed, 187 insertions(+), 8 deletions(-) create mode 100644 apps/web/lib/__tests__/constants.test.ts create mode 100644 apps/web/lib/constants.ts diff --git a/apps/web/app/(app)/onboarding/page.tsx b/apps/web/app/(app)/onboarding/page.tsx index ac554055..07cb66c2 100644 --- a/apps/web/app/(app)/onboarding/page.tsx +++ b/apps/web/app/(app)/onboarding/page.tsx @@ -32,6 +32,7 @@ import { import { GoogleDrive, Notion, OneDrive } from "@ui/assets/icons" import { Sparkles, ChevronLeft, ChevronRight } from "lucide-react" import { analytics } from "@/lib/analytics" +import { consumePendingConnectUrl } from "@/lib/constants" type DetectedSource = "x" | "linkedin" | "resume" | null type Status = "idle" | "processing" | "done" | "error" @@ -374,6 +375,12 @@ export default function OnboardingPage() { const skippingRef = useRef(false) const [spotlightCategory, setSpotlightCategory] = useState("productivity") + + /** Navigate home, or back to the plugin connect page if one is pending. */ + const goHomeOrPendingConnect = useCallback(() => { + const pendingPath = consumePendingConnectUrl() + router.push(pendingPath ?? "/") + }, [router]) const [pauseSpotlight, setPauseSpotlight] = useState(false) const spotlightCatalog = useMemo( @@ -467,7 +474,8 @@ export default function OnboardingPage() { skippingRef.current = true try { await ensureOrg() - router.push("/") + const pendingPath = consumePendingConnectUrl() + router.push(pendingPath ?? "/") } catch (err) { console.error(err) skippingRef.current = false @@ -1077,7 +1085,7 @@ export default function OnboardingPage() {