Spaces:
Configuration error
Configuration error
| "use client" | |
| import { useState } from "react" | |
| import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card" | |
| import { Button } from "@/components/ui/button" | |
| import { Badge } from "@/components/ui/badge" | |
| import { Label } from "@/components/ui/label" | |
| import { | |
| Code, | |
| Copy, | |
| Check, | |
| ExternalLink, | |
| Moon, | |
| Sun | |
| } from "lucide-react" | |
| import { cn } from "@/lib/utils" | |
| interface EmbedCodeGeneratorProps { | |
| promptSlug: string | |
| promptTitle: string | |
| } | |
| export function EmbedCodeGenerator({ promptSlug, promptTitle }: EmbedCodeGeneratorProps) { | |
| const [theme, setTheme] = useState<"light" | "dark">("light") | |
| const [minimal, setMinimal] = useState(false) | |
| const [copied, setCopied] = useState(false) | |
| const baseUrl = typeof window !== 'undefined' | |
| ? window.location.origin | |
| : 'https://open-prompt.netlify.app' | |
| const embedUrl = `${baseUrl}/embed/${promptSlug}?theme=${theme}${minimal ? '&minimal=true' : ''}` | |
| const iframeCode = `<iframe | |
| src="${embedUrl}" | |
| width="100%" | |
| height="600" | |
| frameborder="0" | |
| title="${promptTitle}" | |
| style="border-radius: 12px; border: 1px solid #e5e7eb;" | |
| ></iframe>` | |
| const copyCode = async () => { | |
| await navigator.clipboard.writeText(iframeCode) | |
| setCopied(true) | |
| setTimeout(() => setCopied(false), 2000) | |
| } | |
| return ( | |
| <Card> | |
| <CardHeader> | |
| <CardTitle className="text-lg flex items-center gap-2"> | |
| <Code className="h-5 w-5" /> | |
| Embed This Prompt | |
| </CardTitle> | |
| <CardDescription> | |
| Add this prompt to your website, blog, or documentation | |
| </CardDescription> | |
| </CardHeader> | |
| <CardContent className="space-y-4"> | |
| {/* Options */} | |
| <div className="flex flex-wrap gap-4"> | |
| <div className="space-y-2"> | |
| <Label className="text-sm">Theme</Label> | |
| <div className="flex gap-2"> | |
| <Button | |
| variant={theme === "light" ? "default" : "outline"} | |
| size="sm" | |
| onClick={() => setTheme("light")} | |
| className="gap-1" | |
| > | |
| <Sun className="h-4 w-4" /> | |
| Light | |
| </Button> | |
| <Button | |
| variant={theme === "dark" ? "default" : "outline"} | |
| size="sm" | |
| onClick={() => setTheme("dark")} | |
| className="gap-1" | |
| > | |
| <Moon className="h-4 w-4" /> | |
| Dark | |
| </Button> | |
| </div> | |
| </div> | |
| <div className="space-y-2"> | |
| <Label className="text-sm">Style</Label> | |
| <div className="flex gap-2"> | |
| <Button | |
| variant={!minimal ? "default" : "outline"} | |
| size="sm" | |
| onClick={() => setMinimal(false)} | |
| > | |
| Full | |
| </Button> | |
| <Button | |
| variant={minimal ? "default" : "outline"} | |
| size="sm" | |
| onClick={() => setMinimal(true)} | |
| > | |
| Minimal | |
| </Button> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Preview Info */} | |
| <div className="p-4 bg-muted rounded-lg"> | |
| <p className="text-sm text-muted-foreground mb-2">Preview URL:</p> | |
| <div className="flex items-center gap-2"> | |
| <code className="text-xs flex-1 truncate">{embedUrl}</code> | |
| <a | |
| href={embedUrl} | |
| target="_blank" | |
| rel="noopener noreferrer" | |
| className="text-primary hover:underline" | |
| > | |
| <ExternalLink className="h-4 w-4" /> | |
| </a> | |
| </div> | |
| </div> | |
| {/* Code Block */} | |
| <div className="relative"> | |
| <pre className="p-4 bg-slate-900 text-slate-100 rounded-lg overflow-x-auto text-sm"> | |
| <code>{iframeCode}</code> | |
| </pre> | |
| <Button | |
| size="sm" | |
| variant="secondary" | |
| className="absolute top-2 right-2 gap-1" | |
| onClick={copyCode} | |
| > | |
| {copied ? ( | |
| <> | |
| <Check className="h-3 w-3" /> | |
| Copied! | |
| </> | |
| ) : ( | |
| <> | |
| <Copy className="h-3 w-3" /> | |
| Copy | |
| </> | |
| )} | |
| </Button> | |
| </div> | |
| {/* Footer Note */} | |
| <p className="text-xs text-muted-foreground"> | |
| The embed includes a "Powered by OpenPrompt" footer that links back to your prompt. | |
| </p> | |
| </CardContent> | |
| </Card> | |
| ) | |
| } | |