feat: Implement 'Show More/Less' functionality for specialization cards, refine expertise tag extraction logic, and update the 'Browse Experts' navigation link.
This commit is contained in:
@@ -168,18 +168,24 @@ function ProfileCard({ profile }: ProfileCardProps) {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extract expertise tags from fieldValues
|
// Extract expertise tags from fieldValues - only include expertise-related fields
|
||||||
const getExpertiseTags = (): string[] => {
|
const getExpertiseTags = (): string[] => {
|
||||||
const tags: string[] = [];
|
const tags: string[] = [];
|
||||||
|
|
||||||
// Fields to exclude from tags (they're displayed elsewhere, e.g., state/city shown in location)
|
// Only include expertise-related field slugs (matching profileDataMapper.ts)
|
||||||
const excludedFieldSlugs = ['state', 'city', 'description'];
|
const expertiseFieldSlugs = [
|
||||||
|
'about_me_expertise',
|
||||||
|
'expertise_areas',
|
||||||
|
'specializations',
|
||||||
|
'areas_of_expertise',
|
||||||
|
'expertise',
|
||||||
|
];
|
||||||
|
|
||||||
// Add from fieldValues (dynamic profile fields like client_specialization, property_type, loan_type)
|
// Add from fieldValues - only expertise-related fields
|
||||||
if (profile.fieldValues && profile.fieldValues.length > 0) {
|
if (profile.fieldValues && profile.fieldValues.length > 0) {
|
||||||
profile.fieldValues.forEach((fv) => {
|
profile.fieldValues.forEach((fv) => {
|
||||||
// Skip excluded fields
|
// Only include expertise-related fields
|
||||||
if (excludedFieldSlugs.includes(fv.field.slug)) {
|
if (!expertiseFieldSlugs.includes(fv.field.slug)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,12 +199,16 @@ function ProfileCard({ profile }: ProfileCardProps) {
|
|||||||
.split('_')
|
.split('_')
|
||||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||||
.join(' ');
|
.join(' ');
|
||||||
|
if (!tags.includes(displayValue)) {
|
||||||
tags.push(displayValue);
|
tags.push(displayValue);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else if (typeof value === 'string' && value.trim()) {
|
} else if (typeof value === 'string' && value.trim()) {
|
||||||
|
if (!tags.includes(value)) {
|
||||||
tags.push(value);
|
tags.push(value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ export function TopProfessionals() {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* Browse Experts Button */}
|
{/* Browse Experts Button */}
|
||||||
<Link href="/agents">
|
<Link href="/user/profiles">
|
||||||
<button className="bg-[#e58625] hover:bg-[#d47820] text-white font-fractul font-bold text-[16px] leading-[19px] px-8 py-3 rounded-[15px] transition-colors">
|
<button className="bg-[#e58625] hover:bg-[#d47820] text-white font-fractul font-bold text-[16px] leading-[19px] px-8 py-3 rounded-[15px] transition-colors">
|
||||||
Browse Experts
|
Browse Experts
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,36 +1,61 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
|
||||||
interface SpecializationCardProps {
|
interface SpecializationCardProps {
|
||||||
title: string;
|
title: string;
|
||||||
items: string[];
|
items: string[];
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
|
initialItemsToShow?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SpecializationCard({ title, items, icon }: SpecializationCardProps) {
|
export function SpecializationCard({
|
||||||
|
title,
|
||||||
|
items,
|
||||||
|
icon,
|
||||||
|
initialItemsToShow = 3
|
||||||
|
}: SpecializationCardProps) {
|
||||||
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
|
||||||
|
// Determine if we need to show the toggle button
|
||||||
|
const hasMoreItems = items.length > initialItemsToShow;
|
||||||
|
|
||||||
|
// Get the items to display based on expanded state
|
||||||
|
const displayedItems = isExpanded ? items : items.slice(0, initialItemsToShow);
|
||||||
|
|
||||||
|
const handleToggle = () => {
|
||||||
|
setIsExpanded(!isExpanded);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded-[20px] p-6 text-center flex flex-col h-full border-[0.7px] border-[#E58625]">
|
<div className="bg-white rounded-[20px] p-6 text-center flex flex-col h-full border-[0.7px] border-[#E58625]">
|
||||||
<div className="flex justify-center mb-3">{icon}</div>
|
<div className="flex justify-center mb-3">{icon}</div>
|
||||||
<h4 className="font-bold text-[#00293D] text-[14px] leading-[17px] mb-4 font-fractul">{title}</h4>
|
<h4 className="font-bold text-[#00293D] text-[14px] leading-[17px] mb-4 font-fractul">{title}</h4>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
{items.map((item, idx) => (
|
{displayedItems.map((item, idx) => (
|
||||||
<p key={idx} className="text-[#00293D] text-[14px] leading-[25px] font-normal font-serif text-center">
|
<p key={idx} className="text-[#00293D] text-[14px] leading-[25px] font-normal font-serif text-center">
|
||||||
{item}
|
{item}
|
||||||
</p>
|
</p>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
{hasMoreItems && (
|
||||||
<div className="mt-4 flex justify-center">
|
<div className="mt-4 flex justify-center">
|
||||||
<button className="inline-flex items-center justify-center gap-1 h-[20px] w-[87px] border border-[#e58625] rounded-[20px] text-[#e58625] text-[10px] leading-[22px] font-bold font-serif hover:bg-[#e58625]/5 transition-colors">
|
<button
|
||||||
Show More
|
onClick={handleToggle}
|
||||||
|
className="inline-flex items-center justify-center gap-1 h-[20px] px-3 border border-[#e58625] rounded-[20px] text-[#e58625] text-[10px] leading-[22px] font-bold font-serif hover:bg-[#e58625]/5 transition-colors cursor-pointer"
|
||||||
|
>
|
||||||
|
{isExpanded ? 'Show Less' : 'Show More'}
|
||||||
<Image
|
<Image
|
||||||
src="/assets/icons/chevron-down-icon.svg"
|
src="/assets/icons/chevron-down-icon.svg"
|
||||||
alt="Show more"
|
alt={isExpanded ? 'Show less' : 'Show more'}
|
||||||
width={10}
|
width={10}
|
||||||
height={10}
|
height={10}
|
||||||
|
className={`transition-transform duration-200 ${isExpanded ? 'rotate-180' : ''}`}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user