sort and filter added to tenders web

This commit is contained in:
amirrezaghabeli
2025-09-23 13:15:41 +03:30
parent 9efc7b7f1a
commit 801e170d7c
10 changed files with 190 additions and 28 deletions
+131 -11
View File
@@ -1,11 +1,13 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:tm_app/core/utils/device_utils.dart';
import 'package:tm_app/data/repositories/tenders_repository.dart';
import 'package:tm_app/data/services/model/feedback_data/feedback_data.dart';
import 'package:tm_app/data/services/model/feedback_response/feedback_response.dart';
import 'package:tm_app/data/services/model/tenders/tenders_response/tenders_response.dart';
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
import '../core/utils/result.dart';
import 'home_view_model.dart';
@@ -47,6 +49,88 @@ class TendersViewModel with ChangeNotifier {
bool get hasMoreData => _hasMoreData;
// Filter States
DateTimeRange? selectedDateRange;
String selectedStatus = 'All';
String selectedSort = '';
String sortBy = '';
String sortOrder = '';
final _fmt = DateFormat('yyyy/MM/dd');
String get startDateFormatted =>
selectedDateRange?.start != null
? _fmt.format(selectedDateRange!.start)
: 'YYYY/MM/DD';
String get endDateFormatted =>
selectedDateRange?.end != null
? _fmt.format(selectedDateRange!.end)
: 'YYYY/MM/DD';
String get startDateUnix =>
selectedDateRange?.start != null
? (selectedDateRange!.start.millisecondsSinceEpoch ~/ 1000).toString()
: '';
String get endDateUnix =>
selectedDateRange?.end != null
? (selectedDateRange!.end.millisecondsSinceEpoch ~/ 1000).toString()
: '';
// --- Filter Actions ---
void setDateRange(DateTimeRange? range) {
selectedDateRange = range;
notifyListeners();
}
void setStatus(String status) {
// Clear data when status changes
_clearAllData();
selectedStatus = status;
currentPage = 1;
notifyListeners();
}
void setSort(String sort) {
// Clear data when status changes
_clearAllData();
selectedSort = sort;
if (sort == TendersStrings.lessBudget) {
sortBy = 'estimated_value';
sortOrder = 'asc';
} else if (sort == TendersStrings.moreBudget) {
sortBy = 'estimated_value';
sortOrder = 'desc';
} else if (sort == TendersStrings.minimumTime) {
sortBy = 'submission_deadline';
sortOrder = 'asc';
} else if (sort == TendersStrings.mostOfTheTime) {
sortBy = 'submission_deadline';
sortOrder = 'desc';
}
currentPage = 1;
notifyListeners();
}
void _clearAllData() {
_tendersResponse = null;
_errorMessage = null;
_currentOffset = 0;
_hasMoreData = true;
currentPage = 1;
sortBy = '';
sortOrder = '';
selectedSort = '';
selectedStatus = '';
notifyListeners();
}
void init(BuildContext context) async {
clearAll();
await getTenders(context: context);
}
/// Get feedback for a specific tender
FeedbackData? getFeedbackForTender(String tenderId) {
try {
@@ -61,10 +145,13 @@ class TendersViewModel with ChangeNotifier {
return feedbacks.any((f) => f.tender == tenderId);
}
Future<void> getTenders({String? query, BuildContext? context}) async {
Future<void> getTenders({
required BuildContext context,
String? query,
}) async {
_isLoading = true;
notifyListeners();
if (context != null && DeviceUtils.isDesktop(context)) {
if (DeviceUtils.isDesktop(context)) {
await getTendersDesktop(query: query);
} else {
await getTendersMobile(query: query);
@@ -72,7 +159,7 @@ class TendersViewModel with ChangeNotifier {
}
Future<void> getTendersMobile({String? query}) async {
clearAll(); // Clear all data before fetching new tenders
// Clear all data before fetching new tenders
_currentOffset = 0;
_hasMoreData = true;
@@ -82,6 +169,8 @@ class TendersViewModel with ChangeNotifier {
limit: _pageSize,
offset: _currentOffset,
query: query,
sortBy: '',
sortOrder: '',
);
switch (result) {
case Ok<TendersResponse>():
@@ -111,9 +200,16 @@ class TendersViewModel with ChangeNotifier {
notifyListeners();
}
Future<void> getTendersDesktop({String? query}) async {
clearAll(); // Clear all data before fetching new tenders
Future<void> getTendersDesktop({
String? query,
String? sortBy,
String? sortOrder,
String? publicationDateFrom,
String? publicationDateTo,
}) async {
// Clear all data before fetching new tenders
_isLoading = true;
notifyListeners();
_currentOffset = 0;
_hasMoreData = true;
_searchQuery = query;
@@ -122,6 +218,10 @@ class TendersViewModel with ChangeNotifier {
limit: _pageSize,
offset: _currentOffset,
query: query,
sortBy: sortBy ?? '',
sortOrder: sortOrder ?? '',
publicationDateFrom: publicationDateFrom ?? '',
publicationDateTo: publicationDateTo ?? '',
);
switch (result) {
case Ok<TendersResponse>():
@@ -166,6 +266,8 @@ class TendersViewModel with ChangeNotifier {
limit: _pageSize,
offset: _currentOffset,
query: _searchQuery,
sortBy: sortBy,
sortOrder: sortOrder,
);
switch (result) {
@@ -356,13 +458,24 @@ class TendersViewModel with ChangeNotifier {
notifyListeners();
}
Future<void> callWithSortAndStatus() async {
await getTendersDesktop(
sortBy: sortBy,
sortOrder: sortOrder,
publicationDateFrom: startDateUnix,
publicationDateTo: endDateUnix,
);
}
/// Search tenders with query
Future<void> searchTenders(String query) async {
if (query.trim().isEmpty) {
await getTendersDesktop();
} else {
await getTendersDesktop(query: query.trim());
}
await getTendersDesktop(
query: query.trim(),
sortBy: sortBy,
sortOrder: sortOrder,
publicationDateFrom: startDateUnix,
publicationDateTo: endDateUnix,
);
}
/// Clear all data (tenders, feedbacks, and approvals)
@@ -370,6 +483,11 @@ class TendersViewModel with ChangeNotifier {
clearTenders();
clearFeedbacks();
_searchQuery = null;
selectedSort = '';
selectedStatus = '';
selectedDateRange = null;
sortBy = '';
sortOrder = '';
notifyListeners();
}
@@ -389,6 +507,8 @@ class TendersViewModel with ChangeNotifier {
limit: _pageSize,
offset: _currentOffset,
query: _searchQuery,
sortBy: sortBy,
sortOrder: sortOrder,
);
switch (result) {