Files
J621/frontend/src/features/online/PostCard.tsx
T
JakeBreath 26f5069aa2 Fix pool post cards rendering as a colored sliver
PostCard's Link is inline by default; wrapped in a div on the pool detail
page it stopped being blockified like a grid child, so its rating-tinted
border collapsed into a vertical line on the left. The card is now
block-level, and the pool grid only wraps blacklisted posts (for the red
ring), so normal cards render exactly like the Online grid.
2026-09-17 14:32:24 -05:00

80 lines
2.6 KiB
TypeScript

import { CheckCircle2 } from "lucide-react";
import { Link } from "react-router-dom";
import { cn } from "@/lib/cn";
import type { E621Post } from "@/lib/e621";
import { formatBytes } from "@/lib/format";
const ratingBorder: Record<string, string> = {
s: "border-ctp-green/25 hover:border-ctp-green/60",
q: "border-ctp-peach/25 hover:border-ctp-peach/60",
e: "border-ctp-red/25 hover:border-ctp-red/60",
};
const ratingPill: Record<string, string> = {
s: "bg-ctp-green text-ctp-crust",
q: "bg-ctp-peach text-ctp-crust",
e: "bg-ctp-red text-ctp-crust",
};
export function PostCard({
post,
inLibrary,
from,
}: {
post: E621Post;
inLibrary: boolean;
from?: string;
}) {
return (
<Link
to={`/detail/${post.id}`}
state={from ? { from } : undefined}
className={cn(
"group block overflow-hidden rounded-lg border bg-ctp-base transition",
ratingBorder[post.rating] ?? "border-ctp-surface0",
)}
>
<div className="relative aspect-square overflow-hidden bg-ctp-mantle">
{post.preview.url ? (
<img
src={post.preview.url}
alt={`Post #${post.id}`}
loading="lazy"
className="h-full w-full object-cover transition duration-200 group-hover:scale-[1.03]"
/>
) : (
<div className="flex h-full w-full items-center justify-center text-xs text-ctp-overlay0">
No preview
</div>
)}
<span
className={cn(
"absolute left-2 top-2 rounded-full px-1.5 py-0.5 font-mono text-[10px] font-semibold uppercase",
ratingPill[post.rating] ?? "bg-ctp-surface1 text-ctp-text",
)}
>
{post.rating}
</span>
<span className="absolute right-2 top-2 rounded-sm bg-ctp-crust/80 px-1.5 py-0.5 font-mono text-[10px] uppercase text-ctp-overlay1">
{post.file.ext}
</span>
{inLibrary ? (
<span
className="absolute bottom-2 right-2 flex items-center gap-1 rounded-full bg-ctp-green/90 px-1.5 py-0.5 font-mono text-[10px] font-medium text-ctp-crust"
title="Already in your library"
>
<CheckCircle2 className="h-3 w-3" /> IN
</span>
) : null}
</div>
<div className="flex items-center justify-between gap-2 px-2.5 py-2">
<span className="font-mono text-xs text-ctp-subtext1">#{post.id}</span>
<span className="font-mono text-[11px] text-ctp-overlay0">
▲ {post.score.total} · {formatBytes(post.file.size)}
</span>
</div>
</Link>
);
}