feat: add interactive tutorial slideshows for Agents and MCP
- Add /docs/tutorials page with tutorial index - Create step-by-step Agents tutorial (7 slides) - API key setup - Agent creation - Tool attachment - Chat interface usage - Create step-by-step MCP tutorial (8 slides) - What is MCP - Creating collections - Configuring Claude Desktop - Configuring Cursor - Using tools Each tutorial features: - Progress bar and slide indicators - Previous/Next navigation - Direct links to relevant dashboard pages
This commit is contained in:
parent
0b1bb7725d
commit
bfed830187
3 changed files with 1141 additions and 0 deletions
478
apps/web/src/app/docs/tutorials/agents/page.tsx
Normal file
478
apps/web/src/app/docs/tutorials/agents/page.tsx
Normal file
|
|
@ -0,0 +1,478 @@
|
|||
'use client';
|
||||
|
||||
import { Button } from '@tpmjs/ui/Button/Button';
|
||||
import { Icon } from '@tpmjs/ui/Icon/Icon';
|
||||
import Link from 'next/link';
|
||||
import { useState } from 'react';
|
||||
import { AppFooter } from '~/components/AppFooter';
|
||||
import { AppHeader } from '~/components/AppHeader';
|
||||
|
||||
interface Slide {
|
||||
id: string;
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
content: React.ReactNode;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
const slides: Slide[] = [
|
||||
{
|
||||
id: 'intro',
|
||||
title: 'Build Your First AI Agent',
|
||||
subtitle: 'A step-by-step guide to creating custom AI assistants with TPMJS',
|
||||
icon: '🤖',
|
||||
content: (
|
||||
<div className="text-center space-y-6">
|
||||
<p className="text-xl text-foreground-secondary max-w-2xl mx-auto">
|
||||
AI Agents are custom assistants that can use tools from TPMJS to accomplish tasks. In just
|
||||
5 steps, you'll have your own agent up and running.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-4 mt-8">
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary rounded-full">
|
||||
<span>🔑</span>
|
||||
<span className="text-sm">Add API Key</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary rounded-full">
|
||||
<span>✨</span>
|
||||
<span className="text-sm">Create Agent</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary rounded-full">
|
||||
<span>🔧</span>
|
||||
<span className="text-sm">Add Tools</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary rounded-full">
|
||||
<span>💬</span>
|
||||
<span className="text-sm">Start Chatting</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-1-api-key',
|
||||
title: 'Step 1: Get Your API Key',
|
||||
subtitle: 'You bring your own AI provider key',
|
||||
icon: '🔑',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<p className="text-lg text-foreground-secondary text-center max-w-2xl mx-auto">
|
||||
TPMJS supports multiple AI providers. Get an API key from any of these:
|
||||
</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 max-w-4xl mx-auto">
|
||||
{[
|
||||
{ name: 'OpenAI', url: 'platform.openai.com/api-keys', models: 'GPT-4o, GPT-4 Turbo' },
|
||||
{
|
||||
name: 'Anthropic',
|
||||
url: 'console.anthropic.com/settings/keys',
|
||||
models: 'Claude 3.5 Sonnet',
|
||||
},
|
||||
{ name: 'Google', url: 'aistudio.google.com/apikey', models: 'Gemini 2.0 Flash' },
|
||||
{ name: 'Groq', url: 'console.groq.com/keys', models: 'Llama 3.3 70B' },
|
||||
{ name: 'Mistral', url: 'console.mistral.ai/api-keys', models: 'Mistral Large' },
|
||||
].map((provider) => (
|
||||
<div
|
||||
key={provider.name}
|
||||
className="p-4 bg-surface-secondary rounded-lg border border-border"
|
||||
>
|
||||
<h4 className="font-semibold text-foreground">{provider.name}</h4>
|
||||
<p className="text-sm text-foreground-tertiary mt-1">{provider.models}</p>
|
||||
<a
|
||||
href={`https://${provider.url}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-primary hover:underline mt-2 inline-block"
|
||||
>
|
||||
Get key →
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-foreground-secondary">
|
||||
💡 We recommend <strong>OpenAI</strong> or <strong>Anthropic</strong> for the best
|
||||
tool-calling support.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-2-add-key',
|
||||
title: 'Step 2: Add Your API Key to TPMJS',
|
||||
subtitle: 'Your key is encrypted and stored securely',
|
||||
icon: '🔐',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<div className="max-w-2xl mx-auto space-y-6">
|
||||
<div className="flex items-start gap-4 p-4 bg-surface-secondary rounded-lg">
|
||||
<div className="w-8 h-8 bg-primary/20 rounded-full flex items-center justify-center text-primary font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-foreground font-medium">Go to Settings</p>
|
||||
<p className="text-foreground-secondary text-sm">
|
||||
Navigate to{' '}
|
||||
<span className="font-mono bg-background px-2 py-0.5 rounded">
|
||||
Dashboard → Settings → API Keys
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-4 p-4 bg-surface-secondary rounded-lg">
|
||||
<div className="w-8 h-8 bg-primary/20 rounded-full flex items-center justify-center text-primary font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-foreground font-medium">Click "Add Key" for your provider</p>
|
||||
<p className="text-foreground-secondary text-sm">
|
||||
Each provider card has an "Add Key" button
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-4 p-4 bg-surface-secondary rounded-lg">
|
||||
<div className="w-8 h-8 bg-primary/20 rounded-full flex items-center justify-center text-primary font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-foreground font-medium">Paste your API key and save</p>
|
||||
<p className="text-foreground-secondary text-sm">
|
||||
Your key is encrypted with AES-256 before storage
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Link href="/dashboard/settings/api-keys">
|
||||
<Button variant="default">Go to API Keys Settings →</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-3-create-agent',
|
||||
title: 'Step 3: Create Your Agent',
|
||||
subtitle: 'Configure your AI assistant',
|
||||
icon: '✨',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<div className="max-w-3xl mx-auto grid md:grid-cols-2 gap-6">
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-lg font-semibold text-foreground">Basic Info</h4>
|
||||
<div className="space-y-3">
|
||||
<div className="p-3 bg-surface-secondary rounded-lg">
|
||||
<p className="text-sm font-medium text-foreground">Name</p>
|
||||
<p className="text-sm text-foreground-tertiary">
|
||||
e.g., "Code Helper", "Data Analyst"
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-3 bg-surface-secondary rounded-lg">
|
||||
<p className="text-sm font-medium text-foreground">Description</p>
|
||||
<p className="text-sm text-foreground-tertiary">What does your agent do?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-lg font-semibold text-foreground">Model Settings</h4>
|
||||
<div className="space-y-3">
|
||||
<div className="p-3 bg-surface-secondary rounded-lg">
|
||||
<p className="text-sm font-medium text-foreground">Provider & Model</p>
|
||||
<p className="text-sm text-foreground-tertiary">
|
||||
Choose from your configured providers
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-3 bg-surface-secondary rounded-lg">
|
||||
<p className="text-sm font-medium text-foreground">System Prompt</p>
|
||||
<p className="text-sm text-foreground-tertiary">
|
||||
Define your agent's personality & capabilities
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto p-4 bg-primary/5 border border-primary/20 rounded-lg">
|
||||
<p className="text-sm text-foreground">
|
||||
<strong>💡 Tip:</strong> Start with the default settings (temperature 0.7) and adjust
|
||||
based on results. Lower temperature = more focused, higher = more creative.
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Link href="/dashboard/agents">
|
||||
<Button variant="default">Create an Agent →</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-4-add-tools',
|
||||
title: 'Step 4: Add Tools to Your Agent',
|
||||
subtitle: 'Give your agent superpowers',
|
||||
icon: '🔧',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<p className="text-lg text-foreground-secondary text-center max-w-2xl mx-auto">
|
||||
Tools let your agent take actions: run code, search the web, fetch data, and more.
|
||||
</p>
|
||||
<div className="max-w-3xl mx-auto grid md:grid-cols-2 gap-6">
|
||||
<div className="p-6 bg-surface-secondary rounded-lg border border-border">
|
||||
<h4 className="text-lg font-semibold text-foreground mb-3">📦 Individual Tools</h4>
|
||||
<p className="text-foreground-secondary text-sm mb-4">
|
||||
Add specific tools one at a time. Great for focused agents.
|
||||
</p>
|
||||
<ul className="space-y-2 text-sm text-foreground-secondary">
|
||||
<li className="flex items-center gap-2">
|
||||
<span className="text-green-500">✓</span>
|
||||
<span>Execute JavaScript/Python</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<span className="text-green-500">✓</span>
|
||||
<span>Fetch web pages</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<span className="text-green-500">✓</span>
|
||||
<span>Web search</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="p-6 bg-surface-secondary rounded-lg border border-border">
|
||||
<h4 className="text-lg font-semibold text-foreground mb-3">📚 Tool Collections</h4>
|
||||
<p className="text-foreground-secondary text-sm mb-4">
|
||||
Add entire collections of related tools at once.
|
||||
</p>
|
||||
<ul className="space-y-2 text-sm text-foreground-secondary">
|
||||
<li className="flex items-center gap-2">
|
||||
<span className="text-green-500">✓</span>
|
||||
<span>Pre-curated tool sets</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<span className="text-green-500">✓</span>
|
||||
<span>One-click to add many tools</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<span className="text-green-500">✓</span>
|
||||
<span>Community collections</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Link href="/tools">
|
||||
<Button variant="secondary">Browse Available Tools →</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-5-chat',
|
||||
title: 'Step 5: Start Chatting!',
|
||||
subtitle: 'Your agent is ready to help',
|
||||
icon: '💬',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<p className="text-lg text-foreground-secondary text-center max-w-2xl mx-auto">
|
||||
Click the "Chat" button on your agent to start a conversation. Your agent will use its
|
||||
tools to help you.
|
||||
</p>
|
||||
<div className="max-w-2xl mx-auto bg-surface-secondary rounded-lg border border-border overflow-hidden">
|
||||
<div className="p-4 bg-background border-b border-border">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 bg-primary/20 rounded-lg flex items-center justify-center">
|
||||
<span className="text-sm">🤖</span>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-foreground">Code Helper</p>
|
||||
<p className="text-xs text-foreground-tertiary">OpenAI • GPT-4o</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-4 space-y-4">
|
||||
<div className="flex justify-end">
|
||||
<div className="bg-primary text-primary-foreground rounded-lg px-4 py-2 max-w-[80%]">
|
||||
<p className="text-sm">
|
||||
Can you run this JavaScript and tell me the result: [1,2,3].map(x => x * 2)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-start">
|
||||
<div className="bg-background rounded-lg px-4 py-2 max-w-[80%] border border-border">
|
||||
<p className="text-sm text-foreground-secondary mb-2">[Using: code-executor]</p>
|
||||
<p className="text-sm text-foreground">
|
||||
The result is <code className="bg-surface-secondary px-1 rounded">[2, 4, 6]</code>{' '}
|
||||
- each element was multiplied by 2.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto p-4 bg-green-500/10 border border-green-500/20 rounded-lg">
|
||||
<p className="text-sm text-foreground text-center">
|
||||
🎉 <strong>Conversations are automatically saved</strong> — pick up where you left off
|
||||
anytime!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'complete',
|
||||
title: "You're All Set!",
|
||||
subtitle: 'Start building amazing AI agents',
|
||||
icon: '🚀',
|
||||
content: (
|
||||
<div className="space-y-8 text-center">
|
||||
<p className="text-xl text-foreground-secondary max-w-2xl mx-auto">
|
||||
You now know everything you need to create powerful AI agents with TPMJS.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-4">
|
||||
<Link href="/dashboard/agents">
|
||||
<Button size="lg">Create Your First Agent</Button>
|
||||
</Link>
|
||||
<Link href="/docs/agents">
|
||||
<Button variant="secondary" size="lg">
|
||||
View Full Documentation
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto pt-8 border-t border-border mt-8">
|
||||
<h4 className="text-lg font-semibold text-foreground mb-4">What's Next?</h4>
|
||||
<div className="grid md:grid-cols-3 gap-4 text-left">
|
||||
<div className="p-4 bg-surface-secondary rounded-lg">
|
||||
<p className="font-medium text-foreground">Use the API</p>
|
||||
<p className="text-sm text-foreground-secondary">Integrate agents into your apps</p>
|
||||
</div>
|
||||
<div className="p-4 bg-surface-secondary rounded-lg">
|
||||
<p className="font-medium text-foreground">Create Collections</p>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
Curate tools for specific use cases
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-4 bg-surface-secondary rounded-lg">
|
||||
<p className="font-medium text-foreground">Publish Tools</p>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
Add your own tools to the registry
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export default function AgentsTutorialPage(): React.ReactElement {
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
|
||||
const goToSlide = (index: number) => {
|
||||
setCurrentSlide(Math.max(0, Math.min(slides.length - 1, index)));
|
||||
};
|
||||
|
||||
const nextSlide = () => goToSlide(currentSlide + 1);
|
||||
const prevSlide = () => goToSlide(currentSlide - 1);
|
||||
|
||||
const slide = slides[currentSlide];
|
||||
const progress = ((currentSlide + 1) / slides.length) * 100;
|
||||
|
||||
if (!slide) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background flex flex-col">
|
||||
<AppHeader />
|
||||
|
||||
{/* Progress bar */}
|
||||
<div className="w-full h-1 bg-surface-secondary">
|
||||
<div
|
||||
className="h-full bg-primary transition-all duration-300"
|
||||
style={{ width: `${progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<main className="flex-1 flex flex-col">
|
||||
{/* Navigation header */}
|
||||
<div className="border-b border-border">
|
||||
<div className="max-w-6xl mx-auto px-4 py-4 flex items-center justify-between">
|
||||
<Link
|
||||
href="/docs/tutorials"
|
||||
className="flex items-center gap-2 text-foreground-secondary hover:text-foreground transition-colors"
|
||||
>
|
||||
<Icon icon="arrowLeft" size="sm" />
|
||||
<span>Back to Tutorials</span>
|
||||
</Link>
|
||||
<div className="text-sm text-foreground-secondary">
|
||||
{currentSlide + 1} / {slides.length}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Slide content */}
|
||||
<div className="flex-1 flex items-center justify-center px-4 py-8">
|
||||
<div className="w-full max-w-5xl">
|
||||
{/* Slide header */}
|
||||
<div className="text-center mb-12">
|
||||
{slide.icon && <span className="text-6xl mb-4 block">{slide.icon}</span>}
|
||||
<h1 className="text-3xl md:text-4xl font-bold text-foreground mb-3">{slide.title}</h1>
|
||||
{slide.subtitle && (
|
||||
<p className="text-lg text-foreground-secondary">{slide.subtitle}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Slide content */}
|
||||
<div className="mb-12">{slide.content}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Navigation footer */}
|
||||
<div className="border-t border-border">
|
||||
<div className="max-w-6xl mx-auto px-4 py-4">
|
||||
{/* Slide indicators */}
|
||||
<div className="flex justify-center gap-2 mb-4">
|
||||
{slides.map((s, index) => (
|
||||
<button
|
||||
key={s.id}
|
||||
type="button"
|
||||
onClick={() => goToSlide(index)}
|
||||
className={`w-3 h-3 rounded-full transition-colors ${
|
||||
index === currentSlide
|
||||
? 'bg-primary'
|
||||
: index < currentSlide
|
||||
? 'bg-primary/40'
|
||||
: 'bg-surface-secondary'
|
||||
}`}
|
||||
aria-label={`Go to slide ${index + 1}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Navigation buttons */}
|
||||
<div className="flex items-center justify-between">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={prevSlide}
|
||||
disabled={currentSlide === 0}
|
||||
className="min-w-[120px]"
|
||||
>
|
||||
<Icon icon="arrowLeft" size="xs" className="mr-2" />
|
||||
Previous
|
||||
</Button>
|
||||
|
||||
{currentSlide === slides.length - 1 ? (
|
||||
<Link href="/dashboard/agents">
|
||||
<Button className="min-w-[120px]">Get Started →</Button>
|
||||
</Link>
|
||||
) : (
|
||||
<Button onClick={nextSlide} className="min-w-[120px]">
|
||||
Next →
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<AppFooter />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
536
apps/web/src/app/docs/tutorials/mcp/page.tsx
Normal file
536
apps/web/src/app/docs/tutorials/mcp/page.tsx
Normal file
|
|
@ -0,0 +1,536 @@
|
|||
'use client';
|
||||
|
||||
import { Button } from '@tpmjs/ui/Button/Button';
|
||||
import { Icon } from '@tpmjs/ui/Icon/Icon';
|
||||
import Link from 'next/link';
|
||||
import { useState } from 'react';
|
||||
import { AppFooter } from '~/components/AppFooter';
|
||||
import { AppHeader } from '~/components/AppHeader';
|
||||
|
||||
interface Slide {
|
||||
id: string;
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
content: React.ReactNode;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
const slides: Slide[] = [
|
||||
{
|
||||
id: 'intro',
|
||||
title: 'Connect TPMJS Tools to Your AI',
|
||||
subtitle: 'Use MCP to add powerful tools to Claude Desktop, Cursor, and more',
|
||||
icon: '🔌',
|
||||
content: (
|
||||
<div className="text-center space-y-6">
|
||||
<p className="text-xl text-foreground-secondary max-w-2xl mx-auto">
|
||||
The Model Context Protocol (MCP) lets AI assistants use external tools. TPMJS provides an
|
||||
MCP server that gives your AI access to our entire tool registry.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-4 mt-8">
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary rounded-full">
|
||||
<span>🎯</span>
|
||||
<span className="text-sm">Create Collection</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary rounded-full">
|
||||
<span>📋</span>
|
||||
<span className="text-sm">Copy MCP URL</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary rounded-full">
|
||||
<span>⚙️</span>
|
||||
<span className="text-sm">Add to Config</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary rounded-full">
|
||||
<span>✨</span>
|
||||
<span className="text-sm">Use Tools</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pt-6">
|
||||
<p className="text-sm text-foreground-tertiary">
|
||||
Works with: Claude Desktop • Cursor • Any MCP-compatible client
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'what-is-mcp',
|
||||
title: 'What is MCP?',
|
||||
subtitle: 'A simple way for AI assistants to use tools',
|
||||
icon: '📖',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<div className="max-w-3xl mx-auto grid md:grid-cols-2 gap-8">
|
||||
<div className="p-6 bg-surface-secondary rounded-lg border border-border">
|
||||
<h4 className="text-lg font-semibold text-foreground mb-3">Without MCP</h4>
|
||||
<ul className="space-y-3 text-foreground-secondary">
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-red-500 mt-0.5">✗</span>
|
||||
<span>AI can only process text</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-red-500 mt-0.5">✗</span>
|
||||
<span>No access to external data</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-red-500 mt-0.5">✗</span>
|
||||
<span>Can't take real actions</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-red-500 mt-0.5">✗</span>
|
||||
<span>Limited to knowledge cutoff</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="p-6 bg-primary/5 rounded-lg border border-primary/20">
|
||||
<h4 className="text-lg font-semibold text-foreground mb-3">With MCP + TPMJS</h4>
|
||||
<ul className="space-y-3 text-foreground-secondary">
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-green-500 mt-0.5">✓</span>
|
||||
<span>Execute code in 40+ languages</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-green-500 mt-0.5">✓</span>
|
||||
<span>Fetch data from any URL</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-green-500 mt-0.5">✓</span>
|
||||
<span>Search the web in real-time</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-green-500 mt-0.5">✓</span>
|
||||
<span>Use specialized tools</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-foreground-secondary">
|
||||
MCP is an <strong>open protocol</strong> by Anthropic for connecting AI to external
|
||||
capabilities.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-1-collection',
|
||||
title: 'Step 1: Create a Collection',
|
||||
subtitle: 'Group the tools you want to use',
|
||||
icon: '📦',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<p className="text-lg text-foreground-secondary text-center max-w-2xl mx-auto">
|
||||
Collections bundle related tools together. Create one with the tools you need.
|
||||
</p>
|
||||
<div className="max-w-2xl mx-auto space-y-6">
|
||||
<div className="flex items-start gap-4 p-4 bg-surface-secondary rounded-lg">
|
||||
<div className="w-8 h-8 bg-primary/20 rounded-full flex items-center justify-center text-primary font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-foreground font-medium">Go to Collections</p>
|
||||
<p className="text-foreground-secondary text-sm">
|
||||
Navigate to{' '}
|
||||
<span className="font-mono bg-background px-2 py-0.5 rounded">
|
||||
Dashboard → Collections
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-4 p-4 bg-surface-secondary rounded-lg">
|
||||
<div className="w-8 h-8 bg-primary/20 rounded-full flex items-center justify-center text-primary font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-foreground font-medium">Create New Collection</p>
|
||||
<p className="text-foreground-secondary text-sm">
|
||||
Give it a name like "My Development Tools" or "Research Assistant"
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-4 p-4 bg-surface-secondary rounded-lg">
|
||||
<div className="w-8 h-8 bg-primary/20 rounded-full flex items-center justify-center text-primary font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-foreground font-medium">Add Tools</p>
|
||||
<p className="text-foreground-secondary text-sm">
|
||||
Search for and add tools you want: code execution, web fetching, etc.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Link href="/dashboard/collections">
|
||||
<Button variant="default">Create a Collection →</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-2-mcp-url',
|
||||
title: 'Step 2: Get Your MCP URL',
|
||||
subtitle: 'Each collection has a unique MCP endpoint',
|
||||
icon: '🔗',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<p className="text-lg text-foreground-secondary text-center max-w-2xl mx-auto">
|
||||
Your collection page shows the MCP URL. Just copy it!
|
||||
</p>
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<div className="bg-surface-secondary rounded-lg border border-border overflow-hidden">
|
||||
<div className="p-4 border-b border-border bg-background">
|
||||
<p className="font-medium text-foreground">Collection: My Dev Tools</p>
|
||||
<p className="text-sm text-foreground-tertiary">5 tools</p>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<p className="text-sm font-medium text-foreground mb-2">MCP Server URL</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<code className="flex-1 px-3 py-2 bg-background rounded border border-border text-sm font-mono text-foreground-secondary overflow-x-auto">
|
||||
https://tpmjs.com/mcp/c/your-collection-uid
|
||||
</code>
|
||||
<Button variant="secondary" size="sm">
|
||||
<Icon icon="copy" size="xs" className="mr-1" />
|
||||
Copy
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto p-4 bg-primary/5 border border-primary/20 rounded-lg">
|
||||
<p className="text-sm text-foreground">
|
||||
<strong>💡 Tip:</strong> The URL format is{' '}
|
||||
<code className="bg-background px-1.5 py-0.5 rounded text-xs">
|
||||
tpmjs.com/mcp/c/{'{collection-uid}'}
|
||||
</code>
|
||||
— you can also find it on your collection's detail page.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-3-claude',
|
||||
title: 'Step 3: Configure Claude Desktop',
|
||||
subtitle: 'Add the MCP server to your config file',
|
||||
icon: '🖥️',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<p className="text-lg text-foreground-secondary text-center max-w-2xl mx-auto">
|
||||
Open your Claude Desktop config file and add the TPMJS MCP server.
|
||||
</p>
|
||||
<div className="max-w-3xl mx-auto space-y-4">
|
||||
<div className="p-3 bg-surface-secondary rounded-lg">
|
||||
<p className="text-sm font-medium text-foreground mb-1">Config File Location</p>
|
||||
<div className="space-y-1 text-sm text-foreground-secondary font-mono">
|
||||
<p>
|
||||
<span className="text-foreground-tertiary">macOS:</span> ~/Library/Application
|
||||
Support/Claude/claude_desktop_config.json
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-foreground-tertiary">Windows:</span>{' '}
|
||||
%APPDATA%\Claude\claude_desktop_config.json
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-background rounded-lg border border-border overflow-hidden">
|
||||
<div className="px-4 py-2 bg-surface-secondary border-b border-border">
|
||||
<p className="text-sm font-medium text-foreground">claude_desktop_config.json</p>
|
||||
</div>
|
||||
<pre className="p-4 text-sm overflow-x-auto">
|
||||
<code className="text-foreground-secondary">{`{
|
||||
"mcpServers": {
|
||||
"tpmjs-dev-tools": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"mcp-remote",
|
||||
"https://tpmjs.com/mcp/c/your-collection-uid"
|
||||
]
|
||||
}
|
||||
}
|
||||
}`}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-center space-y-2">
|
||||
<p className="text-foreground-secondary text-sm">
|
||||
Replace <code className="bg-surface-secondary px-1.5 rounded">your-collection-uid</code>{' '}
|
||||
with your actual collection UID
|
||||
</p>
|
||||
<p className="text-foreground-tertiary text-sm">
|
||||
💡 Restart Claude Desktop after saving the config
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-3-cursor',
|
||||
title: 'Alternative: Configure Cursor',
|
||||
subtitle: 'Same concept, slightly different config',
|
||||
icon: '✏️',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<p className="text-lg text-foreground-secondary text-center max-w-2xl mx-auto">
|
||||
Cursor also supports MCP! Add the server in Cursor settings.
|
||||
</p>
|
||||
<div className="max-w-3xl mx-auto space-y-4">
|
||||
<div className="p-3 bg-surface-secondary rounded-lg">
|
||||
<p className="text-sm font-medium text-foreground mb-1">Open Cursor Settings</p>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
<code className="bg-background px-1.5 py-0.5 rounded">
|
||||
Settings → Features → MCP Servers → + Add Server
|
||||
</code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-background rounded-lg border border-border overflow-hidden">
|
||||
<div className="px-4 py-2 bg-surface-secondary border-b border-border">
|
||||
<p className="text-sm font-medium text-foreground">mcp.json (or via Settings UI)</p>
|
||||
</div>
|
||||
<pre className="p-4 text-sm overflow-x-auto">
|
||||
<code className="text-foreground-secondary">{`{
|
||||
"mcpServers": {
|
||||
"tpmjs": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"mcp-remote",
|
||||
"https://tpmjs.com/mcp/c/your-collection-uid"
|
||||
]
|
||||
}
|
||||
}
|
||||
}`}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto p-4 bg-primary/5 border border-primary/20 rounded-lg">
|
||||
<p className="text-sm text-foreground">
|
||||
<strong>Any MCP client works!</strong> The URL format is the same regardless of which
|
||||
client you're using. Check your client's documentation for config file location.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'step-4-use-tools',
|
||||
title: 'Step 4: Use Your Tools!',
|
||||
subtitle: 'Ask Claude to use any tool in your collection',
|
||||
icon: '🎉',
|
||||
content: (
|
||||
<div className="space-y-8">
|
||||
<p className="text-lg text-foreground-secondary text-center max-w-2xl mx-auto">
|
||||
After restarting, Claude will have access to all the tools in your collection.
|
||||
</p>
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<div className="bg-surface-secondary rounded-lg border border-border overflow-hidden">
|
||||
<div className="p-4 border-b border-border bg-background">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 bg-orange-500/20 rounded-lg flex items-center justify-center">
|
||||
<span className="text-sm">🦊</span>
|
||||
</div>
|
||||
<p className="font-medium text-foreground">Claude Desktop</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-4 space-y-4">
|
||||
<div className="flex justify-end">
|
||||
<div className="bg-primary text-primary-foreground rounded-lg px-4 py-2 max-w-[80%]">
|
||||
<p className="text-sm">
|
||||
Run this Python code and show me the output: print("Hello from TPMJS!")
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-start">
|
||||
<div className="bg-background rounded-lg px-4 py-2 max-w-[80%] border border-border">
|
||||
<p className="text-xs text-primary mb-2">
|
||||
Using tool: unsandbox-executeCodeAsync
|
||||
</p>
|
||||
<p className="text-sm text-foreground">Here's the result:</p>
|
||||
<pre className="mt-2 p-2 bg-surface-secondary rounded text-xs font-mono">
|
||||
Hello from TPMJS!
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-center gap-3 text-sm text-foreground-secondary">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="text-green-500">✓</span> Code execution
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="text-green-500">✓</span> Web fetching
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="text-green-500">✓</span> Web search
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="text-green-500">✓</span> And more!
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'complete',
|
||||
title: "You're Connected!",
|
||||
subtitle: 'Your AI now has superpowers',
|
||||
icon: '🚀',
|
||||
content: (
|
||||
<div className="space-y-8 text-center">
|
||||
<p className="text-xl text-foreground-secondary max-w-2xl mx-auto">
|
||||
That's it! Your AI assistant can now use any tool in your TPMJS collection.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-4">
|
||||
<Link href="/dashboard/collections">
|
||||
<Button size="lg">Manage Collections</Button>
|
||||
</Link>
|
||||
<Link href="/docs">
|
||||
<Button variant="secondary" size="lg">
|
||||
View Full Documentation
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto pt-8 border-t border-border mt-8">
|
||||
<h4 className="text-lg font-semibold text-foreground mb-4">Quick Reference</h4>
|
||||
<div className="grid md:grid-cols-2 gap-4 text-left">
|
||||
<div className="p-4 bg-surface-secondary rounded-lg">
|
||||
<p className="font-medium text-foreground">Collection MCP URL</p>
|
||||
<code className="text-xs text-foreground-tertiary font-mono">
|
||||
tpmjs.com/mcp/c/{'{uid}'}
|
||||
</code>
|
||||
</div>
|
||||
<div className="p-4 bg-surface-secondary rounded-lg">
|
||||
<p className="font-medium text-foreground">Individual Tool MCP URL</p>
|
||||
<code className="text-xs text-foreground-tertiary font-mono">
|
||||
tpmjs.com/mcp/t/{'{tool-slug}'}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-foreground-tertiary mt-4">
|
||||
You can also use individual tools without creating a collection!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export default function McpTutorialPage(): React.ReactElement {
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
|
||||
const goToSlide = (index: number) => {
|
||||
setCurrentSlide(Math.max(0, Math.min(slides.length - 1, index)));
|
||||
};
|
||||
|
||||
const nextSlide = () => goToSlide(currentSlide + 1);
|
||||
const prevSlide = () => goToSlide(currentSlide - 1);
|
||||
|
||||
const slide = slides[currentSlide];
|
||||
const progress = ((currentSlide + 1) / slides.length) * 100;
|
||||
|
||||
if (!slide) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background flex flex-col">
|
||||
<AppHeader />
|
||||
|
||||
{/* Progress bar */}
|
||||
<div className="w-full h-1 bg-surface-secondary">
|
||||
<div
|
||||
className="h-full bg-primary transition-all duration-300"
|
||||
style={{ width: `${progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<main className="flex-1 flex flex-col">
|
||||
{/* Navigation header */}
|
||||
<div className="border-b border-border">
|
||||
<div className="max-w-6xl mx-auto px-4 py-4 flex items-center justify-between">
|
||||
<Link
|
||||
href="/docs/tutorials"
|
||||
className="flex items-center gap-2 text-foreground-secondary hover:text-foreground transition-colors"
|
||||
>
|
||||
<Icon icon="arrowLeft" size="sm" />
|
||||
<span>Back to Tutorials</span>
|
||||
</Link>
|
||||
<div className="text-sm text-foreground-secondary">
|
||||
{currentSlide + 1} / {slides.length}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Slide content */}
|
||||
<div className="flex-1 flex items-center justify-center px-4 py-8">
|
||||
<div className="w-full max-w-5xl">
|
||||
{/* Slide header */}
|
||||
<div className="text-center mb-12">
|
||||
{slide.icon && <span className="text-6xl mb-4 block">{slide.icon}</span>}
|
||||
<h1 className="text-3xl md:text-4xl font-bold text-foreground mb-3">{slide.title}</h1>
|
||||
{slide.subtitle && (
|
||||
<p className="text-lg text-foreground-secondary">{slide.subtitle}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Slide content */}
|
||||
<div className="mb-12">{slide.content}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Navigation footer */}
|
||||
<div className="border-t border-border">
|
||||
<div className="max-w-6xl mx-auto px-4 py-4">
|
||||
{/* Slide indicators */}
|
||||
<div className="flex justify-center gap-2 mb-4">
|
||||
{slides.map((s, index) => (
|
||||
<button
|
||||
key={s.id}
|
||||
type="button"
|
||||
onClick={() => goToSlide(index)}
|
||||
className={`w-3 h-3 rounded-full transition-colors ${
|
||||
index === currentSlide
|
||||
? 'bg-primary'
|
||||
: index < currentSlide
|
||||
? 'bg-primary/40'
|
||||
: 'bg-surface-secondary'
|
||||
}`}
|
||||
aria-label={`Go to slide ${index + 1}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Navigation buttons */}
|
||||
<div className="flex items-center justify-between">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={prevSlide}
|
||||
disabled={currentSlide === 0}
|
||||
className="min-w-[120px]"
|
||||
>
|
||||
<Icon icon="arrowLeft" size="xs" className="mr-2" />
|
||||
Previous
|
||||
</Button>
|
||||
|
||||
{currentSlide === slides.length - 1 ? (
|
||||
<Link href="/dashboard/collections">
|
||||
<Button className="min-w-[120px]">Get Started →</Button>
|
||||
</Link>
|
||||
) : (
|
||||
<Button onClick={nextSlide} className="min-w-[120px]">
|
||||
Next →
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<AppFooter />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
127
apps/web/src/app/docs/tutorials/page.tsx
Normal file
127
apps/web/src/app/docs/tutorials/page.tsx
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import { Icon } from '@tpmjs/ui/Icon/Icon';
|
||||
import Link from 'next/link';
|
||||
import { AppFooter } from '~/components/AppFooter';
|
||||
import { AppHeader } from '~/components/AppHeader';
|
||||
|
||||
interface Tutorial {
|
||||
title: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
href: string;
|
||||
duration: string;
|
||||
steps: number;
|
||||
}
|
||||
|
||||
const tutorials: Tutorial[] = [
|
||||
{
|
||||
title: 'Build Your First AI Agent',
|
||||
description:
|
||||
'Create a custom AI assistant with tool integration and persistent conversations. Learn how to set up API keys, configure agents, and attach tools.',
|
||||
icon: '🤖',
|
||||
href: '/docs/tutorials/agents',
|
||||
duration: '5 min',
|
||||
steps: 7,
|
||||
},
|
||||
{
|
||||
title: 'Connect MCP to Your AI',
|
||||
description:
|
||||
'Add TPMJS tools to Claude Desktop, Cursor, or any MCP-compatible client. Create collections and configure your AI to use external tools.',
|
||||
icon: '🔌',
|
||||
href: '/docs/tutorials/mcp',
|
||||
duration: '4 min',
|
||||
steps: 8,
|
||||
},
|
||||
];
|
||||
|
||||
export default function TutorialsPage(): React.ReactElement {
|
||||
return (
|
||||
<div className="min-h-screen bg-background flex flex-col">
|
||||
<AppHeader />
|
||||
|
||||
<main className="flex-1">
|
||||
<div className="max-w-4xl mx-auto px-4 py-12">
|
||||
{/* Header */}
|
||||
<div className="mb-12">
|
||||
<div className="flex items-center gap-4 mb-6">
|
||||
<Link
|
||||
href="/docs"
|
||||
className="text-foreground-secondary hover:text-foreground transition-colors"
|
||||
>
|
||||
<Icon icon="arrowLeft" size="sm" />
|
||||
</Link>
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-foreground">Tutorials</h1>
|
||||
<p className="text-foreground-secondary mt-1">
|
||||
Step-by-step guides to get you started with TPMJS
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tutorial Cards */}
|
||||
<div className="space-y-6">
|
||||
{tutorials.map((tutorial) => (
|
||||
<Link key={tutorial.href} href={tutorial.href} className="block group">
|
||||
<div className="p-6 bg-surface-secondary rounded-lg border border-border hover:border-primary/50 transition-all hover:shadow-lg">
|
||||
<div className="flex items-start gap-6">
|
||||
<div className="text-5xl">{tutorial.icon}</div>
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<h2 className="text-xl font-semibold text-foreground group-hover:text-primary transition-colors">
|
||||
{tutorial.title}
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-foreground-secondary mb-4">{tutorial.description}</p>
|
||||
<div className="flex items-center gap-4 text-sm text-foreground-tertiary">
|
||||
<span className="flex items-center gap-1">⏱️ {tutorial.duration}</span>
|
||||
<span className="flex items-center gap-1">📄 {tutorial.steps} steps</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center text-foreground-tertiary group-hover:text-primary transition-colors text-xl">
|
||||
→
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* More Resources */}
|
||||
<div className="mt-12 pt-8 border-t border-border">
|
||||
<h3 className="text-lg font-semibold text-foreground mb-4">More Resources</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<Link href="/docs">
|
||||
<div className="p-4 bg-background border border-border rounded-lg hover:border-primary/50 transition-colors">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-2xl">📚</span>
|
||||
<div>
|
||||
<p className="font-medium text-foreground">Full Documentation</p>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
Complete API reference and guides
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
<Link href="/docs/agents">
|
||||
<div className="p-4 bg-background border border-border rounded-lg hover:border-primary/50 transition-colors">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-2xl">🤖</span>
|
||||
<div>
|
||||
<p className="font-medium text-foreground">Agents Documentation</p>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
In-depth AI agents reference
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<AppFooter />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue