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.
 
 
 
FreeBug/frontend/edu-connect/src/components/elements/DiscussionForm.tsx

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;