"use client"; import React, { useState } from "react"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Input } from "@/components/ui/input"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Plus, X, Calculator } from "lucide-react"; import { CalculationNode, CalculationStep, AdditionalFieldDefinition } from "./types"; interface CalculationBuilderProps { steps: CalculationStep[]; availableFields: AdditionalFieldDefinition[]; onChange: (steps: CalculationStep[]) => void; } export const CalculationBuilder: React.FC = ({ steps, availableFields, onChange, }) => { const [previewValues, setPreviewValues] = useState>({}); // 새 단계 추가 const addStep = () => { const newStep: CalculationStep = { id: `step_${Date.now()}`, label: `단계 ${steps.length + 1}`, expression: { type: "field", fieldName: "", }, }; onChange([...steps, newStep]); }; // 단계 삭제 const removeStep = (stepId: string) => { onChange(steps.filter((s) => s.id !== stepId)); }; // 단계 업데이트 const updateStep = (stepId: string, updates: Partial) => { onChange( steps.map((s) => (s.id === stepId ? { ...s, ...updates } : s)) ); }; // 간단한 표현식 렌더링 const renderSimpleExpression = (step: CalculationStep) => { return (
{/* 왼쪽 항 */} {step.expression.type === "constant" && ( { updateStep(step.id, { expression: { ...step.expression, value: parseFloat(e.target.value) || 0, }, }); }} className="h-8 w-24 text-xs" placeholder="값" /> )}
{/* 연산 추가 버튼 */} {step.expression.type !== "operation" && ( )} {/* 연산식 */} {step.expression.type === "operation" && (
{renderOperationExpression(step)}
)}
); }; // 연산식 렌더링 const renderOperationExpression = (step: CalculationStep) => { if (step.expression.type !== "operation") return null; return (
{/* 왼쪽 항 */}
{renderNodeLabel(step.expression.left)}
{/* 연산자 */} {/* 오른쪽 항 */} {step.expression.right?.type === "constant" && ( { updateStep(step.id, { expression: { ...step.expression, right: { ...step.expression.right!, value: parseFloat(e.target.value) || 0, }, }, }); }} className="h-7 w-24 text-xs" placeholder="값" /> )}
); }; // 노드 라벨 표시 const renderNodeLabel = (node?: CalculationNode): string => { if (!node) return ""; switch (node.type) { case "field": const field = availableFields.find((f) => f.name === node.fieldName); return field?.label || node.fieldName || "필드"; case "constant": return String(node.value || 0); case "previous": return "이전 결과"; case "operation": const left = renderNodeLabel(node.left); const right = renderNodeLabel(node.right); const op = node.operator === "*" ? "×" : node.operator === "/" ? "÷" : node.operator; return `(${left} ${op} ${right})`; default: return ""; } }; // 함수 적용 UI const renderFunctionStep = (step: CalculationStep) => { if (step.expression.type !== "function") return null; return (
{(step.expression.functionName === "round" || step.expression.functionName === "floor" || step.expression.functionName === "ceil") && ( <> 단위: )}
); }; return (
{steps.length === 0 ? (

계산 단계를 추가하여 계산식을 만드세요

) : (
{steps.map((step, idx) => (
{step.label || `단계 ${idx + 1}`}
updateStep(step.id, { label: e.target.value })} placeholder={`단계 ${idx + 1}`} className="h-6 w-24 text-xs" />
{step.expression.type === "function" ? renderFunctionStep(step) : renderSimpleExpression(step)} {/* 함수 적용 버튼 */} {step.expression.type !== "function" && ( )}
))}
)} {/* 미리보기 */} {steps.length > 0 && (
계산식:
{steps.map((step, idx) => (
{idx + 1}. {renderNodeLabel(step.expression)}
))}
)}
); };