fix(ads): AdCard matches PostCard layout — same header, image, footer structure

This commit is contained in:
admin committed 2026-06-21 16:23:24 +02:00
1 parent 6f671cfc63
commit a9793a5ad2
1 file changed
+58 -49
+58 -49
View File
@@ -14,62 +14,71 @@ type AdCardAd = {
export function AdCard({ ad }: { ad: AdCardAd }) {
const imageUrl = getMediaUrl(ad.imageKey);
const inner = (
<div className="rounded-2xl border border-orange-200/20 bg-card overflow-hidden">
{/* Image */}
{imageUrl && (
// eslint-disable-next-line @next/next/no-img-element
<img
src={imageUrl}
alt={ad.title}
className="w-full object-cover max-h-80"
/>
)}
return (
<article className="bg-card border border-border rounded-lg overflow-hidden">
{/* Header — mirrors PostCard layout */}
<div className="flex items-center gap-3 px-4 py-3">
{/* Sponsor "avatar" — orange circle with paw */}
<div className="w-8 h-8 rounded-full bg-orange-500/15 border border-orange-400/30 flex items-center justify-center shrink-0">
<span className="text-base leading-none select-none" aria-hidden="true">🐾</span>
</div>
{/* Text area */}
<div className="px-4 py-3 flex flex-col gap-1.5">
{/* Sponsored badge row */}
<div className="flex items-center justify-between">
<span className="text-[10px] font-semibold uppercase tracking-widest text-orange-400 bg-orange-400/10 px-2 py-0.5 rounded-full">
Sponsored
</span>
{/* Name + badge row */}
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<p className="text-base font-semibold text-foreground leading-tight truncate">
{ad.title}
</p>
<span className="shrink-0 text-[10px] font-semibold uppercase tracking-widest text-orange-400 bg-orange-400/10 px-2 py-0.5 rounded-full">
Sponsored
</span>
</div>
{ad.targetUrl && (
<ExternalLink className="h-3.5 w-3.5 text-muted-foreground" />
<p className="text-xs text-muted-foreground truncate">
{ad.targetUrl.replace(/^https?:\/\//, "").replace(/\/$/, "")}
</p>
)}
</div>
<p className="text-sm font-semibold text-foreground leading-snug">
{ad.title}
</p>
{ad.caption && (
<p className="text-sm text-muted-foreground leading-relaxed">
{ad.caption}
</p>
)}
{/* External link button — mirrors options button position */}
{ad.targetUrl && (
<p className="text-xs text-orange-400/70 truncate mt-0.5">
{ad.targetUrl.replace(/^https?:\/\//, "")}
</p>
<a
href={ad.targetUrl}
target="_blank"
rel="noopener noreferrer sponsored"
className="flex items-center justify-center w-11 h-11 rounded-full hover:bg-muted transition-colors"
aria-label={`${ad.title} besuchen`}
>
<ExternalLink className="h-5 w-5 text-muted-foreground" aria-hidden="true" />
</a>
)}
</div>
</div>
{/* Image area — same dimensions as PostCard single image */}
{imageUrl && (
<a
href={ad.targetUrl ?? undefined}
target={ad.targetUrl ? "_blank" : undefined}
rel={ad.targetUrl ? "noopener noreferrer sponsored" : undefined}
className={ad.targetUrl ? "block" : undefined}
tabIndex={ad.targetUrl ? 0 : -1}
aria-label={ad.targetUrl ? `${ad.title} besuchen` : undefined}
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={imageUrl}
alt={ad.title}
className="w-full object-cover max-h-[560px]"
/>
</a>
)}
{/* Footer — caption only, mirrors PostCard footer */}
{ad.caption && (
<div className="px-4 py-3">
<p className="text-sm text-foreground">{ad.caption}</p>
</div>
)}
</article>
);
if (ad.targetUrl) {
return (
<a
href={ad.targetUrl}
target="_blank"
rel="noopener noreferrer sponsored"
className="block no-underline hover:opacity-90 transition-opacity"
aria-label={`Gesponsert: ${ad.title}`}
>
{inner}
</a>
);
}
return inner;
}