File size: 2,645 Bytes
c2d42ec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Download, Copy, Play, X } from "lucide-react";
import { useToast } from "@/hooks/use-toast";

type CodePanelProps = {
  fileName: string;
  language: string;
  code: string;
  onClose?: () => void;
  onRun?: () => void;
};

export function CodePanel({ fileName, language, code, onClose, onRun }: CodePanelProps) {
  const { toast } = useToast();
  const [copied, setCopied] = useState(false);

  const handleCopy = async () => {
    await navigator.clipboard.writeText(code);
    setCopied(true);
    toast({
      title: "Copied!",
      description: "Code copied to clipboard",
    });
    setTimeout(() => setCopied(false), 2000);
  };

  const handleDownload = () => {
    const blob = new Blob([code], { type: "text/plain" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = fileName;
    a.click();
    URL.revokeObjectURL(url);
    toast({
      title: "Downloaded!",
      description: `${fileName} has been downloaded`,
    });
  };

  return (
    <div className="flex flex-col h-full border-l border-border bg-card">
      <div className="flex items-center justify-between p-4 border-b border-card-border">
        <div className="flex items-center gap-3">
          <h3 className="font-semibold text-sm" data-testid="text-filename">{fileName}</h3>
          <Badge variant="secondary" className="text-xs">{language}</Badge>
        </div>
        <div className="flex items-center gap-2">
          {onRun && (
            <Button variant="outline" size="sm" onClick={onRun} data-testid="button-run-code">
              <Play className="h-4 w-4 mr-2" />
              Run
            </Button>
          )}
          <Button variant="outline" size="sm" onClick={handleCopy} data-testid="button-copy-code">
            <Copy className="h-4 w-4 mr-2" />
            {copied ? "Copied!" : "Copy"}
          </Button>
          <Button variant="outline" size="sm" onClick={handleDownload} data-testid="button-download-code">
            <Download className="h-4 w-4 mr-2" />
            Download
          </Button>
          {onClose && (
            <Button variant="ghost" size="icon" onClick={onClose} data-testid="button-close-panel">
              <X className="h-5 w-5" />
            </Button>
          )}
        </div>
      </div>

      <div className="flex-1 overflow-auto p-4 bg-muted/30">
        <pre className="font-mono text-sm">
          <code>{code}</code>
        </pre>
      </div>
    </div>
  );
}