diff --git a/apps/web/app/(navigation)/page.tsx b/apps/web/app/(navigation)/page.tsx index b8c81985..d2be1ad8 100644 --- a/apps/web/app/(navigation)/page.tsx +++ b/apps/web/app/(navigation)/page.tsx @@ -6,6 +6,7 @@ import { ChevronsDown, LoaderIcon } from "lucide-react" import { useRouter } from "next/navigation" import { useEffect } from "react" import { InstallPrompt } from "@/components/install-prompt" +import { ChromeExtensionButton } from "@/components/chrome-extension-button" import { ChatInput } from "@/components/chat-input" import { BackgroundPlus } from "@ui/components/grid-plus" import { Memories } from "@/components/memories" @@ -76,6 +77,7 @@ export default function Page() { + ) } diff --git a/apps/web/components/chrome-extension-button.tsx b/apps/web/components/chrome-extension-button.tsx new file mode 100644 index 00000000..5fd58cac --- /dev/null +++ b/apps/web/components/chrome-extension-button.tsx @@ -0,0 +1,234 @@ +"use client" + +import { Button } from "@ui/components/button" +import { + Bookmark, + Zap, + CircleX, + Users, + Lock, + ChromeIcon, + TwitterIcon, +} from "lucide-react" +import { useEffect, useState } from "react" +import { motion } from "framer-motion" +import Image from "next/image" +import { analytics } from "@/lib/analytics" + +export function ChromeExtensionButton() { + const [isExtensionInstalled, setIsExtensionInstalled] = useState(false) + const [isChecking, setIsChecking] = useState(true) + const [isDismissed, setIsDismissed] = useState(false) + const [isMinimized, setIsMinimized] = useState(false) + + useEffect(() => { + const dismissed = + localStorage.getItem("chrome-extension-dismissed") === "true" + setIsDismissed(dismissed) + + const checkExtension = () => { + const message = { action: "check-extension" } + + const timeout = setTimeout(() => { + setIsExtensionInstalled(false) + setIsChecking(false) + // Auto-minimize after 3 seconds if extension is not installed and not dismissed + if (!dismissed) { + setTimeout(() => { + setIsMinimized(true) + }, 3000) + } + }, 1000) + + const handleMessage = (event: MessageEvent) => { + if (event.data?.action === "extension-detected") { + clearTimeout(timeout) + setIsExtensionInstalled(true) + setIsChecking(false) + window.removeEventListener("message", handleMessage) + } + } + + window.addEventListener("message", handleMessage) + + window.postMessage(message, "*") + + return () => { + clearTimeout(timeout) + window.removeEventListener("message", handleMessage) + } + } + + if (!dismissed) { + checkExtension() + } else { + setIsChecking(false) + } + }, []) + + const handleInstall = () => { + analytics.extensionInstallClicked() + window.open( + "https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc", + "_blank", + "noopener,noreferrer", + ) + } + + const handleDismiss = () => { + localStorage.setItem("chrome-extension-dismissed", "true") + setIsDismissed(true) + } + + // Don't show if extension is installed, checking, or dismissed + if (isExtensionInstalled || isChecking || isDismissed) { + return null + } + + return ( + +
+ {!isMinimized && ( + +
+
+
+

+ supermemory extension +

+

+ your second brain for the web. +

+
+
+
+ +
+
+
+ +
+
+

+ Twitter Imports +

+

+ Import your twitter timeline & save tweets. +

+
+
+ +
+
+ +
+
+

+ Save All Bookmarks +

+

+ Instantly save any webpage to your memory. +

+
+
+ +
+
+ +
+
+

+ Charge Empty Memory +

+

+ Automatically capture & organize your browsing history. +

+
+
+
+ +
+ +
+ +
+
+ + 4K+ users +
+
+ + Privacy first +
+
+
+ )} + + {isMinimized && ( +
+ + +
+ )} +
+
+ ) +} diff --git a/apps/web/components/header.tsx b/apps/web/components/header.tsx index b51b4b84..c055e94d 100644 --- a/apps/web/components/header.tsx +++ b/apps/web/components/header.tsx @@ -1,7 +1,17 @@ import { Button } from "@ui/components/button" import { Logo, LogoFull } from "@ui/assets/Logo" import Link from "next/link" -import { MoonIcon, Plus, SunIcon, MonitorIcon, Network } from "lucide-react" +import { + MoonIcon, + Plus, + SunIcon, + MonitorIcon, + Network, + User, + CreditCard, + Chrome, + LogOut, +} from "lucide-react" import { DropdownMenuContent, DropdownMenuTrigger, @@ -93,13 +103,27 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) { router.push("/settings")}> + Profile router.push("/settings/billing")} > + Billing + { + window.open( + "https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc", + "_blank", + "noopener,noreferrer", + ) + }} + > + + Chrome Extension + e.preventDefault()} @@ -164,6 +188,7 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) { handleSignOut()}> + Logout diff --git a/apps/web/public/icons/chrome-transparent.svg b/apps/web/public/icons/chrome-transparent.svg new file mode 100644 index 00000000..a4bb01b7 --- /dev/null +++ b/apps/web/public/icons/chrome-transparent.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/web/public/images/extension-bg.png b/apps/web/public/images/extension-bg.png new file mode 100644 index 00000000..c414d088 Binary files /dev/null and b/apps/web/public/images/extension-bg.png differ diff --git a/apps/web/public/images/extension-logo.png b/apps/web/public/images/extension-logo.png new file mode 100644 index 00000000..549d267d Binary files /dev/null and b/apps/web/public/images/extension-logo.png differ