140 lines
4.0 KiB
Dart
140 lines
4.0 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';
|
|
import 'package:real_estate_mobile/features/agents/presentation/providers/agents_provider.dart';
|
|
|
|
class SearchAgentsState {
|
|
final List<AgentProfile> agents;
|
|
final List<AgentType> agentTypes;
|
|
final bool isLoading;
|
|
final bool isLoadingMore;
|
|
final String? error;
|
|
final String searchQuery;
|
|
final String? selectedAgentTypeId;
|
|
final int currentPage;
|
|
final int totalPages;
|
|
|
|
const SearchAgentsState({
|
|
this.agents = const [],
|
|
this.agentTypes = const [],
|
|
this.isLoading = false,
|
|
this.isLoadingMore = false,
|
|
this.error,
|
|
this.searchQuery = '',
|
|
this.selectedAgentTypeId,
|
|
this.currentPage = 1,
|
|
this.totalPages = 1,
|
|
});
|
|
|
|
bool get hasMore => currentPage < totalPages;
|
|
|
|
SearchAgentsState copyWith({
|
|
List<AgentProfile>? agents,
|
|
List<AgentType>? agentTypes,
|
|
bool? isLoading,
|
|
bool? isLoadingMore,
|
|
String? error,
|
|
String? searchQuery,
|
|
String? selectedAgentTypeId,
|
|
bool clearAgentTypeId = false,
|
|
int? currentPage,
|
|
int? totalPages,
|
|
}) {
|
|
return SearchAgentsState(
|
|
agents: agents ?? this.agents,
|
|
agentTypes: agentTypes ?? this.agentTypes,
|
|
isLoading: isLoading ?? this.isLoading,
|
|
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
|
|
error: error,
|
|
searchQuery: searchQuery ?? this.searchQuery,
|
|
selectedAgentTypeId: clearAgentTypeId
|
|
? null
|
|
: (selectedAgentTypeId ?? this.selectedAgentTypeId),
|
|
currentPage: currentPage ?? this.currentPage,
|
|
totalPages: totalPages ?? this.totalPages,
|
|
);
|
|
}
|
|
}
|
|
|
|
class SearchAgentsNotifier extends StateNotifier<SearchAgentsState> {
|
|
final AgentsRepository _repository;
|
|
|
|
SearchAgentsNotifier(this._repository)
|
|
: super(const SearchAgentsState(isLoading: true)) {
|
|
_init();
|
|
}
|
|
|
|
Future<void> _init() async {
|
|
try {
|
|
final agentTypes = await _repository.getAgentTypes();
|
|
state = state.copyWith(agentTypes: agentTypes);
|
|
await _fetchAgents(page: 1);
|
|
} catch (e) {
|
|
state = state.copyWith(isLoading: false, error: e.toString());
|
|
}
|
|
}
|
|
|
|
Future<void> _fetchAgents({required int page, bool append = false}) async {
|
|
try {
|
|
final response = await _repository.searchAgents(
|
|
search: state.searchQuery.isNotEmpty ? state.searchQuery : null,
|
|
agentTypeId: state.selectedAgentTypeId,
|
|
page: page,
|
|
limit: 10,
|
|
);
|
|
|
|
state = state.copyWith(
|
|
agents: append ? [...state.agents, ...response.data] : response.data,
|
|
currentPage: response.page,
|
|
totalPages: response.totalPages,
|
|
isLoading: false,
|
|
isLoadingMore: false,
|
|
);
|
|
} catch (e) {
|
|
state = state.copyWith(
|
|
isLoading: false,
|
|
isLoadingMore: false,
|
|
error: e.toString(),
|
|
);
|
|
}
|
|
}
|
|
|
|
void search(String query) {
|
|
state = state.copyWith(
|
|
searchQuery: query,
|
|
isLoading: true,
|
|
currentPage: 1,
|
|
);
|
|
_fetchAgents(page: 1);
|
|
}
|
|
|
|
void filterByAgentType(String? agentTypeId) {
|
|
state = state.copyWith(
|
|
selectedAgentTypeId: agentTypeId,
|
|
clearAgentTypeId: agentTypeId == null,
|
|
isLoading: true,
|
|
currentPage: 1,
|
|
);
|
|
_fetchAgents(page: 1);
|
|
}
|
|
|
|
void loadMore() {
|
|
if (state.isLoadingMore || !state.hasMore) return;
|
|
state = state.copyWith(isLoadingMore: true);
|
|
_fetchAgents(page: state.currentPage + 1, append: true);
|
|
}
|
|
|
|
Future<void> refresh() async {
|
|
state = state.copyWith(isLoading: true, currentPage: 1);
|
|
await _fetchAgents(page: 1);
|
|
}
|
|
}
|
|
|
|
final searchAgentsProvider =
|
|
StateNotifierProvider.autoDispose<SearchAgentsNotifier, SearchAgentsState>(
|
|
(ref) {
|
|
final repository = ref.watch(agentsRepositoryProvider);
|
|
return SearchAgentsNotifier(repository);
|
|
});
|