Files
2026-10-19 00:58:45 -06:00

101 lines
4.6 KiB
TypeScript

import Link from "next/link";
import type { Post, PostCategory } from "@/app/data/feed";
/** Badge por categoría: colores exactos de la plantilla. */
const BADGES: Record<PostCategory, { label: string; classes: string }> = {
logro: { label: "LOGRO", classes: "bg-[#CFEBD8] text-[#3E9B6C]" },
actividad: { label: "ACTIVIDAD", classes: "bg-[#C7E7F1] text-[#2E89A6]" },
anuncio: { label: "ANUNCIO", classes: "bg-[#CCD8F4] text-[#4E72C8]" },
};
/**
* Colores dinámicos → utilities Tailwind con valores exactos.
* El set de pares del mock es cerrado; nunca se usan atributos style.
*/
const AVATAR_COLORS: Record<string, string> = {
"A9D9E8-1F7A93": "bg-[#A9D9E8] text-[#1F7A93]",
"CCD8F4-4E72C8": "bg-[#CCD8F4] text-[#4E72C8]",
};
function avatarClasses(post: Post): string {
const key = `${post.authorColors.bg.replace("#", "")}-${post.authorColors.text.replace("#", "")}`;
return AVATAR_COLORS[key] ?? "";
}
export default function PostCard({ post }: { post: Post }) {
const badge = BADGES[post.category];
return (
<article className="rounded-[20px] border border-[#ECE0D0] bg-[#FFFDF9] px-[22px] py-5 shadow-[0_4px_16px_-12px_rgba(120,90,60,.5)]">
{/* Encabezado: avatar + autor + badge */}
<div className="mb-[14px] flex items-center gap-3">
<div
className={`flex h-11 w-11 flex-none items-center justify-center rounded-full font-display text-[17px] font-semibold ${avatarClasses(post)}`}
>
{post.authorInitial ? (
post.authorInitial
) : (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="m3 11 18-5v12L3 14v-3zM11.6 16.8a3 3 0 1 1-5.8-1.6" />
</svg>
)}
</div>
<div className="flex-1">
<div className="font-display text-[16.5px] font-semibold text-[#3F362E]">{post.authorName}</div>
<div className="text-[12.5px] text-[#A89A8B]">
{post.timeLabel} · {post.publishedBy}
</div>
</div>
<div className={`flex items-center gap-[7px] rounded-full px-3 py-[6px] ${badge.classes}`}>
<span className="h-2 w-2 rounded-full bg-current" />
<span className="text-xs font-extrabold tracking-[.5px]">{badge.label}</span>
</div>
</div>
{/* Destinatario */}
<div className="mb-2.5 text-[12.5px] text-[#A89A8B]">Para: {post.audience}</div>
{/* Contenido */}
<p className="text-[15.5px] leading-[1.55] text-[#4A4038]">{post.body}</p>
{/* Placeholder de foto (solo posts de actividad con foto) */}
{post.photoLabel && (
<Link
href="/foto"
className="mt-[14px] flex h-[200px] flex-col items-center justify-center gap-2 rounded-2xl border-[1.5px] border-dashed border-[#DBCDBA] bg-[#F4ECE1] text-[#B0A290]"
>
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
<rect x="3" y="3" width="18" height="18" rx="2" />
<circle cx="9" cy="9" r="2" />
<path d="m21 15-3.6-3.6a2 2 0 0 0-2.8 0L6 21" />
</svg>
<span className="text-[13.5px]">Foto · {post.photoLabel}</span>
</Link>
)}
{/* Acciones */}
<div className="mt-4 flex items-center gap-[18px] border-t border-[#F0E6D8] pt-[14px]">
<span className="flex items-center gap-[7px] text-sm font-bold text-[#E0654A]">
<svg width="19" height="19" viewBox="0 0 24 24" fill="#E0654A" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1-1.1a5.5 5.5 0 0 0-7.8 7.8l1 1L12 21.2l7.8-7.8 1-1a5.5 5.5 0 0 0 0-7.8z" />
</svg>
{post.likes}
</span>
<Link
href="/detalle-publicacion"
className="flex items-center gap-[7px] text-sm font-bold text-[#94887B]"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8z" />
</svg>
{post.comments}
</Link>
<span className="flex-1" />
<Link href="/crear-publicacion" className="text-sm font-extrabold text-[#C5503A]">
Editar
</Link>
</div>
</article>
);
}