fix force close

This commit is contained in:
efrilm 2025-10-07 21:49:15 +07:00
parent 455a6afd70
commit 613b216c04
5 changed files with 76 additions and 58 deletions

View File

@ -117,4 +117,14 @@ class CategoryModel {
'updated_at': updatedAt.toIso8601String(), 'updated_at': updatedAt.toIso8601String(),
}; };
} }
factory CategoryModel.all() => CategoryModel(
id: 'all',
organizationId: '',
name: 'Semua',
businessType: 'restaurant',
metadata: {},
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
);
} }

View File

@ -65,6 +65,8 @@ class CategoryLoaderBloc
log('✅ Categories loaded: ${categories.length}, hasReachedMax: $hasReachedMax'); log('✅ Categories loaded: ${categories.length}, hasReachedMax: $hasReachedMax');
categories.insert(0, CategoryModel.all());
emit(CategoryLoaderState.loaded( emit(CategoryLoaderState.loaded(
categories: categories, categories: categories,
hasReachedMax: hasReachedMax, hasReachedMax: hasReachedMax,

View File

@ -49,48 +49,45 @@ class _CategoryTabBarState extends State<CategoryTabBar>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DefaultTabController( return Column(
length: widget.categories.length, crossAxisAlignment: CrossAxisAlignment.start,
child: Column( children: [
crossAxisAlignment: CrossAxisAlignment.start, Material(
children: [ elevation: 0,
Material( color: Colors.white,
elevation: 0, borderOnForeground: false,
color: Colors.white, child: Padding(
borderOnForeground: false, padding: const EdgeInsets.symmetric(vertical: 16),
child: Padding( child: TabBar(
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(
controller: _tabController, 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,
),
),
],
); );
} }
} }

View File

@ -1,6 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart'; import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/presentation/home/dialog/variant_dialog.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/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/constants/variables.dart'; import 'package:enaklo_pos/core/constants/variables.dart';
@ -54,26 +55,34 @@ class ProductCard extends StatelessWidget {
ClipRRect( ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(8.0)), borderRadius: BorderRadius.all(Radius.circular(8.0)),
child: CachedNetworkImage( child: CachedNetworkImage(
imageUrl: (data.imageUrl ?? "").contains('http') imageUrl: (data.imageUrl ?? "").contains('http')
? data.imageUrl! ? data.imageUrl!
: '${Variables.baseUrl}/${data.imageUrl}', : '${Variables.baseUrl}/${data.imageUrl}',
fit: BoxFit.cover, fit: BoxFit.cover,
width: double.infinity,
height: 120,
memCacheHeight: 120,
memCacheWidth: 120,
errorWidget: (context, url, error) => Container(
width: double.infinity, width: double.infinity,
height: 120, height: 120,
decoration: BoxDecoration( memCacheHeight: 120,
color: AppColors.disabled.withOpacity(0.4), memCacheWidth: 120,
), errorWidget: (context, url, error) {
child: const Icon( FirebaseCrashlytics.instance.recordError(
Icons.image, error,
color: AppColors.grey, 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(), const Spacer(),
Text( Text(

View File

@ -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 # 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 # 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. # 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: environment:
sdk: ">=3.2.4 <4.0.0" sdk: ">=3.2.4 <4.0.0"