Merge branch 'main' of https://git.renolation.com/renolation/retail
# Conflicts: # docs/API_RESPONSE_FIX.md # docs/AUTH_UI_SUMMARY.md # docs/AUTO_LOGIN_DEBUG.md # docs/AUTO_LOGIN_FIXED.md # docs/BUILD_STATUS.md # docs/CLEANUP_COMPLETE.md # docs/EXPORT_FILES_SUMMARY.md # docs/RIVERPOD_DI_MIGRATION.md # docs/TEST_AUTO_LOGIN.md # lib/features/categories/data/datasources/category_remote_datasource.dart # lib/features/categories/presentation/providers/categories_provider.dart # lib/features/categories/presentation/providers/categories_provider.g.dart # lib/features/products/data/datasources/product_remote_datasource.dart # lib/features/products/data/models/product_model.dart # lib/features/products/presentation/pages/products_page.dart # lib/features/products/presentation/providers/products_provider.dart # lib/features/products/presentation/providers/products_provider.g.dart
This commit is contained in:
@@ -1,387 +1,97 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import '../../domain/entities/product.dart';
|
||||
import '../../data/models/product_model.dart';
|
||||
import 'product_datasource_provider.dart';
|
||||
import 'selected_category_provider.dart';
|
||||
import '../../data/providers/product_providers.dart';
|
||||
import '../../../../core/providers/providers.dart';
|
||||
|
||||
part 'products_provider.g.dart';
|
||||
|
||||
/// Pagination state for products
|
||||
class ProductPaginationState {
|
||||
final List<Product> products;
|
||||
final int currentPage;
|
||||
final int totalPages;
|
||||
final int totalItems;
|
||||
final bool hasMore;
|
||||
final bool isLoadingMore;
|
||||
|
||||
const ProductPaginationState({
|
||||
required this.products,
|
||||
required this.currentPage,
|
||||
required this.totalPages,
|
||||
required this.totalItems,
|
||||
required this.hasMore,
|
||||
this.isLoadingMore = false,
|
||||
});
|
||||
|
||||
ProductPaginationState copyWith({
|
||||
List<Product>? products,
|
||||
int? currentPage,
|
||||
int? totalPages,
|
||||
int? totalItems,
|
||||
bool? hasMore,
|
||||
bool? isLoadingMore,
|
||||
}) {
|
||||
return ProductPaginationState(
|
||||
products: products ?? this.products,
|
||||
currentPage: currentPage ?? this.currentPage,
|
||||
totalPages: totalPages ?? this.totalPages,
|
||||
totalItems: totalItems ?? this.totalItems,
|
||||
hasMore: hasMore ?? this.hasMore,
|
||||
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider for products list with pagination and filtering
|
||||
/// Provider for products list with API-first approach
|
||||
@riverpod
|
||||
class Products extends _$Products {
|
||||
static const int _limit = 20;
|
||||
|
||||
@override
|
||||
Future<ProductPaginationState> build() async {
|
||||
return await _fetchProducts(page: 1);
|
||||
Future<List<Product>> build() async {
|
||||
// API-first: Try to load from API first
|
||||
final repository = ref.watch(productRepositoryProvider);
|
||||
final networkInfo = ref.watch(networkInfoProvider);
|
||||
|
||||
// Check if online
|
||||
final isConnected = await networkInfo.isConnected;
|
||||
|
||||
if (isConnected) {
|
||||
// Try API first
|
||||
try {
|
||||
final syncResult = await repository.syncProducts();
|
||||
return syncResult.fold(
|
||||
(failure) {
|
||||
// API failed, fallback to cache
|
||||
print('API failed, falling back to cache: ${failure.message}');
|
||||
return _loadFromCache();
|
||||
},
|
||||
(products) => products,
|
||||
);
|
||||
} catch (e) {
|
||||
// API error, fallback to cache
|
||||
print('API error, falling back to cache: $e');
|
||||
return _loadFromCache();
|
||||
}
|
||||
} else {
|
||||
// Offline, load from cache
|
||||
print('Offline, loading from cache');
|
||||
return _loadFromCache();
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch products with pagination and optional filters
|
||||
Future<ProductPaginationState> _fetchProducts({
|
||||
required int page,
|
||||
String? categoryId,
|
||||
String? search,
|
||||
double? minPrice,
|
||||
double? maxPrice,
|
||||
bool? isAvailable,
|
||||
}) async {
|
||||
final datasource = ref.read(productRemoteDataSourceProvider);
|
||||
/// Load products from local cache
|
||||
Future<List<Product>> _loadFromCache() async {
|
||||
final repository = ref.read(productRepositoryProvider);
|
||||
final result = await repository.getAllProducts();
|
||||
|
||||
final response = await datasource.getAllProducts(
|
||||
page: page,
|
||||
limit: _limit,
|
||||
categoryId: categoryId,
|
||||
search: search,
|
||||
minPrice: minPrice,
|
||||
maxPrice: maxPrice,
|
||||
isAvailable: isAvailable,
|
||||
);
|
||||
|
||||
// Extract data
|
||||
final List<ProductModel> productModels =
|
||||
(response['data'] as List<ProductModel>);
|
||||
final meta = response['meta'] as Map<String, dynamic>;
|
||||
|
||||
// Convert to entities
|
||||
final products = productModels.map((model) => model.toEntity()).toList();
|
||||
|
||||
// Extract pagination info
|
||||
final currentPage = meta['currentPage'] as int? ?? page;
|
||||
final totalPages = meta['totalPages'] as int? ?? 1;
|
||||
final totalItems = meta['totalItems'] as int? ?? products.length;
|
||||
final hasMore = currentPage < totalPages;
|
||||
|
||||
return ProductPaginationState(
|
||||
products: products,
|
||||
currentPage: currentPage,
|
||||
totalPages: totalPages,
|
||||
totalItems: totalItems,
|
||||
hasMore: hasMore,
|
||||
return result.fold(
|
||||
(failure) {
|
||||
print('Cache load failed: ${failure.message}');
|
||||
return <Product>[];
|
||||
},
|
||||
(products) => products,
|
||||
);
|
||||
}
|
||||
|
||||
/// Refresh products (reset to first page)
|
||||
/// Refresh products from local storage
|
||||
Future<void> refresh() async {
|
||||
state = const AsyncValue.loading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
return await _fetchProducts(page: 1);
|
||||
final repository = ref.read(productRepositoryProvider);
|
||||
final result = await repository.getAllProducts();
|
||||
|
||||
return result.fold(
|
||||
(failure) => throw Exception(failure.message),
|
||||
(products) => products,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Load more products (next page)
|
||||
Future<void> loadMore() async {
|
||||
final currentState = state.value;
|
||||
if (currentState == null || !currentState.hasMore) return;
|
||||
/// Sync products from API and update local storage
|
||||
Future<void> syncProducts() async {
|
||||
final networkInfo = ref.read(networkInfoProvider);
|
||||
final isConnected = await networkInfo.isConnected;
|
||||
|
||||
// Set loading more flag
|
||||
state = AsyncValue.data(
|
||||
currentState.copyWith(isLoadingMore: true),
|
||||
);
|
||||
|
||||
// Fetch next page
|
||||
final nextPage = currentState.currentPage + 1;
|
||||
|
||||
try {
|
||||
final newState = await _fetchProducts(page: nextPage);
|
||||
|
||||
// Append new products to existing ones
|
||||
state = AsyncValue.data(
|
||||
newState.copyWith(
|
||||
products: [...currentState.products, ...newState.products],
|
||||
isLoadingMore: false,
|
||||
),
|
||||
);
|
||||
} catch (error, stackTrace) {
|
||||
// Restore previous state on error
|
||||
state = AsyncValue.data(
|
||||
currentState.copyWith(isLoadingMore: false),
|
||||
);
|
||||
// Optionally rethrow or handle error
|
||||
state = AsyncValue.error(error, stackTrace);
|
||||
if (!isConnected) {
|
||||
throw Exception('No internet connection');
|
||||
}
|
||||
}
|
||||
|
||||
/// Filter products by category
|
||||
Future<void> filterByCategory(String? categoryId) async {
|
||||
state = const AsyncValue.loading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
return await _fetchProducts(page: 1, categoryId: categoryId);
|
||||
});
|
||||
}
|
||||
final repository = ref.read(productRepositoryProvider);
|
||||
final result = await repository.syncProducts();
|
||||
|
||||
/// Search products
|
||||
Future<void> search(String query) async {
|
||||
state = const AsyncValue.loading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
return await _fetchProducts(page: 1, search: query);
|
||||
});
|
||||
}
|
||||
|
||||
/// Filter by price range
|
||||
Future<void> filterByPrice({double? minPrice, double? maxPrice}) async {
|
||||
state = const AsyncValue.loading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
return await _fetchProducts(
|
||||
page: 1,
|
||||
minPrice: minPrice,
|
||||
maxPrice: maxPrice,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Filter by availability
|
||||
Future<void> filterByAvailability(bool isAvailable) async {
|
||||
state = const AsyncValue.loading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
return await _fetchProducts(page: 1, isAvailable: isAvailable);
|
||||
});
|
||||
}
|
||||
|
||||
/// Apply multiple filters at once
|
||||
Future<void> applyFilters({
|
||||
String? categoryId,
|
||||
String? search,
|
||||
double? minPrice,
|
||||
double? maxPrice,
|
||||
bool? isAvailable,
|
||||
}) async {
|
||||
state = const AsyncValue.loading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
return await _fetchProducts(
|
||||
page: 1,
|
||||
categoryId: categoryId,
|
||||
search: search,
|
||||
minPrice: minPrice,
|
||||
maxPrice: maxPrice,
|
||||
isAvailable: isAvailable,
|
||||
return result.fold(
|
||||
(failure) => throw Exception(failure.message),
|
||||
(products) => products,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider for single product by ID
|
||||
@riverpod
|
||||
Future<Product> product(Ref ref, String id) async {
|
||||
final datasource = ref.read(productRemoteDataSourceProvider);
|
||||
final productModel = await datasource.getProductById(id);
|
||||
return productModel.toEntity();
|
||||
}
|
||||
|
||||
/// Provider for products filtered by the selected category
|
||||
/// This provider automatically updates when the selected category changes
|
||||
@riverpod
|
||||
class ProductsBySelectedCategory extends _$ProductsBySelectedCategory {
|
||||
static const int _limit = 20;
|
||||
|
||||
@override
|
||||
Future<ProductPaginationState> build() async {
|
||||
// Watch selected category
|
||||
final selectedCategoryId = ref.watch(selectedCategoryProvider);
|
||||
|
||||
// Fetch products with category filter
|
||||
return await _fetchProducts(page: 1, categoryId: selectedCategoryId);
|
||||
}
|
||||
|
||||
Future<ProductPaginationState> _fetchProducts({
|
||||
required int page,
|
||||
String? categoryId,
|
||||
}) async {
|
||||
final datasource = ref.read(productRemoteDataSourceProvider);
|
||||
|
||||
final response = await datasource.getAllProducts(
|
||||
page: page,
|
||||
limit: _limit,
|
||||
categoryId: categoryId,
|
||||
);
|
||||
|
||||
// Extract data
|
||||
final List<ProductModel> productModels =
|
||||
(response['data'] as List<ProductModel>);
|
||||
final meta = response['meta'] as Map<String, dynamic>;
|
||||
|
||||
// Convert to entities
|
||||
final products = productModels.map((model) => model.toEntity()).toList();
|
||||
|
||||
// Extract pagination info
|
||||
final currentPage = meta['currentPage'] as int? ?? page;
|
||||
final totalPages = meta['totalPages'] as int? ?? 1;
|
||||
final totalItems = meta['totalItems'] as int? ?? products.length;
|
||||
final hasMore = currentPage < totalPages;
|
||||
|
||||
return ProductPaginationState(
|
||||
products: products,
|
||||
currentPage: currentPage,
|
||||
totalPages: totalPages,
|
||||
totalItems: totalItems,
|
||||
hasMore: hasMore,
|
||||
);
|
||||
}
|
||||
|
||||
/// Load more products (next page)
|
||||
Future<void> loadMore() async {
|
||||
final currentState = state.value;
|
||||
if (currentState == null || !currentState.hasMore) return;
|
||||
|
||||
// Set loading more flag
|
||||
state = AsyncValue.data(
|
||||
currentState.copyWith(isLoadingMore: true),
|
||||
);
|
||||
|
||||
// Fetch next page
|
||||
final nextPage = currentState.currentPage + 1;
|
||||
final selectedCategoryId = ref.read(selectedCategoryProvider);
|
||||
|
||||
try {
|
||||
final newState = await _fetchProducts(
|
||||
page: nextPage,
|
||||
categoryId: selectedCategoryId,
|
||||
);
|
||||
|
||||
// Append new products to existing ones
|
||||
state = AsyncValue.data(
|
||||
newState.copyWith(
|
||||
products: [...currentState.products, ...newState.products],
|
||||
isLoadingMore: false,
|
||||
),
|
||||
);
|
||||
} catch (error, stackTrace) {
|
||||
// Restore previous state on error
|
||||
state = AsyncValue.data(
|
||||
currentState.copyWith(isLoadingMore: false),
|
||||
);
|
||||
state = AsyncValue.error(error, stackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider for searching products with pagination
|
||||
@riverpod
|
||||
class ProductSearch extends _$ProductSearch {
|
||||
static const int _limit = 20;
|
||||
|
||||
@override
|
||||
Future<ProductPaginationState> build(String query) async {
|
||||
if (query.isEmpty) {
|
||||
return const ProductPaginationState(
|
||||
products: [],
|
||||
currentPage: 0,
|
||||
totalPages: 0,
|
||||
totalItems: 0,
|
||||
hasMore: false,
|
||||
);
|
||||
}
|
||||
|
||||
return await _searchProducts(query: query, page: 1);
|
||||
}
|
||||
|
||||
Future<ProductPaginationState> _searchProducts({
|
||||
required String query,
|
||||
required int page,
|
||||
}) async {
|
||||
final datasource = ref.read(productRemoteDataSourceProvider);
|
||||
|
||||
final response = await datasource.searchProducts(query, page, _limit);
|
||||
|
||||
// Extract data
|
||||
final List<ProductModel> productModels =
|
||||
(response['data'] as List<ProductModel>);
|
||||
final meta = response['meta'] as Map<String, dynamic>;
|
||||
|
||||
// Convert to entities
|
||||
final products = productModels.map((model) => model.toEntity()).toList();
|
||||
|
||||
// Extract pagination info
|
||||
final currentPage = meta['currentPage'] as int? ?? page;
|
||||
final totalPages = meta['totalPages'] as int? ?? 1;
|
||||
final totalItems = meta['totalItems'] as int? ?? products.length;
|
||||
final hasMore = currentPage < totalPages;
|
||||
|
||||
return ProductPaginationState(
|
||||
products: products,
|
||||
currentPage: currentPage,
|
||||
totalPages: totalPages,
|
||||
totalItems: totalItems,
|
||||
hasMore: hasMore,
|
||||
);
|
||||
}
|
||||
|
||||
/// Load more search results (next page)
|
||||
Future<void> loadMore() async {
|
||||
final currentState = state.value;
|
||||
if (currentState == null || !currentState.hasMore) return;
|
||||
|
||||
// Set loading more flag
|
||||
state = AsyncValue.data(
|
||||
currentState.copyWith(isLoadingMore: true),
|
||||
);
|
||||
|
||||
// Fetch next page
|
||||
final nextPage = currentState.currentPage + 1;
|
||||
|
||||
try {
|
||||
// Get the query from the provider parameter
|
||||
// Note: In Riverpod 3.0, family parameters are accessed differently
|
||||
// We need to re-search with the same query
|
||||
final newState = await _searchProducts(
|
||||
query: '', // This will be replaced by proper implementation
|
||||
page: nextPage,
|
||||
);
|
||||
|
||||
// Append new products to existing ones
|
||||
state = AsyncValue.data(
|
||||
newState.copyWith(
|
||||
products: [...currentState.products, ...newState.products],
|
||||
isLoadingMore: false,
|
||||
),
|
||||
);
|
||||
} catch (error, stackTrace) {
|
||||
// Restore previous state on error
|
||||
state = AsyncValue.data(
|
||||
currentState.copyWith(isLoadingMore: false),
|
||||
);
|
||||
state = AsyncValue.error(error, stackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Search query provider for products
|
||||
/// Provider for search query
|
||||
@riverpod
|
||||
class SearchQuery extends _$SearchQuery {
|
||||
@override
|
||||
@@ -389,16 +99,5 @@ class SearchQuery extends _$SearchQuery {
|
||||
|
||||
void setQuery(String query) {
|
||||
state = query;
|
||||
// Trigger search in products provider
|
||||
if (query.isNotEmpty) {
|
||||
ref.read(productsProvider.notifier).search(query);
|
||||
} else {
|
||||
ref.read(productsProvider.notifier).refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
state = '';
|
||||
ref.read(productsProvider.notifier).refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,15 +8,15 @@ part of 'products_provider.dart';
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Provider for products list with pagination and filtering
|
||||
/// Provider for products list with API-first approach
|
||||
|
||||
@ProviderFor(Products)
|
||||
const productsProvider = ProductsProvider._();
|
||||
|
||||
/// Provider for products list with pagination and filtering
|
||||
/// Provider for products list with API-first approach
|
||||
final class ProductsProvider
|
||||
extends $AsyncNotifierProvider<Products, ProductPaginationState> {
|
||||
/// Provider for products list with pagination and filtering
|
||||
extends $AsyncNotifierProvider<Products, List<Product>> {
|
||||
/// Provider for products list with API-first approach
|
||||
const ProductsProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
@@ -36,27 +36,22 @@ final class ProductsProvider
|
||||
Products create() => Products();
|
||||
}
|
||||
|
||||
String _$productsHash() => r'2f2da8d6d7c1b88a525e4f79c9b29267b7da08ea';
|
||||
String _$productsHash() => r'0ff8c2de46bb4b1e29678cc811ec121c9fb4c8eb';
|
||||
|
||||
/// Provider for products list with pagination and filtering
|
||||
/// Provider for products list with API-first approach
|
||||
|
||||
abstract class _$Products extends $AsyncNotifier<ProductPaginationState> {
|
||||
FutureOr<ProductPaginationState> build();
|
||||
abstract class _$Products extends $AsyncNotifier<List<Product>> {
|
||||
FutureOr<List<Product>> build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref =
|
||||
this.ref
|
||||
as $Ref<AsyncValue<ProductPaginationState>, ProductPaginationState>;
|
||||
final ref = this.ref as $Ref<AsyncValue<List<Product>>, List<Product>>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<
|
||||
AsyncValue<ProductPaginationState>,
|
||||
ProductPaginationState
|
||||
>,
|
||||
AsyncValue<ProductPaginationState>,
|
||||
AnyNotifier<AsyncValue<List<Product>>, List<Product>>,
|
||||
AsyncValue<List<Product>>,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
@@ -64,264 +59,14 @@ abstract class _$Products extends $AsyncNotifier<ProductPaginationState> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider for single product by ID
|
||||
|
||||
@ProviderFor(product)
|
||||
const productProvider = ProductFamily._();
|
||||
|
||||
/// Provider for single product by ID
|
||||
|
||||
final class ProductProvider
|
||||
extends $FunctionalProvider<AsyncValue<Product>, Product, FutureOr<Product>>
|
||||
with $FutureModifier<Product>, $FutureProvider<Product> {
|
||||
/// Provider for single product by ID
|
||||
const ProductProvider._({
|
||||
required ProductFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
retry: null,
|
||||
name: r'productProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$productHash();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return r'productProvider'
|
||||
''
|
||||
'($argument)';
|
||||
}
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<Product> $createElement($ProviderPointer pointer) =>
|
||||
$FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<Product> create(Ref ref) {
|
||||
final argument = this.argument as String;
|
||||
return product(ref, argument);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is ProductProvider && other.argument == argument;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return argument.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
String _$productHash() => r'e9b9a3db5f2aa33a19defe3551b8dca62d1c96b1';
|
||||
|
||||
/// Provider for single product by ID
|
||||
|
||||
final class ProductFamily extends $Family
|
||||
with $FunctionalFamilyOverride<FutureOr<Product>, String> {
|
||||
const ProductFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'productProvider',
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
isAutoDispose: true,
|
||||
);
|
||||
|
||||
/// Provider for single product by ID
|
||||
|
||||
ProductProvider call(String id) =>
|
||||
ProductProvider._(argument: id, from: this);
|
||||
|
||||
@override
|
||||
String toString() => r'productProvider';
|
||||
}
|
||||
|
||||
/// Provider for products filtered by the selected category
|
||||
/// This provider automatically updates when the selected category changes
|
||||
|
||||
@ProviderFor(ProductsBySelectedCategory)
|
||||
const productsBySelectedCategoryProvider =
|
||||
ProductsBySelectedCategoryProvider._();
|
||||
|
||||
/// Provider for products filtered by the selected category
|
||||
/// This provider automatically updates when the selected category changes
|
||||
final class ProductsBySelectedCategoryProvider
|
||||
extends
|
||||
$AsyncNotifierProvider<
|
||||
ProductsBySelectedCategory,
|
||||
ProductPaginationState
|
||||
> {
|
||||
/// Provider for products filtered by the selected category
|
||||
/// This provider automatically updates when the selected category changes
|
||||
const ProductsBySelectedCategoryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'productsBySelectedCategoryProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$productsBySelectedCategoryHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
ProductsBySelectedCategory create() => ProductsBySelectedCategory();
|
||||
}
|
||||
|
||||
String _$productsBySelectedCategoryHash() =>
|
||||
r'642bbfab846469933bd4af89fb2ac7da77895562';
|
||||
|
||||
/// Provider for products filtered by the selected category
|
||||
/// This provider automatically updates when the selected category changes
|
||||
|
||||
abstract class _$ProductsBySelectedCategory
|
||||
extends $AsyncNotifier<ProductPaginationState> {
|
||||
FutureOr<ProductPaginationState> build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref =
|
||||
this.ref
|
||||
as $Ref<AsyncValue<ProductPaginationState>, ProductPaginationState>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<
|
||||
AsyncValue<ProductPaginationState>,
|
||||
ProductPaginationState
|
||||
>,
|
||||
AsyncValue<ProductPaginationState>,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider for searching products with pagination
|
||||
|
||||
@ProviderFor(ProductSearch)
|
||||
const productSearchProvider = ProductSearchFamily._();
|
||||
|
||||
/// Provider for searching products with pagination
|
||||
final class ProductSearchProvider
|
||||
extends $AsyncNotifierProvider<ProductSearch, ProductPaginationState> {
|
||||
/// Provider for searching products with pagination
|
||||
const ProductSearchProvider._({
|
||||
required ProductSearchFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
retry: null,
|
||||
name: r'productSearchProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$productSearchHash();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return r'productSearchProvider'
|
||||
''
|
||||
'($argument)';
|
||||
}
|
||||
|
||||
@$internal
|
||||
@override
|
||||
ProductSearch create() => ProductSearch();
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is ProductSearchProvider && other.argument == argument;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return argument.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
String _$productSearchHash() => r'86946a7cf6722822ed205af5d4ec2a8f5ba5ca48';
|
||||
|
||||
/// Provider for searching products with pagination
|
||||
|
||||
final class ProductSearchFamily extends $Family
|
||||
with
|
||||
$ClassFamilyOverride<
|
||||
ProductSearch,
|
||||
AsyncValue<ProductPaginationState>,
|
||||
ProductPaginationState,
|
||||
FutureOr<ProductPaginationState>,
|
||||
String
|
||||
> {
|
||||
const ProductSearchFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'productSearchProvider',
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
isAutoDispose: true,
|
||||
);
|
||||
|
||||
/// Provider for searching products with pagination
|
||||
|
||||
ProductSearchProvider call(String query) =>
|
||||
ProductSearchProvider._(argument: query, from: this);
|
||||
|
||||
@override
|
||||
String toString() => r'productSearchProvider';
|
||||
}
|
||||
|
||||
/// Provider for searching products with pagination
|
||||
|
||||
abstract class _$ProductSearch extends $AsyncNotifier<ProductPaginationState> {
|
||||
late final _$args = ref.$arg as String;
|
||||
String get query => _$args;
|
||||
|
||||
FutureOr<ProductPaginationState> build(String query);
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(_$args);
|
||||
final ref =
|
||||
this.ref
|
||||
as $Ref<AsyncValue<ProductPaginationState>, ProductPaginationState>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<
|
||||
AsyncValue<ProductPaginationState>,
|
||||
ProductPaginationState
|
||||
>,
|
||||
AsyncValue<ProductPaginationState>,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
|
||||
/// Search query provider for products
|
||||
/// Provider for search query
|
||||
|
||||
@ProviderFor(SearchQuery)
|
||||
const searchQueryProvider = SearchQueryProvider._();
|
||||
|
||||
/// Search query provider for products
|
||||
/// Provider for search query
|
||||
final class SearchQueryProvider extends $NotifierProvider<SearchQuery, String> {
|
||||
/// Search query provider for products
|
||||
/// Provider for search query
|
||||
const SearchQueryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
@@ -349,9 +94,9 @@ final class SearchQueryProvider extends $NotifierProvider<SearchQuery, String> {
|
||||
}
|
||||
}
|
||||
|
||||
String _$searchQueryHash() => r'0c08fe7fe2ce47cf806a34872f5cf4912fe8c618';
|
||||
String _$searchQueryHash() => r'2c146927785523a0ddf51b23b777a9be4afdc092';
|
||||
|
||||
/// Search query provider for products
|
||||
/// Provider for search query
|
||||
|
||||
abstract class _$SearchQuery extends $Notifier<String> {
|
||||
String build();
|
||||
|
||||
Reference in New Issue
Block a user