// frontend/components/tasks/Comments.tsx "use client"; import { useState } from "react"; import { Icon } from "@/components/Icon"; import type { Person, TaskComment } from "@/lib/types"; function relTime(iso: string): string { if (!iso) return "방금"; const then = new Date(iso).getTime(); if (Number.isNaN(then)) return "방금"; const diff = Date.now() - then; const m = Math.floor(diff / 60000); if (m < 1) return "방금"; if (m < 60) return `${m}분 전`; const h = Math.floor(m / 60); if (h < 24) return `${h}시간 전`; const d = Math.floor(h / 24); if (d === 1) return "어제"; if (d < 7) return `${d}일 전`; const dt = new Date(iso); return `${dt.getMonth() + 1}/${dt.getDate()}`; } export function Comments({ list, people, me, onAdd, onEdit, onDelete, }: { list: TaskComment[]; people: Record; me: Person; onAdd: (text: string) => void; onEdit?: (cid: string, text: string) => void; onDelete?: (cid: string) => void; }) { const [txt, setTxt] = useState(""); const [editId, setEditId] = useState(null); const [editTxt, setEditTxt] = useState(""); const submit = () => { if (txt.trim()) { onAdd(txt.trim()); setTxt(""); } }; const startEdit = (c: TaskComment) => { setEditId(c.id); setEditTxt(c.text); }; const saveEdit = () => { if (editId && editTxt.trim()) onEdit?.(editId, editTxt.trim()); setEditId(null); setEditTxt(""); }; return (
{list.length === 0 && (
아직 코멘트가 없어요. 첫 의견을 남겨보세요.
)} {list.map((c) => { const p = people[c.person_id] || me; const mine = c.person_id === me.id; const editing = editId === c.id; return (
{p.initial}
{p.name} {p.is_me ? " (나)" : ""} {relTime(c.created_at)} {c.edited_at ? " · 수정됨" : ""} {mine && onEdit && onDelete && !editing && ( )}
{editing ? (
setEditTxt(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") saveEdit(); if (e.key === "Escape") setEditId(null); }} />
) : (
{c.text}
)}
); })}
{me.initial}
setTxt(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
); }