import { useMemo, useState } from "react"; import type { Task, TaskComment } from "@fusion/core"; import { addTaskComment, updateTaskComment, deleteTaskComment } from "../api"; import type { ToastType } from "../hooks/useToast"; interface TaskCommentsProps { task: Task; onTaskUpdated?: (task: Task) => void; addToast: (message: string, type?: ToastType) => void; currentAuthor?: string; } function formatCommentTimestamp(comment: TaskComment): string { const timestamp = comment.updatedAt || comment.createdAt; const label = new Date(timestamp).toLocaleString(); return comment.updatedAt ? `${label} (edited)` : label; } export function TaskComments({ task, onTaskUpdated, addToast, currentAuthor = "user" }: TaskCommentsProps) { const [draft, setDraft] = useState(""); const [editingId, setEditingId] = useState(null); const [editingText, setEditingText] = useState(""); const [submitting, setSubmitting] = useState(false); const [deletingId, setDeletingId] = useState(null); const comments = useMemo(() => task.comments || [], [task.comments]); async function handleAddComment() { const text = draft.trim(); if (!text) return; setSubmitting(true); try { const updated = await addTaskComment(task.id, text, currentAuthor); setDraft(""); onTaskUpdated?.(updated); addToast("Comment added", "success"); } catch (error: any) { addToast(error.message || "Failed to add comment", "error"); } finally { setSubmitting(false); } } async function handleSaveEdit(commentId: string) { const text = editingText.trim(); if (!text) return; setSubmitting(true); try { const updated = await updateTaskComment(task.id, commentId, text); setEditingId(null); setEditingText(""); onTaskUpdated?.(updated); addToast("Comment updated", "success"); } catch (error: any) { addToast(error.message || "Failed to update comment", "error"); } finally { setSubmitting(false); } } async function handleDelete(commentId: string) { setDeletingId(commentId); try { const updated = await deleteTaskComment(task.id, commentId); onTaskUpdated?.(updated); addToast("Comment deleted", "success"); } catch (error: any) { addToast(error.message || "Failed to delete comment", "error"); } finally { setDeletingId(null); } } return (

Comments

{comments.length === 0 ? (
No comments yet.
) : (
{comments.map((comment) => { const canEdit = comment.author === currentAuthor; const isEditing = editingId === comment.id; return (
{comment.author} {formatCommentTimestamp(comment)}
{canEdit && !isEditing ? (
) : null}
{isEditing ? (