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

import { Check, Loader2 } from "lucide-react";
import type { DocumentDetail } from "@/lib/types";

/**
 * A slim live stepper that reflects pipeline progress by inspecting which
 * parts of the document detail have been populated. Renders only while the
 * document is still processing.
 */
export default function ProcessingBar({ detail }: { detail: DocumentDetail }) {
  if (detail.status === "ready" || detail.status === "failed") return null;

  const steps = [
    { label: "Parsing", done: (detail.pages?.length ?? 0) > 0 },
    { label: "Classifying", done: !!detail.classification },
    { label: "Extracting", done: !!detail.extraction },
    { label: "Summarizing", done: !!detail.summary },
  ];
  const activeIdx = steps.findIndex((s) => !s.done);

  return (
    <div className="border-b border-white/[0.06] bg-surface-900/50 px-4 py-2.5">
      <div className="flex items-center gap-2">
        {steps.map((s, i) => {
          const active = i === activeIdx;
          return (
            <div key={s.label} className="flex flex-1 items-center gap-2">
              <div className="flex items-center gap-1.5">
                <span
                  className={`flex h-4 w-4 items-center justify-center rounded-full text-[9px] ${
                    s.done
                      ? "bg-emerald-500/20 text-emerald-400"
                      : active
                        ? "bg-brand-500/20 text-brand-300"
                        : "bg-white/[0.05] text-white/30"
                  }`}
                >
                  {s.done ? (
                    <Check size={10} />
                  ) : active ? (
                    <Loader2 size={10} className="animate-spin" />
                  ) : (
                    i + 1
                  )}
                </span>
                <span
                  className={`text-[11px] font-medium ${
                    s.done
                      ? "text-white/60"
                      : active
                        ? "text-brand-200"
                        : "text-white/30"
                  }`}
                >
                  {s.label}
                </span>
              </div>
              {i < steps.length - 1 && (
                <div className="h-px flex-1 bg-white/[0.07]">
                  <div
                    className={`h-px transition-all duration-500 ${
                      s.done ? "w-full bg-emerald-500/40" : "w-0"
                    }`}
                  />
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}