first commit
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import { EyeIcon, HeartIcon, PencilIcon, Trash2Icon } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { StatusBadge } from "@/components/hexa/status-badge"
|
||||
|
||||
interface PostCardAuthor {
|
||||
name: string
|
||||
role?: string
|
||||
avatarUrl?: string
|
||||
}
|
||||
|
||||
interface PostCardProps {
|
||||
imageUrl?: string
|
||||
title: string
|
||||
description: string
|
||||
tag?: string
|
||||
author: PostCardAuthor
|
||||
published: boolean
|
||||
likes: number
|
||||
createdAt: string
|
||||
liked?: boolean
|
||||
onToggleLike?: () => void
|
||||
onView?: () => void
|
||||
onEdit?: () => void
|
||||
onDelete?: () => void
|
||||
className?: string
|
||||
}
|
||||
|
||||
function PostCard({
|
||||
imageUrl,
|
||||
title,
|
||||
description,
|
||||
tag,
|
||||
author,
|
||||
published,
|
||||
likes,
|
||||
createdAt,
|
||||
liked,
|
||||
onToggleLike,
|
||||
onView,
|
||||
onEdit,
|
||||
onDelete,
|
||||
className,
|
||||
}: PostCardProps) {
|
||||
return (
|
||||
<Card className={cn("gap-0 overflow-hidden p-0", className)}>
|
||||
{imageUrl && (
|
||||
<div className="aspect-video w-full overflow-hidden bg-muted">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img src={imageUrl} alt="" className="size-full object-cover" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col gap-3 p-4">
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<h3 className="font-semibold">{title}</h3>
|
||||
<StatusBadge status={published ? "success" : "neutral"}>
|
||||
{published ? "Published" : "Draft"}
|
||||
</StatusBadge>
|
||||
</div>
|
||||
|
||||
<p className="line-clamp-2 text-sm text-muted-foreground">{description}</p>
|
||||
|
||||
{tag && (
|
||||
<Badge variant="secondary" className="w-fit">
|
||||
{tag}
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-between gap-2 border-t pt-3">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
<Avatar size="sm">
|
||||
<AvatarImage src={author.avatarUrl} alt={author.name} />
|
||||
<AvatarFallback>{author.name.slice(0, 1)}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="min-w-0 leading-tight">
|
||||
<p className="truncate text-sm font-medium">{author.name}</p>
|
||||
{author.role && (
|
||||
<p className="truncate text-xs text-muted-foreground">{author.role}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center gap-3 text-xs text-muted-foreground">
|
||||
{onToggleLike ? (
|
||||
<button
|
||||
type="button"
|
||||
aria-label={liked ? "Unlike post" : "Like post"}
|
||||
className="flex items-center gap-1"
|
||||
onClick={onToggleLike}
|
||||
>
|
||||
<HeartIcon
|
||||
className={cn(
|
||||
"size-3.5",
|
||||
liked ? "fill-rose-500 text-rose-500" : "text-muted-foreground"
|
||||
)}
|
||||
/>
|
||||
{likes}
|
||||
</button>
|
||||
) : (
|
||||
<span className="flex items-center gap-1">
|
||||
<HeartIcon className="size-3.5 fill-rose-500 text-rose-500" />
|
||||
{likes}
|
||||
</span>
|
||||
)}
|
||||
<span>{createdAt}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{(onView || onEdit || onDelete) && (
|
||||
<div className="flex items-center justify-end gap-1.5">
|
||||
{onView && (
|
||||
<Button variant="outline" size="icon-sm" aria-label="View" onClick={onView}>
|
||||
<EyeIcon />
|
||||
</Button>
|
||||
)}
|
||||
{onEdit && (
|
||||
<Button variant="outline" size="icon-sm" aria-label="Edit" onClick={onEdit}>
|
||||
<PencilIcon />
|
||||
</Button>
|
||||
)}
|
||||
{onDelete && (
|
||||
<Button variant="destructive" size="icon-sm" aria-label="Delete" onClick={onDelete}>
|
||||
<Trash2Icon />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export { PostCard }
|
||||
export type { PostCardAuthor }
|
||||
Reference in New Issue
Block a user