You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

122 lines
4.6 KiB

"use client";
import Link from "next/link";
import { useMarriageAdvisorsQuery } from "@/hooks/marriage/use-marriage-advisors";
import { localizePath } from "@/translations/config";
import { useI18n } from "@/translations/provider";
import NetworkImage from "./network-image";
const FALLBACK_AVATAR = "/assets/images/Avatar Image.png";
export type AdvisorAvatar = {
id: string;
src: string;
};
type AdvisorActionsCardProps = {
title: string;
description: string;
/** Static fallback avatars — used only while the API hasn't responded yet. */
avatars: AdvisorAvatar[];
extraCount: number;
getAdvisorLabel: string;
getAdvisorHref?: string;
onGetAdvisor?: () => void;
className?: string;
};
export function AdvisorActionsCard({
title,
description,
avatars: fallbackAvatars,
extraCount: fallbackExtraCount,
getAdvisorLabel,
getAdvisorHref,
onGetAdvisor,
className,
}: AdvisorActionsCardProps) {
const { locale } = useI18n();
const { data, isLoading } = useMarriageAdvisorsQuery();
const advisors = data?.results ?? [];
// Derive up to 3 avatars from API response (or fallback if empty).
const realAvatars: AdvisorAvatar[] = advisors.slice(0, 3).map((a, idx) => ({
id: a.username || `advisor-${idx}`,
src: a.avatar_url || (fallbackAvatars[idx]?.src ?? FALLBACK_AVATAR),
}));
const displayAvatars =
realAvatars.length > 0 ? realAvatars : fallbackAvatars.slice(0, 3);
// Show total remaining advisors (capped at advisor count minus shown avatars).
const totalCount =
advisors.length > 0
? advisors.length
: fallbackAvatars.length + fallbackExtraCount;
const displayExtraCount = Math.max(0, totalCount - displayAvatars.length);
return (
<section className={["w-full", className].filter(Boolean).join(" ")}>
<div className="rounded-[14px] border border-white/80 bg-white/75 px-4 py-3.5 text-left rtl:text-right shadow-none backdrop-blur-sm">
<h2 className="text-[13.5px] leading-tight font-bold text-[#1C1C1C]">
{title}
</h2>
<p className="mt-1.5 max-w-md text-[10.5px] leading-[1.4] font-medium text-[#8A8A8A]">
{description}
</p>
<div className="mt-3 flex items-center justify-between gap-3">
<div className="flex items-center shrink-0">
{isLoading
? /* ── Shimmer circles while API loads ── */
Array.from({ length: 3 }).map((_, i) => (
<span
key={`shimmer-${i}`}
className="-ms-1.5 flex h-[28px] w-[28px] overflow-hidden rounded-full border-2 border-white first:ms-0 shimmer-bg shrink-0"
/>
))
: displayAvatars.map((avatar, idx) => (
<span
key={avatar.id || idx}
className="-ms-1.5 flex h-[28px] w-[28px] overflow-hidden rounded-full border-2 border-white bg-[#E7E7E7] first:ms-0 shrink-0"
>
<NetworkImage
src={avatar.src}
fallbackSrc={FALLBACK_AVATAR}
alt=""
width={28}
height={28}
className="h-full w-full object-cover"
/>
</span>
))}
{!isLoading && displayExtraCount > 0 && (
<span className="-ms-1.5 flex h-[28px] w-[28px] items-center justify-center rounded-full border-2 border-white bg-[#EDEEF1] text-[10px] font-bold text-[#1C1C1C] shrink-0">
+{displayExtraCount}
</span>
)}
</div>
{getAdvisorHref ? (
<Link
href={localizePath(getAdvisorHref, locale)}
className="inline-flex h-[36px] min-w-[105px] px-3.5 shrink-0 items-center justify-center rounded-[9px] border-none bg-[#EBEDF0] text-[12.5px] font-bold text-[#111111] shadow-none hover:bg-[#E2E4E8] active:scale-[0.98] transition-all cursor-pointer whitespace-nowrap"
>
{getAdvisorLabel}
</Link>
) : (
<button
type="button"
onClick={onGetAdvisor}
className="inline-flex h-[36px] min-w-[105px] px-3.5 shrink-0 items-center justify-center rounded-[9px] border-none bg-[#EBEDF0] text-[12.5px] font-bold text-[#111111] shadow-none hover:bg-[#E2E4E8] active:scale-[0.98] transition-all cursor-pointer whitespace-nowrap"
>
{getAdvisorLabel}
</button>
)}
</div>
</div>
</section>
);
}
export default AdvisorActionsCard;