From 3a867585611161a2c5f572449f79ad0822058b34 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Wed, 15 Apr 2026 19:02:49 +0530 Subject: [PATCH] fix: invalidate agent cache on profile update and add expandable list support for expertise and certifications --- .../screens/agent_edit_profile_screen.dart | 10 ++ .../screens/agent_home_screen.dart | 135 ++++++++++++------ 2 files changed, 102 insertions(+), 43 deletions(-) diff --git a/lib/features/agents/presentation/screens/agent_edit_profile_screen.dart b/lib/features/agents/presentation/screens/agent_edit_profile_screen.dart index 58eb60e..b74d253 100644 --- a/lib/features/agents/presentation/screens/agent_edit_profile_screen.dart +++ b/lib/features/agents/presentation/screens/agent_edit_profile_screen.dart @@ -8,6 +8,8 @@ import 'package:go_router/go_router.dart'; import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; import 'package:real_estate_mobile/core/constants/app_colors.dart'; +import 'package:real_estate_mobile/features/agents/presentation/providers/agent_detail_provider.dart'; +import 'package:real_estate_mobile/features/auth/presentation/providers/auth_provider.dart'; import 'package:real_estate_mobile/features/profile/data/profile_repository.dart'; // --------------------------------------------------------------------------- @@ -385,6 +387,14 @@ class _AgentEditProfileScreenState } } + // Invalidate the agent detail provider so the dashboard refetches + // field values after save (was showing stale cached data). + final userId = ref.read(authProvider).user?.id; + if (userId != null) { + ref.invalidate(agentDetailProvider(userId)); + } + ref.invalidate(_editProfileDataProvider); + if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( diff --git a/lib/features/agents/presentation/screens/agent_home_screen.dart b/lib/features/agents/presentation/screens/agent_home_screen.dart index 1aef7e4..6b6f68a 100644 --- a/lib/features/agents/presentation/screens/agent_home_screen.dart +++ b/lib/features/agents/presentation/screens/agent_home_screen.dart @@ -869,11 +869,15 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> { color: AppColors.primaryDark)), ), const SizedBox(height: 8), - _buildTagsWrap(state.expertiseYears - .map((e) => e['years']!.isNotEmpty - ? '${e['area']} – ${e['years']}' - : e['area']!) - .toList(), sectionKey: 'expertise'), + _buildTagsWrap( + state.expertiseYears + .map((e) => e['years']!.isNotEmpty + ? '${e['area']} – ${e['years']}' + : e['area']!) + .toList(), + sectionKey: 'expertise', + initialCount: 4, + ), ], if (state.certifications.isNotEmpty) ...[ const SizedBox(height: 16), @@ -887,47 +891,87 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> { color: AppColors.primaryDark)), ), const SizedBox(height: 8), - ...state.certifications.map((cert) => Padding( - padding: const EdgeInsets.only(bottom: 12, left: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - const Text('\u2022 ', - style: TextStyle( - fontSize: 14, - color: AppColors.primaryDark)), - Expanded( - child: Text(cert['name']!, - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 14, - color: AppColors.primaryDark)), - ), - ], - ), - if (cert['org']!.isNotEmpty) - Padding( - padding: const EdgeInsets.only(left: 16), - child: Opacity( - opacity: 0.5, - child: Text(cert['org']!, - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 14, - color: AppColors.primaryDark)), - ), - ), - ], - ), - )), + _buildCertificationsList(state.certifications), ], ], ), ); } + // Certifications list with "+N More" (initial 2, matching web) + Widget _buildCertificationsList(List> certs) { + const initialCount = 2; + final sectionKey = 'certifications'; + final isExpanded = _expandedTagSections.contains(sectionKey); + final display = isExpanded ? certs : certs.take(initialCount).toList(); + final remaining = certs.length - initialCount; + + Widget certRow(Map cert) => Padding( + padding: const EdgeInsets.only(bottom: 12, left: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + const Text('\u2022 ', + style: TextStyle( + fontSize: 14, color: AppColors.primaryDark)), + Expanded( + child: Text(cert['name']!, + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + color: AppColors.primaryDark)), + ), + ], + ), + if ((cert['org'] ?? '').isNotEmpty) + Padding( + padding: const EdgeInsets.only(left: 16), + child: Opacity( + opacity: 0.5, + child: Text(cert['org']!, + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + color: AppColors.primaryDark)), + ), + ), + ], + ), + ); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...display.map(certRow), + if (remaining > 0) + Padding( + padding: const EdgeInsets.only(left: 8, top: 4), + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => setState(() { + if (isExpanded) { + _expandedTagSections.remove(sectionKey); + } else { + _expandedTagSections.add(sectionKey); + } + }), + child: Text( + isExpanded ? 'Show Less' : '+$remaining More', + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + fontWeight: FontWeight.w600, + color: AppColors.accentOrange, + ), + ), + ), + ), + ], + ); + } + Widget _buildExperienceRow(String label, String value) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -959,10 +1003,15 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> { ); } - Widget _buildTagsWrap(List tags, {required String sectionKey}) { + Widget _buildTagsWrap( + List tags, { + required String sectionKey, + int initialCount = 6, + }) { final isExpanded = _expandedTagSections.contains(sectionKey); - final displayTags = isExpanded ? tags : tags.take(6).toList(); - final remaining = tags.length - 6; + final displayTags = + isExpanded ? tags : tags.take(initialCount).toList(); + final remaining = tags.length - initialCount; return Wrap( spacing: 8,