213 lines
8.7 KiB
TypeScript
213 lines
8.7 KiB
TypeScript
import Link from "next/link";
|
|
import { notFound } from "next/navigation";
|
|
import Sidebar from "@/app/components/Sidebar";
|
|
import { avatarClasses } from "@/app/components/KidCard";
|
|
import type { Kid, Parent, ParentStatus } from "@/app/data/kids";
|
|
import { kids } from "@/app/data/kids";
|
|
|
|
/** Página 100% estática que deriva de params: permitido bloquear, sin Suspense. */
|
|
export const instant = false;
|
|
|
|
/** Los 8 slugs del mock se prerenderizan; cualquier otro cae en notFound(). */
|
|
export function generateStaticParams() {
|
|
return kids.map((kid) => ({ slug: kid.slug }));
|
|
}
|
|
|
|
/**
|
|
* Colores dinámicos → utilities Tailwind con valores exactos.
|
|
* El set de fondos del mock es cerrado; nunca se usan atributos style.
|
|
*/
|
|
const PARENT_BG: Record<string, string> = {
|
|
C9B6E8: "bg-[#C9B6E8]",
|
|
A9C7E8: "bg-[#A9C7E8]",
|
|
F4B8CC: "bg-[#F4B8CC]",
|
|
B9DEC4: "bg-[#B9DEC4]",
|
|
F2937A: "bg-[#F2937A]",
|
|
F4DC8E: "bg-[#F4DC8E]",
|
|
};
|
|
|
|
const STATUS_BADGE: Record<ParentStatus, { label: string; classes: string }> = {
|
|
activa: { label: "ACTIVA", classes: "bg-[#CFEBD8] text-[#3E9B6C]" },
|
|
pendiente: { label: "PENDIENTE", classes: "bg-[#F7E7A6] text-[#9A7B1E]" },
|
|
};
|
|
|
|
function parentClasses(parent: Parent): string {
|
|
return PARENT_BG[parent.bg.replace("#", "")] ?? "";
|
|
}
|
|
|
|
function ParentRow({ parent }: { parent: Parent }) {
|
|
const badge = STATUS_BADGE[parent.status];
|
|
return (
|
|
<div className="flex items-center gap-3">
|
|
<div
|
|
className={`flex h-10 w-10 flex-none items-center justify-center rounded-full font-display text-base font-semibold text-white ${parentClasses(parent)}`}
|
|
>
|
|
{parent.initial}
|
|
</div>
|
|
<div className="min-w-0 flex-1">
|
|
<div className="text-[14.5px] font-extrabold text-[#3F362E]">{parent.name}</div>
|
|
<div className="text-[12.5px] text-[#A89A8B]">
|
|
{parent.role} · {parent.note}
|
|
</div>
|
|
</div>
|
|
<span className={`flex-none rounded-full px-[9px] py-1 text-[10.5px] font-extrabold ${badge.classes}`}>
|
|
{badge.label}
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default async function KidProfilePage({ params }: { params: Promise<{ slug: string }> }) {
|
|
const { slug } = await params;
|
|
const kid: Kid | undefined = kids.find((candidate) => candidate.slug === slug);
|
|
if (!kid) notFound();
|
|
|
|
return (
|
|
<div className="flex min-h-screen bg-[#F6ECDF]">
|
|
<Sidebar activeHref="/kids" />
|
|
<main className="h-screen min-w-0 flex-1 overflow-y-auto">
|
|
<div className="mx-auto w-full max-w-[820px] px-10 pb-20 pt-[34px]">
|
|
{/* Breadcrumb */}
|
|
<Link
|
|
href="/kids"
|
|
className="mb-5 flex items-center gap-[7px] text-[14px] font-bold text-[#94887B]"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2.2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<path d="m15 18-6-6 6-6" />
|
|
</svg>
|
|
Volver a Niños
|
|
</Link>
|
|
|
|
<div className="flex flex-wrap items-start gap-[26px]">
|
|
{/* Columna izquierda */}
|
|
<div className="flex min-w-[300px] flex-1 flex-col gap-[18px]">
|
|
{/* Identidad */}
|
|
<div className="flex items-center gap-[18px]">
|
|
<div
|
|
className={`flex h-[84px] w-[84px] flex-none items-center justify-center rounded-full font-display text-[34px] font-semibold ${avatarClasses(kid)}`}
|
|
>
|
|
{kid.initial}
|
|
</div>
|
|
<div className="flex-1">
|
|
<h1 className="font-display text-[28px] font-semibold leading-[1.2] text-[#3F362E]">{kid.name}</h1>
|
|
<p className="mt-[3px] text-[15px] text-[#94887B]">
|
|
{kid.age} años · Sala {kid.room}
|
|
</p>
|
|
</div>
|
|
<Link
|
|
href="/agregar-nino"
|
|
className="rounded-[12px] border-[1.5px] border-[#ECE0D0] bg-[#FFFDF9] px-4 py-[9px] text-sm font-bold text-[#6E6359]"
|
|
>
|
|
Editar
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Alergias y notas (solo si tiene) */}
|
|
{kid.allergyNote && (
|
|
<div className="flex gap-[14px] rounded-[16px] bg-[#FBDAD6] px-[18px] py-4">
|
|
<div className="flex h-10 w-10 flex-none items-center justify-center rounded-[11px] bg-[#F4A8A0]">
|
|
<svg
|
|
width="22"
|
|
height="22"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="#fff"
|
|
strokeWidth="2.2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z" />
|
|
<path d="M12 9v4M12 17h.01" />
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<div className="mb-[2px] text-[15px] font-extrabold text-[#C5413A]">Alergias y notas</div>
|
|
<div className="text-[14.5px] leading-[1.5] text-[#B25249]">{kid.allergyNote}</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Datos */}
|
|
<div className="overflow-hidden rounded-[16px] border border-[#ECE0D0] bg-[#FFFDF9]">
|
|
<div className="flex justify-between border-b border-[#F0E6D8] px-[18px] py-[15px]">
|
|
<span className="text-[14.5px] text-[#94887B]">Fecha de nacimiento</span>
|
|
<span className="text-[14.5px] font-extrabold text-[#3F362E]">{kid.birthDate}</span>
|
|
</div>
|
|
<div className="flex justify-between border-b border-[#F0E6D8] px-[18px] py-[15px]">
|
|
<span className="text-[14.5px] text-[#94887B]">Sala</span>
|
|
<span className="text-[14.5px] font-extrabold text-[#3F362E]">{kid.room}</span>
|
|
</div>
|
|
<div className="flex justify-between px-[18px] py-[15px]">
|
|
<span className="text-[14.5px] text-[#94887B]">Ingreso</span>
|
|
<span className="text-[14.5px] font-extrabold text-[#3F362E]">{kid.admission}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Columna derecha */}
|
|
<div className="flex w-[300px] flex-none flex-col gap-[14px]">
|
|
<Link
|
|
href="/resumen-dia"
|
|
className="flex w-full items-center justify-center gap-[9px] rounded-[14px] bg-[#3F362E] py-[13px] text-[15px] font-extrabold text-white"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="#fff"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<circle cx="12" cy="12" r="4" />
|
|
<path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" />
|
|
</svg>
|
|
Resumen del día
|
|
</Link>
|
|
|
|
{/* Padres vinculados */}
|
|
<div className="rounded-[16px] border border-[#ECE0D0] bg-[#FFFDF9] px-[18px] py-4">
|
|
<div className="mb-[14px] text-[12.5px] font-extrabold tracking-[.8px] text-[#8A7C6D]">
|
|
PADRES VINCULADOS
|
|
</div>
|
|
<div className="flex flex-col gap-[14px]">
|
|
{kid.parents.map((parent) => (
|
|
<ParentRow key={parent.name} parent={parent} />
|
|
))}
|
|
<Link href="/vincular-padre" className="flex items-center gap-3 pt-2">
|
|
<span className="flex h-10 w-10 flex-none items-center justify-center rounded-full border-[1.5px] border-dashed border-[#D8CBBA] text-[#B0A290]">
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2.2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<path d="M12 5v14M5 12h14" />
|
|
</svg>
|
|
</span>
|
|
<span className="text-[14.5px] font-extrabold text-[#C5503A]">Vincular otro padre</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|