import { useT } from "@agent-native/core/client/i18n"; import { IconX, IconCheck, IconTrash, IconMessageCircle, IconChevronDown, IconAlertTriangle, IconRefresh, } from "@tabler/icons-react"; import { useState, useRef, useEffect } from "react"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; import { useSlideComments, useCreateSlideComment, useResolveSlideComment, useDeleteSlideComment, emailToColor, formatRelativeTime, type CommentThread, type SlideComment, } from "@/hooks/use-slide-comments"; interface SlideCommentsPanelProps { deckId: string | null; slideId: string | null; pendingComment: { quotedText: string } | null; onPendingDone: () => void; onClose: () => void; } /** Initials avatar */ function Avatar({ email, name }: { email: string; name?: string | null }) { const color = emailToColor(email); const initials = (name || email) .split(/[@.\s]/) .filter(Boolean) .slice(0, 2) .map((s) => s[0].toUpperCase()) .join("") .slice(0, 2); return (
{initials}
); } /** Single comment (inside a thread) */ function CommentItem({ comment, onDelete, }: { comment: SlideComment; onDelete: () => void; }) { const t = useT(); const [hovered, setHovered] = useState(false); return (
setHovered(true)} onMouseLeave={() => setHovered(false)} >
{comment.author_name || comment.author_email.split("@")[0]}
{formatRelativeTime(comment.created_at)} {hovered && ( {t("comments.deleteComment")} )}

{comment.content}

); } /** Pending new comment input */ function PendingCommentInput({ quotedText, deckId, slideId, onDone, onCancel, }: { quotedText: string; deckId: string; slideId: string; onDone: () => void; onCancel: () => void; }) { const t = useT(); const [text, setText] = useState(""); const [error, setError] = useState(null); const textareaRef = useRef(null); const createComment = useCreateSlideComment(); useEffect(() => { textareaRef.current?.focus(); }, []); const submit = async () => { const trimmed = text.trim(); if (!trimmed) return; setError(null); try { await createComment.mutateAsync({ deckId, slideId, content: trimmed, quotedText: quotedText || undefined, }); setText(""); onDone(); } catch (err) { setError( err instanceof Error ? err.message : t("comments.saveCommentFailed"), ); } }; return (
{quotedText && (
"{quotedText}"
)}