mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-07-09 17:18:51 +00:00
chore(web): remove unused @lobbyside/react integration (#1156)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
32a6055f7c
commit
b3017eb121
4 changed files with 0 additions and 329 deletions
|
|
@ -1,310 +0,0 @@
|
|||
"use client"
|
||||
|
||||
import { useCallback, useEffect, useState } from "react"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { Phone, Users, X as XIcon } from "lucide-react"
|
||||
import { useLobbyside } from "@lobbyside/react"
|
||||
import { useAuth } from "@lib/auth-context"
|
||||
import { cn } from "@lib/utils"
|
||||
import { dmSans125ClassName } from "@/lib/fonts"
|
||||
import { analytics } from "@/lib/analytics"
|
||||
|
||||
const STORAGE_KEY = "sm_next_app_research_cta_dismissed_v1"
|
||||
|
||||
const BOOK_CALL_HREF = "https://cal.com/supermemory/growth"
|
||||
|
||||
const LOBBYSIDE_WIDGET_ID = "e385c52f-4dd3-4fb2-81eb-da3a78059014"
|
||||
|
||||
function ResearchCtaHeroGraphic({
|
||||
avatarUrl,
|
||||
hostName,
|
||||
}: {
|
||||
avatarUrl?: string
|
||||
hostName?: string
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
id="next-app-research-cta-hero"
|
||||
className={cn(
|
||||
"relative flex min-h-[4.5rem] w-full shrink-0 items-center justify-center overflow-hidden rounded-xl py-5",
|
||||
"border border-white/[0.1] bg-gradient-to-b from-[#141c28] to-[#0D121A]",
|
||||
)}
|
||||
aria-hidden
|
||||
>
|
||||
<div
|
||||
className="pointer-events-none absolute inset-0 opacity-[0.45]"
|
||||
style={{
|
||||
background:
|
||||
"radial-gradient(ellipse 85% 90% at 50% 30%, rgba(59, 130, 246, 0.2), transparent 65%)",
|
||||
}}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
||||
<div
|
||||
className="h-[120%] w-px bg-gradient-to-b from-transparent via-[#5B8DEF]/35 to-transparent"
|
||||
style={{ transform: "rotate(52deg)" }}
|
||||
/>
|
||||
<div
|
||||
className="absolute h-[120%] w-px bg-gradient-to-b from-transparent via-[#9B7AFF]/30 to-transparent"
|
||||
style={{ transform: "rotate(-52deg)" }}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative z-10 flex flex-row items-center justify-center gap-10 px-3">
|
||||
<div className="flex size-9 items-center justify-center">
|
||||
<Phone className="size-[24px] text-[#7EB0FF]" strokeWidth={1.65} />
|
||||
</div>
|
||||
<span
|
||||
className={cn(
|
||||
dmSans125ClassName(),
|
||||
"select-none text-[17px] font-light leading-none text-[#6B9FFF]/75",
|
||||
)}
|
||||
>
|
||||
×
|
||||
</span>
|
||||
{avatarUrl ? (
|
||||
<span className="relative inline-flex">
|
||||
<img
|
||||
src={avatarUrl}
|
||||
alt={hostName ?? ""}
|
||||
className="size-9 rounded-full object-cover ring-1 ring-[#B49CFB]/40"
|
||||
/>
|
||||
<span
|
||||
aria-hidden
|
||||
className="absolute bottom-0 right-0 size-[10px] rounded-full bg-[#22c55e] ring-2 ring-[#0D121A]"
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
<div className="flex size-9 items-center justify-center">
|
||||
<Users className="size-[24px] text-[#B49CFB]" strokeWidth={1.65} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function NextAppResearchCta() {
|
||||
const pathname = usePathname()
|
||||
const [mounted, setMounted] = useState(false)
|
||||
const [dismissed, setDismissed] = useState(false)
|
||||
const widget = useLobbyside(LOBBYSIDE_WIDGET_ID)
|
||||
const { user, org } = useAuth()
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
setDismissed(localStorage.getItem(STORAGE_KEY) === "1")
|
||||
}, [])
|
||||
|
||||
const handleDismiss = useCallback((e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
localStorage.setItem(STORAGE_KEY, "1")
|
||||
setDismissed(true)
|
||||
analytics.nextAppResearchCtaDismissed()
|
||||
}, [])
|
||||
|
||||
const handleJoinCall = useCallback(async () => {
|
||||
if (widget.status !== "online" || widget.isQueueFull) return
|
||||
analytics.nextAppResearchCtaLobbysideCallClicked()
|
||||
// Open the tab synchronously so Safari/iOS keep the user-activation
|
||||
// gesture. We redirect it once joinCall() resolves, or fall back to
|
||||
// the book-a-call URL if the host goes offline / queue fills / the
|
||||
// request errors between render and click.
|
||||
const pendingTab = window.open("", "_blank")
|
||||
const navigate = (url: string) => {
|
||||
if (pendingTab && !pendingTab.closed) {
|
||||
pendingTab.location.href = url
|
||||
} else {
|
||||
window.open(url, "_blank", "noopener,noreferrer")
|
||||
}
|
||||
}
|
||||
try {
|
||||
const visitor: Record<string, string> = {}
|
||||
if (user?.email) visitor.email = user.email
|
||||
if (user?.name) visitor.name = user.name
|
||||
if (org?.name) visitor.company = org.name
|
||||
const github = (user as { github?: unknown } | null)?.github
|
||||
if (typeof github === "string" && github) visitor.github = github
|
||||
const joinArgs = Object.keys(visitor).length > 0 ? { visitor } : undefined
|
||||
const { entryUrl } = await widget.joinCall(joinArgs)
|
||||
navigate(entryUrl)
|
||||
} catch (err) {
|
||||
console.error("[Lobbyside] joinCall failed", err)
|
||||
navigate(BOOK_CALL_HREF)
|
||||
}
|
||||
}, [widget, user, org])
|
||||
|
||||
const handleCardKeyDown = useCallback(
|
||||
(e: React.KeyboardEvent<HTMLElement>) => {
|
||||
if (e.target !== e.currentTarget) return
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault()
|
||||
handleJoinCall()
|
||||
}
|
||||
},
|
||||
[handleJoinCall],
|
||||
)
|
||||
|
||||
const handleBookClick = useCallback(() => {
|
||||
analytics.nextAppResearchCtaBookCallClicked()
|
||||
}, [])
|
||||
|
||||
if (
|
||||
!mounted ||
|
||||
dismissed ||
|
||||
pathname.startsWith("/onboarding") ||
|
||||
widget.status === "loading"
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
const cardBaseClasses = cn(
|
||||
"fixed z-[45] bottom-4 left-4 min-w-[280px] max-w-[min(calc(100vw-2rem),22.5rem)]",
|
||||
"rounded-xl border border-white/[0.08] bg-[#0D121A]/95 backdrop-blur-md",
|
||||
"shadow-[0_8px_32px_rgba(0,0,0,0.35)] p-3.5",
|
||||
)
|
||||
|
||||
if (widget.status !== "online" || widget.isQueueFull) {
|
||||
return (
|
||||
<section
|
||||
id="next-app-research-cta"
|
||||
className={cardBaseClasses}
|
||||
aria-label="Research participant invitation"
|
||||
>
|
||||
<div className="flex flex-col gap-3">
|
||||
<ResearchCtaHeroGraphic />
|
||||
<div className="min-w-0 w-full">
|
||||
<div className="flex items-start gap-1">
|
||||
<p
|
||||
className={cn(
|
||||
dmSans125ClassName(),
|
||||
"flex-1 min-w-0 font-medium text-[12px] text-[#FAFAFA] tracking-[-0.12px]",
|
||||
)}
|
||||
>
|
||||
Be part of the next supermemory app
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleDismiss}
|
||||
className={cn(
|
||||
"shrink-0 rounded-md p-1 -mr-1 -mt-0.5",
|
||||
"text-muted-foreground hover:text-foreground transition-colors",
|
||||
"cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
)}
|
||||
aria-label="Dismiss"
|
||||
>
|
||||
<XIcon className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
<p
|
||||
className={cn(
|
||||
dmSans125ClassName(),
|
||||
"mt-1 text-[12px] text-[#737373] tracking-[-0.12px]",
|
||||
)}
|
||||
>
|
||||
Share what you want next. We’d love a quick call.
|
||||
</p>
|
||||
<div className="mt-2.5 flex justify-end">
|
||||
<a
|
||||
href={BOOK_CALL_HREF}
|
||||
onClick={handleBookClick}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={cn(
|
||||
dmSans125ClassName(),
|
||||
"inline-flex text-[13px] font-medium text-[#A3A3A3]",
|
||||
"tracking-[-0.13px] underline underline-offset-4 decoration-white/20",
|
||||
"hover:text-[#FAFAFA] hover:decoration-white/40 transition-colors",
|
||||
)}
|
||||
>
|
||||
Book a call
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
id="next-app-research-cta"
|
||||
tabIndex={0}
|
||||
onClick={handleJoinCall}
|
||||
onKeyDown={handleCardKeyDown}
|
||||
className={cn(
|
||||
cardBaseClasses,
|
||||
"cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
)}
|
||||
aria-label={`${widget.buttonText} with ${widget.hostName}`}
|
||||
>
|
||||
<div className="flex flex-col gap-3">
|
||||
<ResearchCtaHeroGraphic
|
||||
avatarUrl={widget.avatarUrl}
|
||||
hostName={widget.hostName}
|
||||
/>
|
||||
<div className="min-w-0 w-full">
|
||||
<div className="flex items-start gap-1">
|
||||
<p
|
||||
className={cn(
|
||||
dmSans125ClassName(),
|
||||
"flex-1 min-w-0 font-medium text-[12px] text-[#FAFAFA] tracking-[-0.12px]",
|
||||
)}
|
||||
>
|
||||
{widget.ctaText}
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleDismiss}
|
||||
className={cn(
|
||||
"shrink-0 rounded-md p-1 -mr-1 -mt-0.5",
|
||||
"text-muted-foreground hover:text-foreground transition-colors",
|
||||
"cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
)}
|
||||
aria-label="Dismiss"
|
||||
>
|
||||
<XIcon className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-2.5 flex items-center justify-between gap-2">
|
||||
<div className="min-w-0 flex-1">
|
||||
<p
|
||||
className={cn(
|
||||
dmSans125ClassName(),
|
||||
"truncate text-[12px] font-medium text-[#FAFAFA] tracking-[-0.12px]",
|
||||
)}
|
||||
>
|
||||
{widget.hostName}
|
||||
</p>
|
||||
{widget.hostTitle ? (
|
||||
<p
|
||||
className={cn(
|
||||
dmSans125ClassName(),
|
||||
"truncate text-[11px] text-[#737373] tracking-[-0.11px]",
|
||||
)}
|
||||
>
|
||||
{widget.hostTitle}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
handleJoinCall()
|
||||
}}
|
||||
className={cn(
|
||||
dmSans125ClassName(),
|
||||
"shrink-0 inline-flex text-[13px] font-medium text-[#A3A3A3]",
|
||||
"tracking-[-0.13px] underline underline-offset-4 decoration-white/20",
|
||||
"hover:text-[#FAFAFA] hover:decoration-white/40 transition-colors",
|
||||
"cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm",
|
||||
)}
|
||||
>
|
||||
{widget.buttonText}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
|
@ -94,13 +94,6 @@ export const analytics = {
|
|||
close_reason: "dismiss" | "close_button" | "im_good" | "action"
|
||||
}) => safeCapture("integration_info_modal_closed", props),
|
||||
|
||||
nextAppResearchCtaDismissed: () =>
|
||||
safeCapture("next_app_research_cta_dismissed"),
|
||||
nextAppResearchCtaBookCallClicked: () =>
|
||||
safeCapture("next_app_research_cta_book_call_clicked"),
|
||||
nextAppResearchCtaLobbysideCallClicked: () =>
|
||||
safeCapture("next_app_research_cta_lobbyside_call_clicked"),
|
||||
|
||||
mcpViewOpened: () => safeCapture("mcp_view_opened"),
|
||||
mcpInstallCmdCopied: () => safeCapture("mcp_install_cmd_copied"),
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@floating-ui/react": "^0.27.0",
|
||||
"@lobbyside/react": "0.2.0",
|
||||
"@opennextjs/cloudflare": "^1.12.0",
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.14",
|
||||
|
|
|
|||
11
bun.lock
11
bun.lock
|
|
@ -140,7 +140,6 @@
|
|||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@floating-ui/react": "^0.27.0",
|
||||
"@lobbyside/react": "0.2.0",
|
||||
"@opennextjs/cloudflare": "^1.12.0",
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.14",
|
||||
|
|
@ -981,10 +980,6 @@
|
|||
|
||||
"@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="],
|
||||
|
||||
"@instantdb/core": ["@instantdb/core@1.0.15", "", { "dependencies": { "@instantdb/version": "1.0.15", "mutative": "^1.0.10", "uuid": "^11.1.0" } }, "sha512-1A4n47U0YLHKhvl0G+CiPGfBynq1cj+NqIVRhUMc/yHYT6rePeRWesxvevNiEJU2sLxOKML6Htcbtdh7jUjSQA=="],
|
||||
|
||||
"@instantdb/version": ["@instantdb/version@1.0.15", "", {}, "sha512-xHDT23QK0tKAdxC2Z98mBx+znwnVShYWDsp0juY4xxzTGjrb37qNqRYb+6IIJc1J3GZ+xW/fCIexVK3b0B6fog=="],
|
||||
|
||||
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
||||
|
||||
"@isaacs/ttlcache": ["@isaacs/ttlcache@2.1.4", "", {}, "sha512-7kMz0BJpMvgAMkyglums7B2vtrn5g0a0am77JY0GjkZZNetOBCFn7AG7gKCwT0QPiXyxW7YIQSgtARknUEOcxQ=="],
|
||||
|
|
@ -1015,8 +1010,6 @@
|
|||
|
||||
"@levischuck/tiny-cbor": ["@levischuck/tiny-cbor@0.2.11", "", {}, "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow=="],
|
||||
|
||||
"@lobbyside/react": ["@lobbyside/react@0.2.0", "", { "peerDependencies": { "@instantdb/core": ">=1.0.0", "react": ">=18.0.0" } }, "sha512-24dTNDImAqZrlCu+vlPKulP1fvL3yTIc6qwxqBsqvit4z9WXnAdMRwB5Bvn31dTuaBokQEVZa3t0VfMnyhGvuw=="],
|
||||
|
||||
"@lukeed/csprng": ["@lukeed/csprng@1.1.0", "", {}, "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA=="],
|
||||
|
||||
"@lukeed/uuid": ["@lukeed/uuid@2.0.1", "", { "dependencies": { "@lukeed/csprng": "^1.1.0" } }, "sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w=="],
|
||||
|
|
@ -3877,8 +3870,6 @@
|
|||
|
||||
"multimatch": ["multimatch@6.0.0", "", { "dependencies": { "@types/minimatch": "^3.0.5", "array-differ": "^4.0.0", "array-union": "^3.0.1", "minimatch": "^3.0.4" } }, "sha512-I7tSVxHGPlmPN/enE3mS1aOSo6bWBfls+3HmuEeCUBCE7gWnm3cBXCBkpurzFjVRwC6Kld8lLaZ1Iv5vOcjvcQ=="],
|
||||
|
||||
"mutative": ["mutative@1.3.0", "", {}, "sha512-8MJj6URmOZAV70dpFe1YnSppRTKC4DsMkXQiBDFayLcDI4ljGokHxmpqaBQuDWa4iAxWaJJ1PS8vAmbntjjKmQ=="],
|
||||
|
||||
"mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="],
|
||||
|
||||
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
|
||||
|
|
@ -5241,8 +5232,6 @@
|
|||
|
||||
"@inquirer/core/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="],
|
||||
|
||||
"@instantdb/core/uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
|
||||
|
||||
"@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
||||
|
||||
"@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue