2025-08-05 20:00:58 +07:00

142 lines
5.6 KiB
Dart

import 'package:enaklo_pos/core/components/buttons.dart';
import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/data/datasources/product_remote_datasource.dart';
import 'package:enaklo_pos/presentation/setting/bloc/get_products/get_products_bloc.dart';
import 'package:enaklo_pos/presentation/setting/bloc/update_product/update_product_bloc.dart';
import 'package:enaklo_pos/presentation/setting/bloc/sync_product/sync_product_bloc.dart';
import 'package:enaklo_pos/presentation/setting/bloc/add_product/add_product_bloc.dart';
import 'package:enaklo_pos/presentation/setting/dialogs/form_product_dialog.dart';
import 'package:enaklo_pos/presentation/setting/widgets/menu_product_item.dart';
import 'package:enaklo_pos/presentation/setting/widgets/settings_title.dart';
class ProductPage extends StatefulWidget {
const ProductPage({super.key});
@override
State<ProductPage> createState() => _ProductPageState();
}
class _ProductPageState extends State<ProductPage> {
ScrollController scrollController = ScrollController();
@override
void initState() {
context.read<GetProductsBloc>().add(const GetProductsEvent.fetch());
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.background,
body: Column(
children: [
SettingsTitle(
'Kelola Produk',
subtitle: 'Kelola produk anda',
actionWidget: [
Button.outlined(
onPressed: () {
showDialog(
context: context,
builder: (context) => MultiBlocProvider(
providers: [
BlocProvider(
create: (context) =>
AddProductBloc(ProductRemoteDatasource()),
),
BlocProvider.value(
value: context.read<SyncProductBloc>(),
),
BlocProvider.value(
value: context.read<GetProductsBloc>(),
),
],
child: const FormProductDialog(),
),
);
},
label: "Tambah Produk",
icon: Icon(Icons.add, color: AppColors.primary),
)
],
),
Expanded(
child: BlocBuilder<GetProductsBloc, GetProductsState>(
builder: (context, state) {
return NotificationListener<ScrollNotification>(
onNotification: (notification) {
return state.maybeWhen(
orElse: () => false,
success: (products, hasReachedMax, currentPage, _) {
if (notification is ScrollEndNotification &&
scrollController.position.extentAfter == 0) {
context
.read<GetProductsBloc>()
.add(const GetProductsEvent.loadMore());
return true;
}
return true;
});
},
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, success: (products, hasReachedMax, currentPage, _) {
return GridView.builder(
padding: EdgeInsets.all(16),
controller: scrollController,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
mainAxisSpacing: 30,
crossAxisSpacing: 30,
childAspectRatio: 0.85,
),
itemCount: products.length,
itemBuilder: (BuildContext context, int index) {
final item = products[index];
return MenuProductItem(
data: item,
onTapEdit: () {
showDialog(
context: context,
builder: (context) => MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => UpdateProductBloc(
ProductRemoteDatasource()),
),
BlocProvider.value(
value: context.read<SyncProductBloc>(),
),
BlocProvider.value(
value: context.read<GetProductsBloc>(),
),
],
child: FormProductDialog(product: item),
),
);
},
);
},
);
}),
);
},
),
),
],
),
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// },
// child: const Icon(Icons.add),
// ),
);
}
}