diff --git a/lib/features/agents/data/models/agent_profile.dart b/lib/features/agents/data/models/agent_profile.dart index 06bf89d..625e641 100644 --- a/lib/features/agents/data/models/agent_profile.dart +++ b/lib/features/agents/data/models/agent_profile.dart @@ -23,6 +23,9 @@ class AgentProfile { final AgentUser? user; final List fieldValues; final String? createdAt; + final List legacySpecializations; + final List languages; + final List serviceAreas; const AgentProfile({ required this.id, @@ -47,6 +50,9 @@ class AgentProfile { this.user, this.fieldValues = const [], this.createdAt, + this.legacySpecializations = const [], + this.languages = const [], + this.serviceAreas = const [], }); String get fullName => '$firstName $lastName'.trim(); @@ -69,6 +75,16 @@ class AgentProfile { /// Get avatar URL — check agent avatar first, then user avatar String? get avatarUrl => avatar ?? user?.avatar; + /// Get description — check fieldValues 'description' first, then bio (matches web) + String get description { + for (final fv in fieldValues) { + if (fv.fieldSlug == 'description' && fv.textValue != null && fv.textValue!.isNotEmpty) { + return fv.textValue!; + } + } + return bio ?? ''; + } + String get location { // Direct fields first if (city != null && state != null) return '$city, $state'; @@ -89,6 +105,9 @@ class AgentProfile { final parts = [fvCity, fvState].where((s) => s != null && s.isNotEmpty); if (parts.isNotEmpty) return parts.join(', '); + if (country != null && country!.isNotEmpty) return country!; + if (serviceAreas.isNotEmpty) return serviceAreas.first; + return ''; } @@ -159,6 +178,17 @@ class AgentProfile { if (!tags.contains(display)) tags.add(display); } } + + // Add from legacy specializations array + for (final spec in legacySpecializations) { + if (spec.isNotEmpty && !tags.contains(spec)) tags.add(spec); + } + + // Add from languages array + for (final lang in languages) { + if (lang.isNotEmpty && !tags.contains(lang)) tags.add(lang); + } + return tags; } @@ -193,6 +223,18 @@ class AgentProfile { .toList() ?? const [], createdAt: json['createdAt'] as String?, + legacySpecializations: (json['specializations'] as List?) + ?.map((e) => e.toString()) + .toList() ?? + const [], + languages: (json['languages'] as List?) + ?.map((e) => e.toString()) + .toList() ?? + const [], + serviceAreas: (json['serviceAreas'] as List?) + ?.map((e) => e.toString()) + .toList() ?? + const [], ); } } @@ -241,11 +283,14 @@ class AgentFieldValue { }); factory AgentFieldValue.fromJson(Map json) { + // API returns field info nested: { field: { slug, name, fieldType } } + // Fallback to top-level fieldSlug/fieldName/fieldType for compatibility + final field = json['field'] as Map?; return AgentFieldValue( id: json['id'] as String? ?? '', - fieldSlug: json['fieldSlug'] as String? ?? '', - fieldName: json['fieldName'] as String? ?? '', - fieldType: json['fieldType'] as String? ?? '', + fieldSlug: field?['slug'] as String? ?? json['fieldSlug'] as String? ?? '', + fieldName: field?['name'] as String? ?? json['fieldName'] as String? ?? '', + fieldType: field?['fieldType'] as String? ?? json['fieldType'] as String? ?? '', textValue: json['textValue'] as String?, numberValue: json['numberValue'] as num?, booleanValue: json['booleanValue'] as bool?, diff --git a/lib/features/agents/presentation/screens/agent_search_screen.dart b/lib/features/agents/presentation/screens/agent_search_screen.dart index 58d301b..4cedfcf 100644 --- a/lib/features/agents/presentation/screens/agent_search_screen.dart +++ b/lib/features/agents/presentation/screens/agent_search_screen.dart @@ -86,39 +86,49 @@ class _AgentSearchScreenState extends ConsumerState { Expanded( child: Container( decoration: BoxDecoration( + color: Colors.white, border: Border.all( color: AppColors.primaryDark, width: 0.1, ), borderRadius: BorderRadius.circular(7), ), - child: TextField( - controller: _searchController, - style: const TextStyle( - fontFamily: 'Fractul', - fontSize: 14, - fontWeight: FontWeight.w500, - color: AppColors.primaryDark, + child: Theme( + data: Theme.of(context).copyWith( + inputDecorationTheme: const InputDecorationTheme( + filled: false, + border: InputBorder.none, + ), ), - decoration: InputDecoration( - hintText: 'Search Agents', - hintStyle: TextStyle( + child: TextField( + controller: _searchController, + style: const TextStyle( fontFamily: 'Fractul', fontSize: 14, fontWeight: FontWeight.w500, - color: Colors.black.withValues(alpha: 0.5), + color: AppColors.primaryDark, ), - border: InputBorder.none, - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - contentPadding: const EdgeInsets.symmetric( - horizontal: 14, - vertical: 10, + decoration: InputDecoration( + hintText: 'Search Agents', + hintStyle: TextStyle( + fontFamily: 'Fractul', + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.black.withValues(alpha: 0.5), + ), + filled: false, + border: InputBorder.none, + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + contentPadding: const EdgeInsets.symmetric( + horizontal: 14, + vertical: 10, + ), ), + onSubmitted: (value) { + ref.read(searchAgentsProvider.notifier).search(value); + }, ), - onSubmitted: (value) { - ref.read(searchAgentsProvider.notifier).search(value); - }, ), ), ), @@ -140,7 +150,13 @@ class _AgentSearchScreenState extends ConsumerState { ), borderRadius: BorderRadius.circular(7), ), - child: const Icon(Icons.search, color: Colors.white, size: 24), + child: Center( + child: SvgPicture.string( + '', + width: 24, + height: 24, + ), + ), ), ), ], @@ -413,7 +429,7 @@ class _AgentCardState extends State<_AgentCard> { Widget build(BuildContext context) { final agent = widget.agent; final specializations = agent.specializations; - final bio = agent.bio ?? ''; + final bio = agent.description; final matchPercent = agent.averageRating != null ? '${(agent.averageRating! * 20).round()}%' : null;