feat(v0210): NoteCard 원문 영역 편집 UI (textarea + 저장/취소 + updateRawText)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -118,6 +118,9 @@ export function NoteCard({ note, onDeleted, onUpdated, mode = 'inbox', onRestore
|
||||
// v0.2.9 Cut B Task 6 — 이동 메뉴 dropdown + MoveStatusModal target.
|
||||
const [moveTarget, setMoveTarget] = useState<NoteStatus | null>(null);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [editingRaw, setEditingRaw] = useState(false);
|
||||
const [draftRaw, setDraftRaw] = useState('');
|
||||
const [showRevisions, setShowRevisions] = useState(false);
|
||||
|
||||
const possibleTargets: NoteStatus[] = (
|
||||
['active', 'completed', 'archived', 'trashed'] as NoteStatus[]
|
||||
@@ -150,6 +153,17 @@ export function NoteCard({ note, onDeleted, onUpdated, mode = 'inbox', onRestore
|
||||
setLocal(updated); onUpdated(updated);
|
||||
}
|
||||
|
||||
async function saveRaw() {
|
||||
const next = draftRaw;
|
||||
if (next.trim().length === 0) return;
|
||||
const r = await inboxApi.updateRawText(note.id, next);
|
||||
if (!r.ok) return;
|
||||
const updated = { ...local, rawText: next, updatedAt: new Date().toISOString() };
|
||||
setLocal(updated);
|
||||
onUpdated(updated);
|
||||
setEditingRaw(false);
|
||||
}
|
||||
|
||||
async function removeTag(tagName: string) {
|
||||
const removed = local.tags.find((t) => t.name === tagName);
|
||||
const nextTagNames = local.tags.filter((t) => t.name !== tagName).map((t) => t.name);
|
||||
@@ -371,9 +385,32 @@ export function NoteCard({ note, onDeleted, onUpdated, mode = 'inbox', onRestore
|
||||
{rawOpen ? '▾ 원문 접기' : '▸ 원문 보기'}
|
||||
</button>
|
||||
{rawOpen && (
|
||||
<pre style={{ marginTop: 6, whiteSpace: 'pre-wrap', fontSize: 12, color: '#555', background: '#fafafa', padding: 8, borderRadius: 4 }}>
|
||||
{local.rawText}
|
||||
</pre>
|
||||
<div style={{ marginTop: 6 }}>
|
||||
{editingRaw ? (
|
||||
<div>
|
||||
<textarea
|
||||
aria-label="원문 편집"
|
||||
value={draftRaw}
|
||||
onChange={(e) => setDraftRaw(e.target.value)}
|
||||
style={{ width: '100%', minHeight: 80, fontSize: 12, fontFamily: 'inherit', padding: 8, border: '1px solid #ddd', borderRadius: 4, boxSizing: 'border-box' }}
|
||||
/>
|
||||
<div style={{ marginTop: 4, display: 'flex', gap: 6, justifyContent: 'flex-end' }}>
|
||||
<button onClick={() => setEditingRaw(false)} style={{ background: 'none', border: '1px solid #ccc', color: '#444', cursor: 'pointer', fontSize: 12, padding: '3px 10px', borderRadius: 4 }}>취소</button>
|
||||
<button onClick={() => { void saveRaw(); }} style={{ background: '#0a4b80', border: 'none', color: '#fff', cursor: 'pointer', fontSize: 12, padding: '3px 10px', borderRadius: 4 }}>저장</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', fontSize: 12, color: '#555', background: '#fafafa', padding: 8, borderRadius: 4 }}>
|
||||
{local.rawText}
|
||||
</pre>
|
||||
<div style={{ marginTop: 4, display: 'flex', gap: 6, justifyContent: 'flex-end' }}>
|
||||
<button onClick={() => setShowRevisions(true)} style={{ background: 'none', border: 'none', color: '#0a4b80', cursor: 'pointer', fontSize: 12, padding: 0 }}>이력</button>
|
||||
<button onClick={() => { setDraftRaw(local.rawText); setEditingRaw(true); }} style={{ background: 'none', border: '1px solid #ccc', color: '#444', cursor: 'pointer', fontSize: 12, padding: '3px 10px', borderRadius: 4 }}>편집</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user