From ede0f393030e1006fa5463394e7d1219ca74e1f3 Mon Sep 17 00:00:00 2001 From: alexf37 <122472971+alexf37@users.noreply.github.com> Date: Wed, 1 Oct 2025 21:59:53 +0000 Subject: [PATCH] feat: new onboarding flow (#408) This is the onboarding flow that you have all seen in my demo. --- apps/web/app/layout.tsx | 22 +- apps/web/app/onboarding/animated-text.tsx | 53 ++ apps/web/app/onboarding/bio-form.tsx | 86 +++ apps/web/app/onboarding/connections-form.tsx | 213 ++++++ apps/web/app/onboarding/extension-form.tsx | 707 ++++++++++++++++++ apps/web/app/onboarding/floating-orbs.tsx | 228 ++++++ apps/web/app/onboarding/intro.tsx | 116 +++ apps/web/app/onboarding/mcp-form.tsx | 206 +++++ apps/web/app/onboarding/name-form.tsx | 95 +++ apps/web/app/onboarding/nav-menu.tsx | 44 ++ .../web/app/onboarding/onboarding-context.tsx | 202 +++++ apps/web/app/onboarding/onboarding-form.tsx | 99 +++ apps/web/app/onboarding/page.tsx | 28 + apps/web/app/onboarding/progress-bar.tsx | 26 + apps/web/app/onboarding/welcome.tsx | 20 + apps/web/components/text-effect.tsx | 294 ++++++++ apps/web/components/text-morph.tsx | 74 ++ apps/web/package.json | 3 +- apps/web/public/images/gdrive.svg | 8 + apps/web/public/images/icon-16.png | Bin 0 -> 33814 bytes apps/web/public/images/notion.svg | 4 + apps/web/public/images/onedrive.svg | 1 + bun.lock | 8 +- packages/lib/api.ts | 5 + packages/ui/components/carousel.tsx | 8 +- packages/ui/components/hover-card.tsx | 44 ++ packages/ui/package.json | 1 + 27 files changed, 2582 insertions(+), 13 deletions(-) create mode 100644 apps/web/app/onboarding/animated-text.tsx create mode 100644 apps/web/app/onboarding/bio-form.tsx create mode 100644 apps/web/app/onboarding/connections-form.tsx create mode 100644 apps/web/app/onboarding/extension-form.tsx create mode 100644 apps/web/app/onboarding/floating-orbs.tsx create mode 100644 apps/web/app/onboarding/intro.tsx create mode 100644 apps/web/app/onboarding/mcp-form.tsx create mode 100644 apps/web/app/onboarding/name-form.tsx create mode 100644 apps/web/app/onboarding/nav-menu.tsx create mode 100644 apps/web/app/onboarding/onboarding-context.tsx create mode 100644 apps/web/app/onboarding/onboarding-form.tsx create mode 100644 apps/web/app/onboarding/page.tsx create mode 100644 apps/web/app/onboarding/progress-bar.tsx create mode 100644 apps/web/app/onboarding/welcome.tsx create mode 100644 apps/web/components/text-effect.tsx create mode 100644 apps/web/components/text-morph.tsx create mode 100644 apps/web/public/images/gdrive.svg create mode 100644 apps/web/public/images/icon-16.png create mode 100644 apps/web/public/images/notion.svg create mode 100644 apps/web/public/images/onedrive.svg create mode 100644 packages/ui/components/hover-card.tsx diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index e6d9094d..8b1adc85 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,5 +1,5 @@ import type { Metadata } from "next"; -import { Inter, JetBrains_Mono } from "next/font/google"; +import { Inter, JetBrains_Mono, Instrument_Serif } from "next/font/google"; import "../globals.css"; import "@ui/globals.css"; import { AuthProvider } from "@lib/auth-context"; @@ -11,6 +11,8 @@ import { Suspense } from "react"; import { Toaster } from "sonner"; import { TourProvider } from "@/components/tour"; import { MobilePanelProvider } from "@/lib/mobile-panel-context"; +import { NuqsAdapter } from 'nuqs/adapters/next/app' + import { ViewModeProvider } from "@/lib/view-mode-context"; @@ -24,6 +26,12 @@ const mono = JetBrains_Mono({ variable: "--font-mono", }); +const serif = Instrument_Serif({ + subsets: ["latin"], + variable: "--font-serif", + weight: ["400"], +}); + export const metadata: Metadata = { metadataBase: new URL("https://app.supermemory.ai"), description: "Your memories, wherever you are", @@ -38,7 +46,7 @@ export default function RootLayout({ return ( - - {children} - - + + + {children} + + + diff --git a/apps/web/app/onboarding/animated-text.tsx b/apps/web/app/onboarding/animated-text.tsx new file mode 100644 index 00000000..c3616482 --- /dev/null +++ b/apps/web/app/onboarding/animated-text.tsx @@ -0,0 +1,53 @@ +'use client'; +import { useEffect } from 'react'; +import { TextEffect } from '@/components/text-effect'; + +export function AnimatedText({ children, trigger, delay }: { children: string, trigger: boolean, delay: number }) { + const blurSlideVariants = { + container: { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { staggerChildren: 0.01 }, + }, + exit: { + transition: { staggerChildren: 0.01, staggerDirection: 1 }, + }, + }, + item: { + hidden: { + opacity: 0, + filter: 'blur(10px) brightness(0%)', + y: 0, + }, + visible: { + opacity: 1, + y: 0, + filter: 'blur(0px) brightness(100%)', + transition: { + duration: 0.4, + }, + }, + exit: { + opacity: 0, + y: -30, + filter: 'blur(10px) brightness(0%)', + transition: { + duration: 0.3, + }, + }, + }, + }; + + return ( + + {children} + + ); +} diff --git a/apps/web/app/onboarding/bio-form.tsx b/apps/web/app/onboarding/bio-form.tsx new file mode 100644 index 00000000..984309a9 --- /dev/null +++ b/apps/web/app/onboarding/bio-form.tsx @@ -0,0 +1,86 @@ +"use client"; + +import { Textarea } from "@ui/components/textarea"; +import { useOnboarding } from "./onboarding-context"; +import { useState } from "react"; +import { Button } from "@ui/components/button"; +import { AnimatePresence, motion } from "motion/react"; +import { NavMenu } from "./nav-menu"; +import { $fetch } from "@lib/api"; + +export function BioForm() { + const [bio, setBio] = useState(""); + const { totalSteps, nextStep, getStepNumberFor } = useOnboarding(); + + function handleNext() { + const trimmed = bio.trim(); + if (!trimmed) { + nextStep(); + return; + } + + nextStep(); + void $fetch("@post/memories", { + body: { + content: trimmed, + containerTags: ["sm_project_default"], + metadata: { sm_source: "consumer" }, + }, + }).catch((error) => { + console.error("Failed to save onboarding bio memory:", error); + }); + } + return ( +
+
+ +

+ Step {getStepNumberFor("bio")} of {totalSteps} +

+
+

Tell us about yourself

+

+ What should Supermemory know about you? +

+
+