fix: [esign] 체크박스 필드를 단순화 - 변수 연결 대신 위치에 체크 표시 렌더링

- 체크박스는 변수 연결 불필요, 배치한 위치에 무조건 ☑ 표시
- PDF 오버레이에서 체크박스 필드는 ☑ 아이콘으로 표시
- 커스텀 변수에서 체크박스 타입 옵션 제거 (불필요)
This commit is contained in:
김보곤
2026-03-11 15:16:28 +09:00
parent 678d0614e7
commit 124490355f

View File

@@ -247,10 +247,16 @@ className={`w-full relative rounded border-2 transition-all ${p === currentPage
boxShadow: resizeMode ? `0 0 0 2px ${color}, 0 2px 12px rgba(0,0,0,0.2)` : (selected ? `0 0 0 1px ${color}, 0 2px 8px rgba(0,0,0,0.15)` : 'none'),
}}
className={`flex items-center select-none group transition-shadow ${{'L':'justify-start','C':'justify-center','R':'justify-end'}[field.text_align] || 'justify-start'}`}>
<div className="flex items-center gap-0.5 text-[10px] font-medium truncate px-1" style={{ color }}>
<span>{typeInfo.icon}</span>
<span className="truncate">{field.field_variable ? `{{${field.field_variable}}}` : (field.field_label || signerName)}</span>
</div>
{field.field_type === 'checkbox' ? (
<div className="flex items-center justify-center w-full h-full" style={{ color }}>
<span style={{ fontSize: 'min(80%, 1.2em)', lineHeight: 1 }}></span>
</div>
) : (
<div className="flex items-center gap-0.5 text-[10px] font-medium truncate px-1" style={{ color }}>
<span>{typeInfo.icon}</span>
<span className="truncate">{field.field_variable ? `{{${field.field_variable}}}` : (field.field_label || signerName)}</span>
</div>
)}
{/* 리사이즈 모드 안내 툴팁 */}
{resizeMode && (
<div style={{ position: 'absolute', top: -20, left: 0, fontSize: 9, backgroundColor: '#374151', color: 'white', padding: '1px 6px', borderRadius: 3, whiteSpace: 'nowrap', zIndex: 40, lineHeight: '16px' }}>
@@ -290,14 +296,13 @@ className={`flex items-center select-none group transition-shadow ${{'L':'justif
const signers = Array.from({ length: signerCount }, (_, i) => ({ order: i + 1, label: SIGNER_LABELS[i] || `서명자 ${i + 1}` }));
const [newVarKey, setNewVarKey] = React.useState('');
const [newVarLabel, setNewVarLabel] = React.useState('');
const [newVarType, setNewVarType] = React.useState('text');
const addVariable = () => {
const key = newVarKey.trim();
const label = newVarLabel.trim();
if (!key || !label) return;
if (templateVariables.some(v => v.key === key)) { alert('이미 존재하는 변수 키입니다.'); return; }
onSetTemplateVariables([...templateVariables, { key, label, type: newVarType, default: newVarType === 'checkbox' ? false : '' }]);
onSetTemplateVariables([...templateVariables, { key, label, type: 'text', default: '' }]);
setNewVarKey('');
setNewVarLabel('');
};
@@ -333,12 +338,9 @@ className="border rounded px-2 py-1 text-xs flex-1">
<div className="space-y-1 mb-2">
{templateVariables.length === 0 && <p className="text-[10px] text-gray-400">정의된 변수 없음</p>}
{templateVariables.map(v => (
<div key={v.key} className={`flex items-center justify-between rounded px-2 py-1 ${v.type === 'checkbox' ? 'bg-green-50' : 'bg-amber-50'}`}>
<div key={v.key} className="flex items-center justify-between bg-amber-50 rounded px-2 py-1">
<div className="min-w-0">
<div className="flex items-center gap-1">
<span className="text-[10px] font-mono text-amber-700 truncate">{v.key}</span>
{v.type === 'checkbox' && <span className="text-[8px] bg-green-200 text-green-700 px-1 rounded"></span>}
</div>
<span className="text-[10px] font-mono text-amber-700 block truncate">{v.key}</span>
<span className="text-[10px] text-gray-500 block truncate">{v.label}</span>
</div>
<button onClick={() => removeVariable(v.key)} className="text-gray-300 hover:text-red-500 flex-shrink-0 ml-1 text-xs">&times;</button>
@@ -346,13 +348,8 @@ className="border rounded px-2 py-1 text-xs flex-1">
))}
</div>
<div className="flex gap-1">
<select value={newVarType} onChange={e => setNewVarType(e.target.value)}
className="border rounded px-1 py-1 text-[10px] w-14 flex-shrink-0">
<option value="text">텍스트</option>
<option value="checkbox">체크</option>
</select>
<input type="text" value={newVarKey} onChange={e => setNewVarKey(e.target.value.replace(/[^a-z0-9_]/gi, ''))}
placeholder="키 (영문)" className="border rounded px-1.5 py-1 text-[10px] w-16" />
placeholder="키 (영문)" className="border rounded px-1.5 py-1 text-[10px] w-20" />
<input type="text" value={newVarLabel} onChange={e => setNewVarLabel(e.target.value)}
placeholder="표시명" className="border rounded px-1.5 py-1 text-[10px] flex-1"
onKeyDown={e => e.key === 'Enter' && addVariable()} />
@@ -416,28 +413,30 @@ className="w-full border rounded px-2 py-1 text-xs mt-0.5">
placeholder="선택사항"
className="w-full border rounded px-2 py-1 text-xs mt-0.5" />
</div>
{['text', 'date', 'checkbox'].includes(selectedField.field_type) && (
{selectedField.field_type === 'checkbox' && (
<div className="px-2 py-1.5 bg-green-50 border border-green-200 rounded text-[10px] text-green-700">
위치에 체크 표시가 렌더링됩니다
</div>
)}
{['text', 'date'].includes(selectedField.field_type) && (
<div>
<label className="text-[10px] text-gray-500">변수 연결</label>
<select value={selectedField.field_variable || ''}
onChange={e => onUpdateField(selectedFieldIndex, { field_variable: e.target.value || null })}
className={`w-full border rounded px-2 py-1 text-xs mt-0.5 ${selectedField.field_variable ? 'border-amber-400 bg-amber-50' : ''}`}>
<option value="">{selectedField.field_type === 'checkbox' ? '(없음 - 수동 체크)' : '(없음 - 수동 입력)'}</option>
{selectedField.field_type !== 'checkbox' && (
<option value="">(없음 - 수동 입력)</option>
<optgroup label="시스템 변수">
{SYSTEM_VARIABLES.map(v => <option key={v.key} value={v.key}>{v.label}</option>)}
</optgroup>
)}
{templateVariables.length > 0 && (
<optgroup label="커스텀 변수">
{templateVariables.filter(v => selectedField.field_type === 'checkbox' ? v.type === 'checkbox' : v.type !== 'checkbox').map(v => <option key={v.key} value={v.key}>{v.label}</option>)}
{templateVariables.map(v => <option key={v.key} value={v.key}>{v.label}</option>)}
</optgroup>
)}
</select>
{selectedField.field_variable && (
<div className="mt-1 px-2 py-1 bg-amber-50 border border-amber-200 rounded">
<span className="text-[10px] text-amber-700 font-mono">{`{{${selectedField.field_variable}}}`}</span>
{selectedField.field_type === 'checkbox' && <span className="text-[10px] text-gray-500 ml-1">(체크 표시)</span>}
</div>
)}
</div>