feat: Implement agent search functionality and update the home screen to dynamically display professional data.

This commit is contained in:
pradeepkumar
2026-03-07 10:25:53 +05:30
parent 379fbfe0a8
commit aefe80253f
18 changed files with 1655 additions and 627 deletions

View File

@@ -0,0 +1,139 @@
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);
});