diff --git a/lib/data/models/response/category_response_model.dart b/lib/data/models/response/category_response_model.dart index 7755386..7db2115 100644 --- a/lib/data/models/response/category_response_model.dart +++ b/lib/data/models/response/category_response_model.dart @@ -117,4 +117,14 @@ class CategoryModel { 'updated_at': updatedAt.toIso8601String(), }; } + + factory CategoryModel.all() => CategoryModel( + id: 'all', + organizationId: '', + name: 'Semua', + businessType: 'restaurant', + metadata: {}, + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + ); } diff --git a/lib/presentation/home/bloc/category_loader/category_loader_bloc.dart b/lib/presentation/home/bloc/category_loader/category_loader_bloc.dart index ce56006..98b37d2 100644 --- a/lib/presentation/home/bloc/category_loader/category_loader_bloc.dart +++ b/lib/presentation/home/bloc/category_loader/category_loader_bloc.dart @@ -65,6 +65,8 @@ class CategoryLoaderBloc log('✅ Categories loaded: ${categories.length}, hasReachedMax: $hasReachedMax'); + categories.insert(0, CategoryModel.all()); + emit(CategoryLoaderState.loaded( categories: categories, hasReachedMax: hasReachedMax, diff --git a/lib/presentation/home/widgets/category_tab_bar.dart b/lib/presentation/home/widgets/category_tab_bar.dart index ea4fd25..8dbbd6f 100644 --- a/lib/presentation/home/widgets/category_tab_bar.dart +++ b/lib/presentation/home/widgets/category_tab_bar.dart @@ -49,48 +49,45 @@ class _CategoryTabBarState extends State @override Widget build(BuildContext context) { - return DefaultTabController( - length: widget.categories.length, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Material( - elevation: 0, - color: Colors.white, - borderOnForeground: false, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 16), - child: TabBar( - controller: _tabController, - isScrollable: true, - tabAlignment: TabAlignment.start, - labelColor: AppColors.primary, - labelStyle: TextStyle( - fontWeight: FontWeight.bold, - ), - dividerColor: AppColors.primary, - unselectedLabelColor: AppColors.primary, - indicatorSize: TabBarIndicatorSize.label, - indicatorWeight: 4, - indicatorColor: AppColors.primary, - tabs: widget.categories - .map((category) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Tab(text: category.name), - )) - .toList(), - ), - ), - ), - Expanded( - // ✅ ini bagian penting - child: TabBarView( + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Material( + elevation: 0, + color: Colors.white, + borderOnForeground: false, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: TabBar( controller: _tabController, - children: widget.tabViews, + isScrollable: true, + tabAlignment: TabAlignment.start, + labelColor: AppColors.primary, + labelStyle: TextStyle( + fontWeight: FontWeight.bold, + ), + dividerColor: AppColors.primary, + unselectedLabelColor: AppColors.primary, + indicatorSize: TabBarIndicatorSize.label, + indicatorWeight: 4, + indicatorColor: AppColors.primary, + tabs: widget.categories + .map((category) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Tab(text: category.name), + )) + .toList(), ), ), - ], - ), + ), + Expanded( + // ✅ ini bagian penting + child: TabBarView( + controller: _tabController, + children: widget.tabViews, + ), + ), + ], ); } } diff --git a/lib/presentation/home/widgets/product_card.dart b/lib/presentation/home/widgets/product_card.dart index 01e31b0..399c2ab 100644 --- a/lib/presentation/home/widgets/product_card.dart +++ b/lib/presentation/home/widgets/product_card.dart @@ -1,6 +1,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:enaklo_pos/core/extensions/int_ext.dart'; import 'package:enaklo_pos/presentation/home/dialog/variant_dialog.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:enaklo_pos/core/constants/variables.dart'; @@ -54,26 +55,34 @@ class ProductCard extends StatelessWidget { ClipRRect( borderRadius: BorderRadius.all(Radius.circular(8.0)), child: CachedNetworkImage( - imageUrl: (data.imageUrl ?? "").contains('http') - ? data.imageUrl! - : '${Variables.baseUrl}/${data.imageUrl}', - fit: BoxFit.cover, - width: double.infinity, - height: 120, - memCacheHeight: 120, - memCacheWidth: 120, - errorWidget: (context, url, error) => Container( + imageUrl: (data.imageUrl ?? "").contains('http') + ? data.imageUrl! + : '${Variables.baseUrl}/${data.imageUrl}', + fit: BoxFit.cover, width: double.infinity, height: 120, - decoration: BoxDecoration( - color: AppColors.disabled.withOpacity(0.4), - ), - child: const Icon( - Icons.image, - color: AppColors.grey, - ), - ), - ), + memCacheHeight: 120, + memCacheWidth: 120, + errorWidget: (context, url, error) { + FirebaseCrashlytics.instance.recordError( + error, + StackTrace.current, + reason: + 'Failed to load image from: $url, productId: ${data.id}, productName: ${data.name}', + fatal: false, + ); + return Container( + width: double.infinity, + height: 120, + decoration: BoxDecoration( + color: AppColors.disabled.withOpacity(0.4), + ), + child: const Icon( + Icons.image, + color: AppColors.grey, + ), + ); + }), ), const Spacer(), Text( diff --git a/pubspec.yaml b/pubspec.yaml index ce3a0dc..6879e02 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.1+4 +version: 1.0.2+4 environment: sdk: ">=3.2.4 <4.0.0"