"use client"; import { useState } from "react"; import { CommentComposer } from "@/components/chat-comments/comment-composer/comment-composer"; import { CommentItem } from "@/components/chat-comments/comment-item/comment-item"; import type { CommentData } from "@/components/chat-comments/comment-item/types"; import { CommentPanel } from "@/components/chat-comments/comment-panel/comment-panel"; import { CommentThread } from "@/components/chat-comments/comment-thread/comment-thread"; import type { CommentThreadData } from "@/components/chat-comments/comment-thread/types"; import { CommentTrigger } from "@/components/chat-comments/comment-trigger/comment-trigger"; import { MemberMentionPicker } from "@/components/chat-comments/member-mention-picker/member-mention-picker"; import type { MemberOption } from "@/components/chat-comments/member-mention-picker/types"; const fakeMembersData: MemberOption[] = [ { id: "550e8400-e29b-41d4-a716-446655440001", displayName: "Alice Smith", email: "alice@example.com", avatarUrl: null, }, { id: "550e8400-e29b-41d4-a716-446655440002", displayName: "Bob Johnson", email: "bob.johnson@example.com", avatarUrl: null, }, { id: "550e8400-e29b-41d4-a716-446655440003", displayName: "Charlie Brown", email: "charlie@example.com", avatarUrl: null, }, { id: "550e8400-e29b-41d4-a716-446655440004", displayName: null, email: "david.wilson@example.com", avatarUrl: null, }, { id: "550e8400-e29b-41d4-a716-446655440005", displayName: "Emma Davis", email: "emma@example.com", avatarUrl: null, }, ]; const fakeCommentsData: CommentData[] = [ { id: 1, content: "This is a great response! @Alice Smith can you review?", contentRendered: "This is a great response! @Alice Smith can you review?", author: { id: "550e8400-e29b-41d4-a716-446655440002", displayName: "Bob Johnson", email: "bob.johnson@example.com", avatarUrl: null, }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), isEdited: false, canEdit: true, canDelete: true, }, { id: 2, content: "I checked this yesterday and it looks good.", contentRendered: "I checked this yesterday and it looks good.", author: { id: "550e8400-e29b-41d4-a716-446655440001", displayName: "Alice Smith", email: "alice@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 86400000).toISOString(), updatedAt: new Date(Date.now() - 3600000).toISOString(), isEdited: true, canEdit: false, canDelete: true, }, { id: 3, content: "Thanks @Bob Johnson and @Alice Smith for the quick turnaround!", contentRendered: "Thanks @Bob Johnson and @Alice Smith for the quick turnaround!", author: { id: "550e8400-e29b-41d4-a716-446655440004", displayName: null, email: "david.wilson@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 3600000 * 3).toISOString(), updatedAt: new Date(Date.now() - 3600000 * 3).toISOString(), isEdited: false, canEdit: true, canDelete: false, }, ]; const fakeThreadsData: CommentThreadData[] = [ { id: 1, messageId: 101, content: "This is a great response! @Alice Smith can you review?", contentRendered: "This is a great response! @Alice Smith can you review?", author: { id: "550e8400-e29b-41d4-a716-446655440002", displayName: "Bob Johnson", email: "bob.johnson@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 3600000).toISOString(), updatedAt: new Date(Date.now() - 3600000).toISOString(), isEdited: false, canEdit: true, canDelete: true, replyCount: 2, replies: [ { id: 2, content: "I checked this yesterday and it looks good.", contentRendered: "I checked this yesterday and it looks good.", author: { id: "550e8400-e29b-41d4-a716-446655440001", displayName: "Alice Smith", email: "alice@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 1800000).toISOString(), updatedAt: new Date(Date.now() - 1800000).toISOString(), isEdited: false, canEdit: false, canDelete: true, }, { id: 3, content: "Thanks @Alice Smith!", contentRendered: "Thanks @Alice Smith!", author: { id: "550e8400-e29b-41d4-a716-446655440002", displayName: "Bob Johnson", email: "bob.johnson@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 900000).toISOString(), updatedAt: new Date(Date.now() - 900000).toISOString(), isEdited: false, canEdit: true, canDelete: true, }, ], }, { id: 4, messageId: 101, content: "Can we also add some documentation for this feature?", contentRendered: "Can we also add some documentation for this feature?", author: { id: "550e8400-e29b-41d4-a716-446655440003", displayName: "Charlie Brown", email: "charlie@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 7200000).toISOString(), updatedAt: new Date(Date.now() - 7200000).toISOString(), isEdited: false, canEdit: false, canDelete: true, replyCount: 1, replies: [ { id: 5, content: "Good idea @Charlie Brown, I'll create a ticket for that.", contentRendered: "Good idea @Charlie Brown, I'll create a ticket for that.", author: { id: "550e8400-e29b-41d4-a716-446655440002", displayName: "Bob Johnson", email: "bob.johnson@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 6000000).toISOString(), updatedAt: new Date(Date.now() - 6000000).toISOString(), isEdited: false, canEdit: true, canDelete: true, }, ], }, { id: 6, messageId: 101, content: "I think we should also consider edge cases here. What happens if the input is empty?", contentRendered: "I think we should also consider edge cases here. What happens if the input is empty?", author: { id: "550e8400-e29b-41d4-a716-446655440001", displayName: "Alice Smith", email: "alice@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 10800000).toISOString(), updatedAt: new Date(Date.now() - 10800000).toISOString(), isEdited: false, canEdit: false, canDelete: true, replyCount: 3, replies: [ { id: 7, content: "Good point! We should add validation.", contentRendered: "Good point! We should add validation.", author: { id: "550e8400-e29b-41d4-a716-446655440002", displayName: "Bob Johnson", email: "bob.johnson@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 10000000).toISOString(), updatedAt: new Date(Date.now() - 10000000).toISOString(), isEdited: false, canEdit: true, canDelete: true, }, { id: 8, content: "I'll handle the validation logic @Alice Smith", contentRendered: "I'll handle the validation logic @Alice Smith", author: { id: "550e8400-e29b-41d4-a716-446655440003", displayName: "Charlie Brown", email: "charlie@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 9500000).toISOString(), updatedAt: new Date(Date.now() - 9500000).toISOString(), isEdited: false, canEdit: false, canDelete: true, }, { id: 9, content: "Thanks @Charlie Brown!", contentRendered: "Thanks @Charlie Brown!", author: { id: "550e8400-e29b-41d4-a716-446655440001", displayName: "Alice Smith", email: "alice@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 9000000).toISOString(), updatedAt: new Date(Date.now() - 9000000).toISOString(), isEdited: false, canEdit: false, canDelete: true, }, ], }, { id: 10, messageId: 101, content: "The performance looks great in the benchmarks. Nice work everyone!", contentRendered: "The performance looks great in the benchmarks. Nice work everyone!", author: { id: "550e8400-e29b-41d4-a716-446655440005", displayName: "Emma Davis", email: "emma@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 14400000).toISOString(), updatedAt: new Date(Date.now() - 14400000).toISOString(), isEdited: false, canEdit: false, canDelete: true, replyCount: 0, replies: [], }, { id: 11, messageId: 101, content: "Should we schedule a review meeting for this?", contentRendered: "Should we schedule a review meeting for this?", author: { id: "550e8400-e29b-41d4-a716-446655440004", displayName: null, email: "david.wilson@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 18000000).toISOString(), updatedAt: new Date(Date.now() - 18000000).toISOString(), isEdited: true, canEdit: true, canDelete: true, replyCount: 2, replies: [ { id: 12, content: "Yes, let's do it tomorrow at 10am", contentRendered: "Yes, let's do it tomorrow at 10am", author: { id: "550e8400-e29b-41d4-a716-446655440002", displayName: "Bob Johnson", email: "bob.johnson@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 17000000).toISOString(), updatedAt: new Date(Date.now() - 17000000).toISOString(), isEdited: false, canEdit: true, canDelete: true, }, { id: 13, content: "Works for me!", contentRendered: "Works for me!", author: { id: "550e8400-e29b-41d4-a716-446655440005", displayName: "Emma Davis", email: "emma@example.com", avatarUrl: null, }, createdAt: new Date(Date.now() - 16000000).toISOString(), updatedAt: new Date(Date.now() - 16000000).toISOString(), isEdited: false, canEdit: false, canDelete: true, }, ], }, ]; export default function ChatCommentsPreviewPage() { const [highlightedIndex, setHighlightedIndex] = useState(0); const [selectedMember, setSelectedMember] = useState(null); const [submittedContent, setSubmittedContent] = useState(null); const [isPanelOpen, setIsPanelOpen] = useState(false); const [isEmptyPanelOpen, setIsEmptyPanelOpen] = useState(false); return (

Chat Comments UI Preview

Preview page for chat comments components with fake data

{/* Full Integration Simulation */}

🎯 Full Integration Simulation

Two scenarios: no comments (hover to see trigger) and with comments (always visible).

{/* Scenario 1: No comments yet */}

No comments yet — hover to see trigger, click to add first comment

AI Assistant

This is an AI response with no comments yet. Hover over this message to reveal the comment trigger icon on the right. Click to open the panel and add the first comment.

setIsEmptyPanelOpen(!isEmptyPanelOpen)} /> {isEmptyPanelOpen && ( alert(`Create first comment: ${content}`)} onCreateReply={() => {}} onEditComment={() => {}} onDeleteComment={() => {}} maxHeight={300} /> )}
{/* Scenario 2: Has comments */}

Has comments — trigger always visible, click to toggle panel

AI Assistant

Based on my analysis, the quarterly revenue increased by 15% compared to the previous period. The main drivers were the expansion into new markets and improved customer retention rates. I recommend focusing on the following areas for continued growth...

setIsPanelOpen(!isPanelOpen)} /> {isPanelOpen && ( alert(`Create comment: ${content}`)} onCreateReply={(id, content) => alert(`Reply to ${id}: ${content}`)} onEditComment={(id) => alert(`Edit ${id}`)} onDeleteComment={(id) => alert(`Delete ${id}`)} maxHeight={350} /> )}
{/* Comment Composer Section */}

