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) => {},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'quotes_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Quotes Local Data Source Provider
|
||||
|
||||
@ProviderFor(quotesLocalDataSource)
|
||||
const quotesLocalDataSourceProvider = QuotesLocalDataSourceProvider._();
|
||||
|
||||
/// Quotes Local Data Source Provider
|
||||
|
||||
final class QuotesLocalDataSourceProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
QuotesLocalDataSource,
|
||||
QuotesLocalDataSource,
|
||||
QuotesLocalDataSource
|
||||
>
|
||||
with $Provider<QuotesLocalDataSource> {
|
||||
/// Quotes Local Data Source Provider
|
||||
const QuotesLocalDataSourceProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'quotesLocalDataSourceProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$quotesLocalDataSourceHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<QuotesLocalDataSource> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
QuotesLocalDataSource create(Ref ref) {
|
||||
return quotesLocalDataSource(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(QuotesLocalDataSource value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<QuotesLocalDataSource>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$quotesLocalDataSourceHash() =>
|
||||
r'02a822db926d8d80460bcc27a08ea494dff6c441';
|
||||
|
||||
/// Quotes Provider
|
||||
///
|
||||
/// Provides list of all quotes from local data source.
|
||||
|
||||
@ProviderFor(Quotes)
|
||||
const quotesProvider = QuotesProvider._();
|
||||
|
||||
/// Quotes Provider
|
||||
///
|
||||
/// Provides list of all quotes from local data source.
|
||||
final class QuotesProvider
|
||||
extends $AsyncNotifierProvider<Quotes, List<QuoteModel>> {
|
||||
/// Quotes Provider
|
||||
///
|
||||
/// Provides list of all quotes from local data source.
|
||||
const QuotesProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'quotesProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$quotesHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
Quotes create() => Quotes();
|
||||
}
|
||||
|
||||
String _$quotesHash() => r'f5011c354218f10da95af16269c956416fca3303';
|
||||
|
||||
/// Quotes Provider
|
||||
///
|
||||
/// Provides list of all quotes from local data source.
|
||||
|
||||
abstract class _$Quotes extends $AsyncNotifier<List<QuoteModel>> {
|
||||
FutureOr<List<QuoteModel>> build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref =
|
||||
this.ref as $Ref<AsyncValue<List<QuoteModel>>, List<QuoteModel>>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<AsyncValue<List<QuoteModel>>, List<QuoteModel>>,
|
||||
AsyncValue<List<QuoteModel>>,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
|
||||
/// Quote Search Query Provider
|
||||
|
||||
@ProviderFor(QuoteSearchQuery)
|
||||
const quoteSearchQueryProvider = QuoteSearchQueryProvider._();
|
||||
|
||||
/// Quote Search Query Provider
|
||||
final class QuoteSearchQueryProvider
|
||||
extends $NotifierProvider<QuoteSearchQuery, String> {
|
||||
/// Quote Search Query Provider
|
||||
const QuoteSearchQueryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'quoteSearchQueryProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$quoteSearchQueryHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
QuoteSearchQuery create() => QuoteSearchQuery();
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(String value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<String>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$quoteSearchQueryHash() => r'cc889177beb9905a80b223cba14612bb0c419103';
|
||||
|
||||
/// Quote Search Query Provider
|
||||
|
||||
abstract class _$QuoteSearchQuery extends $Notifier<String> {
|
||||
String build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<String, String>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<String, String>,
|
||||
String,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
|
||||
/// Selected Quote Status Filter Provider
|
||||
|
||||
@ProviderFor(SelectedQuoteStatus)
|
||||
const selectedQuoteStatusProvider = SelectedQuoteStatusProvider._();
|
||||
|
||||
/// Selected Quote Status Filter Provider
|
||||
final class SelectedQuoteStatusProvider
|
||||
extends $NotifierProvider<SelectedQuoteStatus, QuoteStatus?> {
|
||||
/// Selected Quote Status Filter Provider
|
||||
const SelectedQuoteStatusProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'selectedQuoteStatusProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$selectedQuoteStatusHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
SelectedQuoteStatus create() => SelectedQuoteStatus();
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(QuoteStatus? value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<QuoteStatus?>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$selectedQuoteStatusHash() =>
|
||||
r'5c1ecf114bbb85a00174dad255c939288722658b';
|
||||
|
||||
/// Selected Quote Status Filter Provider
|
||||
|
||||
abstract class _$SelectedQuoteStatus extends $Notifier<QuoteStatus?> {
|
||||
QuoteStatus? build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<QuoteStatus?, QuoteStatus?>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<QuoteStatus?, QuoteStatus?>,
|
||||
QuoteStatus?,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
|
||||
/// Filtered Quotes Provider
|
||||
///
|
||||
/// Filters quotes by search query and status.
|
||||
|
||||
@ProviderFor(filteredQuotes)
|
||||
const filteredQuotesProvider = FilteredQuotesProvider._();
|
||||
|
||||
/// Filtered Quotes Provider
|
||||
///
|
||||
/// Filters quotes by search query and status.
|
||||
|
||||
final class FilteredQuotesProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<List<QuoteModel>>,
|
||||
List<QuoteModel>,
|
||||
FutureOr<List<QuoteModel>>
|
||||
>
|
||||
with $FutureModifier<List<QuoteModel>>, $FutureProvider<List<QuoteModel>> {
|
||||
/// Filtered Quotes Provider
|
||||
///
|
||||
/// Filters quotes by search query and status.
|
||||
const FilteredQuotesProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'filteredQuotesProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$filteredQuotesHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<List<QuoteModel>> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<List<QuoteModel>> create(Ref ref) {
|
||||
return filteredQuotes(ref);
|
||||
}
|
||||
}
|
||||
|
||||
String _$filteredQuotesHash() => r'77076cfa483cb81cc56972bca6a3c1e97861165c';
|
||||
|
||||
/// Quotes Count by Status Provider
|
||||
|
||||
@ProviderFor(quotesCountByStatus)
|
||||
const quotesCountByStatusProvider = QuotesCountByStatusProvider._();
|
||||
|
||||
/// Quotes Count by Status Provider
|
||||
|
||||
final class QuotesCountByStatusProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<Map<QuoteStatus, int>>,
|
||||
Map<QuoteStatus, int>,
|
||||
FutureOr<Map<QuoteStatus, int>>
|
||||
>
|
||||
with
|
||||
$FutureModifier<Map<QuoteStatus, int>>,
|
||||
$FutureProvider<Map<QuoteStatus, int>> {
|
||||
/// Quotes Count by Status Provider
|
||||
const QuotesCountByStatusProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'quotesCountByStatusProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$quotesCountByStatusHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<Map<QuoteStatus, int>> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<Map<QuoteStatus, int>> create(Ref ref) {
|
||||
return quotesCountByStatus(ref);
|
||||
}
|
||||
}
|
||||
|
||||
String _$quotesCountByStatusHash() =>
|
||||
r'474b62ad0ccf890df1c33c64a17f9a0f428f676e';
|
||||
Reference in New Issue
Block a user