"use client" import { dmSans125ClassName } from "@/lib/fonts" import { analytics } from "@/lib/analytics" import { cn } from "@lib/utils" import { authClient } from "@lib/auth" import { useAuth } from "@lib/auth-context" import { generateId } from "@lib/generate-id" import { ADD_MEMORY_SHORTCUT_URL, RAYCAST_EXTENSION_URL, SEARCH_MEMORY_SHORTCUT_URL, } from "@repo/lib/constants" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogPortal, } from "@ui/components/dialog" import { useMutation } from "@tanstack/react-query" import { Check, Copy, Download, Key, Loader, Plus, Search } from "lucide-react" import Image from "next/image" import { useSearchParams } from "next/navigation" import { useEffect, useId, useState } from "react" import { toast } from "sonner" function SectionTitle({ children }: { children: React.ReactNode }) { return (

{children}

) } function IntegrationCard({ children, id, }: { children: React.ReactNode id?: string }) { return (
{children}
) } function PillButton({ children, onClick, className, disabled, }: { children: React.ReactNode onClick?: () => void className?: string disabled?: boolean }) { return ( ) } function FeatureItem({ text }: { text: string }) { return (
{text}
) } function ChromeIcon({ className }: { className?: string }) { return ( Google Chrome Icon ) } function AppleShortcutsIcon() { return (
Apple Shortcuts
) } function RaycastIcon({ className }: { className?: string }) { return ( Raycast Icon ) } export default function Integrations() { const { org } = useAuth() const searchParams = useSearchParams() // iOS Shortcuts state const [showApiKeyModal, setShowApiKeyModal] = useState(false) const [apiKey, setApiKey] = useState("") const [copied, setCopied] = useState(false) const [selectedShortcutType, setSelectedShortcutType] = useState< "add" | "search" | null >(null) const apiKeyId = useId() // Raycast state const [showRaycastApiKeyModal, setShowRaycastApiKeyModal] = useState(false) const [raycastApiKey, setRaycastApiKey] = useState("") const [raycastCopied, setRaycastCopied] = useState(false) const [hasTriggeredRaycast, setHasTriggeredRaycast] = useState(false) const raycastApiKeyId = useId() const handleCopyApiKey = async (key: string, isRaycast = false) => { try { await navigator.clipboard.writeText(key) if (isRaycast) { setRaycastCopied(true) setTimeout(() => setRaycastCopied(false), 2000) } else { setCopied(true) setTimeout(() => setCopied(false), 2000) } toast.success("API key copied to clipboard!") } catch { toast.error("Failed to copy API key") } } const createApiKeyMutation = useMutation({ mutationFn: async () => { const res = await authClient.apiKey.create({ metadata: { organizationId: org?.id, type: "ios-shortcut", }, name: `ios-${generateId().slice(0, 8)}`, prefix: `sm_${org?.id}_`, }) return res.key }, onSuccess: (key) => { setApiKey(key) setShowApiKeyModal(true) setCopied(false) handleCopyApiKey(key) }, onError: (error) => { toast.error("Failed to create API key", { description: error instanceof Error ? error.message : "Unknown error", }) }, }) const createRaycastApiKeyMutation = useMutation({ mutationFn: async () => { if (!org?.id) { throw new Error("Organization ID is required") } const res = await authClient.apiKey.create({ metadata: { organizationId: org.id, type: "raycast-extension", }, name: `raycast-${generateId().slice(0, 8)}`, prefix: `sm_${org.id}_`, }) return res.key }, onSuccess: (key) => { setRaycastApiKey(key) setShowRaycastApiKeyModal(true) setRaycastCopied(false) handleCopyApiKey(key, true) }, onError: (error) => { toast.error("Failed to create Raycast API key", { description: error instanceof Error ? error.message : "Unknown error", }) }, }) useEffect(() => { const qParam = searchParams.get("q") if ( qParam === "raycast" && !hasTriggeredRaycast && !createRaycastApiKeyMutation.isPending && org?.id ) { setHasTriggeredRaycast(true) createRaycastApiKeyMutation.mutate() } }, [searchParams, hasTriggeredRaycast, createRaycastApiKeyMutation, org]) const handleChromeInstall = () => { window.open( "https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc", "_blank", "noopener,noreferrer", ) analytics.onboardingChromeExtensionClicked({ source: "settings" }) analytics.extensionInstallClicked() } const handleShortcutClick = (shortcutType: "add" | "search") => { setSelectedShortcutType(shortcutType) createApiKeyMutation.mutate() } const handleOpenShortcut = () => { if (!selectedShortcutType) { toast.error("No shortcut type selected") return } if (selectedShortcutType === "add") { window.open(ADD_MEMORY_SHORTCUT_URL, "_blank") } else if (selectedShortcutType === "search") { window.open(SEARCH_MEMORY_SHORTCUT_URL, "_blank") } } const handleRaycastClick = () => { createRaycastApiKeyMutation.mutate() } const handleRaycastInstall = () => { window.open(RAYCAST_EXTENSION_URL, "_blank") analytics.onboardingChromeExtensionClicked({ source: "settings" }) analytics.extensionInstallClicked() } const handleDialogClose = (open: boolean) => { setShowApiKeyModal(open) if (!open) { setSelectedShortcutType(null) setApiKey("") setCopied(false) } } const handleRaycastDialogClose = (open: boolean) => { setShowRaycastApiKeyModal(open) if (!open) { setRaycastApiKey("") setRaycastCopied(false) } } return (
Integrations

Chrome extension

Save any webpage directly from your browser

Add to Chrome

Apple shortcuts

Add memories directly from iPhone, iPad or Mac

handleShortcutClick("add")} disabled={createApiKeyMutation.isPending} > {createApiKeyMutation.isPending && selectedShortcutType === "add" ? ( ) : ( )} {createApiKeyMutation.isPending && selectedShortcutType === "add" ? "Creating..." : "Add memory shortcut"} handleShortcutClick("search")} disabled={createApiKeyMutation.isPending} > {createApiKeyMutation.isPending && selectedShortcutType === "search" ? ( ) : ( )} {createApiKeyMutation.isPending && selectedShortcutType === "search" ? "Creating..." : "Search memory shortcut"}

Raycast extension

Add and search memories from Mac and Windows

{createRaycastApiKeyMutation.isPending ? ( ) : ( )} {createRaycastApiKeyMutation.isPending ? "Generating..." : "Get API key"} Install extension
Setup Apple Shortcut

Follow these steps:

1

Click "Add to Shortcuts" below to open the shortcut

2

Paste your API key when prompted

3

Start using your shortcut!

Setup Raycast Extension

Follow these steps:

1

Install the Raycast extension from the Raycast Store

2

Open Raycast preferences and paste your API key

3

Use "Add Memory" or "Search Memories" commands!

) }