mirror of
https://github.com/trycua/computer.git
synced 2026-01-04 20:40:15 -06:00
Merge pull request #537 from sarinali/feat/llm-compatible-docs
Robots + Advanced Copy Options
This commit is contained in:
@@ -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",
|
||||
|
||||
12
docs/pnpm-lock.yaml
generated
12
docs/pnpm-lock.yaml
generated
@@ -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
|
||||
|
||||
@@ -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 (
|
||||
<div className="mt-4">
|
||||
<DocActionsMenu pageUrl={page.url} pageTitle={page.data.title} filePath={page.file.path} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<DocsPage toc={page.data.toc} tableOfContent={{ header: tocHeader() }} full={page.data.full}>
|
||||
<DocsPage
|
||||
toc={page.data.toc}
|
||||
tableOfContent={{ header: tocHeader(), footer: tocFooter() }}
|
||||
full={page.data.full}
|
||||
>
|
||||
<div className="flex flex-row w-full items-start">
|
||||
<div className="flex-1">
|
||||
<div className="flex flex-row w-full">
|
||||
<DocsTitle>{page.data.title}</DocsTitle>
|
||||
|
||||
<div className="ml-auto">
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
{apiSection && versionItems.length > 1 && (
|
||||
<Popover>
|
||||
<PopoverTrigger
|
||||
|
||||
13
docs/src/app/robots.ts
Normal file
13
docs/src/app/robots.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
return {
|
||||
rules: {
|
||||
userAgent: '*',
|
||||
allow: ['/', '/llms.txt'],
|
||||
disallow: [],
|
||||
},
|
||||
sitemap: 'https://cua.ai/docs/sitemap.xml',
|
||||
host: 'https://cua.ai',
|
||||
};
|
||||
}
|
||||
126
docs/src/components/doc-actions-menu.tsx
Normal file
126
docs/src/components/doc-actions-menu.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { SiOpenai, SiAnthropic, SiMarkdown, SiGithub } from 'react-icons/si';
|
||||
import posthog from 'posthog-js';
|
||||
|
||||
interface DocActionsMenuProps {
|
||||
pageUrl: string;
|
||||
pageTitle: string;
|
||||
filePath: string;
|
||||
}
|
||||
|
||||
export function DocActionsMenu({ pageUrl, pageTitle, filePath }: DocActionsMenuProps) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopyMarkdown = async () => {
|
||||
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 (
|
||||
<div className="flex flex-col gap-2">
|
||||
<button
|
||||
onClick={handleCopyMarkdown}
|
||||
className="inline-flex gap-3 w-full items-center rounded-md p-1 text-sm hover:bg-fd-accent hover:text-fd-accent-foreground text-left transition-colors px-2 hover:cursor-pointer"
|
||||
>
|
||||
<SiMarkdown className="w-2 h-4 flex-shrink-0" />
|
||||
<span>{copied ? 'Copied!' : 'Copy as markdown'}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={handleEditGithub}
|
||||
className="inline-flex gap-3 w-full items-center rounded-md p-1 text-sm hover:bg-fd-accent hover:text-fd-accent-foreground text-left transition-colors px-2 hover:cursor-pointer"
|
||||
>
|
||||
<SiGithub className="w-4 h-4 flex-shrink-0" />
|
||||
<span>Edit on GitHub</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={handleOpenChatGPT}
|
||||
className="inline-flex gap-3 w-full items-center rounded-md p-1 text-sm hover:bg-fd-accent hover:text-fd-accent-foreground text-left transition-colors px-2 hover:cursor-pointer"
|
||||
>
|
||||
<SiOpenai className="w-4 h-4 flex-shrink-0" />
|
||||
<span>Open in ChatGPT</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={handleOpenClaude}
|
||||
className="inline-flex gap-3 w-full items-center rounded-md p-1 text-sm hover:bg-fd-accent hover:text-fd-accent-foreground text-left transition-colors px-2 hover:cursor-pointer"
|
||||
>
|
||||
<SiAnthropic className="w-4 h-4 flex-shrink-0" />
|
||||
<span>Open in Claude</span>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user