fix force close
This commit is contained in:
parent
455a6afd70
commit
613b216c04
@ -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(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user