140 lines
3.9 KiB
Dart
140 lines
3.9 KiB
Dart
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);
|
|
|
|
// Find agent and lender type IDs by name
|
|
String? agentTypeId;
|
|
String? lenderTypeId;
|
|
|
|
for (final type in agentTypes) {
|
|
final name = type.name.toLowerCase();
|
|
if (name.contains('lender') || name.contains('lending')) {
|
|
lenderTypeId = type.id;
|
|
} else if (name.contains('professional') ||
|
|
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',
|
|
),
|
|
if (lenderTypeId != null)
|
|
_repository.searchAgents(
|
|
agentTypeId: lenderTypeId,
|
|
limit: 10,
|
|
sortBy: 'averageRating',
|
|
sortOrder: 'desc',
|
|
),
|
|
]);
|
|
|
|
state = state.copyWith(
|
|
agents: results[0].data,
|
|
lenders: results.length > 1 ? results[1].data : [],
|
|
isLoading: false,
|
|
);
|
|
} catch (e) {
|
|
state = state.copyWith(
|
|
isLoading: false,
|
|
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);
|
|
});
|