'use client' /** * Shared block: framework picker, tracking script snippet with copy, and integration guide links. * Used on welcome (step 5), /sites/new (step 2), and site settings. */ import { useState, useCallback } from 'react' import Link from 'next/link' import { API_URL, APP_URL } from '@/lib/api/client' import { integrations, getIntegration } from '@/lib/integrations' import { toast } from '@ciphera-net/ui' import { CheckIcon } from '@ciphera-net/ui' const POPULAR_INTEGRATIONS = integrations.filter((i) => i.category === 'framework').slice(0, 10) export interface ScriptSetupBlockSite { domain: string name?: string } interface ScriptSetupBlockProps { /** Site domain (and optional name for display). */ site: ScriptSetupBlockSite /** Called when user copies the script (e.g. for analytics). */ onScriptCopy?: () => void /** Show framework picker and "View all integrations" / "See full guide" links. Default true. */ showFrameworkPicker?: boolean /** Optional class for the root wrapper. */ className?: string } export default function ScriptSetupBlock({ site, onScriptCopy, showFrameworkPicker = true, className = '', }: ScriptSetupBlockProps) { const [selectedIntegrationSlug, setSelectedIntegrationSlug] = useState(null) const [scriptCopied, setScriptCopied] = useState(false) const copyScript = useCallback(() => { const script = `` navigator.clipboard.writeText(script) setScriptCopied(true) toast.success('Script copied to clipboard') onScriptCopy?.() setTimeout(() => setScriptCopied(false), 2000) }, [site.domain, onScriptCopy]) return (
{showFrameworkPicker && ( <>

Add the script to your site

Choose your framework for setup instructions.

{POPULAR_INTEGRATIONS.map((int) => ( ))}

View all integrations →

)}
{``}

Default: cross-tab (localStorage). Optional: data-storage="session" to opt out (per-tab, ephemeral). Optional: data-storage-ttl="48" to set expiry in hours (default: 24).

Optional: add {``} for rage click and dead click detection.

{showFrameworkPicker && selectedIntegrationSlug && getIntegration(selectedIntegrationSlug) && (

See full {getIntegration(selectedIntegrationSlug)!.name} guide →

)}
) }