"use client"; import Image from "next/image"; import { useEffect, useState } from "react"; import { AudioLines, Images, PlayCircle } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent } from "@/components/ui/card"; import { formatDateTime } from "@/lib/format"; import { getPostAuthor, getPostPreviewMedia, getUserLabel } from "@/lib/post-utils"; import type { ApiPost } from "@/types/api"; function formatDuration(durationSeconds?: number | null) { if (typeof durationSeconds !== "number" || !Number.isFinite(durationSeconds) || durationSeconds <= 0) { return null; } const minutes = Math.floor(durationSeconds / 60); const seconds = Math.floor(durationSeconds % 60); return `${minutes}:${seconds.toString().padStart(2, "0")}`; } export function PostPreviewCard({ post }: { post: ApiPost }) { const author = getPostAuthor(post); const media = getPostPreviewMedia(post); const likes = post.engagement?.likesCount ?? post.likesCount ?? 0; const comments = post.engagement?.commentsCount ?? post.commentsCount ?? 0; const shares = post.engagement?.shareCount ?? post.shareCount ?? 0; const waveformPeaks = Array.isArray(post.waveformPeaks) && post.waveformPeaks.length ? post.waveformPeaks : [18, 32, 24, 44, 28, 40, 22, 36, 26, 30]; const durationLabel = formatDuration(post.durationSeconds); const [imageFailed, setImageFailed] = useState(false); const [sourceFailed, setSourceFailed] = useState(false); const [isVideoPlaying, setIsVideoPlaying] = useState(false); useEffect(() => { setImageFailed(false); setSourceFailed(false); setIsVideoPlaying(false); }, [media.url, media.sourceUrl]); const showAudioPreview = media.kind === "audio" && !!media.sourceUrl && !sourceFailed; const showVideoPreview = media.kind === "video" && !!media.sourceUrl && !sourceFailed && (isVideoPlaying || !media.url || imageFailed); const showImagePreview = !!media.url && !imageFailed && !(media.kind === "video" && isVideoPlaying); const showMediaShell = media.kind !== "text"; const showUnavailable = !showImagePreview && !showVideoPreview && !showAudioPreview; return ( {showMediaShell ? (
{showImagePreview ? ( {post.content setImageFailed(true)} className="object-cover" /> ) : null} {showVideoPreview ? (
) : null}
{post.visibility ?? "public"} {post.moderationStatus ?? "active"}
{getUserLabel(author)}
{formatDateTime(post.createdAt)}

{post.content?.trim() || "Media post without caption."}

{likes} likes {comments} comments {shares} shares
); }