From c0e05c8923ced05f4f488b42e0d7ba895a15206f Mon Sep 17 00:00:00 2001 From: Sarina Li Date: Thu, 30 Oct 2025 20:02:56 -0400 Subject: [PATCH] robots + copy actions --- docs/package.json | 1 + docs/pnpm-lock.yaml | 12 +++ docs/src/app/(home)/[[...slug]]/page.tsx | 17 ++- docs/src/app/robots.ts | 13 +++ docs/src/components/doc-actions-menu.tsx | 126 +++++++++++++++++++++++ 5 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 docs/src/app/robots.ts create mode 100644 docs/src/components/doc-actions-menu.tsx diff --git a/docs/package.json b/docs/package.json index 232e4f47..2008d840 100644 --- a/docs/package.json +++ b/docs/package.json @@ -19,6 +19,7 @@ "posthog-js": "^1.276.0", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-icons": "^5.5.0", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-mdx": "^3.1.0", diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 21932097..aad925c4 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: react-dom: specifier: ^19.1.0 version: 19.1.0(react@19.1.0) + react-icons: + specifier: ^5.5.0 + version: 5.5.0(react@19.1.0) remark: specifier: ^15.0.1 version: 15.0.1 @@ -2054,6 +2057,11 @@ packages: peerDependencies: react: ^19.1.0 + react-icons@5.5.0: + resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} + peerDependencies: + react: '*' + react-medium-image-zoom@5.2.14: resolution: {integrity: sha512-nfTVYcAUnBzXQpPDcZL+cG/e6UceYUIG+zDcnemL7jtAqbJjVVkA85RgneGtJeni12dTyiRPZVM6Szkmwd/o8w==} peerDependencies: @@ -4622,6 +4630,10 @@ snapshots: react: 19.1.0 scheduler: 0.26.0 + react-icons@5.5.0(react@19.1.0): + dependencies: + react: 19.1.0 + react-medium-image-zoom@5.2.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: react: 19.1.0 diff --git a/docs/src/app/(home)/[[...slug]]/page.tsx b/docs/src/app/(home)/[[...slug]]/page.tsx index 8aa89620..60840ece 100644 --- a/docs/src/app/(home)/[[...slug]]/page.tsx +++ b/docs/src/app/(home)/[[...slug]]/page.tsx @@ -10,6 +10,7 @@ import type { Metadata } from 'next'; import Link from 'next/link'; import { notFound, redirect } from 'next/navigation'; import { PageFeedback } from '@/components/page-feedback'; +import { DocActionsMenu } from '@/components/doc-actions-menu'; export default async function Page(props: { params: Promise<{ slug?: string[] }> }) { const params = await props.params; @@ -177,14 +178,26 @@ export default async function Page(props: { params: Promise<{ slug?: string[] }> ); }; + const tocFooter = () => { + return ( +
+ +
+ ); + }; + return ( - +
{page.data.title} -
+
{apiSection && versionItems.length > 1 && ( { + try { + const githubRawUrl = `https://raw.githubusercontent.com/trycua/cua/refs/heads/main/docs/content/docs/${filePath}`; + + const response = await fetch(githubRawUrl); + if (!response.ok) { + throw new Error('Failed to fetch markdown'); + } + const markdown = await response.text(); + + await navigator.clipboard.writeText(markdown); + + setCopied(true); + setTimeout(() => setCopied(false), 2000); + + posthog.capture('docs_copy_markdown_clicked', { + page: pageUrl, + page_title: pageTitle, + success: true, + }); + } catch (error) { + console.error('Error copying markdown:', error); + + try { + const urlWithUtm = `https://cua.ai${pageUrl}?utm_source=cua.ai/docs`; + await navigator.clipboard.writeText(urlWithUtm); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (fallbackError) { + console.error('Error copying URL:', fallbackError); + } + + posthog.capture('docs_copy_markdown_clicked', { + page: pageUrl, + page_title: pageTitle, + success: false, + error: error instanceof Error ? error.message : 'Unknown error', + }); + } + }; + + const handleEditGithub = () => { + posthog.capture('docs_edit_github_clicked', { + page: pageUrl, + page_title: pageTitle, + }); + + const githubEditUrl = `https://github.com/trycua/cua/edit/main/docs/content/docs/${filePath}`; + window.open(githubEditUrl, '_blank', 'noopener,noreferrer'); + }; + + const handleOpenChatGPT = () => { + posthog.capture('docs_open_chatgpt_clicked', { + page: pageUrl, + page_title: pageTitle, + }); + + const docUrl = `https://cua.ai${pageUrl}?utm_source=cua.ai/docs`; + const prompt = `I need help understanding this cua.ai documentation page: "${pageTitle}". Please read and help me with: ${docUrl}`; + const chatgptUrl = `https://chatgpt.com/?q=${encodeURIComponent(prompt)}`; + window.open(chatgptUrl, '_blank', 'noopener,noreferrer'); + }; + + const handleOpenClaude = () => { + posthog.capture('docs_open_claude_clicked', { + page: pageUrl, + page_title: pageTitle, + }); + + const docUrl = `https://cua.ai${pageUrl}?utm_source=cua.ai/docs`; + const prompt = `I need help understanding this cua.ai documentation page: "${pageTitle}". Please read and help me with: ${docUrl}`; + const claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(prompt)}`; + window.open(claudeUrl, '_blank', 'noopener,noreferrer'); + }; + + return ( +
+ + + + + + + +
+ ); +}