"use client"; import React, { useEffect, useState } from "react"; import { FlowComponent } from "@/types/screen-management"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { AlertCircle, Loader2 } from "lucide-react"; import { getFlowById, getAllStepCounts } from "@/lib/api/flow"; import type { FlowDefinition, FlowStep } from "@/types/flow"; import { FlowDataListModal } from "@/components/flow/FlowDataListModal"; interface FlowWidgetProps { component: FlowComponent; onStepClick?: (stepId: number, stepName: string) => void; } export function FlowWidget({ component, onStepClick }: FlowWidgetProps) { const [flowData, setFlowData] = useState(null); const [steps, setSteps] = useState([]); const [stepCounts, setStepCounts] = useState>({}); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // 모달 상태 const [modalOpen, setModalOpen] = useState(false); const [selectedStep, setSelectedStep] = useState<{ id: number; name: string } | null>(null); // componentConfig에서 플로우 설정 추출 (DynamicComponentRenderer에서 전달됨) const config = (component as any).componentConfig || (component as any).config || {}; const flowId = config.flowId || component.flowId; const flowName = config.flowName || component.flowName; const displayMode = config.displayMode || component.displayMode || "horizontal"; const showStepCount = config.showStepCount !== false && component.showStepCount !== false; // 기본값 true const allowDataMove = config.allowDataMove || component.allowDataMove || false; console.log("🔍 FlowWidget 렌더링:", { component, componentConfig: config, flowId, flowName, displayMode, showStepCount, allowDataMove, }); useEffect(() => { console.log("🔍 FlowWidget useEffect 실행:", { flowId, hasFlowId: !!flowId, config, }); if (!flowId) { setLoading(false); return; } const loadFlowData = async () => { try { setLoading(true); setError(null); // 플로우 정보 조회 const flowResponse = await getFlowById(flowId!); if (!flowResponse.success || !flowResponse.data) { throw new Error("플로우를 찾을 수 없습니다"); } setFlowData(flowResponse.data); // 스텝 목록 조회 const stepsResponse = await fetch(`/api/flow/definitions/${flowId}/steps`); if (!stepsResponse.ok) { throw new Error("스텝 목록을 불러올 수 없습니다"); } const stepsData = await stepsResponse.json(); if (stepsData.success && stepsData.data) { const sortedSteps = stepsData.data.sort((a: FlowStep, b: FlowStep) => a.stepOrder - b.stepOrder); setSteps(sortedSteps); // 스텝별 데이터 건수 조회 if (showStepCount) { const countsResponse = await getAllStepCounts(flowId!); if (countsResponse.success && countsResponse.data) { // 배열을 Record로 변환 const countsMap: Record = {}; countsResponse.data.forEach((item: any) => { countsMap[item.stepId] = item.count; }); setStepCounts(countsMap); } } } } catch (err: any) { console.error("Failed to load flow data:", err); setError(err.message || "플로우 데이터를 불러오는데 실패했습니다"); } finally { setLoading(false); } }; loadFlowData(); }, [flowId, showStepCount]); // 스텝 클릭 핸들러 const handleStepClick = (stepId: number, stepName: string) => { if (onStepClick) { onStepClick(stepId, stepName); } else { // 기본 동작: 모달 열기 setSelectedStep({ id: stepId, name: stepName }); setModalOpen(true); } }; // 데이터 이동 후 리프레시 const handleDataMoved = async () => { if (!flowId) return; try { // 스텝별 데이터 건수 다시 조회 const countsResponse = await getAllStepCounts(flowId); if (countsResponse.success && countsResponse.data) { // 배열을 Record로 변환 const countsMap: Record = {}; countsResponse.data.forEach((item: any) => { countsMap[item.stepId] = item.count; }); setStepCounts(countsMap); } } catch (err) { console.error("Failed to refresh step counts:", err); } }; if (loading) { return (
플로우 로딩 중...
); } if (error) { return (
{error}
); } if (!flowId || !flowData) { return (
플로우를 선택해주세요
); } if (steps.length === 0) { return (
플로우에 스텝이 없습니다
); } const containerClass = displayMode === "horizontal" ? "flex flex-wrap items-center justify-center gap-3" : "flex flex-col items-center gap-4"; return (
{/* 플로우 제목 */}

{flowData.name}

{flowData.description &&

{flowData.description}

}
{/* 플로우 스텝 목록 */}
{steps.map((step, index) => ( {/* 스텝 카드 */} {/* 화살표 (마지막 스텝 제외) */} {index < steps.length - 1 && (
{displayMode === "horizontal" ? "→" : "↓"}
)}
))}
{/* 데이터 목록 모달 */} {selectedStep && flowId && ( )}
); }