"use client" import { useState } from "react" import { Button } from "@ui/components/button" import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, } from "@ui/components/drawer" import { GoogleDrive, Notion, OneDrive } from "@ui/assets/icons" import { Logo } from "@ui/assets/Logo" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@ui/components/select" import { AlertTriangle, ArrowRight, Check, Database, FolderOpen, Github, Globe, Mic, Plus, } from "lucide-react" import { AppleShortcutsIcon, ChromeIcon, RaycastIcon, } from "@/components/integration-icons" function XBookmarksIcon({ className }: { className?: string }) { return ( ) } function GmailIcon({ className }: { className?: string }) { return ( ) } import { cn } from "@lib/utils" import { dmSans125ClassName } from "@/lib/fonts" import { $fetch } from "@lib/api" import { toast } from "sonner" type SourceId = "drive" | "notion" | "gmail" | "github" | "onedrive" type SourceState = "idle" | "connecting" | "connected" | "waitlist" type DriveScope = "selective" | "full" export interface SourcesValues { connected: Partial> driveScope: DriveScope } interface Props { containerTag: string workspaceName: string values: SourcesValues onChange: (next: SourcesValues) => void onContinue: () => void } const modalCardStyle = { boxShadow: "0 2.842px 14.211px 0 rgba(0, 0, 0, 0.25), 0.711px 0.711px 0.711px 0 rgba(255, 255, 255, 0.10) inset", } const inputBevelStyle = { boxShadow: "0px 1px 2px 0px rgba(0,43,87,0.1), inset 0px 0px 0px 1px rgba(43,49,67,0.08), inset 0px 1px 1px 0px rgba(0,0,0,0.08), inset 0px 2px 4px 0px rgba(0,0,0,0.02)", } export function StepSources({ containerTag, workspaceName, values, onChange, onContinue, }: Props) { const [moreOpen, setMoreOpen] = useState(false) const setState = (id: SourceId, state: SourceState) => { onChange({ ...values, connected: { ...values.connected, [id]: state } }) } const connectRealProvider = async ( provider: "google-drive" | "notion" | "onedrive", id: SourceId, ) => { setState(id, "connecting") try { const metadata: Record = {} if (provider === "google-drive") { metadata.scope = values.driveScope } const res = await $fetch("@post/connections/:provider", { params: { provider }, body: { redirectUrl: window.location.href, containerTags: [containerTag], metadata: Object.keys(metadata).length > 0 ? metadata : undefined, }, }) const data = "data" in res ? res.data : null if (data && "authLink" in data && data.authLink) { window.location.href = data.authLink return } throw new Error("No auth link returned") } catch (err) { setState(id, "idle") toast.error( err instanceof Error ? err.message : "Could not start connection", ) } } const connectedCount = Object.values(values.connected).filter( (s) => s === "connected" || s === "waitlist", ).length return (

Connect your team's signals

Start with the sources that carry the most context. Add more anytime.

} state={values.connected.drive ?? "idle"} ctaLabel="Connect" perks={[ "Docs, sheets, slides — all parsed", "Stays in sync as files change", "You pick what to share at sign-in", ]} onConnect={() => connectRealProvider("google-drive", "drive")} headerNote={ values.driveScope === "full" ? (

Full Drive can exhaust your monthly usage.

) : null } footerLeft={ onChange({ ...values, driveScope: s })} /> } footerRight={} /> } state={values.connected.notion ?? "idle"} ctaLabel="Connect" perks={[ "Pages and database rows", "Stays in sync when you edit", "Pick which workspaces ingest", ]} onConnect={() => connectRealProvider("notion", "notion")} footerRight={} />
setMoreOpen(false)} containerTag={containerTag} connectRealProvider={connectRealProvider} />
) } function RoutingChip({ workspaceName }: { workspaceName: string }) { return (
Routing to {workspaceName || "your brain"}
) } function SourceCard({ title, blurb, icon, state, ctaLabel, perks, soft, headerNote, footerLeft, footerRight, onConnect, }: { title: string blurb: string icon: React.ReactNode state: SourceState ctaLabel: string perks: string[] soft?: boolean headerNote?: React.ReactNode footerLeft?: React.ReactNode footerRight?: React.ReactNode onConnect: () => void }) { const isDone = state === "connected" || state === "waitlist" return (
{icon}

{title}

{blurb}

{headerNote}
{isDone ? ( {state === "waitlist" ? "Requested" : "Connected"} ) : ( )}
    {perks.map((p) => (
  • {p}
  • ))}
{soft && !isDone && (

OAuth lands shortly — request access and we'll auto-enable it.

)} {(footerLeft || footerRight) && (
{footerLeft}
{footerRight}
)}
) } function SpaceChip({ name }: { name: string }) { return (
Saves to {name}
) } function DriveScopePicker({ value, onChange, }: { value: DriveScope onChange: (s: DriveScope) => void }) { return ( ) } function MoreDrawer({ open, onClose, containerTag, connectRealProvider, }: { open: boolean onClose: () => void containerTag: string connectRealProvider: ( provider: "google-drive" | "notion" | "onedrive", id: SourceId, ) => void }) { return ( !o && onClose()}> More integrations

Add any of these alongside your spotlight sources. Everything routes to {containerTag}.

} action="Request access" soft /> } action="Request access" soft /> } action="Connect" onAction={() => connectRealProvider("onedrive", "onedrive")} /> } action="Coming soon" soft /> } action="Connect" soft /> } action="Connect" soft /> } action="Install" soft /> } action="Install" soft /> } action="Install" soft /> } action="Import" soft />
) } function MoreItem({ title, blurb, icon, action, soft, onAction, }: { title: string blurb: string icon: React.ReactNode action: string soft?: boolean onAction?: () => void }) { return (
{icon}

{title}

{blurb}

) }