Comment Composer

Type @ to trigger mention picker. Use Tab/Shift+Tab/Arrow keys to navigate, Enter to select.

setSubmittedContent(content)} onCancel={() => setSubmittedContent(null)} autoFocus />
{submittedContent && (
Submitted content: {submittedContent}
)}
{/* Comment Trigger Section */}

Comment Trigger

Toggle button on AI messages. Clicking opens/closes the comment panel.

No comments yet

Hidden until hover

AI response... {}} />

5 comments exist

Always visible with count

AI response... {}} />

Panel is open

Active/pressed state

AI response... {}} />
{/* Comment Panel Section */}

Comment Panel

Full panel with scrollable threads and composer. Shows alongside AI responses.

With comments

alert(`Create: ${content}`)} onCreateReply={(id, content) => alert(`Reply ${id}: ${content}`)} onEditComment={(id) => alert(`Edit ${id}`)} onDeleteComment={(id) => alert(`Delete ${id}`)} />

Empty state

alert(`Create: ${content}`)} onCreateReply={(id, content) => alert(`Reply ${id}: ${content}`)} onEditComment={(id) => alert(`Edit ${id}`)} onDeleteComment={(id) => alert(`Delete ${id}`)} />

Loading

{}} onCreateReply={() => {}} onEditComment={() => {}} onDeleteComment={() => {}} />
{/* Comment Thread Section */}

Comment Thread

Two top-level comments with replies. Click Reply to open composer. Click the replies count to collapse/expand.

{fakeThreadsData.map((thread) => ( alert(`Reply to ${commentId}: ${content}`)} onEditComment={(commentId) => alert(`Edit comment ${commentId}`)} onDeleteComment={(commentId) => alert(`Delete comment ${commentId}`)} /> ))}
{/* Comment Item Section */}

Comment Item (Standalone)

Individual comment components. Hover to see action menu.

alert(`Edit comment ${id}`)} onDelete={(id) => alert(`Delete comment ${id}`)} onReply={(id) => alert(`Reply to comment ${id}`)} />
{/* Member Mention Picker Section */}

Member Mention Picker (Standalone)

After typing @

Shows all members

setSelectedMember(member)} onHighlightChange={setHighlightedIndex} />
{selectedMember && (
Selected: @[{selectedMember.id.slice(0, 8)}...]
)}

After typing @ali

Filtered to matching members

{}} onHighlightChange={() => {}} />

Loading State

While fetching members

{}} onHighlightChange={() => {}} />

No Results

After typing @xyz (no match)

{}} onHighlightChange={() => {}} />
); }