add quotes
This commit is contained in:
138
lib/features/quotes/presentation/providers/quotes_provider.dart
Normal file
138
lib/features/quotes/presentation/providers/quotes_provider.dart
Normal file
@@ -0,0 +1,138 @@
|
||||
/// Providers: Quotes
|
||||
///
|
||||
/// Riverpod providers for managing quotes state.
|
||||
library;
|
||||
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:worker/core/database/models/enums.dart';
|
||||
import 'package:worker/features/quotes/data/datasources/quotes_local_datasource.dart';
|
||||
import 'package:worker/features/quotes/data/models/quote_model.dart';
|
||||
|
||||
part 'quotes_provider.g.dart';
|
||||
|
||||
/// Quotes Local Data Source Provider
|
||||
@riverpod
|
||||
QuotesLocalDataSource quotesLocalDataSource(Ref ref) {
|
||||
return QuotesLocalDataSource();
|
||||
}
|
||||
|
||||
/// Quotes Provider
|
||||
///
|
||||
/// Provides list of all quotes from local data source.
|
||||
@riverpod
|
||||
class Quotes extends _$Quotes {
|
||||
@override
|
||||
Future<List<QuoteModel>> build() async {
|
||||
final datasource = ref.read(quotesLocalDataSourceProvider);
|
||||
|
||||
// Seed mock data on first load
|
||||
final quotes = await datasource.getAllQuotes();
|
||||
if (quotes.isEmpty) {
|
||||
await datasource.seedMockQuotes();
|
||||
return await datasource.getAllQuotes();
|
||||
}
|
||||
|
||||
return quotes;
|
||||
}
|
||||
|
||||
/// Refresh quotes
|
||||
Future<void> refresh() async {
|
||||
state = const AsyncValue.loading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
return await ref.read(quotesLocalDataSourceProvider).getAllQuotes();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Quote Search Query Provider
|
||||
@riverpod
|
||||
class QuoteSearchQuery extends _$QuoteSearchQuery {
|
||||
@override
|
||||
String build() {
|
||||
return '';
|
||||
}
|
||||
|
||||
void updateQuery(String query) {
|
||||
state = query;
|
||||
}
|
||||
|
||||
void clearQuery() {
|
||||
state = '';
|
||||
}
|
||||
}
|
||||
|
||||
/// Selected Quote Status Filter Provider
|
||||
@riverpod
|
||||
class SelectedQuoteStatus extends _$SelectedQuoteStatus {
|
||||
@override
|
||||
QuoteStatus? build() {
|
||||
return null; // null means show all statuses
|
||||
}
|
||||
|
||||
void selectStatus(QuoteStatus? status) {
|
||||
state = status;
|
||||
}
|
||||
|
||||
void clearFilter() {
|
||||
state = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Filtered Quotes Provider
|
||||
///
|
||||
/// Filters quotes by search query and status.
|
||||
@riverpod
|
||||
Future<List<QuoteModel>> filteredQuotes(Ref ref) async {
|
||||
final quotesAsync = ref.watch(quotesProvider);
|
||||
final searchQuery = ref.watch(quoteSearchQueryProvider);
|
||||
final selectedStatus = ref.watch(selectedQuoteStatusProvider);
|
||||
|
||||
return quotesAsync.when(
|
||||
data: (quotes) {
|
||||
var filtered = quotes;
|
||||
|
||||
// Filter by search query
|
||||
if (searchQuery.isNotEmpty) {
|
||||
final lowerQuery = searchQuery.toLowerCase();
|
||||
filtered = filtered.where((quote) {
|
||||
final matchesNumber = quote.quoteNumber.toLowerCase().contains(lowerQuery);
|
||||
final matchesProject =
|
||||
quote.projectName?.toLowerCase().contains(lowerQuery) ?? false;
|
||||
return matchesNumber || matchesProject;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
// Filter by status
|
||||
if (selectedStatus != null) {
|
||||
filtered = filtered.where((quote) => quote.status == selectedStatus).toList();
|
||||
}
|
||||
|
||||
// Sort by creation date (newest first)
|
||||
filtered.sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||||
|
||||
return filtered;
|
||||
},
|
||||
loading: () => [],
|
||||
error: (error, stack) => [],
|
||||
);
|
||||
}
|
||||
|
||||
/// Quotes Count by Status Provider
|
||||
@riverpod
|
||||
Future<Map<QuoteStatus, int>> quotesCountByStatus(Ref ref) async {
|
||||
final quotesAsync = ref.watch(quotesProvider);
|
||||
|
||||
return quotesAsync.when(
|
||||
data: (quotes) {
|
||||
final counts = <QuoteStatus, int>{};
|
||||
|
||||
for (final status in QuoteStatus.values) {
|
||||
counts[status] = quotes.where((quote) => quote.status == status).length;
|
||||
}
|
||||
|
||||
return counts;
|
||||
},
|
||||
loading: () => {},
|
||||
error: (error, stack) => {},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user