File size: 3,508 Bytes
42ae0b9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { useState } from "react";
import { Copy, Check, ArrowLeftRight, Wand2 } from "lucide-react";
import { toast } from "sonner";
import type { FormatResult } from "@/lib/api";

interface FormatterPanelProps {
  result: FormatResult | null;
  onApplyToEditor?: (sql: string) => void;
}

export function FormatterPanel({ result, onApplyToEditor }: FormatterPanelProps) {
  const [copied, setCopied] = useState(false);

  const handleCopy = async () => {
    if (!result) return;
    await navigator.clipboard.writeText(result.formatted);
    setCopied(true);
    toast.success("Copied to clipboard");
    setTimeout(() => setCopied(false), 2000);
  };

  const handleApply = () => {
    if (!result) return;
    onApplyToEditor?.(result.formatted);
    toast.success("Applied to editor");
  };

  if (!result) {
    return (
      <div className="flex flex-col items-center justify-center h-full gap-3 text-[oklch(0.45_0.010_264)]">
        <Wand2 size={32} className="opacity-30" />
        <p className="text-sm">Run analysis to see formatted SQL</p>
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full">
      {/* Toolbar */}
      <div className="flex items-center gap-2 px-3 py-2 border-b border-[oklch(0.22_0.010_264)] flex-shrink-0">
        <div className="flex items-center gap-2 flex-1">
          {result.changed ? (
            <div className="flex items-center gap-1.5 text-xs" style={{ color: "oklch(0.72 0.17 160)" }}>
              <Wand2 size={13} />
              <span className="font-medium">{result.fixes_applied} fix{result.fixes_applied !== 1 ? "es" : ""} applied</span>
            </div>
          ) : (
            <div className="flex items-center gap-1.5 text-xs text-[oklch(0.55_0.010_264)]">
              <Check size={13} />
              <span>No formatting changes needed</span>
            </div>
          )}
          <span className="text-[10px] text-[oklch(0.38_0.010_264)] font-mono ml-2">
            dialect: {result.dialect}
          </span>
        </div>

        <button
          onClick={handleCopy}
          className="flex items-center gap-1.5 h-7 px-2 text-xs rounded transition-colors"
          style={{ color: "var(--text-secondary)", background: "transparent" }}
        >
          {copied ? <Check size={12} /> : <Copy size={12} />}
          {copied ? "Copied" : "Copy"}
        </button>

        <button
          onClick={handleApply}
          className="flex items-center gap-1.5 h-7 px-2 text-xs font-semibold rounded"
          style={{ background: "var(--accent-blue)", color: "var(--bg-base)" }}
        >
          <ArrowLeftRight size={12} />
          Apply to Editor
        </button>
      </div>

      {/* Diff indicator */}
      {result.changed && (
        <div className="flex items-center gap-2 px-3 py-1.5 border-b border-[oklch(0.22_0.010_264)] flex-shrink-0 bg-[oklch(0.72_0.17_160_/_0.05)]">
          <ArrowLeftRight size={11} style={{ color: "oklch(0.72 0.17 160)" }} />
          <span className="text-[10px] text-[oklch(0.60_0.010_264)]">
            Formatted SQL differs from original
          </span>
        </div>
      )}

      {/* Formatted SQL output */}
      <div className="flex-1 overflow-auto">
        <pre
          className="p-4 text-xs font-mono leading-relaxed text-[oklch(0.85_0.010_264)] whitespace-pre-wrap break-words"
          style={{ fontFamily: "'JetBrains Mono', monospace" }}
        >
          {result.formatted}
        </pre>
      </div>
    </div>
  );
}