This commit is contained in:
Phuoc Nguyen
2025-10-10 16:38:07 +07:00
parent e5b247d622
commit b94c158004
177 changed files with 25080 additions and 152 deletions

View File

@@ -0,0 +1,46 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../../domain/entities/category.dart';
part 'categories_provider.g.dart';
/// Provider for categories list
@riverpod
class Categories extends _$Categories {
@override
Future<List<Category>> build() async {
// TODO: Implement with repository
return [];
}
Future<void> refresh() async {
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
// Fetch categories from repository
return [];
});
}
Future<void> syncCategories() async {
// TODO: Implement sync logic with remote data source
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
// Sync categories from API
return [];
});
}
}
/// Provider for selected category
@riverpod
class SelectedCategory extends _$SelectedCategory {
@override
String? build() => null;
void select(String? categoryId) {
state = categoryId;
}
void clear() {
state = null;
}
}

View File

@@ -0,0 +1,119 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'categories_provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
/// Provider for categories list
@ProviderFor(Categories)
const categoriesProvider = CategoriesProvider._();
/// Provider for categories list
final class CategoriesProvider
extends $AsyncNotifierProvider<Categories, List<Category>> {
/// Provider for categories list
const CategoriesProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'categoriesProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$categoriesHash();
@$internal
@override
Categories create() => Categories();
}
String _$categoriesHash() => r'aa7afc38a5567b0f42ff05ca23b287baa4780cbe';
/// Provider for categories list
abstract class _$Categories extends $AsyncNotifier<List<Category>> {
FutureOr<List<Category>> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<AsyncValue<List<Category>>, List<Category>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AsyncValue<List<Category>>, List<Category>>,
AsyncValue<List<Category>>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
/// Provider for selected category
@ProviderFor(SelectedCategory)
const selectedCategoryProvider = SelectedCategoryProvider._();
/// Provider for selected category
final class SelectedCategoryProvider
extends $NotifierProvider<SelectedCategory, String?> {
/// Provider for selected category
const SelectedCategoryProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'selectedCategoryProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$selectedCategoryHash();
@$internal
@override
SelectedCategory create() => SelectedCategory();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(String? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<String?>(value),
);
}
}
String _$selectedCategoryHash() => r'a47cd2de07ad285d4b73b2294ba954cb1cdd8e4c';
/// Provider for selected category
abstract class _$SelectedCategory 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);
}
}

View File

@@ -0,0 +1,14 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../../data/datasources/category_local_datasource.dart';
import '../../../../core/database/hive_database.dart';
import '../../data/models/category_model.dart';
part 'category_datasource_provider.g.dart';
/// Provider for category local data source
/// This is kept alive as it's a dependency injection provider
@Riverpod(keepAlive: true)
CategoryLocalDataSource categoryLocalDataSource(Ref ref) {
final box = HiveDatabase.instance.getBox<CategoryModel>('categories');
return CategoryLocalDataSourceImpl(box);
}

View File

