diff --git a/lib/pages/spaces_management/space_model/bloc/add_device_model_bloc.dart b/lib/pages/spaces_management/space_model/bloc/add_device_model_bloc.dart new file mode 100644 index 00000000..31c99dc4 --- /dev/null +++ b/lib/pages/spaces_management/space_model/bloc/add_device_model_bloc.dart @@ -0,0 +1,30 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; + +class AddDeviceTypeModelBloc extends Cubit> { + AddDeviceTypeModelBloc(List initialProducts) + : super(initialProducts); + + void updateProductCount(String productId, int count) { + final existingProduct = state.firstWhere( + (p) => p.productId == productId, + orElse: () => SelectedProduct(productId: productId, count: 0), + ); + + if (count > 0) { + if (!state.contains(existingProduct)) { + emit([...state, SelectedProduct(productId: productId, count: count)]); + } else { + final updatedList = state.map((p) { + if (p.productId == productId) { + return SelectedProduct(productId: p.productId, count: count); + } + return p; + }).toList(); + emit(updatedList); + } + } else { + emit(state.where((p) => p.productId != productId).toList()); + } + } +} diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/add_device_type_model_widget.dart b/lib/pages/spaces_management/space_model/widgets/dialog/add_device_type_model_widget.dart index 85285502..06ec6bf4 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/add_device_type_model_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/add_device_type_model_widget.dart @@ -1,14 +1,15 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/counter_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/bloc/add_device_model_bloc.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; -import 'package:syncrow_web/utils/extension/build_context_x.dart'; -class AddDeviceTypeModelWidget extends StatefulWidget { +class AddDeviceTypeModelWidget extends StatelessWidget { final List? products; final ValueChanged>? onProductsSelected; final List? initialSelectedProducts; @@ -20,101 +21,93 @@ class AddDeviceTypeModelWidget extends StatefulWidget { this.onProductsSelected, }); - @override - _AddDeviceWidgetState createState() => _AddDeviceWidgetState(); -} - -class _AddDeviceWidgetState extends State { - late final ScrollController _scrollController; - late List productCounts; - - @override - void initState() { - super.initState(); - _scrollController = ScrollController(); - productCounts = widget.initialSelectedProducts != null - ? List.from(widget.initialSelectedProducts!) - : []; - } - - @override - void dispose() { - _scrollController.dispose(); - super.dispose(); - } - @override Widget build(BuildContext context) { final size = MediaQuery.of(context).size; - - // Adjust the GridView properties based on screen width final crossAxisCount = size.width > 1200 ? 8 : size.width > 800 ? 5 : 3; - return AlertDialog( - title: const Text('Add Devices'), - backgroundColor: ColorsManager.whiteColors, - content: SingleChildScrollView( - child: Container( - width: size.width * 0.9, - height: size.height * 0.65, - color: ColorsManager.textFieldGreyColor, - child: Column( - children: [ - const SizedBox(height: 16), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Scrollbar( - controller: _scrollController, - thumbVisibility: false, - child: GridView.builder( - shrinkWrap: true, - controller: _scrollController, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: crossAxisCount, - mainAxisSpacing: 6, - crossAxisSpacing: 4, - childAspectRatio: .8, + return BlocProvider( + create: (_) => AddDeviceTypeModelBloc( + initialSelectedProducts ?? []), // Initialize with initial products + child: AlertDialog( + title: const Text('Add Devices'), + backgroundColor: ColorsManager.whiteColors, + content: SingleChildScrollView( + child: Container( + width: size.width * 0.9, + height: size.height * 0.65, + color: ColorsManager.textFieldGreyColor, + child: Column( + children: [ + const SizedBox(height: 16), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Scrollbar( + thumbVisibility: false, + child: BlocBuilder>( + builder: (context, productCounts) { + return GridView.builder( + shrinkWrap: true, + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: crossAxisCount, + mainAxisSpacing: 6, + crossAxisSpacing: 4, + childAspectRatio: .8, + ), + itemCount: products?.length ?? 0, + itemBuilder: (context, index) { + final product = products![index]; + return _buildDeviceTypeTile( + context, product, size, productCounts); + }, + ); + }, ), - itemCount: widget.products?.length ?? 0, - itemBuilder: (context, index) { - final product = widget.products![index]; - return _buildDeviceTypeTile(product, size); - }, ), ), ), + ], + ), + ), + ), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildActionButton( + 'Cancel', + ColorsManager.boxColor, + ColorsManager.blackColor, + () => Navigator.of(context).pop(), + ), + _buildActionButton( + 'Continue', + ColorsManager.secondaryColor, + ColorsManager.whiteColors, + () { + Navigator.of(context).pop(); + if (onProductsSelected != null) { + final selectedProducts = + context.read().state; + onProductsSelected!(selectedProducts); + } + }, ), ], ), - ), + ], ), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _buildActionButton( - 'Cancel', ColorsManager.boxColor, ColorsManager.blackColor, () { - Navigator.of(context).pop(); - }), - _buildActionButton( - 'Continue', ColorsManager.secondaryColor, Colors.white, () { - Navigator.of(context).pop(); - if (widget.onProductsSelected != null) { - widget.onProductsSelected!(productCounts); - } - }), - ], - ), - ], ); } - Widget _buildDeviceTypeTile(ProductModel product, Size size) { + Widget _buildDeviceTypeTile(BuildContext context, ProductModel product, + Size size, List productCounts) { final selectedProduct = productCounts.firstWhere( (p) => p.productId == product.uuid, orElse: () => SelectedProduct(productId: product.uuid, count: 0), @@ -137,28 +130,14 @@ class _AddDeviceWidgetState extends State { children: [ _buildDeviceIcon(product, size), const SizedBox(height: 4), - _buildDeviceName(product, size), + _buildDeviceName(context,product, size), const SizedBox(height: 4), CounterWidget( initialCount: selectedProduct.count, onCountChanged: (newCount) { - setState(() { - if (newCount > 0) { - if (!productCounts.contains(selectedProduct)) { - productCounts.add(SelectedProduct( - productId: product.uuid, count: newCount)); - } else { - selectedProduct.count = newCount; - } - } else { - productCounts - .removeWhere((p) => p.productId == product.uuid); - } - - if (widget.onProductsSelected != null) { - widget.onProductsSelected!(productCounts); - } - }); + context + .read() + .updateProductCount(product.uuid, newCount); }, ), ], @@ -190,12 +169,12 @@ class _AddDeviceWidgetState extends State { ); } - Widget _buildDeviceName(ProductModel product, Size size) { + Widget _buildDeviceName(BuildContext context, product, Size size) { return SizedBox( height: size.width > 800 ? 35 : 25, child: Text( product.name ?? '', - style: context.textTheme.bodySmall + style: Theme.of(context).textTheme.bodySmall ?.copyWith(color: ColorsManager.blackColor), textAlign: TextAlign.center, maxLines: 2,