1import { useState } from "react";
2import { useAgentPrompt } from "./agentPrompt";
3
4export default function HeroCta() {
5 return (
6 <>
7 <div className="hero-cta hero-cta--cards">
8 <a
9 className="hero-cta__card hero-cta__card--human"
10 href="/getting-started"
11 >
12 <span className="hero-cta__eyebrow">For humans</span>
13 <span className="hero-cta__title">
14 Get started <span aria-hidden>→</span>
15 </span>
16 </a>
17 <CopyCard />
18 </div>
19 <div className="hero-cta hero-cta--simple">
20 <div className="hero-cta__buttons">
21 <a className="alc-btn alc-btn--primary" href="/getting-started">
22 Get started <span aria-hidden>→</span>
23 </a>
24 <a
25 className="alc-btn alc-btn--secondary"
26 href="/cloudflare/tutorial/part-1"
27 >
28 Tutorial
29 </a>
30 </div>
31 <div className="hero-cta__line" data-nosnippet="">
32 <span>
33 <span aria-hidden>🤖</span> Using a coding agent?
34 </span>
35 <InlineCopyChip />
36 </div>
37 </div>
38 </>
39 );
40}
41
42function InlineCopyChip() {
43 const [copied, setCopied] = useState(false);
44 const PROMPT = useAgentPrompt();
45 const onCopy = () => copy(PROMPT, setCopied);
46 return (
47 <button
48 type="button"
49 className="hero-cta__chip"
50 onClick={onCopy}
51 aria-label={copied ? "Copied" : "Copy prompt"}
52 >
53 {copied ? <CheckIcon /> : <CopyIcon />}
54 <span>{copied ? "Copied" : "Copy prompt"}</span>
55 </button>
56 );
57}
58
59function CopyCard() {
60 const [copied, setCopied] = useState(false);
61 const PROMPT = useAgentPrompt();
62 const onCopy = () => copy(PROMPT, setCopied);
63 return (
64 <button
65 type="button"
66 className="hero-cta__card hero-cta__card--agent"
67 onClick={onCopy}
68 aria-label={
69 copied ? "Copied prompt" : "Copy prompt for your coding agent"
70 }
71 >
72 <span className="hero-cta__eyebrow">
73 For coding agents
74 <span className="hero-cta__icon" aria-hidden>
75 {copied ? <CheckIcon /> : <CopyIcon />}
76 </span>
77 </span>
78 <code className="hero-cta__prompt-code" data-nosnippet="">
79 {PROMPT}
80 </code>
81 </button>
82 );
83}
84
85function copy(text: string, setCopied: (b: boolean) => void) {
86 const finish = () => {
87 setCopied(true);
88 window.setTimeout(() => setCopied(false), 1600);
89 };
90 if (navigator.clipboard?.writeText) {
91 navigator.clipboard.writeText(text).then(finish, finish);
92 return;
93 }
94 const ta = document.createElement("textarea");
95 ta.value = text;
96 ta.style.position = "fixed";
97 ta.style.opacity = "0";
98 document.body.appendChild(ta);
99 ta.select();
100 try {
101 document.execCommand("copy");
102 } finally {
103 document.body.removeChild(ta);
104 }
105 finish();
106}
107
108function CopyIcon() {
109 return (
110 <svg
111 aria-hidden
112 width="13"
113 height="13"
114 viewBox="0 0 24 24"
115 fill="none"
116 stroke="currentColor"
117 strokeWidth="2"
118 strokeLinecap="round"
119 strokeLinejoin="round"
120 >
121 <rect x="9" y="9" width="13" height="13" rx="2" />
122 <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
123 </svg>
124 );
125}
126
127function CheckIcon() {
128 return (
129 <svg
130 aria-hidden
131 width="13"
132 height="13"
133 viewBox="0 0 24 24"
134 fill="none"
135 stroke="currentColor"
136 strokeWidth="2.25"
137 strokeLinecap="round"
138 strokeLinejoin="round"
139 >
140 <path d="M20 6 9 17l-5-5" />
141 </svg>
142 );
143}