import React from 'react'; import { Link } from 'react-router-dom'; import { ArrowUp, ArrowDown, MessageSquare } from 'lucide-react'; import { formatDistanceToNow } from 'date-fns'; import type { Post } from '@opchan/core'; import { RelevanceIndicator } from '@/components/ui/relevance-indicator'; import { AuthorDisplay } from '@/components/ui/author-display'; import { BookmarkButton } from '@/components/ui/bookmark-button'; import { LinkRenderer } from '@/components/ui/link-renderer'; import { useAuth, useContent, usePermissions } from '@/hooks'; import { ShareButton } from '@/components/ui/ShareButton'; interface PostCardProps { post: Post; } const PostCard: React.FC = ({ post }) => { const { bookmarks, pending, vote, togglePostBookmark, cells, commentsByPost, } = useContent(); const permissions = usePermissions(); const { currentUser } = useAuth(); const cellName = cells.find(c => c.id === post.cellId)?.name || 'unknown'; const commentCount = commentsByPost[post.id]?.length || 0; const isPending = pending.isPending(post.id); const isBookmarked = bookmarks.some( b => b.targetId === post.id && b.type === 'post' ); const [bookmarkLoading, setBookmarkLoading] = React.useState(false); const score = post.upvotes.length - post.downvotes.length; const userUpvoted = Boolean( post.upvotes.some(v => v.author === currentUser?.address) ); const userDownvoted = Boolean( post.downvotes.some(v => v.author === currentUser?.address) ); const contentText = typeof post.content === 'string' ? post.content : String(post.content ?? ''); const contentPreview = contentText.length > 200 ? contentText.substring(0, 200) + '...' : contentText; const handleVote = async (e: React.MouseEvent, isUpvote: boolean) => { e.preventDefault(); await vote({ targetId: post.id, isUpvote }); }; const handleBookmark = async (e?: React.MouseEvent) => { if (e) { e.preventDefault(); e.stopPropagation(); } setBookmarkLoading(true); try { await togglePostBookmark(post, post.cellId); } finally { setBookmarkLoading(false); } }; return (
{/* Voting column */}
{score} {isPending && ( syncing… )}
{/* Content column */}
{/* Post metadata */}
{ if (!cellName) e.preventDefault(); }} title={cellName ? `Go to /${cellName}` : undefined} > r/{cellName || 'unknown'} Posted by u/ {formatDistanceToNow(new Date(post.timestamp), { addSuffix: true, })} {'relevanceScore' in post && typeof (post as Post).relevanceScore === 'number' && ( <> )}
{/* Post title and content - clickable to navigate to post */}

{post.title}

{/* Post content preview */}

{/* Post actions */}
{commentCount} comments
{isPending && ( syncing… )}
); }; export default PostCard;