diff --git a/frontend/src/components/partials/PostCard.tsx b/frontend/src/components/partials/PostCard.tsx new file mode 100644 index 0000000..15d57cd --- /dev/null +++ b/frontend/src/components/partials/PostCard.tsx @@ -0,0 +1,174 @@ +import { Link } from "react-router-dom" +import { Card } from "@/components/ui/card" +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" +import { File, FileText, Play, ImagePlay } from "lucide-react" +import { relativeTime, getFirstGrapheme } from "@/lib/utils" + +import { getFileUrl } from "@/services/api" + +interface PostCardProps { + post_id: string + title: string + description: string + creator: { + [key: string]: string + } + date: { + [key: string]: string + } + media: Array<{ + [key: string]: string + }> + media_count: number + source_site: { + [key: string]: string + } +} + +export function PostCard({ post_id, title, description, creator, date, media, media_count, source_site }: PostCardProps) { + const renderMedia = () => { + const mediaCount = media.length; + + const baseImageClass = "object-cover w-full h-full rounded-md"; + + if (mediaCount === 0) { + return ( +
+

No attached files

+
+ ); + } + + if (mediaCount === 1) { + return ( +
+ {`${title} + {renderMediaBadge(media[0])} +
+ ); + } + + if (mediaCount === 2) { + return ( +
+ {media.map((item, index) => ( +
+ {`${title} + {renderMediaBadge(item)} +
+ ))} +
+ ); + } + + if (mediaCount === 3) { + return ( +
+
+ {`${title} + {renderMediaBadge(media[0])} +
+
+ {`${title} + {renderMediaBadge(media[1])} +
+
+ {`${title} + {renderMediaBadge(media[2])} +
+
+ ); + } + + return ( +
+ {media.slice(0, 4).map((item, index) => ( +
+ {`${title} + {renderMediaBadge(item)} + {index === 3 && mediaCount > 4 && ( +
+ +{mediaCount - 4} +
+ )} +
+ ))} +
+ ); + }; + + const renderMediaBadge = (item: { type: 'image' | 'video' | 'gif' | 'pdf', src: string }) => { + if (item.type === 'video') { + return ( +
+ + Video +
+ ); + } else if (item.type === 'gif') { + return ( +
+ + GIF +
+ ); + } else if (item.type === 'pdf') { + return ( +
+ + Doc +
+ ); + }; + return null; + }; + + const renderSourceSiteIcon = () => { + if (source_site.slug === 'twitter') { + return ( +
+ Twitter Icon +
+ ) + } else if (source_site.slug === 'furaffinity') { + return ( +
+ Furaffinity Icon +
+ ) + } + } + + return ( + + +
+ {renderMedia()} + {renderSourceSiteIcon()} +
+

+ {title || (description.length > 28 ? `${description.substring(0, 28)}...` : description)} +

+
+
+ + {creator.avatar && } + {getFirstGrapheme(creator.name)} + +
{creator.name}
+
+
+
{relativeTime(date.created)}
+
+ +
{media_count}
+
+
+
+
+
+
+ + ) +} +