157 lines
3.9 KiB
Dart
157 lines
3.9 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
|
|
import '../models/bar_tab.dart';
|
|
import '../models/closed_tab.dart';
|
|
import '../services/bar_tab_service.dart';
|
|
|
|
class HistoryViewModel extends ChangeNotifier {
|
|
final BarTabService barTabService;
|
|
|
|
HistoryViewModel({required this.barTabService});
|
|
|
|
static const int _pageSize = 20;
|
|
|
|
List<ClosedTab> _closedTabs = [];
|
|
List<BarTab> _openTabs = [];
|
|
List<String> _customerNames = [];
|
|
String? _selectedCustomer;
|
|
int _offset = 0;
|
|
int _totalCount = 0;
|
|
bool _isLoading = false;
|
|
bool _hasLoaded = false;
|
|
bool _isLoadingMore = false;
|
|
String? _errorMessage;
|
|
String _searchQuery = '';
|
|
|
|
List<ClosedTab> get closedTabs {
|
|
return _closedTabs
|
|
.where((tab) => _matchesCustomer(tab.customerName))
|
|
.toList();
|
|
}
|
|
|
|
List<BarTab> get openTabs {
|
|
return _openTabs
|
|
.where((tab) => _matchesCustomer(tab.customerName))
|
|
.toList();
|
|
}
|
|
|
|
List<String> get customerNames => _customerNames;
|
|
|
|
String? get selectedCustomer => _selectedCustomer;
|
|
|
|
bool get isLoading => _isLoading;
|
|
|
|
bool get hasLoaded => _hasLoaded;
|
|
|
|
bool get isLoadingMore => _isLoadingMore;
|
|
|
|
bool get hasMore => _closedTabs.length < _totalCount;
|
|
|
|
String? get errorMessage => _errorMessage;
|
|
|
|
Future<void> ensureLoaded() async {
|
|
if (_hasLoaded || _isLoading) return;
|
|
|
|
await load();
|
|
}
|
|
|
|
Future<void> load() async {
|
|
if (_isLoading) return;
|
|
|
|
_isLoading = true;
|
|
_errorMessage = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final results = await Future.wait([
|
|
_fetchPage(offset: 0),
|
|
barTabService.getClosedTabCount(customerName: _selectedCustomer),
|
|
barTabService.getDistinctCustomerNames(),
|
|
barTabService.getOpenTabs(includeRemoved: true),
|
|
]);
|
|
|
|
_closedTabs = (results[0] as List<ClosedTab>).toList()
|
|
..sort(_compareClosedTabs);
|
|
_totalCount = results[1] as int;
|
|
_openTabs = (results[3] as List<BarTab>).toList()..sort(_compareOpenTabs);
|
|
_customerNames = {
|
|
...(results[2] as List<String>),
|
|
..._openTabs.map((tab) => tab.customerName),
|
|
}.toList()..sort();
|
|
_offset = _closedTabs.length;
|
|
} catch (e) {
|
|
debugPrint('HistoryViewModel: load error: $e');
|
|
_errorMessage = 'Could not load tab history.';
|
|
} finally {
|
|
_hasLoaded = true;
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> loadMore() async {
|
|
if (_isLoadingMore || !hasMore) return;
|
|
|
|
_isLoadingMore = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final more = await _fetchPage(offset: _offset);
|
|
_closedTabs = [..._closedTabs, ...more]..sort(_compareClosedTabs);
|
|
_offset = _closedTabs.length;
|
|
} catch (e) {
|
|
debugPrint('HistoryViewModel: loadMore error: $e');
|
|
_errorMessage = 'Could not load more tabs.';
|
|
} finally {
|
|
_isLoadingMore = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<List<ClosedTab>> _fetchPage({required int offset}) {
|
|
return barTabService.getClosedTabsPaginated(
|
|
limit: _pageSize,
|
|
offset: offset,
|
|
customerName: _selectedCustomer,
|
|
);
|
|
}
|
|
|
|
int _compareClosedTabs(ClosedTab a, ClosedTab b) {
|
|
final byClosedAt = b.closedAt.compareTo(a.closedAt);
|
|
if (byClosedAt != 0) return byClosedAt;
|
|
|
|
return b.id.compareTo(a.id);
|
|
}
|
|
|
|
int _compareOpenTabs(BarTab a, BarTab b) {
|
|
final byOpenedAt = b.openedAt.compareTo(a.openedAt);
|
|
if (byOpenedAt != 0) return byOpenedAt;
|
|
|
|
return b.id.compareTo(a.id);
|
|
}
|
|
|
|
void search(String query) {
|
|
_searchQuery = query;
|
|
notifyListeners();
|
|
}
|
|
|
|
bool _matchesCustomer(String customerName) {
|
|
if (_selectedCustomer != null && customerName != _selectedCustomer) {
|
|
return false;
|
|
}
|
|
|
|
if (_searchQuery.isEmpty) return true;
|
|
|
|
return customerName.toLowerCase().contains(_searchQuery.toLowerCase());
|
|
}
|
|
|
|
Future<void> filterByCustomer(String? customerName) async {
|
|
_selectedCustomer = customerName;
|
|
_searchQuery = '';
|
|
_offset = 0;
|
|
_closedTabs = [];
|
|
|
|
await load();
|
|
}
|
|
}
|