File size: 2,387 Bytes
a414867
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use client";

import { AlertTriangle, CheckCircle2, XCircle } from "lucide-react";
import { Badge } from "@/components/ui/Badge";
import type { ValidationResult } from "@/lib/tree/types";

export function TreeValidationPanel({ validation }: { validation: ValidationResult | null }) {
  if (!validation) {
    return (
      <div className="rounded-lg border border-paper-300 bg-white/70 p-3 text-sm text-ink-500">
        Validation has not run yet.
      </div>
    );
  }

  const errors = validation.issues.filter((issue) => issue.level === "error").length;
  const warnings = validation.issues.filter((issue) => issue.level === "warning").length;

  return (
    <div className="rounded-lg border border-paper-300 bg-white/78 p-3 shadow-sm">
      <div className="mb-3 flex items-center justify-between gap-3">
        <div className="flex items-center gap-2 text-sm font-semibold text-ink-900">
          {errors > 0 ? (
            <XCircle className="h-4 w-4 text-red-600" />
          ) : warnings > 0 ? (
            <AlertTriangle className="h-4 w-4 text-amber-600" />
          ) : (
            <CheckCircle2 className="h-4 w-4 text-green-600" />
          )}
          Validation
        </div>
        <Badge status={errors > 0 ? "error" : warnings > 0 ? "warning" : "valid"}>
          {errors > 0 ? `${errors} errors` : warnings > 0 ? `${warnings} warnings` : "valid"}
        </Badge>
      </div>
      {validation.issues.length === 0 ? (
        <p className="text-sm text-ink-500">No issues found.</p>
      ) : (
        <div className="max-h-56 space-y-2 overflow-auto pr-1 scrollbar-thin">
          {validation.issues.map((issue, index) => (
            <div
              key={`${issue.code}-${issue.nodeId ?? "tree"}-${index}`}
              className="rounded-md border border-paper-200 bg-paper-50 px-3 py-2"
            >
              <div className="flex items-center gap-2">
                <Badge status={issue.level === "error" ? "error" : "warning"}>{issue.level}</Badge>
                <span className="font-mono text-[11px] text-ink-400">{issue.code}</span>
                {issue.nodeId && <span className="font-mono text-[11px] text-ink-400">{issue.nodeId}</span>}
              </div>
              <p className="mt-1 text-xs leading-5 text-ink-700">{issue.message}</p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}