feat: implement FeaturedAgentItem model and update UI to sync with web CMS, and add form reset functionality to agent edit screen
This commit is contained in:
@@ -504,7 +504,23 @@ class _AgentEditProfileScreenState
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: _saving ? null : () => context.pop(),
|
||||
onPressed: _saving ? null : () {
|
||||
// Reset form to original values (reload from provider)
|
||||
setState(() {
|
||||
_formData.clear();
|
||||
_repeatableEntries.clear();
|
||||
_initialized = false;
|
||||
for (final c in _controllers) {
|
||||
c.dispose();
|
||||
}
|
||||
_controllers.clear();
|
||||
for (final c in _tagControllers.values) {
|
||||
c.dispose();
|
||||
}
|
||||
_tagControllers.clear();
|
||||
});
|
||||
// Re-initialize will happen on next build via _initializeFormData
|
||||
},
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: const BorderSide(color: AppColors.primaryDark),
|
||||
shape: RoundedRectangleBorder(
|
||||
|
||||
@@ -126,15 +126,46 @@ class HeroContent {
|
||||
|
||||
// --- Features Section ---
|
||||
|
||||
class FeaturedAgentItem {
|
||||
final String name;
|
||||
final String role;
|
||||
final String rating;
|
||||
final String location;
|
||||
final String experience;
|
||||
final String imageUrl;
|
||||
|
||||
const FeaturedAgentItem({
|
||||
this.name = '',
|
||||
this.role = '',
|
||||
this.rating = '',
|
||||
this.location = '',
|
||||
this.experience = '',
|
||||
this.imageUrl = '',
|
||||
});
|
||||
|
||||
factory FeaturedAgentItem.fromJson(Map<String, dynamic> json) {
|
||||
return FeaturedAgentItem(
|
||||
name: json['name'] as String? ?? '',
|
||||
role: json['role'] as String? ?? '',
|
||||
rating: json['rating'] as String? ?? '',
|
||||
location: json['location'] as String? ?? '',
|
||||
experience: json['experience'] as String? ?? '',
|
||||
imageUrl: json['imageUrl'] as String? ?? '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FeaturesContent {
|
||||
final String title;
|
||||
final String subtitle;
|
||||
final List<FeatureItem> features;
|
||||
final List<FeaturedAgentItem> featuredAgents;
|
||||
|
||||
const FeaturesContent({
|
||||
this.title = '',
|
||||
this.subtitle = '',
|
||||
this.features = const [],
|
||||
this.featuredAgents = const [],
|
||||
});
|
||||
|
||||
factory FeaturesContent.fromJson(Map<String, dynamic> json) {
|
||||
@@ -146,6 +177,11 @@ class FeaturesContent {
|
||||
(e) => FeatureItem.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
[],
|
||||
featuredAgents: (json['featuredAgents'] as List<dynamic>?)
|
||||
?.map(
|
||||
(e) => FeaturedAgentItem.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,10 +49,10 @@ class _FeaturedProfessionalsSectionState
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final homeState = ref.watch(homeProvider);
|
||||
final cmsContent = homeState.content?.topProfessionals;
|
||||
final featuresContent = homeState.content?.features;
|
||||
|
||||
// Use CMS agents list for the featured carousel
|
||||
final professionals = cmsContent?.agents ?? [];
|
||||
// Use CMS featuredAgents from features section (matches web)
|
||||
final professionals = featuresContent?.featuredAgents ?? [];
|
||||
|
||||
if (homeState.isLoading) {
|
||||
return Padding(
|
||||
@@ -140,7 +140,7 @@ class _FeaturedProfessionalsSectionState
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFeaturedCard(ProfessionalItem item, int index) {
|
||||
Widget _buildFeaturedCard(FeaturedAgentItem item, int index) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
@@ -185,10 +185,10 @@ class _FeaturedProfessionalsSectionState
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
|
||||
// Subtitle
|
||||
if (item.subtitle.isNotEmpty)
|
||||
// Role
|
||||
if (item.role.isNotEmpty)
|
||||
Text(
|
||||
item.subtitle,
|
||||
item.role,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
@@ -200,7 +200,7 @@ class _FeaturedProfessionalsSectionState
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
|
||||
// Verified badge
|
||||
// Verified badge + Rating
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
@@ -223,6 +223,20 @@ class _FeaturedProfessionalsSectionState
|
||||
color: Color(0xFF638559),
|
||||
),
|
||||
),
|
||||
if (item.rating.isNotEmpty) ...[
|
||||
const SizedBox(width: 8),
|
||||
const Icon(Icons.star, size: 16, color: Color(0xFFFFDE21)),
|
||||
const SizedBox(width: 2),
|
||||
Text(
|
||||
'Rating',
|
||||
style: TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.primaryDark,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
|
||||
Reference in New Issue
Block a user