11'use client' ;
22
3- import { useMemo , useState } from 'react' ;
3+ import { useCallback , useMemo , useState } from 'react' ;
44import { usePathname , useRouter , useSearchParams } from 'next/navigation' ;
55import { motion } from 'motion/react' ;
6- import { HandPointingIcon } from '@phosphor-icons/react' ;
6+ import { CheckIcon , CopyIcon , HandPointingIcon } from '@phosphor-icons/react' ;
77import { APP_CONFIG_DEFAULTS } from '@/app-config' ;
88import { THEME_STORAGE_KEY } from '@/lib/env' ;
99import type { ThemeMode } from '@/lib/types' ;
1010import { cn } from '@/lib/utils' ;
1111import EmbedPopupAgentClient from './embed-popup/agent-client' ;
1212import { ThemeToggle } from './theme-toggle' ;
13+ import { Button } from './ui/button' ;
1314
1415export default function Welcome ( ) {
1516 const router = useRouter ( ) ;
@@ -20,17 +21,35 @@ export default function Welcome() {
2021 const [ , forceUpdate ] = useState ( 0 ) ;
2122 const theme = ( localStorage . getItem ( THEME_STORAGE_KEY ) as ThemeMode ) ?? 'dark' ;
2223
23- const embedUrl = useMemo ( ( ) => {
24+ const [ copied , setCopied ] = useState ( false ) ;
25+ const copyEmbedCode = useCallback ( ( embedCode : string ) => {
26+ navigator . clipboard . writeText ( embedCode ) ;
27+
28+ setCopied ( true ) ;
29+ setTimeout ( ( ) => {
30+ setCopied ( false ) ;
31+ } , 1000 ) ;
32+ } , [ ] ) ;
33+
34+ const iframeEmbedUrl = useMemo ( ( ) => {
2435 const url = new URL ( '/embed' , window . location . origin ) ;
2536 url . searchParams . set ( 'theme' , theme ) ;
2637 return url . toString ( ) ;
2738 } , [ theme ] ) ;
2839
29- const embedPopupUrl = useMemo ( ( ) => {
40+ const popupEmbedUrl = useMemo ( ( ) => {
3041 const url = new URL ( '/embed-popup.js' , window . location . origin ) ;
3142 return url . toString ( ) ;
3243 } , [ ] ) ;
3344
45+ const popupEmbedCode = useMemo (
46+ ( ) => `<script\n src="${ popupEmbedUrl } "\n></script>` ,
47+ [ popupEmbedUrl ]
48+ ) ;
49+ const iframeEmbedCode = useMemo ( ( ) => {
50+ return `<iframe\n src="${ iframeEmbedUrl } "\n style="width: 320px; height: 64px;"\n></iframe>` ;
51+ } , [ iframeEmbedUrl ] ) ;
52+
3453 const popupTestUrl = useMemo ( ( ) => {
3554 const url = new URL ( '/popup' , window . location . origin ) ;
3655 return url . toString ( ) ;
@@ -102,24 +121,38 @@ export default function Welcome() {
102121 < h3 className = "sr-only text-lg font-semibold" > IFrame Style</ h3 >
103122 < div >
104123 < h4 className = "text-fg0 mb-1 font-semibold" > Embed code</ h4 >
105- < pre className = "border-separator2 bg-bg2 overflow-auto rounded-md border px-2 py-1" >
124+ < pre className = "border-separator2 bg-bg2 relative overflow-auto rounded-md border px-2 py-1" >
106125 < code className = "font-mono" >
107- { `<iframe\n src="` }
108- < a
109- href = { embedUrl }
110- target = "_blank"
111- rel = "noopener noreferrer"
112- className = "text-primary underline"
113- >
114- { embedUrl }
115- </ a >
116- { `"\n style="width: 320px; height: 64px;"\n></iframe>` }
126+ { iframeEmbedCode . split ( iframeEmbedUrl ) . map ( ( stringPart , index ) => {
127+ if ( index === 0 ) {
128+ return < span key = { index } > { stringPart } </ span > ;
129+ }
130+
131+ return (
132+ < span key = { index } >
133+ < a
134+ href = { iframeEmbedUrl }
135+ target = "_blank"
136+ rel = "noopener noreferrer"
137+ className = "text-primary underline"
138+ >
139+ { iframeEmbedUrl }
140+ </ a >
141+ { stringPart }
142+ </ span >
143+ ) ;
144+ } ) }
117145 </ code >
146+ < div className = "absolute top-0 right-0" >
147+ < Button onClick = { ( ) => copyEmbedCode ( iframeEmbedCode ) } >
148+ { copied ? < CheckIcon className = "text-fgSuccess" /> : < CopyIcon /> }
149+ </ Button >
150+ </ div >
118151 </ pre >
119152 </ div >
120153 < div className = "flex justify-center" >
121154 < iframe
122- src = { embedUrl }
155+ src = { iframeEmbedUrl }
123156 style = { { width : 320 , height : 64 } }
124157 className = "opacity-100 transition-opacity duration-500 [@starting-style]:opacity-0"
125158 />
@@ -132,8 +165,13 @@ export default function Welcome() {
132165 < h3 className = "sr-only text-lg font-semibold" > Popup Style</ h3 >
133166 < div >
134167 < h4 className = "text-fg0 mb-1 font-semibold" > Embed code</ h4 >
135- < pre className = "border-separator2 bg-bg2 overflow-auto rounded-md border px-2 py-1" >
136- < code className = "font-mono" > { `<script src="${ embedPopupUrl } "></script>` } </ code >
168+ < pre className = "border-separator2 bg-bg2 relative overflow-auto rounded-md border px-2 py-1" >
169+ < code className = "font-mono" > { popupEmbedCode } </ code >
170+ < div className = "absolute top-0 right-0" >
171+ < Button onClick = { ( ) => copyEmbedCode ( popupEmbedCode ) } >
172+ { copied ? < CheckIcon className = "text-fgSuccess" /> : < CopyIcon /> }
173+ </ Button >
174+ </ div >
137175 </ pre >
138176 < p className = "text-fg4 my-4 text-sm" >
139177 To apply local changes, run{ ' ' }
0 commit comments