'use client' import { useMemo, useState } from 'react' import { Copy, Check, Download, FileText, Hash } from 'lucide-react' import type { GeneratorData } from '@/types' interface PreviewProps { data: GeneratorData } /** * Generate llms.txt content from generator data */ function generateLlmsTxt(data: GeneratorData): string { const lines: string[] = [] // Title lines.push(`# ${data.siteName}`) lines.push('') // Description if (data.description) { lines.push(`> ${data.description}`) lines.push('') } // Source URL comment if (data.url) { lines.push(``) lines.push('') } // Sections for (const section of data.sections) { if (section.title.trim() || section.content.trim()) { lines.push(`## ${section.title || 'Untitled Section'}`) lines.push('') lines.push(section.content || '') lines.push('') } } return lines.join('\n').trim() } /** * Estimate token count (roughly 4 chars per token) */ function estimateTokens(text: string): number { return Math.ceil(text.length / 4) } export default function Preview({ data }: PreviewProps) { const [copied, setCopied] = useState(false) const content = useMemo(() => generateLlmsTxt(data), [data]) const tokens = useMemo(() => estimateTokens(content), [content]) const handleCopy = async () => { try { await navigator.clipboard.writeText(content) setCopied(true) setTimeout(() => setCopied(false), 2000) } catch (error) { console.error('Failed to copy:', error) } } const handleDownload = () => { const slug = data.siteName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'llms' const filename = `${slug}.txt` const blob = new Blob([content], { type: 'text/plain' }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = filename document.body.appendChild(a) a.click() document.body.removeChild(a) URL.revokeObjectURL(url) } return (
{content || '# Your site name will appear here\n\nAdd some sections to see the preview...'}
llms.txtexample.com/llms.txt)llms-full.txt