File size: 1,983 Bytes
ad5d4b6
bc45e54
e1ed51d
ad5d4b6
bc45e54
 
 
40aa09c
bc45e54
40aa09c
5722fbf
bc45e54
 
 
 
40aa09c
bc45e54
40aa09c
5722fbf
bc45e54
 
e1ed51d
ad5d4b6
bc45e54
ad5d4b6
 
bc45e54
ad5d4b6
 
 
 
 
bc45e54
 
 
ad5d4b6
 
 
 
bc45e54
ad5d4b6
 
bc45e54
 
 
 
e1ed51d
ad5d4b6
bc45e54
 
ad5d4b6
bc45e54
 
e1ed51d
 
 
 
 
40aa09c
e1ed51d
 
 
5722fbf
 
e1ed51d
 
bc45e54
 
 
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
import { useState } from "react";
import { ModelSelector } from "../ModelSelector";
import { DataPreviewModal } from "./DataPreviewModal";
import { AnswerGridEditor, type AnswerGrid } from "./AnswerGridEditor";

interface PromptEditorProps {
  sessionId: number;
  onGenerate: (model: string) => void;
  isGenerating: boolean;
  selectedCount: number;
  selectedIndices: number[];
}

export function PromptEditor({
  sessionId,
  onGenerate,
  isGenerating,
  selectedCount,
  selectedIndices,
}: PromptEditorProps) {
  const [model, setModel] = useState("gpt-5.4");
  const [showPreview, setShowPreview] = useState(false);
  const [confirmedGrid, setConfirmedGrid] = useState<AnswerGrid | null>(null);

  const canGenerate =
    !isGenerating && selectedCount > 0 && confirmedGrid !== null;

  const buttonLabel = (() => {
    if (selectedCount === 0) return "請先選擇學生";
    if (!confirmedGrid) return "請先確認答案表";
    return `預覽並生成報告(${selectedCount} 位學生)→`;
  })();

  return (
    <div className="space-y-4">
      <AnswerGridEditor
        sessionId={sessionId}
        onConfirmedChange={setConfirmedGrid}
      />

      <div className="flex items-center justify-end">
        <ModelSelector value={model} onChange={setModel} label="報告模型:" />
      </div>

      <div className="text-center">
        <button
          onClick={() => setShowPreview(true)}
          disabled={!canGenerate}
          className="btn btn-accent text-lg px-8 py-4 disabled:opacity-50 disabled:cursor-not-allowed"
        >
          {buttonLabel}
        </button>
      </div>

      {showPreview && (
        <DataPreviewModal
          onGenerate={() => {
            setShowPreview(false);
            onGenerate(model);
          }}
          onClose={() => setShowPreview(false)}
          isGenerating={isGenerating}
          sessionId={sessionId}
          selectedIndices={selectedIndices}
        />
      )}
    </div>
  );
}