mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
Refactor AddDeviceTypeWidget and ProductTypeCard Components:
- Replaced ProductTypeCard with ProductsGrid in AddDeviceTypeWidget for improved layout and maintainability. - Converted ProductTypeCardCounter from StatefulWidget to StatelessWidget, simplifying its implementation. - Updated ProductTypeCard to accept count and increment/decrement callbacks, enhancing its reusability and interaction. - Introduced ProductsGrid to manage product display in a grid format, improving UI organization and responsiveness.
This commit is contained in:
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/space_management_v2/modules/products/data/services/remote_products_service.dart';
|
import 'package:syncrow_web/pages/space_management_v2/modules/products/data/services/remote_products_service.dart';
|
||||||
import 'package:syncrow_web/pages/space_management_v2/modules/products/presentation/bloc/products_bloc.dart';
|
import 'package:syncrow_web/pages/space_management_v2/modules/products/presentation/bloc/products_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/space_management_v2/modules/tags/presentation/widgets/product_type_card.dart';
|
import 'package:syncrow_web/pages/space_management_v2/modules/tags/presentation/widgets/products_grid.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
@ -12,13 +12,6 @@ class AddDeviceTypeWidget extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final size = MediaQuery.of(context).size;
|
|
||||||
final crossAxisCount = switch (context.screenWidth) {
|
|
||||||
> 1200 => 8,
|
|
||||||
> 800 => 5,
|
|
||||||
_ => 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (_) => ProductsBloc(RemoteProductsService(HTTPService()))
|
create: (_) => ProductsBloc(RemoteProductsService(HTTPService()))
|
||||||
..add(const LoadProducts()),
|
..add(const LoadProducts()),
|
||||||
@ -27,57 +20,24 @@ class AddDeviceTypeWidget extends StatelessWidget {
|
|||||||
title: const Text('Add Devices'),
|
title: const Text('Add Devices'),
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.whiteColors,
|
||||||
content: BlocBuilder<ProductsBloc, ProductsState>(
|
content: BlocBuilder<ProductsBloc, ProductsState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) => switch (state) {
|
||||||
return switch (state) {
|
ProductsInitial() => const Center(
|
||||||
ProductsInitial() => const Center(
|
child: CircularProgressIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
),
|
||||||
),
|
ProductsLoading() => const Center(
|
||||||
ProductsLoading() => const Center(
|
child: CircularProgressIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
),
|
||||||
),
|
ProductsLoaded(:final products) => ProductsGrid(
|
||||||
ProductsLoaded(:final products) => SingleChildScrollView(
|
products: products,
|
||||||
child: Container(
|
),
|
||||||
width: size.width * 0.9,
|
ProductsFailure(:final errorMessage) => Center(
|
||||||
height: size.height * 0.65,
|
child: Text(
|
||||||
decoration: BoxDecoration(
|
errorMessage,
|
||||||
color: ColorsManager.textFieldGreyColor,
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
borderRadius: BorderRadius.circular(8),
|
color: context.theme.colorScheme.error,
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Expanded(
|
|
||||||
child: GridView.builder(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 20,
|
|
||||||
),
|
|
||||||
shrinkWrap: true,
|
|
||||||
gridDelegate:
|
|
||||||
SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: crossAxisCount,
|
|
||||||
mainAxisSpacing: 6,
|
|
||||||
crossAxisSpacing: 4,
|
|
||||||
childAspectRatio: 0.8,
|
|
||||||
),
|
|
||||||
itemCount: products.length,
|
|
||||||
itemBuilder: (context, index) => ProductTypeCard(
|
|
||||||
product: products[index],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ProductsFailure(:final errorMessage) => Center(
|
),
|
||||||
child: Text(
|
|
||||||
errorMessage,
|
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
|
||||||
color: context.theme.colorScheme.error,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/pages/space_management_v2/modules/products/domain/models/product.dart';
|
import 'package:syncrow_web/pages/space_management_v2/modules/products/domain/models/product.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/counter_widget.dart';
|
import 'package:syncrow_web/pages/space_management_v2/modules/tags/presentation/widgets/product_type_card_counter.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/device_icon_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/device_icon_widget.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
@ -8,9 +8,16 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|||||||
class ProductTypeCard extends StatelessWidget {
|
class ProductTypeCard extends StatelessWidget {
|
||||||
const ProductTypeCard({
|
const ProductTypeCard({
|
||||||
required this.product,
|
required this.product,
|
||||||
|
required this.count,
|
||||||
|
required this.onIncrement,
|
||||||
|
required this.onDecrement,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Product product;
|
final Product product;
|
||||||
|
final int count;
|
||||||
|
final void Function() onIncrement;
|
||||||
|
final void Function() onDecrement;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -27,16 +34,12 @@ class ProductTypeCard extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(child: DeviceIconWidget(icon: product.icon)),
|
||||||
child: DeviceIconWidget(
|
|
||||||
icon: product.icon,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
_buildName(context, product.name),
|
_buildName(context, product.name),
|
||||||
CounterWidget(
|
ProductTypeCardCounter(
|
||||||
isCreate: false,
|
onIncrement: onIncrement,
|
||||||
initialCount: 0,
|
onDecrement: onDecrement,
|
||||||
onCountChanged: (newCount) {},
|
count: count,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
class ProductTypeCardCounter extends StatefulWidget {
|
class ProductTypeCardCounter extends StatelessWidget {
|
||||||
const ProductTypeCardCounter({
|
const ProductTypeCardCounter({
|
||||||
super.key,
|
super.key,
|
||||||
required this.onIncrement,
|
required this.onIncrement,
|
||||||
@ -10,19 +11,11 @@ class ProductTypeCardCounter extends StatefulWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final int count;
|
final int count;
|
||||||
|
|
||||||
final void Function() onIncrement;
|
final void Function() onIncrement;
|
||||||
final void Function() onDecrement;
|
final void Function() onDecrement;
|
||||||
|
|
||||||
@override
|
|
||||||
State<ProductTypeCardCounter> createState() => _ProductTypeCardCounterState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ProductTypeCardCounterState extends State<ProductTypeCardCounter> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -35,15 +28,15 @@ class _ProductTypeCardCounterState extends State<ProductTypeCardCounter> {
|
|||||||
children: [
|
children: [
|
||||||
_buildCounterButton(
|
_buildCounterButton(
|
||||||
Icons.remove,
|
Icons.remove,
|
||||||
widget.onDecrement,
|
onDecrement,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
widget.count.toString(),
|
count.toString(),
|
||||||
style: theme.textTheme.bodyLarge?.copyWith(
|
style: context.textTheme.bodyLarge?.copyWith(
|
||||||
color: ColorsManager.spaceColor,
|
color: ColorsManager.spaceColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_buildCounterButton(Icons.add, widget.onIncrement),
|
_buildCounterButton(Icons.add, onIncrement),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_management_v2/modules/products/domain/models/product.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_management_v2/modules/tags/presentation/widgets/product_type_card.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
|
class ProductsGrid extends StatelessWidget {
|
||||||
|
const ProductsGrid({required this.products, super.key});
|
||||||
|
|
||||||
|
final List<Product> products;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final size = MediaQuery.of(context).size;
|
||||||
|
final crossAxisCount = switch (context.screenWidth) {
|
||||||
|
> 1200 => 8,
|
||||||
|
> 800 => 5,
|
||||||
|
_ => 3,
|
||||||
|
};
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Container(
|
||||||
|
width: size.width * 0.9,
|
||||||
|
height: size.height * 0.65,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.textFieldGreyColor,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Expanded(
|
||||||
|
child: GridView.builder(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 20,
|
||||||
|
),
|
||||||
|
shrinkWrap: true,
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: crossAxisCount,
|
||||||
|
mainAxisSpacing: 6,
|
||||||
|
crossAxisSpacing: 4,
|
||||||
|
childAspectRatio: 0.8,
|
||||||
|
),
|
||||||
|
itemCount: products.length,
|
||||||
|
itemBuilder: (context, index) => ProductTypeCard(
|
||||||
|
product: products[index],
|
||||||
|
count: 0,
|
||||||
|
onIncrement: () {},
|
||||||
|
onDecrement: () {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user