21 | {out} 22 |23 | ))} 24 | {stderr && 25 | stderr.length > 0 && 26 | stderr.map((out: string, index: number) => ( 27 |
28 | {out} 29 |30 | ))} 31 |
25 | {code}
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/components/copy-button.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef, useState } from "react";
2 | import { Button, ButtonProps } from "./ui/button";
3 | import { Check, Copy } from "lucide-react";
4 |
5 | export const CopyButton = forwardRef<
6 | HTMLButtonElement,
7 | {
8 | variant?: ButtonProps["variant"];
9 | content: string;
10 | onCopy?: () => void;
11 | className?: string;
12 | }
13 | >(({ variant = "ghost", content, onCopy, className, ...props }, ref) => {
14 | const [copied, setCopied] = useState(false);
15 |
16 | function copy(content: string) {
17 | setCopied(true);
18 | navigator.clipboard.writeText(content);
19 | setTimeout(() => setCopied(false), 1000);
20 | onCopy?.();
21 | }
22 |
23 | return (
24 |
34 | );
35 | });
36 |
37 | CopyButton.displayName = "CopyButton";
38 |
--------------------------------------------------------------------------------
/components/navbar.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | ArrowRight,
3 | MoonIcon,
4 | RefreshCcw,
5 | SunIcon,
6 | Trash,
7 | Undo,
8 | } from "lucide-react";
9 | import Link from "next/link";
10 | import {
11 | Tooltip,
12 | TooltipContent,
13 | TooltipProvider,
14 | TooltipTrigger,
15 | } from "./ui/tooltip";
16 | import { Button } from "./ui/button";
17 | import { useTheme } from "next-themes";
18 | import { Session } from "@supabase/supabase-js";
19 | import { DropdownMenu, DropdownMenuTrigger } from "./ui/dropdown-menu";
20 | import { Avatar, AvatarImage } from "./ui/avatar";
21 |
22 | export function NavBar({
23 | session,
24 | showLogin,
25 | signOut,
26 | onClear,
27 | canClear,
28 | onSocialClick,
29 | onUndo,
30 | canUndo,
31 | }: {
32 | session: Session | null;
33 | showLogin: () => void;
34 | signOut: () => void;
35 | onClear: () => void;
36 | canClear: boolean;
37 | onSocialClick: (target: "github" | "x" | "discord") => void;
38 | onUndo: () => void;
39 | canUndo: boolean;
40 | }) {
41 | const { theme, setTheme } = useTheme();
42 | return (
43 |
129 | );
130 | }
131 |
--------------------------------------------------------------------------------
/components/preview.tsx:
--------------------------------------------------------------------------------
1 | import { CapsuleSchema } from "@/lib/schema";
2 | import { ExecutionResult, ExecutionResultWeb } from "@/lib/types";
3 | import { DeepPartial } from "ai";
4 | import { Dispatch, SetStateAction } from "react";
5 | import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
6 | import {
7 | Tooltip,
8 | TooltipContent,
9 | TooltipProvider,
10 | TooltipTrigger,
11 | } from "./ui/tooltip";
12 | import { Button } from "./ui/button";
13 | import { ChevronsRight, LoaderCircle } from "lucide-react";
14 | import { CapsuleCode } from "./capsule-code";
15 | import { CapsulePreview } from "./capsule-preview";
16 |
17 | export function Preview({
18 | apiKey,
19 | selectedTab,
20 | onSelectedTabChange,
21 | isChatLoading,
22 | isPreviewLoading,
23 | capsule,
24 | result,
25 | onClose,
26 | }: {
27 | apiKey: string | undefined;
28 | selectedTab: "code" | "capsule";
29 | onSelectedTabChange: Dispatch