You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
6.4 KiB
183 lines
6.4 KiB
import React, { useState } from 'react';
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
import { MessageCircle, ThumbsUp, Reply, X } from "lucide-react";
|
|
|
|
const DiscussionSection = () => {
|
|
const [comment, setComment] = useState('');
|
|
const [replyingTo, setReplyingTo] = useState(null);
|
|
const [discussions, setDiscussions] = useState([
|
|
{
|
|
id: 1,
|
|
user: 'Sarah Chen',
|
|
avatar: '/api/placeholder/32/32',
|
|
content: 'This is really interesting! I particularly liked the section about state management.',
|
|
likes: 12,
|
|
replies: [
|
|
{
|
|
id: 101,
|
|
user: 'Alex Kim',
|
|
avatar: '/api/placeholder/32/32',
|
|
content: '@Sarah Chen Thanks for sharing your thoughts!',
|
|
timestamp: '1 hour ago'
|
|
}
|
|
],
|
|
timestamp: '2 hours ago'
|
|
},
|
|
{
|
|
id: 2,
|
|
user: 'Alex Kim',
|
|
avatar: '/api/placeholder/32/32',
|
|
content: 'Great explanation! Could you elaborate more on the useEffect implementation?',
|
|
likes: 8,
|
|
replies: [],
|
|
timestamp: '1 hour ago'
|
|
}
|
|
]);
|
|
|
|
const handleSubmit = () => {
|
|
if (comment.trim()) {
|
|
if (replyingTo) {
|
|
// Add reply to existing comment
|
|
const updatedDiscussions = discussions.map(discussion => {
|
|
if (discussion.id === replyingTo.commentId) {
|
|
return {
|
|
...discussion,
|
|
replies: [...discussion.replies, {
|
|
id: Date.now(),
|
|
user: 'Current User',
|
|
avatar: '/api/placeholder/32/32',
|
|
content: comment,
|
|
timestamp: 'Just now'
|
|
}]
|
|
};
|
|
}
|
|
return discussion;
|
|
});
|
|
setDiscussions(updatedDiscussions);
|
|
setReplyingTo(null);
|
|
} else {
|
|
// Add new top-level comment
|
|
const newComment = {
|
|
id: Date.now(),
|
|
user: 'Current User',
|
|
avatar: '/api/placeholder/32/32',
|
|
content: comment,
|
|
likes: 0,
|
|
replies: [],
|
|
timestamp: 'Just now'
|
|
};
|
|
setDiscussions([...discussions, newComment]);
|
|
}
|
|
setComment('');
|
|
}
|
|
};
|
|
|
|
const handleReply = (commentId, userName) => {
|
|
setReplyingTo({ commentId, userName });
|
|
setComment(`@${userName} `);
|
|
};
|
|
|
|
const cancelReply = () => {
|
|
setReplyingTo(null);
|
|
setComment('');
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<ScrollArea className="h-auto max-h-128">
|
|
<div className="space-y-6">
|
|
{discussions.map((discussion) => (
|
|
<div key={discussion.id} className="space-y-4">
|
|
<div className="flex gap-4">
|
|
<Avatar className="w-8 h-8">
|
|
<AvatarImage src={discussion.avatar} alt={discussion.user} />
|
|
<AvatarFallback>{discussion.user[0]}</AvatarFallback>
|
|
</Avatar>
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-2 mb-1">
|
|
<span className="font-medium">{discussion.user}</span>
|
|
<span className="text-sm text-gray-500">{discussion.timestamp}</span>
|
|
</div>
|
|
<p className="text-gray-700 mb-2">{discussion.content}</p>
|
|
<div className="flex items-center gap-4">
|
|
<button
|
|
className="flex items-center gap-1 text-sm text-gray-500 hover:text-gray-700"
|
|
onClick={() => handleReply(discussion.id, discussion.user)}
|
|
>
|
|
<Reply className="w-4 h-4" />
|
|
Reply
|
|
</button>
|
|
<div className="flex items-center gap-1 text-sm text-gray-500">
|
|
<MessageCircle className="w-4 h-4" />
|
|
{discussion.replies.length} replies
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Nested replies */}
|
|
{discussion.replies.length > 0 && (
|
|
<div className="ml-12 space-y-4">
|
|
{discussion.replies.map((reply) => (
|
|
<div key={reply.id} className="flex gap-4">
|
|
<Avatar className="w-8 h-8">
|
|
<AvatarImage src={reply.avatar} alt={reply.user} />
|
|
<AvatarFallback>{reply.user[0]}</AvatarFallback>
|
|
</Avatar>
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-2 mb-1">
|
|
<span className="font-medium">{reply.user}</span>
|
|
<span className="text-sm text-gray-500">{reply.timestamp}</span>
|
|
</div>
|
|
<p className="text-gray-700">{reply.content}</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</ScrollArea>
|
|
|
|
<div className="my-6">
|
|
<div className="flex items-start gap-4">
|
|
<Avatar className="w-8 h-8">
|
|
<AvatarImage src="/api/placeholder/32/32" alt="User" />
|
|
<AvatarFallback>U</AvatarFallback>
|
|
</Avatar>
|
|
<div className="flex-1">
|
|
{replyingTo && (
|
|
<div className="flex items-center gap-2 mb-2 text-sm text-gray-500">
|
|
<span>Replying to {replyingTo.userName}</span>
|
|
<button
|
|
onClick={cancelReply}
|
|
className="p-1 hover:bg-gray-100 rounded-full"
|
|
>
|
|
<X className="w-4 h-4" />
|
|
</button>
|
|
</div>
|
|
)}
|
|
<Textarea
|
|
placeholder={replyingTo ? `Reply to ${replyingTo.userName}...` : "Add to the discussion..."}
|
|
value={comment}
|
|
onChange={(e) => setComment(e.target.value)}
|
|
className="min-h-24 mb-6"
|
|
/>
|
|
<div className="w-fit ml-auto">
|
|
<Button onClick={handleSubmit} className="bg-purple-700">
|
|
{replyingTo ? 'Post Reply' : 'Post Comment'}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default DiscussionSection; |