import React, { useState } from 'react' import AuthorBadge from './AuthorBadge' const REACTIONS = [ { key: 'like', label: 'Like', emoji: '👍' }, { key: 'love', label: 'Love', emoji: '❤️' }, { key: 'fire', label: 'Amazing', emoji: '🔥' }, { key: 'laugh', label: 'Funny', emoji: '😂' }, { key: 'disagree', label: 'Disagree', emoji: '👎' }, ] export default function PostCard({ post, thread, isOp = false, isAuthenticated = false, canModerate = false }) { const [reactionState, setReactionState] = useState(post?.reactions ?? { summary: {}, active: null }) const [reacting, setReacting] = useState(false) const author = post?.user const content = post?.rendered_content ?? post?.content ?? '' const postedAt = post?.created_at const editedAt = post?.edited_at const isEdited = post?.is_edited const postId = post?.id const threadSlug = thread?.slug const handleReaction = async (reaction) => { if (reacting || !isAuthenticated) return setReacting(true) try { const res = await fetch(`/forum/post/${postId}/react`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': getCsrf(), 'Accept': 'application/json', }, credentials: 'same-origin', body: JSON.stringify({ reaction }), }) if (res.ok) { const json = await res.json() setReactionState(json) } } catch { /* silent */ } setReacting(false) } return (
{/* Header */}
{postedAt && ( )} {isOp && ( OP )}
{/* Body */}
{isEdited && editedAt && (

Edited {formatTimeAgo(editedAt)}

)} {/* Attachments */} {post?.attachments?.length > 0 && (

Attachments

{post.attachments.map((att) => ( ))}
)}
{/* Footer */}
) } function AttachmentItem({ attachment }) { const mime = attachment?.mime_type ?? '' const isImage = mime.startsWith('image/') const url = attachment?.url ?? '#' return (
{isImage ? ( Attachment ) : ( Download attachment )}
) } function getCsrf() { return document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') ?? '' } function formatDate(dateStr) { try { const d = new Date(dateStr) return d.toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' ' + d.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' }) } catch { return '' } } function formatTimeAgo(dateStr) { try { const now = new Date() const date = new Date(dateStr) const diff = Math.floor((now - date) / 1000) if (diff < 60) return 'just now' if (diff < 3600) return `${Math.floor(diff / 60)}m ago` if (diff < 86400) return `${Math.floor(diff / 3600)}h ago` if (diff < 604800) return `${Math.floor(diff / 86400)}d ago` return formatDate(dateStr) } catch { return '' } }