"use client"; import Image from "next/image"; import Link from "next/link"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import { useEffect, useMemo, useRef, useState } from "react"; import { Icon } from "@iconify/react"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { vscDarkPlus } from "react-syntax-highlighter/dist/esm/styles/prism"; import { Avatar, AvatarFallback, AvatarImage, Badge, Button, Card, Textarea, Typography, } from "poyraz-ui/atoms"; import { Sheet, SheetContent, SheetTitle, SheetTrigger } from "poyraz-ui/molecules"; import type { BlogDetail } from "@/data/blog-detail"; import type { BlogComment, BlogEngagement } from "@/data/blog-engagement"; type BlogDetailContentProps = { post: BlogDetail; engagement: BlogEngagement; }; function MermaidBlock({ chart }: { chart: string }) { const [svg, setSvg] = useState(""); const [error, setError] = useState(""); const idRef = useRef(`mermaid-${Math.random().toString(36).slice(2)}`); useEffect(() => { let mounted = true; const renderChart = async () => { try { const mermaid = (await import("mermaid")).default; mermaid.initialize({ startOnLoad: false, theme: "neutral", securityLevel: "loose" }); const { svg: rendered } = await mermaid.render(idRef.current, chart); if (mounted) { setSvg(rendered); setError(""); } } catch { if (mounted) { setError("Mermaid diagram could not be rendered."); } } }; void renderChart(); return () => { mounted = false; }; }, [chart]); if (error) { return ( {error} ); } if (!svg) { return ( Rendering diagram... ); } return (
); } export function BlogDetailContent({ post, engagement }: BlogDetailContentProps) { const scrollerRef = useRef(null); const [progress, setProgress] = useState(0); const [liked, setLiked] = useState(false); const [likeCount, setLikeCount] = useState(engagement.likes); const [comments, setComments] = useState(engagement.comments); const [commentSheetOpen, setCommentSheetOpen] = useState(false); const [githubAuthed, setGithubAuthed] = useState(false); const [draft, setDraft] = useState(""); const [replyTo, setReplyTo] = useState<{ id: string; author: string } | null>(null); const progressWidth = useMemo(() => `${Math.min(100, Math.max(0, progress))}%`, [progress]); const handleScroll = () => { const el = scrollerRef.current; if (!el) return; const scrollable = el.scrollHeight - el.clientHeight; if (scrollable <= 0) { setProgress(100); return; } setProgress((el.scrollTop / scrollable) * 100); }; const toggleLike = () => { setLiked((prev) => { const next = !prev; setLikeCount((count) => (next ? count + 1 : Math.max(0, count - 1))); return next; }); }; const handleReplyClick = (id: string, author: string) => { setReplyTo({ id, author }); setCommentSheetOpen(true); }; const handleSubmitComment = () => { if (!githubAuthed) return; const content = draft.trim(); if (!content) return; if (replyTo) { setComments((prev) => prev.map((item) => item.id === replyTo.id ? { ...item, replies: [ ...item.replies, { id: `reply-${Date.now()}`, author: "You (GitHub)", avatar: "/logo/logo.jpeg", date: "Just now", content, likes: 0, }, ], } : item, ), ); setReplyTo(null); } else { setComments((prev) => [ { id: `comment-${Date.now()}`, author: "You (GitHub)", avatar: "/logo/logo.jpeg", date: "Just now", content, likes: 0, replies: [], }, ...prev, ]); } setDraft(""); }; return ( <>
{"<- Back to blog"}
{post.category} {post.title} {post.author} - {post.date} - {post.readTime} {post.excerpt}
{post.title}
Comments
{comments.map((item) => (
{item.author.slice(0, 2).toUpperCase()}
{item.author} {item.date}
{item.content}
{item.replies.length > 0 ? (
{item.replies.map((reply) => (
{reply.author.slice(0, 2).toUpperCase()}
{reply.author} {reply.date}
{reply.content}
))}
) : null}
))}
{!githubAuthed ? ( You need to sign in with GitHub before posting comments. ) : null} {replyTo ? (
Replying to {replyTo.author}
) : null}