feat: Implement agent filtering by integrating a new API endpoint for filterable fields, introducing filter data models, and adding a dedicated filter sheet UI, alongside an updated profile icon.

This commit is contained in:
pradeepkumar
2026-03-07 22:33:09 +05:30
parent 402c1cf206
commit ef0fe593ab
7 changed files with 568 additions and 19 deletions

View File

@@ -2,11 +2,13 @@ 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/data/models/filterable_field.dart';
import 'package:real_estate_mobile/features/agents/presentation/providers/agents_provider.dart';
class SearchAgentsState {
final List<AgentProfile> agents;
final List<AgentType> agentTypes;
final List<FilterableField> filterFields;
final bool isLoading;
final bool isLoadingMore;
final String? error;
@@ -14,10 +16,12 @@ class SearchAgentsState {
final String? selectedAgentTypeId;
final int currentPage;
final int totalPages;
final Map<String, List<String>> activeFilters;
const SearchAgentsState({
this.agents = const [],
this.agentTypes = const [],
this.filterFields = const [],
this.isLoading = false,
this.isLoadingMore = false,
this.error,
@@ -25,6 +29,7 @@ class SearchAgentsState {
this.selectedAgentTypeId,
this.currentPage = 1,
this.totalPages = 1,
this.activeFilters = const {},
});
bool get hasMore => currentPage < totalPages;
@@ -32,6 +37,7 @@ class SearchAgentsState {
SearchAgentsState copyWith({
List<AgentProfile>? agents,
List<AgentType>? agentTypes,
List<FilterableField>? filterFields,
bool? isLoading,
bool? isLoadingMore,
String? error,
@@ -40,10 +46,12 @@ class SearchAgentsState {
bool clearAgentTypeId = false,
int? currentPage,
int? totalPages,
Map<String, List<String>>? activeFilters,
}) {
return SearchAgentsState(
agents: agents ?? this.agents,
agentTypes: agentTypes ?? this.agentTypes,
filterFields: filterFields ?? this.filterFields,
isLoading: isLoading ?? this.isLoading,
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
error: error,
@@ -53,6 +61,7 @@ class SearchAgentsState {
: (selectedAgentTypeId ?? this.selectedAgentTypeId),
currentPage: currentPage ?? this.currentPage,
totalPages: totalPages ?? this.totalPages,
activeFilters: activeFilters ?? this.activeFilters,
);
}
}
@@ -67,8 +76,14 @@ class SearchAgentsNotifier extends StateNotifier<SearchAgentsState> {
Future<void> _init() async {
try {
final agentTypes = await _repository.getAgentTypes();
state = state.copyWith(agentTypes: agentTypes);
final results = await Future.wait([
_repository.getAgentTypes(),
_repository.getFilterableFields(),
]);
state = state.copyWith(
agentTypes: results[0] as List<AgentType>,
filterFields: results[1] as List<FilterableField>,
);
await _fetchAgents(page: 1);
} catch (e) {
state = state.copyWith(isLoading: false, error: e.toString());
@@ -82,6 +97,7 @@ class SearchAgentsNotifier extends StateNotifier<SearchAgentsState> {
agentTypeId: state.selectedAgentTypeId,
page: page,
limit: 10,
filters: state.activeFilters.isNotEmpty ? state.activeFilters : null,
);
state = state.copyWith(
@@ -119,6 +135,24 @@ class SearchAgentsNotifier extends StateNotifier<SearchAgentsState> {
_fetchAgents(page: 1);
}
void applyFilters(Map<String, List<String>> filters) {
state = state.copyWith(
activeFilters: filters,
isLoading: true,
currentPage: 1,
);
_fetchAgents(page: 1);
}
void clearFilters() {
state = state.copyWith(
activeFilters: const {},
isLoading: true,
currentPage: 1,
);
_fetchAgents(page: 1);
}
void loadMore() {
if (state.isLoadingMore || !state.hasMore) return;
state = state.copyWith(isLoadingMore: true);