fix: invalidate agent cache on profile update and add expandable list support for expertise and certifications
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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<Map<String, String>> 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<String, String> 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<String> tags, {required String sectionKey}) {
|
||||
Widget _buildTagsWrap(
|
||||
List<String> 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,
|
||||
|
||||
Reference in New Issue
Block a user