Files
mobile-app/lib/features/agents/presentation/providers/agents_provider.dart

139 lines
3.9 KiB
Dart
Raw Normal View History

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:real_estate_mobile/features/agents/data/agents_repository.dart';
import 'package:real_estate_mobile/features/agents/data/models/agent_profile.dart';
import 'package:real_estate_mobile/features/agents/data/models/agent_type.dart';
// Repository provider
final agentsRepositoryProvider = Provider<AgentsRepository>((ref) {
return AgentsRepository();
});
// Top professionals state
class TopProfessionalsState {
final List<AgentProfile> agents;
final List<AgentProfile> lenders;
final List<AgentType> agentTypes;
final bool isLoading;
final String? error;
final String activeTab; // 'agents' or 'lenders'
const TopProfessionalsState({
this.agents = const [],
this.lenders = const [],
this.agentTypes = const [],
this.isLoading = false,
this.error,
this.activeTab = 'agents',
});
TopProfessionalsState copyWith({
List<AgentProfile>? agents,
List<AgentProfile>? lenders,
List<AgentType>? agentTypes,
bool? isLoading,
String? error,
String? activeTab,
}) {
return TopProfessionalsState(
agents: agents ?? this.agents,
lenders: lenders ?? this.lenders,
agentTypes: agentTypes ?? this.agentTypes,
isLoading: isLoading ?? this.isLoading,
error: error,
activeTab: activeTab ?? this.activeTab,
);
}
List<AgentProfile> get activeList =>
activeTab == 'agents' ? agents : lenders;
}
class TopProfessionalsNotifier extends StateNotifier<TopProfessionalsState> {
final AgentsRepository _repository;
TopProfessionalsNotifier(this._repository)
: super(const TopProfessionalsState()) {
_loadData();
}
Future<void> _loadData() async {
state = state.copyWith(isLoading: true, error: null);
try {
// Fetch agent types first to find agent/lender type IDs
final agentTypes = await _repository.getAgentTypes();
state = state.copyWith(agentTypes: agentTypes);
2026-02-24 22:35:16 +05:30
// Find agent and lender type IDs by name
String? agentTypeId;
String? lenderTypeId;
for (final type in agentTypes) {
2026-02-24 22:35:16 +05:30
final name = type.name.toLowerCase();
if (name.contains('lender') || name.contains('lending')) {
lenderTypeId = type.id;
2026-02-24 22:35:16 +05:30
} else if (name.contains('agent') ||
name.contains('realtor') ||
name.contains('broker')) {
agentTypeId = type.id;
}
}
// If no specific agent type found, use first type as agents
if (agentTypeId == null && agentTypes.isNotEmpty) {
agentTypeId = agentTypes.first.id;
// Look for lender in remaining
for (final type in agentTypes) {
if (type.id != agentTypeId) {
lenderTypeId = type.id;
break;
}
}
}
// Fetch agents and lenders in parallel
final results = await Future.wait([
_repository.searchAgents(
agentTypeId: agentTypeId,
limit: 10,
sortBy: 'averageRating',
sortOrder: 'desc',
),
2026-02-24 22:35:16 +05:30
if (lenderTypeId != null)
_repository.searchAgents(
agentTypeId: lenderTypeId,
limit: 10,
sortBy: 'averageRating',
sortOrder: 'desc',
),
]);
state = state.copyWith(
agents: results[0].data,
2026-02-24 22:35:16 +05:30
lenders: results.length > 1 ? results[1].data : [],
isLoading: false,
);
} catch (e) {
state = state.copyWith(
isLoading: false,
2026-02-24 22:35:16 +05:30
error: e.toString(),
);
}
}
void setActiveTab(String tab) {
state = state.copyWith(activeTab: tab);
}
Future<void> refresh() async {
await _loadData();
}
}
final topProfessionalsProvider =
StateNotifierProvider<TopProfessionalsNotifier, TopProfessionalsState>(
(ref) {
final repository = ref.watch(agentsRepositoryProvider);
return TopProfessionalsNotifier(repository);
});