"use client"; import React, { useState, useEffect } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Checkbox } from "@/components/ui/checkbox"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Button } from "@/components/ui/button"; import { Plus, Trash2 } from "lucide-react"; import { TextInputConfig } from "./types"; import { AutoGenerationType, AutoGenerationConfig } from "@/types/screen"; import { AutoGenerationUtils } from "@/lib/utils/autoGeneration"; import { getAvailableNumberingRules, getAvailableNumberingRulesForScreen } from "@/lib/api/numberingRule"; import { NumberingRuleConfig } from "@/types/numbering-rule"; export interface TextInputConfigPanelProps { config: TextInputConfig; onChange: (config: Partial) => void; screenTableName?: string; // πŸ†• ν˜„μž¬ ν™”λ©΄μ˜ ν…Œμ΄λΈ”λͺ… menuObjid?: number; // πŸ†• 메뉴 OBJID (μ‚¬μš©μž 선택) } /** * TextInput μ„€μ • νŒ¨λ„ * μ»΄ν¬λ„ŒνŠΈμ˜ 섀정값듀을 νŽΈμ§‘ν•  수 μžˆλŠ” UI 제곡 */ export const TextInputConfigPanel: React.FC = ({ config, onChange, screenTableName, menuObjid }) => { // μ±„λ²ˆ κ·œμΉ™ λͺ©λ‘ μƒνƒœ const [numberingRules, setNumberingRules] = useState([]); const [loadingRules, setLoadingRules] = useState(false); // λΆ€λͺ¨ 메뉴 λͺ©λ‘ μƒνƒœ (μ±„λ²ˆκ·œμΉ™ μ‚¬μš©μ„ μœ„ν•œ 선택) const [parentMenus, setParentMenus] = useState([]); // useState μ΄ˆκΈ°κ°’μ—μ„œ μ €μž₯된 κ°’ 볡원 (μš°μ„ μˆœμœ„: μ €μž₯된 κ°’ > menuObjid prop) const [selectedMenuObjid, setSelectedMenuObjid] = useState(() => { return config.autoGeneration?.selectedMenuObjid || menuObjid; }); const [loadingMenus, setLoadingMenus] = useState(false); // λΆ€λͺ¨ 메뉴 λͺ©λ‘ λ‘œλ“œ (μ‚¬μš©μž λ©”λ‰΄μ˜ 레벨 2만) useEffect(() => { const loadMenus = async () => { setLoadingMenus(true); try { const { apiClient } = await import("@/lib/api/client"); const response = await apiClient.get("/admin/menus"); if (response.data.success && response.data.data) { const allMenus = response.data.data; // μ‚¬μš©μž 메뉴(menu_type='1')의 레벨 2만 필터링 const level2UserMenus = allMenus.filter((menu: any) => menu.menu_type === '1' && menu.lev === 2 ); setParentMenus(level2UserMenus); } } catch (error) { console.error("λΆ€λͺ¨ 메뉴 λ‘œλ“œ μ‹€νŒ¨:", error); } finally { setLoadingMenus(false); } }; loadMenus(); }, []); // μ±„λ²ˆ κ·œμΉ™ λͺ©λ‘ λ‘œλ“œ (μ„ νƒλœ 메뉴 κΈ°μ€€) useEffect(() => { const loadRules = async () => { // autoGeneration.type이 numbering_rule이 μ•„λ‹ˆλ©΄ λ‘œλ“œν•˜μ§€ μ•ŠμŒ if (config.autoGeneration?.type !== "numbering_rule") { return; } // 메뉴가 μ„ νƒλ˜μ§€ μ•Šμ•˜μœΌλ©΄ λ‘œλ“œν•˜μ§€ μ•ŠμŒ if (!selectedMenuObjid) { setNumberingRules([]); return; } setLoadingRules(true); try { const response = await getAvailableNumberingRules(selectedMenuObjid); if (response.success && response.data) { setNumberingRules(response.data); } } catch (error) { console.error("μ±„λ²ˆ κ·œμΉ™ λͺ©λ‘ λ‘œλ“œ μ‹€νŒ¨:", error); setNumberingRules([]); } finally { setLoadingRules(false); } }; loadRules(); }, [selectedMenuObjid, config.autoGeneration?.type]); const handleChange = (key: keyof TextInputConfig, value: any) => { onChange({ [key]: value }); }; return (
text-input μ„€μ •
{/* ν…μŠ€νŠΈ κ΄€λ ¨ μ„€μ • */}
handleChange("placeholder", e.target.value)} />
handleChange("maxLength", parseInt(e.target.value) || undefined)} />
{/* ꡬ뢄선 */}
κ³ κΈ‰ κΈ°λŠ₯
{/* μˆ¨κΉ€ κΈ°λŠ₯ */}
handleChange("hidden", checked)} />
{/* μžλ™μƒμ„± κΈ°λŠ₯ */}
{ const currentConfig = config.autoGeneration || { type: "none", enabled: false }; handleChange("autoGeneration", { ...currentConfig, enabled: checked as boolean, }); }} />
{/* μžλ™μƒμ„± νƒ€μž… 선택 */} {config.autoGeneration?.enabled && (
{/* μ„ νƒλœ νƒ€μž… μ„€λͺ… */} {config.autoGeneration?.type && config.autoGeneration.type !== "none" && (
{AutoGenerationUtils.getTypeDescription(config.autoGeneration.type)}
)} {/* μ±„λ²ˆ κ·œμΉ™ 선택 */} {config.autoGeneration?.type === "numbering_rule" && ( <> {/* λΆ€λͺ¨ 메뉴 선택 */}

이 μž…λ ₯ ν•„λ“œκ°€ μ–΄λŠ 메뉴에 속할지 μ„ νƒν•˜μ„Έμš” (ν•΄λ‹Ή λ©”λ‰΄μ˜ μ±„λ²ˆκ·œμΉ™μ΄ μ μš©λ©λ‹ˆλ‹€)

{/* μ±„λ²ˆ κ·œμΉ™ 선택 (메뉴 선택 ν›„) */} {selectedMenuObjid ? (

μ„ νƒλœ 메뉴 및 ν˜•μ œ λ©”λ‰΄μ—μ„œ μ‚¬μš© κ°€λŠ₯ν•œ μ±„λ²ˆ κ·œμΉ™λ§Œ ν‘œμ‹œλ©λ‹ˆλ‹€

) : (
λ¨Όμ € λŒ€μƒ 메뉴λ₯Ό μ„ νƒν•˜μ„Έμš”
)} )}
)} {/* μžλ™μƒμ„± μ˜΅μ…˜ */} {config.autoGeneration?.enabled && config.autoGeneration?.type && ["random_string", "random_number", "sequence"].includes(config.autoGeneration.type) && (
{/* 길이 μ„€μ • (랜덀 λ¬Έμžμ—΄/숫자용) */} {["random_string", "random_number"].includes(config.autoGeneration.type) && (
{ const currentConfig = config.autoGeneration!; handleChange("autoGeneration", { ...currentConfig, options: { ...currentConfig.options, length: parseInt(e.target.value) || 8, }, }); }} />
)} {/* 접두사 */}
{ const currentConfig = config.autoGeneration!; handleChange("autoGeneration", { ...currentConfig, options: { ...currentConfig.options, prefix: e.target.value, }, }); }} />
{/* 접미사 */}
{ const currentConfig = config.autoGeneration!; handleChange("autoGeneration", { ...currentConfig, options: { ...currentConfig.options, suffix: e.target.value, }, }); }} />
{/* 미리보기 */}
{AutoGenerationUtils.generatePreviewValue(config.autoGeneration)}
)}
); };