"use client"; import React, { useState, useEffect } from "react"; import { lmsApi, ThreadWithAuthor, PostWithAuthor } from "@/lib/api"; import PostCard from "./PostCard"; import ReplyEditor from "./ReplyEditor"; import { ArrowLeft, Pin, Lock, Bell, BellOff, Eye, MessageSquare } from "lucide-react"; import { formatDistanceToNow } from "date-fns"; import { es } from "date-fns/locale"; import { useAuth } from "@/context/AuthContext"; interface ThreadDetailProps { threadId: string; onBack: () => void; } export default function ThreadDetail({ threadId, onBack }: ThreadDetailProps) { const { user } = useAuth(); const [thread, setThread] = useState(null); const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [showReplyEditor, setShowReplyEditor] = useState(false); const [replyingTo, setReplyingTo] = useState(null); const [isSubscribed, setIsSubscribed] = useState(false); const isInstructor = user?.role === 'instructor' || user?.role === 'admin'; useEffect(() => { loadThread(); }, [threadId]); const loadThread = async () => { setLoading(true); try { const data = await lmsApi.getThreadDetail(threadId); setThread(data.thread); setPosts(data.posts); } catch (error) { console.error("Error loading thread:", error); } finally { setLoading(false); } }; const handleReply = (parentId: string | null) => { setReplyingTo(parentId); setShowReplyEditor(true); }; const handleSubmitReply = async (content: string) => { try { await lmsApi.createPost(threadId, { content, parent_post_id: replyingTo || undefined }); setShowReplyEditor(false); setReplyingTo(null); await loadThread(); // Reload to show new post } catch (error) { console.error("Error creating post:", error); throw error; } }; const handleVote = async (postId: string, voteType: 'upvote' | 'downvote') => { try { await lmsApi.votePost(postId, voteType); await loadThread(); // Reload to update vote counts } catch (error) { console.error("Error voting:", error); } }; const handleEndorse = async (postId: string) => { try { await lmsApi.endorsePost(postId); await loadThread(); // Reload to update endorsed status } catch (error) { console.error("Error endorsing post:", error); } }; const handlePin = async () => { try { await lmsApi.pinThread(threadId); await loadThread(); } catch (error) { console.error("Error pinning thread:", error); } }; const handleLock = async () => { try { await lmsApi.lockThread(threadId); await loadThread(); } catch (error) { console.error("Error locking thread:", error); } }; const handleSubscribe = async () => { try { if (isSubscribed) { await lmsApi.unsubscribeThread(threadId); } else { await lmsApi.subscribeThread(threadId); } setIsSubscribed(!isSubscribed); } catch (error) { console.error("Error toggling subscription:", error); } }; if (loading) { return (
); } if (!thread) { return (

Hilo no encontrado

); } return (
{/* Header */}
{/* Instructor Actions */} {isInstructor && ( <> )} {/* Subscribe Button */}
{/* Thread Card */}

{thread.title}

{thread.author_name} {formatDistanceToNow(new Date(thread.created_at), { addSuffix: true, locale: es })} {thread.view_count} vistas {thread.post_count} respuestas
{thread.content}
{!thread.is_locked && ( )}
{/* Reply Editor */} {showReplyEditor && !thread.is_locked && ( { setShowReplyEditor(false); setReplyingTo(null); }} /> )} {/* Posts */}

{posts.length} {posts.length === 1 ? 'Respuesta' : 'Respuestas'}

{posts.map((post) => ( ))}
); }