forked from CopilotKit/CopilotKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathops-platform-cta.tsx
More file actions
172 lines (160 loc) · 6.19 KB
/
Copy pathops-platform-cta.tsx
File metadata and controls
172 lines (160 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
"use client";
import { ArrowRight, Info, Sparkles } from "lucide-react";
import posthog from "posthog-js";
import { useCallback } from "react";
const DEFAULT_SIGNUP_URL = "https://dashboard.operations.copilotkit.ai/";
const SIGNUP_URL =
process.env.NEXT_PUBLIC_INTELLIGENCE_SIGNUP_URL || DEFAULT_SIGNUP_URL;
export type OpsPlatformCTAVariant = "tile" | "inline" | "card" | "info";
export interface OpsPlatformCTAProps {
/** Visual style: tile = full-width hero, inline = mid-page callout, card = footer */
variant?: OpsPlatformCTAVariant;
/** Headline shown to the user */
title: string;
/** Body copy under the headline */
body?: string;
/** Stable identifier for analytics, e.g. "docs:langgraph/quickstart:whats-next" */
surface: string;
/** Optional override for the link label. Defaults to "Get Intelligence free" */
ctaLabel?: string;
/** Optional className override for the outermost element */
className?: string;
}
function buildHref(surface: string): string {
const url = new URL(SIGNUP_URL);
url.searchParams.set("utm_source", "docs");
url.searchParams.set("utm_medium", "cta");
url.searchParams.set("utm_campaign", "intelligence");
url.searchParams.set("utm_content", surface);
return url.toString();
}
export function OpsPlatformCTA({
variant = "card",
title,
body,
surface,
ctaLabel = "Get Intelligence free",
className,
}: OpsPlatformCTAProps) {
const handleClick = useCallback(() => {
try {
posthog.capture("try_for_free_clicked", { location: surface });
} catch {
// PostHog may be blocked by ad blockers — never let analytics block navigation.
}
}, [surface]);
const href = buildHref(surface);
if (variant === "info") {
return (
<div
className={`not-prose my-6 flex gap-3 rounded-lg border border-blue-200 dark:border-blue-900 bg-blue-50/60 dark:bg-blue-950/30 p-4 ${className ?? ""}`}
>
<Info className="h-5 w-5 text-blue-600 dark:text-blue-300 mt-0.5 flex-shrink-0" />
<div className="min-w-0 flex-1">
<div className="font-semibold text-foreground">{title}</div>
{body ? (
<div className="text-sm text-muted-foreground leading-relaxed mt-1">
{body}
</div>
) : null}
<a
href={href}
target="_blank"
rel="noreferrer"
onClick={handleClick}
className="inline-flex items-center gap-1 mt-2 text-sm font-medium text-blue-700 dark:text-blue-300 hover:text-blue-800 dark:hover:text-blue-200 no-underline"
data-cta-surface={surface}
data-cta-variant={variant}
>
{ctaLabel}
<ArrowRight className="h-3.5 w-3.5" />
</a>
</div>
</div>
);
}
if (variant === "inline") {
return (
<div
className={`not-prose my-6 flex flex-col gap-3 rounded-lg border border-indigo-200 dark:border-indigo-900 bg-gradient-to-r from-indigo-50 to-purple-50 dark:from-indigo-950/40 dark:to-purple-950/40 p-4 sm:flex-row sm:items-center sm:justify-between ${className ?? ""}`}
>
<div className="flex items-start gap-3">
<Sparkles className="h-5 w-5 text-indigo-600 dark:text-indigo-300 mt-0.5 flex-shrink-0" />
<div>
<div className="font-semibold text-foreground">{title}</div>
{body ? (
<div className="text-sm text-muted-foreground leading-relaxed mt-0.5">
{body}
</div>
) : null}
</div>
</div>
<a
href={href}
target="_blank"
rel="noreferrer"
onClick={handleClick}
className="inline-flex items-center gap-1.5 whitespace-nowrap rounded-md bg-indigo-600 hover:bg-indigo-700 text-white text-sm font-medium px-4 py-2 no-underline transition-colors"
data-cta-surface={surface}
data-cta-variant={variant}
>
{ctaLabel}
<ArrowRight className="h-4 w-4" />
</a>
</div>
);
}
if (variant === "tile") {
return (
<a
href={href}
target="_blank"
rel="noreferrer"
onClick={handleClick}
data-cta-surface={surface}
data-cta-variant={variant}
className={`not-prose group flex items-start gap-3 rounded-lg border border-indigo-200 dark:border-indigo-900 bg-gradient-to-br from-indigo-50 to-purple-50 dark:from-indigo-950/40 dark:to-purple-950/40 p-4 no-underline shadow-sm hover:border-indigo-400 dark:hover:border-indigo-700 transition-colors ${className ?? ""}`}
>
<Sparkles className="h-5 w-5 text-indigo-600 dark:text-indigo-300 mt-0.5 flex-shrink-0" />
<div>
<div className="font-semibold text-foreground group-hover:text-indigo-700 dark:group-hover:text-indigo-200 mb-1">
{title}
</div>
{body ? (
<div className="text-sm text-muted-foreground leading-relaxed">
{body}
</div>
) : null}
</div>
</a>
);
}
// variant === "card" (default)
return (
<a
href={href}
target="_blank"
rel="noreferrer"
onClick={handleClick}
data-cta-surface={surface}
data-cta-variant={variant}
className={`not-prose my-8 flex items-center justify-between gap-4 rounded-lg border border-indigo-200 dark:border-indigo-900 bg-gradient-to-r from-indigo-50 to-purple-50 dark:from-indigo-950/40 dark:to-purple-950/40 p-5 no-underline shadow-sm hover:border-indigo-400 dark:hover:border-indigo-700 transition-colors ${className ?? ""}`}
>
<div className="flex items-start gap-3 min-w-0">
<Sparkles className="h-5 w-5 text-indigo-600 dark:text-indigo-300 mt-0.5 flex-shrink-0" />
<div className="min-w-0">
<div className="font-semibold text-foreground mb-1">{title}</div>
{body ? (
<div className="text-sm text-muted-foreground leading-relaxed">
{body}
</div>
) : null}
</div>
</div>
<span className="inline-flex items-center gap-1.5 whitespace-nowrap text-sm font-medium text-indigo-700 dark:text-indigo-200">
{ctaLabel}
<ArrowRight className="h-4 w-4" />
</span>
</a>
);
}