Products: carry the IMVU parent's image and categories
CI / test (push) Successful in 49s

Revisions with an IMVU parent store its public info (image, category path, gender)
from IMVU's product API, looked up after registering and in a periodic pass.
Product views gain parent, image and categories; GET /products takes category and
limit. The website shows the image on cards and product pages.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-30 01:03:02 -07:00
1 parent d57674d90c
commit 6668b55117
15 files changed
+2026 -29

No files matched your search

+18 -2
View File
@@ -21,15 +21,31 @@ export function formatSize(bytes: number): string {
return `${n < 10 ? n.toFixed(1) : Math.round(n)} ${units[i]}`;
}
/** The image of the IMVU product a product derives from (IMVU's, from IMVU), if it has one. */
export function ProductImage({ src, className }: { src: string | null | undefined; className?: string }) {
if (!src) return null;
return (
<img
src={src}
alt=""
referrerPolicy="no-referrer"
loading="lazy"
className={`aspect-[5/4] w-full bg-muted object-contain ${className ?? ""}`}
/>
);
}
export function ProductCard({
product,
children,
}: {
product: Pick<ProductSummary, "id" | "name" | "creator" | "rating" | "latest">;
product: Pick<ProductSummary, "id" | "name" | "creator" | "rating" | "latest" | "image" | "categories">;
children?: React.ReactNode;
}) {
const category = product.categories.at(-1)?.name;
return (
<Card className="h-full">
<ProductImage src={product.image} />
<CardContent className="space-y-2">
<div className="flex items-start justify-between gap-2">
<Link href={`/products/${product.id}`} className="font-medium underline-offset-4 hover:underline">
@@ -38,7 +54,7 @@ export function ProductCard({
<RatingTag rating={product.rating} />
</div>
<p className="text-xs text-muted-foreground">
{[product.creator && `by ${product.creator}`, `revision ${product.latest}`].filter(Boolean).join(" · ")}
{[product.creator && `by ${product.creator}`, category, `revision ${product.latest}`].filter(Boolean).join(" · ")}
</p>
{children}
</CardContent>