You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.4 KiB
TypeScript

// 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,
}: {
list: TaskComment[];
people: Record<string, Person>;
me: Person;
onAdd: (text: string) => void;
}) {
const [txt, setTxt] = useState("");
const submit = () => {
if (txt.trim()) {
onAdd(txt.trim());
setTxt("");
}
};
return (
<div className="cmt">
<div className="cmt-list">
{list.length === 0 && (
<div className="cmt-empty"> . .</div>
)}
{list.map((c) => {
const p = people[c.person_id] || me;
return (
<div className="cmt-row" key={c.id}>
<div className="av" style={{ background: p.color }}>
{p.initial}
</div>
<div className="cmt-bub">
<div className="cmt-top">
<b>
{p.name}
{p.is_me ? " (나)" : ""}
</b>
<span className="t">{relTime(c.created_at)}</span>
</div>
<div className="cmt-text">{c.text}</div>
</div>
</div>
);
})}
</div>
<div className="cmt-compose">
<div className="av" style={{ background: me.color }}>
{me.initial}
</div>
<input
value={txt}
placeholder="코멘트 추가…"
onChange={(e) => setTxt(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") submit();
}}
/>
<button className="cmt-send" onClick={submit} disabled={!txt.trim()} aria-label="코멘트 등록">
<Icon name="send" />
</button>
</div>
</div>
);
}