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: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,