@@ -0,0 +1,65 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'category_datasource_provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
/// Provider for category local data source
/// This is kept alive as it's a dependency injection provider
@ProviderFor(categoryLocalDataSource)
const categoryLocalDataSourceProvider = CategoryLocalDataSourceProvider._();
/// Provider for category local data source
/// This is kept alive as it's a dependency injection provider
final class CategoryLocalDataSourceProvider
extends
$FunctionalProvider<
CategoryLocalDataSource,
CategoryLocalDataSource,
CategoryLocalDataSource
>
with $Provider<CategoryLocalDataSource> {
/// Provider for category local data source
/// This is kept alive as it's a dependency injection provider
const CategoryLocalDataSourceProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'categoryLocalDataSourceProvider',
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$categoryLocalDataSourceHash();
@$internal
@override
$ProviderElement<CategoryLocalDataSource> $createElement(
$ProviderPointer pointer,
) => $ProviderElement(pointer);
@override
CategoryLocalDataSource create(Ref ref) {
return categoryLocalDataSource(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(CategoryLocalDataSource value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<CategoryLocalDataSource>(value),
);
}
}
String _$categoryLocalDataSourceHash() =>
r'1f8412f2dc76a348873f1da4f76ae4a08991f269';

View File

@@ -0,0 +1,35 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../../../products/presentation/providers/products_provider.dart';
part 'category_product_count_provider.g.dart';
/// Provider that calculates product count for a specific category
/// Uses family pattern to create a provider for each category ID
@riverpod
int categoryProductCount(Ref ref, String categoryId) {
final productsAsync = ref.watch(productsProvider);
return productsAsync.when(
data: (products) => products.where((p) => p.categoryId == categoryId).length,
loading: () => 0,
error: (_, __) => 0,
);
}
/// Provider that returns all category product counts as a map
/// Useful for displaying product counts on all category cards at once
@riverpod
Map<String, int> allCategoryProductCounts(Ref ref) {
final productsAsync = ref.watch(productsProvider);
return productsAsync.when(
data: (products) {
// Group products by category and count
final counts = <String, int>{};
for (final product in products) {
counts[product.categoryId] = (counts[product.categoryId] ?? 0) + 1;
}
return counts;
},
loading: () => {},
error: (_, __) => {},
);
}

View File

@@ -0,0 +1,156 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'category_product_count_provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
/// Provider that calculates product count for a specific category
/// Uses family pattern to create a provider for each category ID
@ProviderFor(categoryProductCount)
const categoryProductCountProvider = CategoryProductCountFamily._();
/// Provider that calculates product count for a specific category
/// Uses family pattern to create a provider for each category ID
final class CategoryProductCountProvider
extends $FunctionalProvider<int, int, int>
with $Provider<int> {
/// Provider that calculates product count for a specific category
/// Uses family pattern to create a provider for each category ID
const CategoryProductCountProvider._({
required CategoryProductCountFamily super.from,
required String super.argument,
}) : super(
retry: null,
name: r'categoryProductCountProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$categoryProductCountHash();
@override
String toString() {
return r'categoryProductCountProvider'
''
'($argument)';
}
@$internal
@override
$ProviderElement<int> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
int create(Ref ref) {
final argument = this.argument as String;
return categoryProductCount(ref, argument);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(int value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<int>(value),
);
}
@override
bool operator ==(Object other) {
return other is CategoryProductCountProvider && other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$categoryProductCountHash() =>
r'2d51eea21a4d018964d10ee00d0957a2c38d28c6';
/// Provider that calculates product count for a specific category
/// Uses family pattern to create a provider for each category ID
final class CategoryProductCountFamily extends $Family
with $FunctionalFamilyOverride<int, String> {
const CategoryProductCountFamily._()
: super(
retry: null,
name: r'categoryProductCountProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
/// Provider that calculates product count for a specific category
/// Uses family pattern to create a provider for each category ID
CategoryProductCountProvider call(String categoryId) =>
CategoryProductCountProvider._(argument: categoryId, from: this);
@override
String toString() => r'categoryProductCountProvider';
}
/// Provider that returns all category product counts as a map
/// Useful for displaying product counts on all category cards at once
@ProviderFor(allCategoryProductCounts)
const allCategoryProductCountsProvider = AllCategoryProductCountsProvider._();
/// Provider that returns all category product counts as a map
/// Useful for displaying product counts on all category cards at once
final class AllCategoryProductCountsProvider
extends
$FunctionalProvider<
Map<String, int>,
Map<String, int>,
Map<String, int>
>
with $Provider<Map<String, int>> {
/// Provider that returns all category product counts as a map
/// Useful for displaying product counts on all category cards at once
const AllCategoryProductCountsProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'allCategoryProductCountsProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$allCategoryProductCountsHash();
@$internal
@override
$ProviderElement<Map<String, int>> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
Map<String, int> create(Ref ref) {
return allCategoryProductCounts(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(Map<String, int> value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<Map<String, int>>(value),
);
}
}
String _$allCategoryProductCountsHash() =>
r'a4ecc281916772ac74327333bd76e7b6463a0992';

View File

@@ -0,0 +1,4 @@
/// Export all category providers
export 'category_datasource_provider.dart';
export 'categories_provider.dart';
export 'category_product_count_provider.dart';