"use client"; import React, { useMemo } from "react"; import { NumberingRuleConfig, NumberingRulePart, CodePartType } from "@/types/numbering-rule"; import { CODE_PART_TYPE_OPTIONS } from "@/types/numbering-rule"; /** 파트별 표시값 + 타입 (미리보기 스트립/세그먼트용) */ export interface PartDisplayItem { partType: CodePartType; displayValue: string; order: number; } /** config에서 파트별 표시값 배열 계산 (정렬된 parts 기준) */ export function computePartDisplayItems(config: NumberingRuleConfig): PartDisplayItem[] { if (!config.parts || config.parts.length === 0) return []; const sorted = [...config.parts].sort((a, b) => a.order - b.order); const globalSep = config.separator ?? "-"; return sorted.map((part) => ({ order: part.order, partType: part.partType, displayValue: getPartDisplayValue(part), })); } function getPartDisplayValue(part: NumberingRulePart): string { if (part.generationMethod === "manual") { return part.manualConfig?.value || "XXX"; } const c = part.autoConfig || {}; switch (part.partType) { case "sequence": return String(c.startFrom ?? 1).padStart(c.sequenceLength ?? 3, "0"); case "number": return String(c.numberValue ?? 0).padStart(c.numberLength ?? 4, "0"); case "date": { const format = c.dateFormat || "YYYYMMDD"; if (c.useColumnValue && c.sourceColumnName) { return format === "YYYY" ? "[YYYY]" : format === "YY" ? "[YY]" : format === "YYYYMM" ? "[YYYYMM]" : format === "YYMM" ? "[YYMM]" : format === "YYMMDD" ? "[YYMMDD]" : "[DATE]"; } const now = new Date(); const y = now.getFullYear(); const m = String(now.getMonth() + 1).padStart(2, "0"); const d = String(now.getDate()).padStart(2, "0"); if (format === "YYYY") return String(y); if (format === "YY") return String(y).slice(-2); if (format === "YYYYMM") return `${y}${m}`; if (format === "YYMM") return `${String(y).slice(-2)}${m}`; if (format === "YYYYMMDD") return `${y}${m}${d}`; if (format === "YYMMDD") return `${String(y).slice(-2)}${m}${d}`; return `${y}${m}${d}`; } case "text": return c.textValue || "TEXT"; default: return "XXX"; } } /** 파트 타입별 미리보기용 텍스트 색상 클래스 (CSS 변수 기반) */ export function getPartTypeColorClass(partType: CodePartType): string { switch (partType) { case "date": return "text-warning"; case "text": return "text-primary"; case "sequence": return "text-primary"; case "number": return "text-muted-foreground"; case "category": case "reference": return "text-muted-foreground"; default: return "text-foreground"; } } /** 파트 타입별 점(dot) 배경 색상 (범례용) */ export function getPartTypeDotClass(partType: CodePartType): string { switch (partType) { case "date": return "bg-warning"; case "text": case "sequence": return "bg-primary"; case "number": case "category": case "reference": return "bg-muted-foreground"; default: return "bg-foreground"; } } interface NumberingRulePreviewProps { config: NumberingRuleConfig; compact?: boolean; /** 큰 미리보기 스트립: 28px, 파트별 색상, 하단 범례 */ variant?: "default" | "strip"; } export const NumberingRulePreview: React.FC = ({ config, compact = false, variant = "default", }) => { const partItems = useMemo(() => computePartDisplayItems(config), [config]); const sortedParts = useMemo( () => (config.parts ? [...config.parts].sort((a, b) => a.order - b.order) : []), [config.parts] ); const generatedCode = useMemo(() => { if (partItems.length === 0) return "규칙을 추가해주세요"; const globalSep = config.separator ?? "-"; let result = ""; partItems.forEach((item, idx) => { result += item.displayValue; if (idx < partItems.length - 1) { const part = sortedParts.find((p) => p.order === item.order); result += part?.separatorAfter ?? globalSep; } }); return result; }, [config.separator, partItems, sortedParts]); if (variant === "strip") { const globalSep = config.separator ?? "-"; return (
{partItems.length === 0 ? ( 규칙을 추가해주세요 ) : ( partItems.map((item, idx) => ( {item.displayValue} {idx < partItems.length - 1 && ( {sortedParts.find((p) => p.order === item.order)?.separatorAfter ?? globalSep} )} )) )}
{partItems.length > 0 && (
{CODE_PART_TYPE_OPTIONS.filter((opt) => partItems.some((p) => p.partType === opt.value)).map((opt) => ( {opt.label} ))}
)}
); } if (compact) { return (
{generatedCode}
); } return (
{generatedCode}
); };