From 418e350fad57226d6c527a6fb942f052b26dfd1b Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Tue, 31 Mar 2026 12:33:06 +0530 Subject: [PATCH] refactor: migrate TopProfessionals section to use CMS data and update UI layout constraints --- .../widgets/top_professionals_section.dart | 80 +++++++------------ 1 file changed, 27 insertions(+), 53 deletions(-) diff --git a/lib/features/home/presentation/widgets/top_professionals_section.dart b/lib/features/home/presentation/widgets/top_professionals_section.dart index 776ccab..a567317 100644 --- a/lib/features/home/presentation/widgets/top_professionals_section.dart +++ b/lib/features/home/presentation/widgets/top_professionals_section.dart @@ -5,8 +5,6 @@ import 'package:go_router/go_router.dart'; import 'package:shimmer/shimmer.dart'; import 'package:real_estate_mobile/core/constants/app_colors.dart'; import 'package:real_estate_mobile/core/widgets/s3_image.dart'; -import 'package:real_estate_mobile/features/agents/data/models/agent_profile.dart'; -import 'package:real_estate_mobile/features/agents/presentation/providers/agents_provider.dart'; import 'package:real_estate_mobile/features/home/data/models/landing_page_content.dart'; import 'package:real_estate_mobile/features/home/presentation/providers/home_provider.dart'; @@ -66,17 +64,16 @@ class _TopProfessionalsSectionState @override Widget build(BuildContext context) { - // CMS data for title/CTA text only + // CMS data — same source as web (topProfessionals section) final homeState = ref.watch(homeProvider); final cmsContent = homeState.content?.topProfessionals ?? _defaultCmsContent; - // Dynamic data from database (top-rated agents/lenders, matching web) - final profState = ref.watch(topProfessionalsProvider); - final activeList = _activeTab == 'agents' - ? profState.agents - : profState.lenders; - final isLoading = profState.isLoading || homeState.isLoading; + // Use CMS agents/lenders data (matching web TopProfessionals component) + final cmsAgents = cmsContent.agents; + final cmsLenders = cmsContent.lenders; + final activeList = _activeTab == 'agents' ? cmsAgents : cmsLenders; + final isLoading = homeState.isLoading; return Padding( padding: const EdgeInsets.symmetric(horizontal: 24), @@ -108,7 +105,7 @@ class _TopProfessionalsSectionState else ...[ // Professional Cards - horizontal scroll SizedBox( - height: 510, + height: 430, child: ListView.builder( controller: _scrollController, scrollDirection: Axis.horizontal, @@ -124,12 +121,9 @@ class _TopProfessionalsSectionState left: index == 0 ? 0 : 8, right: index == activeList.length - 1 ? 0 : 8, ), - child: Align( - alignment: Alignment.topCenter, - child: _buildProfessionalCard( - activeList[index], - index: index, - ), + child: _buildProfessionalCard( + activeList[index], + index: index, ), ), ); @@ -291,19 +285,17 @@ class _TopProfessionalsSectionState ); } - // -- Professional Card using dynamic AgentProfile data (matching web) -- - Widget _buildProfessionalCard(AgentProfile agent, {int index = 0}) { - final imageUrl = agent.avatarUrl ?? ''; - final expertiseTags = agent.specializations; - final experience = agent.experienceText; - final locationText = agent.location; - final subtitle = agent.agentType != null - ? '(${agent.agentType!.name})' - : ''; - final rawRating = agent.averageRating ?? 0.0; - final rating = rawRating > 0 ? rawRating : 5.0; + // -- Professional Card using CMS data (matching web) -- + Widget _buildProfessionalCard(ProfessionalItem item, {int index = 0}) { + final imageUrl = item.imageUrl; + final expertiseTags = item.expertise; + final experience = item.experience; + final locationText = item.location; + final subtitle = item.subtitle.isNotEmpty ? '(${item.subtitle})' : ''; + final rating = item.rating > 0 ? item.rating : 5.0; return Container( + constraints: const BoxConstraints(maxHeight: 410), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), @@ -351,7 +343,7 @@ class _TopProfessionalsSectionState children: [ // Name Text( - agent.fullName, + item.name, style: const TextStyle( fontFamily: 'Fractul', fontSize: 14, @@ -378,8 +370,7 @@ class _TopProfessionalsSectionState const SizedBox(height: 4), // Verified badge - if (agent.isVerified) - Row( + Row( children: [ SvgPicture.asset( 'assets/icons/verified_badge_icon.svg', @@ -550,7 +541,7 @@ class _TopProfessionalsSectionState Widget _buildShimmerCards() { return SizedBox( - height: 540, + height: 420, child: Shimmer.fromColors( baseColor: const Color(0xFFE0E0E0), highlightColor: const Color(0xFFF5F5F5), @@ -561,6 +552,7 @@ class _TopProfessionalsSectionState ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ // Image placeholder Container( @@ -571,35 +563,17 @@ class _TopProfessionalsSectionState ), ), Padding( - padding: const EdgeInsets.fromLTRB(16, 12, 16, 12), + padding: const EdgeInsets.fromLTRB(16, 12, 16, 14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ Container(height: 16, width: 160, color: Colors.white), const SizedBox(height: 8), Container(height: 12, width: 100, color: Colors.white), - const SizedBox(height: 12), + const SizedBox(height: 10), Container(height: 14, width: 180, color: Colors.white), - const SizedBox(height: 12), - Container(height: 12, width: 140, color: Colors.white), - const SizedBox(height: 12), - Row( - children: List.generate( - 3, - (_) => Container( - height: 28, - width: 70, - margin: const EdgeInsets.only(right: 8), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - ), - ), - ), - ), - const SizedBox(height: 12), - Container(height: 14, width: 200, color: Colors.white), - const SizedBox(height: 12), + const SizedBox(height: 10), Row( children: List.generate( 5,