2026-01-11 22:09:41 +05:30
'use client' ;
2026-03-23 11:24:49 +05:30
import { useState , useEffect } from 'react' ;
2026-01-20 01:33:44 +05:30
import Image from 'next/image' ;
2026-03-23 11:24:49 +05:30
import type { FeaturesContent , FeaturedAgentItem } from '@/types/cms' ;
import { resolveImageUrl } from '@/services/cms.service' ;
2026-03-28 22:04:20 +05:30
import { agentsService } from '@/services/agents.service' ;
import { uploadService } from '@/services/upload.service' ;
2026-01-20 01:33:44 +05:30
2026-02-22 21:52:54 +05:30
const defaultContent : FeaturesContent = {
title : 'Find Trusted Real Estate Professionals On Demand' ,
subtitle : 'Quickly connect with the right agents exactly when you need them.' ,
features : [
{
iconPath : '/assets/icons/hourglass-icon.svg' ,
title : 'Hire Quickly' ,
description : 'Connect with experienced local real estate agents who match your needs and preferences. Our simple process helps you get started quickly and move forward without delays or unnecessary complexity.' ,
} ,
{
iconPath : '/assets/icons/verified-badge-icon.svg' ,
title : 'Verified Agents' ,
description : 'All agents are carefully identity-verified and background-checked to ensure trust and safety. You can confidently work with professionals who meet quality and reliability standards.' ,
} ,
{
iconPath : '/assets/icons/star-orange-icon.svg' ,
title : 'Top Rated' ,
description : 'Work with highly rated agents known for strong expertise and positive client feedback. Their consistent performance helps you make informed and confident property decisions.' ,
} ,
{
iconPath : '/assets/icons/trusted-people-icon.svg' ,
title : 'Trusted by Thousands' ,
description : 'Thousands of buyers, sellers, and renters trust our platform to find reliable agents. Our professionals help people navigate property journeys with confidence and ease.' ,
} ,
] ,
2026-03-23 11:24:49 +05:30
featuredAgents : [
{ name : 'Anderson' , role : 'Rental & Investment Consultant' , rating : '4.9' , location : 'New York' , experience : '7+ years in the real estate industry.' , imageUrl : '/assets/images/agent-anderson.jpg' } ,
{ name : 'Deepak' , role : 'Rental & Investment Consultant' , rating : '4.9' , location : 'New York' , experience : '7+ years in the real estate industry.' , imageUrl : '/assets/images/agent-deepak.jpg' } ,
{ name : 'Daniel' , role : 'Rental & Investment Consultant' , rating : '4.9' , location : 'New York' , experience : '7+ years in the real estate industry.' , imageUrl : '/assets/images/agent-daniel.jpg' } ,
] ,
2026-02-22 21:52:54 +05:30
} ;
2026-01-11 22:09:41 +05:30
2026-03-23 11:24:49 +05:30
function AgentCard ( { agent , className = '' } : { agent : FeaturedAgentItem ; className? : string } ) {
const [ imgLoaded , setImgLoaded ] = useState ( false ) ;
const [ imgSrc , setImgSrc ] = useState ( agent . imageUrl ) ;
useEffect ( ( ) = > {
// Only resolve if it's an S3 key (not a URL or local path)
if ( agent . imageUrl && ! agent . imageUrl . startsWith ( 'http' ) && ! agent . imageUrl . startsWith ( '/' ) ) {
resolveImageUrl ( agent . imageUrl ) . then ( ( url ) = > {
if ( url ) setImgSrc ( url ) ;
} ) ;
} else {
setImgSrc ( agent . imageUrl ) ;
}
} , [ agent . imageUrl ] ) ;
2026-01-20 01:33:44 +05:30
2026-01-11 22:09:41 +05:30
return (
2026-01-20 01:33:44 +05:30
< div className = { ` bg-white border border-[#00293d]/10 rounded-[15px] w-[254px] overflow-hidden ${ className } ` } >
2026-03-23 11:24:49 +05:30
< div className = "h-[161px] w-full overflow-hidden rounded-t-[15px] bg-gray-100 relative" >
{ imgSrc && (
< img
ref = { ( el ) = > { if ( el ? . complete && el . naturalWidth > 0 ) setImgLoaded ( true ) ; } }
src = { imgSrc }
alt = { agent . name }
className = { ` w-full h-full object-cover transition-opacity duration-300 ${ imgLoaded ? 'opacity-100' : 'opacity-0' } ` }
onLoad = { ( ) = > setImgLoaded ( true ) }
onError = { ( ) = > setImgLoaded ( true ) }
/ >
) }
{ ! imgLoaded && < div className = "absolute inset-0 shimmer-loading" / > }
2026-01-20 01:33:44 +05:30
< / div >
< div className = "p-4" >
2026-03-23 11:24:49 +05:30
< h4 className = "font-fractul font-bold text-[16px] leading-[19px] text-[#00293d]" > { agent . name } < / h4 >
< p className = "font-fractul font-normal text-[14px] leading-[17px] text-[#00293d] mt-1" > { agent . role } < / p >
2026-01-20 01:33:44 +05:30
< div className = "flex items-center gap-4 mt-2" >
< div className = "flex items-center gap-1" >
2026-03-23 11:24:49 +05:30
< Image src = "/assets/icons/verified-icon.svg" alt = "Verified" width = { 14 } height = { 14 } / >
< span className = "font-serif font-medium text-[14px] leading-[19px] text-[#00293d]" > Verified Agent < / span >
2026-01-20 01:33:44 +05:30
< / div >
2026-03-23 11:24:49 +05:30
{ agent . rating && (
< div className = "flex items-center gap-1" >
< Image src = "/assets/icons/star-filled-icon.svg" alt = "Rating" width = { 14 } height = { 14 } / >
< span className = "font-serif font-normal text-[14px] leading-[19px] text-[#00293d]" > { agent . rating } Rating < / span >
< / div >
) }
2026-01-20 01:33:44 +05:30
< / div >
2026-03-23 11:24:49 +05:30
{ agent . location && (
< div className = "flex items-center gap-1 mt-2" >
< Image src = "/assets/icons/location-filled-icon.svg" alt = "Location" width = { 15 } height = { 15 } / >
< span className = "font-serif font-medium text-[14px] leading-[19px] text-[#00293d]" > { agent . location } < / span >
< / div >
) }
{ agent . experience && (
< p className = "mt-2 text-[14px] leading-[19px] text-[#00293d]" >
< span className = "font-serif font-bold" > Experience : < / span >
< span className = "font-serif font-normal" > { agent . experience } < / span >
< / p >
) }
2026-01-20 01:33:44 +05:30
< / div >
< / div >
) ;
}
2026-02-22 21:52:54 +05:30
export function FeaturesSection ( { content } : { content? : FeaturesContent } ) {
const data = content ? ? defaultContent ;
2026-03-28 22:04:20 +05:30
const [ agents , setAgents ] = useState < FeaturedAgentItem [ ] > ( [ ] ) ;
2026-03-23 11:24:49 +05:30
const [ activeCard , setActiveCard ] = useState ( 0 ) ;
2026-02-22 21:52:54 +05:30
2026-03-28 22:04:20 +05:30
useEffect ( ( ) = > {
const fetchFeaturedAgents = async ( ) = > {
try {
const featured = await agentsService . getFeaturedAgents ( 3 ) ;
if ( featured . length > 0 ) {
// Map API response to FeaturedAgentItem format
const mapped = await Promise . all (
featured . map ( async ( agent ) = > {
let imageUrl = '/assets/icons/user-placeholder-icon.svg' ;
if ( agent . avatar ) {
if ( agent . avatar . startsWith ( 'http' ) || agent . avatar . startsWith ( '/' ) ) {
imageUrl = agent . avatar ;
} else {
try {
imageUrl = await uploadService . getPresignedDownloadUrl ( agent . avatar ) ;
} catch ( _e ) {
// use placeholder
}
}
}
return {
name : ` ${ agent . firstName || '' } ${ agent . lastName || '' } ` . trim ( ) ,
role : agent.agentType?.name || '' ,
rating : agent.averageRating ? String ( agent . averageRating ) : '' ,
location : agent.city || agent . state || '' ,
experience : agent.experience ? ` ${ agent . experience } + years in the real estate industry. ` : '' ,
imageUrl ,
} ;
} ) ,
) ;
setAgents ( mapped ) ;
}
} catch ( err ) {
console . error ( 'Failed to fetch featured agents:' , err ) ;
}
} ;
fetchFeaturedAgents ( ) ;
} , [ ] ) ;
2026-01-20 01:33:44 +05:30
return (
< section className = "py-16 md:py-20 bg-white" >
< div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" >
< div className = "flex flex-col lg:flex-row gap-12 lg:gap-8" >
{ /* Left Side - Title & Features */ }
< div className = "lg:w-1/2" >
< div className = "mb-8" >
2026-03-23 11:24:49 +05:30
< h2 className = "font-fractul font-bold text-[32px] md:text-[40px] leading-[1.2] text-[#00293d] mb-4" > { data . title } < / h2 >
< p className = "font-fractul font-medium text-[18px] md:text-[20px] leading-[1.4] text-[#00293d]" > { data . subtitle } < / p >
2026-01-11 22:09:41 +05:30
< / div >
2026-01-20 01:33:44 +05:30
< div className = "grid grid-cols-1 sm:grid-cols-2 gap-4" >
2026-02-22 21:52:54 +05:30
{ data . features . map ( ( feature , index ) = > (
2026-03-23 11:24:49 +05:30
< div key = { index } className = "border border-[#00293d]/10 rounded-[15px] p-5" >
2026-01-20 01:33:44 +05:30
< div className = "mb-3" >
2026-03-23 11:24:49 +05:30
< Image src = { feature . iconPath } alt = { feature . title } width = { 35 } height = { 35 } / >
2026-01-20 01:33:44 +05:30
< / div >
2026-03-23 11:24:49 +05:30
< h3 className = "font-fractul font-semibold text-[20px] leading-[24px] text-[#00293d] mb-2" > { feature . title } < / h3 >
< p className = "font-serif font-normal text-[14px] leading-[19px] text-[#00293d]" > { feature . description } < / p >
2026-01-20 01:33:44 +05:30
< / div >
) ) }
< / div >
< / div >
2026-03-23 11:24:49 +05:30
{ /* Right Side - Agent Cards (Desktop) */ }
2026-03-28 22:04:20 +05:30
{ agents . length > 0 && (
< div className = "lg:w-1/2 relative min-h-[650px] hidden lg:block" >
{ agents [ 0 ] && < AgentCard agent = { agents [ 0 ] } className = "absolute top-0 left-0 shadow-lg z-10" / > }
{ agents [ 1 ] && < AgentCard agent = { agents [ 1 ] } className = "absolute top-[170px] right-0 shadow-lg z-20" / > }
{ agents [ 2 ] && < AgentCard agent = { agents [ 2 ] } className = "absolute top-[320px] left-[60px] shadow-lg z-30" / > }
< / div >
) }
2026-01-20 01:33:44 +05:30
2026-03-23 11:24:49 +05:30
{ /* Mobile Agent Cards - Tab style with dots */ }
2026-03-28 22:04:20 +05:30
{ agents . length > 0 && (
< div className = "lg:hidden" >
< div className = "flex justify-center" >
< AgentCard agent = { agents [ activeCard ] } className = "shadow-lg" / >
< / div >
{ /* Dot indicators */ }
< div className = "flex justify-center gap-2 mt-4" >
{ agents . map ( ( _ , index ) = > (
< button
key = { index }
onClick = { ( ) = > setActiveCard ( index ) }
className = { ` rounded-full transition-all ${
index === activeCard
? 'w-[10px] h-[10px] bg-[#00293d]'
: 'w-[8px] h-[8px] bg-[#00293d]/30'
} ` }
/ >
) ) }
< / div >
2026-01-20 01:33:44 +05:30
< / div >
2026-03-28 22:04:20 +05:30
) }
2026-01-11 22:09:41 +05:30
< / div >
< / div >
< / section >
) ;
}