refactor: migrate TopProfessionals section to use CMS data and update UI layout constraints

This commit is contained in:
pradeepkumar
2026-03-31 12:33:06 +05:30
parent 457ea8a082
commit 418e350fad

View File

@@ -5,8 +5,6 @@ import 'package:go_router/go_router.dart';
import 'package:shimmer/shimmer.dart'; import 'package:shimmer/shimmer.dart';
import 'package:real_estate_mobile/core/constants/app_colors.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/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/data/models/landing_page_content.dart';
import 'package:real_estate_mobile/features/home/presentation/providers/home_provider.dart'; import 'package:real_estate_mobile/features/home/presentation/providers/home_provider.dart';
@@ -66,17 +64,16 @@ class _TopProfessionalsSectionState
@override @override
Widget build(BuildContext context) { 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 homeState = ref.watch(homeProvider);
final cmsContent = final cmsContent =
homeState.content?.topProfessionals ?? _defaultCmsContent; homeState.content?.topProfessionals ?? _defaultCmsContent;
// Dynamic data from database (top-rated agents/lenders, matching web) // Use CMS agents/lenders data (matching web TopProfessionals component)
final profState = ref.watch(topProfessionalsProvider); final cmsAgents = cmsContent.agents;
final activeList = _activeTab == 'agents' final cmsLenders = cmsContent.lenders;
? profState.agents final activeList = _activeTab == 'agents' ? cmsAgents : cmsLenders;
: profState.lenders; final isLoading = homeState.isLoading;
final isLoading = profState.isLoading || homeState.isLoading;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
@@ -108,7 +105,7 @@ class _TopProfessionalsSectionState
else ...[ else ...[
// Professional Cards - horizontal scroll // Professional Cards - horizontal scroll
SizedBox( SizedBox(
height: 510, height: 430,
child: ListView.builder( child: ListView.builder(
controller: _scrollController, controller: _scrollController,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
@@ -124,14 +121,11 @@ class _TopProfessionalsSectionState
left: index == 0 ? 0 : 8, left: index == 0 ? 0 : 8,
right: index == activeList.length - 1 ? 0 : 8, right: index == activeList.length - 1 ? 0 : 8,
), ),
child: Align(
alignment: Alignment.topCenter,
child: _buildProfessionalCard( child: _buildProfessionalCard(
activeList[index], activeList[index],
index: index, index: index,
), ),
), ),
),
); );
}, },
), ),
@@ -291,19 +285,17 @@ class _TopProfessionalsSectionState
); );
} }
// -- Professional Card using dynamic AgentProfile data (matching web) -- // -- Professional Card using CMS data (matching web) --
Widget _buildProfessionalCard(AgentProfile agent, {int index = 0}) { Widget _buildProfessionalCard(ProfessionalItem item, {int index = 0}) {
final imageUrl = agent.avatarUrl ?? ''; final imageUrl = item.imageUrl;
final expertiseTags = agent.specializations; final expertiseTags = item.expertise;
final experience = agent.experienceText; final experience = item.experience;
final locationText = agent.location; final locationText = item.location;
final subtitle = agent.agentType != null final subtitle = item.subtitle.isNotEmpty ? '(${item.subtitle})' : '';
? '(${agent.agentType!.name})' final rating = item.rating > 0 ? item.rating : 5.0;
: '';
final rawRating = agent.averageRating ?? 0.0;
final rating = rawRating > 0 ? rawRating : 5.0;
return Container( return Container(
constraints: const BoxConstraints(maxHeight: 410),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(15),
@@ -351,7 +343,7 @@ class _TopProfessionalsSectionState
children: [ children: [
// Name // Name
Text( Text(
agent.fullName, item.name,
style: const TextStyle( style: const TextStyle(
fontFamily: 'Fractul', fontFamily: 'Fractul',
fontSize: 14, fontSize: 14,
@@ -378,7 +370,6 @@ class _TopProfessionalsSectionState
const SizedBox(height: 4), const SizedBox(height: 4),
// Verified badge // Verified badge
if (agent.isVerified)
Row( Row(
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
@@ -550,7 +541,7 @@ class _TopProfessionalsSectionState
Widget _buildShimmerCards() { Widget _buildShimmerCards() {
return SizedBox( return SizedBox(
height: 540, height: 420,
child: Shimmer.fromColors( child: Shimmer.fromColors(
baseColor: const Color(0xFFE0E0E0), baseColor: const Color(0xFFE0E0E0),
highlightColor: const Color(0xFFF5F5F5), highlightColor: const Color(0xFFF5F5F5),
@@ -561,6 +552,7 @@ class _TopProfessionalsSectionState
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [ children: [
// Image placeholder // Image placeholder
Container( Container(
@@ -571,35 +563,17 @@ class _TopProfessionalsSectionState
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 12), padding: const EdgeInsets.fromLTRB(16, 12, 16, 14),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [ children: [
Container(height: 16, width: 160, color: Colors.white), Container(height: 16, width: 160, color: Colors.white),
const SizedBox(height: 8), const SizedBox(height: 8),
Container(height: 12, width: 100, color: Colors.white), Container(height: 12, width: 100, color: Colors.white),
const SizedBox(height: 12), const SizedBox(height: 10),
Container(height: 14, width: 180, color: Colors.white), Container(height: 14, width: 180, color: Colors.white),
const SizedBox(height: 12), const SizedBox(height: 10),
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),
Row( Row(
children: List.generate( children: List.generate(
5, 5,