"use client"; import { useState, useEffect } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import { Trash2, Plus } from "lucide-react"; import { ScrollArea } from "@/components/ui/scroll-area"; import { useBarcodeDesigner } from "@/contexts/BarcodeDesignerContext"; import { BarcodeLabelComponent } from "@/types/barcode"; // QR 기본 키: 품번, 품명, 규격 const DEFAULT_QR_JSON_KEYS = ["part_no", "part_name", "spec"]; function parseQRJsonValue(str: string): Record { const trimmed = (str || "").trim(); if (!trimmed) return {}; try { const o = JSON.parse(trimmed); if (o && typeof o === "object" && !Array.isArray(o)) { return Object.fromEntries( Object.entries(o).map(([k, v]) => [String(k), v != null ? String(v) : ""]) ); } } catch { // ignore } return {}; } function QRJsonFields({ selected, update, }: { selected: BarcodeLabelComponent; update: (u: Partial) => void; }) { const [pairs, setPairs] = useState<{ key: string; value: string }[]>(() => { const parsed = parseQRJsonValue(selected.barcodeValue || ""); if (Object.keys(parsed).length > 0) { return Object.entries(parsed).map(([key, value]) => ({ key, value })); } return DEFAULT_QR_JSON_KEYS.map((key) => ({ key, value: "" })); }); // 바코드 값이 바깥에서 바뀌면 파싱해서 동기화 useEffect(() => { const parsed = parseQRJsonValue(selected.barcodeValue || ""); if (Object.keys(parsed).length > 0) { setPairs(Object.entries(parsed).map(([key, value]) => ({ key, value: String(value ?? "") }))); } }, [selected.barcodeValue]); const applyJson = () => { const obj: Record = {}; pairs.forEach(({ key, value }) => { const k = key.trim(); if (k) obj[k] = value.trim(); }); update({ barcodeValue: JSON.stringify(obj) }); }; const setPair = (index: number, field: "key" | "value", val: string) => { setPairs((prev) => { const next = [...prev]; if (!next[index]) next[index] = { key: "", value: "" }; next[index] = { ...next[index], [field]: val }; return next; }); }; const addRow = () => setPairs((prev) => [...prev, { key: "", value: "" }]); const removeRow = (index: number) => setPairs((prev) => (prev.length <= 1 ? prev : prev.filter((_, i) => i !== index))); return (

키는 자유 입력, 값 입력 후 적용 버튼을 누르면 QR에 반영됩니다.

{pairs.map((p, i) => (
setPair(i, "key", e.target.value)} /> setPair(i, "value", e.target.value)} />
))}
); } export function BarcodeDesignerRightPanel() { const { components, selectedComponentId, updateComponent, removeComponent, selectComponent, widthMm, heightMm, setWidthMm, setHeightMm, } = useBarcodeDesigner(); const selected = components.find((c) => c.id === selectedComponentId); if (!selected) { return (

요소를 선택하면 속성을 편집할 수 있습니다.

setWidthMm(Number(e.target.value) || 50)} /> × setHeightMm(Number(e.target.value) || 30)} />
); } const update = (updates: Partial) => updateComponent(selected.id, updates); return (
속성
update({ x: Number(e.target.value) || 0 })} />
update({ y: Number(e.target.value) || 0 })} />
update({ width: Number(e.target.value) || 10 })} />
update({ height: Number(e.target.value) || 10 })} />
{selected.type === "text" && ( <>
update({ content: e.target.value })} placeholder="텍스트" />
update({ fontSize: Number(e.target.value) || 10 })} />
update({ fontColor: e.target.value })} className="h-9 w-20 p-1" />
)} {selected.type === "barcode" && ( <>
{selected.barcodeType === "QR" && ( )}
update({ barcodeValue: e.target.value })} placeholder={selected.barcodeType === "QR" ? '{"part_no":"","part_name":"","spec":""}' : "123456789"} />
update({ showBarcodeText: v })} />
)} {selected.type === "line" && ( <>
update({ lineWidth: Number(e.target.value) || 1 })} />
update({ lineColor: e.target.value })} className="h-9 w-20 p-1" />
)} {selected.type === "rectangle" && ( <>
update({ lineWidth: Number(e.target.value) || 0 })} />
update({ lineColor: e.target.value })} className="h-9 w-20 p-1" />
update({ backgroundColor: e.target.value })} className="h-9 w-20 p-1" />
)} {selected.type === "image" && (
update({ imageUrl: e.target.value })} placeholder="https://..." />

또는 나중에 업로드 기능 연동

)}
); }