Browse Source

feat(ui): integrate real marriage advisors data into advisor actions card

Update `AdvisorActionsCard` to fetch real advisor data using `useMarriageAdvisorsQuery`.

The component now:
- Fetches live advisor data and handles loading states with a shimmer effect.
- Derives real avatars from the API response, falling back to provided props if no data is available.
- Dynamically calculates the extra advisor count based on the API results.
- Implements a fallback avatar for missing user profile images.
master
mortezaei 1 week ago
parent
commit
21d734eb48
  1. 43
      src/components/Componentes/advisor-actions-card.tsx

43
src/components/Componentes/advisor-actions-card.tsx

@ -1,8 +1,11 @@
"use client";
import Image from "next/image";
import { useMarriageAdvisorsQuery } from "@/hooks/marriage/use-marriage-advisors";
import Button from "./button";
const FALLBACK_AVATAR = "/assets/images/Avatar Image.png";
export type AdvisorAvatar = {
id: string;
src: string;
@ -11,6 +14,7 @@ export type AdvisorAvatar = {
type AdvisorActionsCardProps = {
title: string;
description: string;
/** Static fallback avatars — used only while the API hasn't responded yet. */
avatars: AdvisorAvatar[];
extraCount: number;
getAdvisorLabel: string;
@ -21,12 +25,33 @@ type AdvisorActionsCardProps = {
export function AdvisorActionsCard({
title,
description,
avatars,
extraCount,
avatars: fallbackAvatars,
extraCount: fallbackExtraCount,
getAdvisorLabel,
getAdvisorHref,
className,
}: AdvisorActionsCardProps) {
const { data, isLoading } = useMarriageAdvisorsQuery();
const advisors = data?.results ?? [];
// Derive real avatars from API response (pick first 3 with an avatar).
const realAvatars: AdvisorAvatar[] = advisors
.filter((a) => a.avatar_url)
.slice(0, 3)
.map((a) => ({
id: a.username,
src: a.avatar_url ?? FALLBACK_AVATAR,
}));
const displayAvatars =
realAvatars.length > 0 ? realAvatars : fallbackAvatars;
// Show total remaining advisors (capped at advisor count minus shown avatars).
const displayExtraCount =
advisors.length > 0
? Math.max(0, advisors.length - displayAvatars.length)
: fallbackExtraCount;
return (
<section className={["space-y-3", className].filter(Boolean).join(" ")}>
<div className="rounded-[13px] border border-white/80 bg-white/72 px-3 py-3.5 text-left shadow-[0_18px_45px_rgba(15,23,42,0.06)] backdrop-blur-sm">
@ -39,7 +64,15 @@ export function AdvisorActionsCard({
<div className="mt-4 flex items-center justify-between gap-3">
<div className="flex items-center pl-1">
{avatars.map((avatar) => (
{isLoading
? /* ── Shimmer circles while API loads ── */
Array.from({ length: 3 }).map((_, i) => (
<span
key={`shimmer-${i}`}
className="-ml-1.5 flex h-[30px] w-[30px] overflow-hidden rounded-full border-2 border-white first:ml-0 shimmer-bg"
/>
))
: displayAvatars.map((avatar) => (
<span
key={avatar.id}
className="-ml-1.5 flex h-[30px] w-[30px] overflow-hidden rounded-full border-2 border-white bg-[#E7E7E7] first:ml-0"
@ -53,9 +86,11 @@ export function AdvisorActionsCard({
/>
</span>
))}
{!isLoading && (
<span className="-ml-1.5 flex h-[30px] w-[30px] items-center justify-center rounded-full border-2 border-white bg-[#EDEEF1] group-10 font-semibold text-[#1C1C1C]">
+{extraCount}
+{displayExtraCount}
</span>
)}
</div>
<Button

Loading…
Cancel
Save