From 0c555cda83574eceac44b779a09095bd3d7c8ee9 Mon Sep 17 00:00:00 2001 From: ashrafzarkanisala Date: Sun, 24 Nov 2024 23:07:03 +0300 Subject: [PATCH] push tab to run and handling automation --- .../common/text_field/custom_text_field.dart | 16 ++ .../view/device_managment_page.dart | 47 +++--- .../bloc/routine_bloc/routine_bloc.dart | 73 +++++--- .../bloc/routine_bloc/routine_event.dart | 8 + .../bloc/routine_bloc/routine_state.dart | 12 ++ lib/pages/routiens/helper/ac_helper.dart | 3 +- lib/pages/routiens/helper/delay_helper.dart | 2 - lib/pages/routiens/helper/setting_helper.dart | 10 +- lib/pages/routiens/widgets/dragable_card.dart | 156 +++++++++++------- lib/pages/routiens/widgets/if_container.dart | 79 +++++++-- .../widgets/routine_search_and_buttons.dart | 7 +- .../routiens/widgets/then_container.dart | 32 ++-- lib/services/routines_api.dart | 4 + 13 files changed, 295 insertions(+), 154 deletions(-) diff --git a/lib/pages/common/text_field/custom_text_field.dart b/lib/pages/common/text_field/custom_text_field.dart index 250ff110..3ba71cd1 100644 --- a/lib/pages/common/text_field/custom_text_field.dart +++ b/lib/pages/common/text_field/custom_text_field.dart @@ -19,6 +19,7 @@ class StatefulTextField extends StatefulWidget { this.icon, this.hintColor, required this.onChanged, + this.isRequired, }); final String title; @@ -34,6 +35,7 @@ class StatefulTextField extends StatefulWidget { final IconData? icon; final Color? hintColor; final Function(String)? onChanged; + final bool? isRequired; @override State createState() => _StatefulTextFieldState(); @@ -62,6 +64,7 @@ class _StatefulTextFieldState extends State { icon: widget.icon, hintColor: widget.hintColor, onChanged: widget.onChanged, + isRequired: widget.isRequired, ); } } @@ -82,6 +85,7 @@ class CustomTextField extends StatelessWidget { this.icon, this.hintColor, required this.onChanged, + this.isRequired, }); final String title; @@ -97,6 +101,7 @@ class CustomTextField extends StatelessWidget { final IconData? icon; final Color? hintColor; final Function(String)? onChanged; + final bool? isRequired; @override Widget build(BuildContext context) { @@ -123,6 +128,7 @@ class CustomTextField extends StatelessWidget { child: TextFormField( controller: controller, style: const TextStyle(color: Colors.black), + decoration: InputDecoration( hintText: hintText, hintStyle: TextStyle( @@ -140,6 +146,16 @@ class CustomTextField extends StatelessWidget { onChanged: (value) { onChanged!(value); }, + + /// required validator + validator: (value) { + if (isRequired == true) { + if (value == null || value.isEmpty) { + return 'This field is required'; + } + } + return null; + }, ), ), ), diff --git a/lib/pages/device_managment/all_devices/view/device_managment_page.dart b/lib/pages/device_managment/all_devices/view/device_managment_page.dart index ffc57131..4044c056 100644 --- a/lib/pages/device_managment/all_devices/view/device_managment_page.dart +++ b/lib/pages/device_managment/all_devices/view/device_managment_page.dart @@ -88,31 +88,32 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { ); }), rightBody: const NavigateHomeGridView(), - scaffoldBody: BlocBuilder( - builder: (context, state) { - if (state is SelectedTabState && state.selectedTab) { - return const RoutinesView(); - } - if (state is ShowCreateRoutineState && state.showCreateRoutine) { - return const CreateNewRoutineView(); - } + scaffoldBody: CreateNewRoutineView(), + // BlocBuilder( + // builder: (context, state) { + // if (state is SelectedTabState && state.selectedTab) { + // return const RoutinesView(); + // } + // if (state is ShowCreateRoutineState && state.showCreateRoutine) { + // return const CreateNewRoutineView(); + // } - return BlocBuilder( - builder: (context, deviceState) { - if (deviceState is DeviceManagementLoading) { - return const Center(child: CircularProgressIndicator()); - } else if (deviceState is DeviceManagementLoaded || - deviceState is DeviceManagementFiltered) { - final devices = (deviceState as dynamic).devices ?? - (deviceState as DeviceManagementFiltered).filteredDevices; + // return BlocBuilder( + // builder: (context, deviceState) { + // if (deviceState is DeviceManagementLoading) { + // return const Center(child: CircularProgressIndicator()); + // } else if (deviceState is DeviceManagementLoaded || + // deviceState is DeviceManagementFiltered) { + // final devices = (deviceState as dynamic).devices ?? + // (deviceState as DeviceManagementFiltered).filteredDevices; - return DeviceManagementBody(devices: devices); - } else { - return const Center(child: Text('Error fetching Devices')); - } - }, - ); - }), + // return DeviceManagementBody(devices: devices); + // } else { + // return const Center(child: Text('Error fetching Devices')); + // } + // }, + // ); + // }), ), ); } diff --git a/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart b/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart index 1490b12d..35a522b6 100644 --- a/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart +++ b/lib/pages/routiens/bloc/routine_bloc/routine_bloc.dart @@ -26,6 +26,7 @@ class RoutineBloc extends Bloc { on(_onSearchRoutines); on(_onAddSelectedIcon); on(_onCreateScene); + on(_onRemoveDragCard); // on(_onRemoveFunction); // on(_onClearFunctions); } @@ -33,7 +34,13 @@ class RoutineBloc extends Bloc { void _onAddToIfContainer(AddToIfContainer event, Emitter emit) { final updatedIfItems = List>.from(state.ifItems) ..add(event.item); - isTabToRun = event.isTabToRun; + if (event.isTabToRun) { + isTabToRun = true; + isAutomation = false; + } else { + isTabToRun = false; + isAutomation = true; + } emit(state.copyWith(ifItems: updatedIfItems)); } @@ -46,30 +53,27 @@ class RoutineBloc extends Bloc { void _onAddFunctionsToRoutine( AddFunctionToRoutine event, Emitter emit) { - final currentSelectedFunctions = - Map>.from(state.selectedFunctions); + try { + if (event.functions.isEmpty) return; - if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) { - currentSelectedFunctions[event.uniqueCustomId]!.addAll(event.functions); - } else { - currentSelectedFunctions[event.uniqueCustomId] = event.functions; + final currentSelectedFunctions = + Map>.from(state.selectedFunctions); + + if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) { + currentSelectedFunctions[event.uniqueCustomId] = + List.from(currentSelectedFunctions[event.uniqueCustomId]!) + ..addAll(event.functions); + } else { + currentSelectedFunctions[event.uniqueCustomId] = + List.from(event.functions); + } + + emit(state.copyWith(selectedFunctions: currentSelectedFunctions)); + } catch (e) { + debugPrint('Error adding functions: $e'); } - - emit(state.copyWith(selectedFunctions: currentSelectedFunctions)); } - // void _onRemoveFunction(RemoveFunction event, Emitter emit) { - // final functions = List.from(state.selectedFunctions) - // ..removeWhere((f) => - // f.functionCode == event.function.functionCode && - // f.value == event.function.value); - // emit(state.copyWith(selectedFunctions: functions)); - // } - - // void _onClearFunctions(ClearFunctions event, Emitter emit) { - // emit(state.copyWith(selectedFunctions: [])); - // } - Future _onLoadScenes( LoadScenes event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); @@ -83,7 +87,9 @@ class RoutineBloc extends Bloc { } catch (e) { emit(state.copyWith( isLoading: false, - errorMessage: 'Failed to load scenes', + loadScenesErrorMessage: 'Failed to load scenes', + errorMessage: '', + loadAutomationErrorMessage: '', )); } } @@ -101,7 +107,9 @@ class RoutineBloc extends Bloc { } catch (e) { emit(state.copyWith( isLoading: false, - errorMessage: 'Failed to load automations', + loadAutomationErrorMessage: 'Failed to load automations', + errorMessage: '', + loadScenesErrorMessage: '', )); } } @@ -178,10 +186,7 @@ class RoutineBloc extends Bloc { final result = await SceneApi.createScene(createSceneModel); if (result['success']) { - emit(state.copyWith( - isLoading: false, - errorMessage: null, - )); + emit(const RoutineState()); } else { emit(state.copyWith( isLoading: false, @@ -195,4 +200,18 @@ class RoutineBloc extends Bloc { )); } } + + FutureOr _onRemoveDragCard( + RemoveDragCard event, Emitter emit) { + if (event.isFromThen) { + /// remove element from thenItems at specific index + final thenItems = List>.from(state.thenItems); + thenItems.removeAt(event.index); + emit(state.copyWith(thenItems: thenItems)); + } else { + final ifItems = List>.from(state.ifItems); + ifItems.removeAt(event.index); + emit(state.copyWith(ifItems: ifItems)); + } + } } diff --git a/lib/pages/routiens/bloc/routine_bloc/routine_event.dart b/lib/pages/routiens/bloc/routine_bloc/routine_event.dart index 6168748d..9e154cf4 100644 --- a/lib/pages/routiens/bloc/routine_bloc/routine_event.dart +++ b/lib/pages/routiens/bloc/routine_bloc/routine_event.dart @@ -79,4 +79,12 @@ class CreateSceneEvent extends RoutineEvent { List get props => []; } +class RemoveDragCard extends RoutineEvent { + final int index; + final bool isFromThen; + const RemoveDragCard({required this.index, required this.isFromThen}); + @override + List get props => [index]; +} + class ClearFunctions extends RoutineEvent {} diff --git a/lib/pages/routiens/bloc/routine_bloc/routine_state.dart b/lib/pages/routiens/bloc/routine_bloc/routine_state.dart index 911992dc..784cd148 100644 --- a/lib/pages/routiens/bloc/routine_bloc/routine_state.dart +++ b/lib/pages/routiens/bloc/routine_bloc/routine_state.dart @@ -9,6 +9,8 @@ class RoutineState extends Equatable { final Map> selectedFunctions; final bool isLoading; final String? errorMessage; + final String? loadScenesErrorMessage; + final String? loadAutomationErrorMessage; final String? routineName; final String? selectedIcon; @@ -23,6 +25,8 @@ class RoutineState extends Equatable { this.errorMessage, this.routineName, this.selectedIcon, + this.loadScenesErrorMessage, + this.loadAutomationErrorMessage, }); RoutineState copyWith({ @@ -35,6 +39,8 @@ class RoutineState extends Equatable { String? errorMessage, String? routineName, String? selectedIcon, + String? loadAutomationErrorMessage, + String? loadScenesErrorMessage, }) { return RoutineState( ifItems: ifItems ?? this.ifItems, @@ -46,6 +52,10 @@ class RoutineState extends Equatable { errorMessage: errorMessage ?? this.errorMessage, routineName: routineName ?? this.routineName, selectedIcon: selectedIcon ?? this.selectedIcon, + loadScenesErrorMessage: + loadScenesErrorMessage ?? this.loadScenesErrorMessage, + loadAutomationErrorMessage: + loadAutomationErrorMessage ?? this.loadAutomationErrorMessage, ); } @@ -60,5 +70,7 @@ class RoutineState extends Equatable { errorMessage, routineName, selectedIcon, + loadScenesErrorMessage, + loadAutomationErrorMessage, ]; } diff --git a/lib/pages/routiens/helper/ac_helper.dart b/lib/pages/routiens/helper/ac_helper.dart index 8b555b7a..10606b69 100644 --- a/lib/pages/routiens/helper/ac_helper.dart +++ b/lib/pages/routiens/helper/ac_helper.dart @@ -96,14 +96,13 @@ class ACHelper { onConfirm: state.addedFunctions.isNotEmpty ? () { /// add the functions to the routine bloc - // for (var function in state.addedFunctions) { context.read().add( AddFunctionToRoutine( state.addedFunctions, uniqueCustomId, ), ); - //} + // Return the device data to be added to the container Navigator.pop(context, { 'deviceId': functions.first.deviceId, diff --git a/lib/pages/routiens/helper/delay_helper.dart b/lib/pages/routiens/helper/delay_helper.dart index 8ecff897..1191ac58 100644 --- a/lib/pages/routiens/helper/delay_helper.dart +++ b/lib/pages/routiens/helper/delay_helper.dart @@ -1,12 +1,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/routiens/bloc/functions_bloc/functions_bloc_bloc.dart'; import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routiens/models/device_functions.dart'; import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; class DelayHelper { static Future?> showDelayPickerDialog( diff --git a/lib/pages/routiens/helper/setting_helper.dart b/lib/pages/routiens/helper/setting_helper.dart index 2c0cee77..621a5219 100644 --- a/lib/pages/routiens/helper/setting_helper.dart +++ b/lib/pages/routiens/helper/setting_helper.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_bloc.dart'; import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_event.dart'; import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_state.dart'; @@ -10,13 +11,14 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:flutter/cupertino.dart'; class SettingHelper { - static Future showSettingDialog( - {required BuildContext context, - String? iconId, - required bool isAutomation}) async { + static Future showSettingDialog({ + required BuildContext context, + String? iconId, + }) async { return showDialog( context: context, builder: (BuildContext context) { + final isAutomation = context.read().isAutomation; return BlocProvider( create: (_) => SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? '')), diff --git a/lib/pages/routiens/widgets/dragable_card.dart b/lib/pages/routiens/widgets/dragable_card.dart index 02c802bc..ae66ce02 100644 --- a/lib/pages/routiens/widgets/dragable_card.dart +++ b/lib/pages/routiens/widgets/dragable_card.dart @@ -11,6 +11,9 @@ class DraggableCard extends StatelessWidget { final String title; final Map deviceData; final EdgeInsetsGeometry? padding; + final void Function()? onRemove; + final bool? isFromThen; + final bool? isFromIf; const DraggableCard({ super.key, @@ -18,6 +21,9 @@ class DraggableCard extends StatelessWidget { required this.title, required this.deviceData, this.padding, + this.onRemove, + this.isFromThen, + this.isFromIf, }); @override @@ -44,75 +50,97 @@ class DraggableCard extends StatelessWidget { Widget _buildCardContent( BuildContext context, List deviceFunctions, {EdgeInsetsGeometry? padding}) { - return Card( - color: ColorsManager.whiteColors, - child: Container( - padding: padding ?? const EdgeInsets.all(16), - width: 110, - height: deviceFunctions.isEmpty ? 123 : null, - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Column( + return Stack( + children: [ + Card( + color: ColorsManager.whiteColors, + child: Container( + padding: padding ?? const EdgeInsets.all(16), + width: 110, + height: deviceFunctions.isEmpty ? 123 : null, + child: Column( + mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container( - height: 50, - width: 50, - decoration: BoxDecoration( - color: ColorsManager.CircleImageBackground, - borderRadius: BorderRadius.circular(90), - border: Border.all( - color: ColorsManager.graysColor, - ), - ), - padding: const EdgeInsets.all(8), - child: imagePath.contains('.svg') - ? SvgPicture.asset( - imagePath, - ) - : Image.network(imagePath), - ), - const SizedBox(height: 8), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 3), - child: Text( - title, - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, - maxLines: 2, - style: context.textTheme.bodySmall?.copyWith( - color: ColorsManager.blackColor, - fontSize: 12, - ), - ), - ), - ], - ), - if (deviceFunctions.isNotEmpty) - // const Divider(height: 1), - ...deviceFunctions.map((function) => Row( - mainAxisSize: MainAxisSize.min, - children: [ - Expanded( - child: Text( - '${function.operationName}: ${function.value}', - style: context.textTheme.bodySmall?.copyWith( - fontSize: 9, - color: ColorsManager.textGray, - height: 1.2, - ), - maxLines: 2, - overflow: TextOverflow.ellipsis, + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 50, + width: 50, + decoration: BoxDecoration( + color: ColorsManager.CircleImageBackground, + borderRadius: BorderRadius.circular(90), + border: Border.all( + color: ColorsManager.graysColor, ), ), - ], - )), - ], + padding: const EdgeInsets.all(8), + child: imagePath.contains('.svg') + ? SvgPicture.asset( + imagePath, + ) + : Image.network(imagePath), + ), + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 3), + child: Text( + title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + maxLines: 2, + style: context.textTheme.bodySmall?.copyWith( + color: ColorsManager.blackColor, + fontSize: 12, + ), + ), + ), + ], + ), + if (deviceFunctions.isNotEmpty) + // const Divider(height: 1), + ...deviceFunctions.map((function) => Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Text( + '${function.operationName}: ${function.value}', + style: context.textTheme.bodySmall?.copyWith( + fontSize: 9, + color: ColorsManager.textGray, + height: 1.2, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + ], + )), + ], + ), + ), ), - ), + Positioned( + top: -4, + right: -6, + child: Visibility( + visible: (isFromIf ?? false) || (isFromThen ?? false), + child: IconButton( + onPressed: onRemove == null + ? null + : () { + onRemove!(); + }, + icon: const Icon( + Icons.close, + color: ColorsManager.boxColor, + ), + ), + ), + ), + ], ); } diff --git a/lib/pages/routiens/widgets/if_container.dart b/lib/pages/routiens/widgets/if_container.dart index a7afa245..cfb1b27c 100644 --- a/lib/pages/routiens/widgets/if_container.dart +++ b/lib/pages/routiens/widgets/if_container.dart @@ -4,6 +4,7 @@ import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart'; import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; +import 'package:uuid/uuid.dart'; class IfContainer extends StatelessWidget { const IfContainer({super.key}); @@ -20,7 +21,9 @@ class IfContainer extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('IF', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + const Text('IF', + style: + TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 16), if (context.read().isTabToRun) const Row( @@ -37,14 +40,23 @@ class IfContainer extends StatelessWidget { Wrap( spacing: 8, runSpacing: 8, - children: state.ifItems - .map((item) => DraggableCard( - // key: Key(item['key']!), - imagePath: item['imagePath'] ?? '', - title: item['title'] ?? 'Tab to run', - deviceData: item, - )) - .toList(), + children: List.generate( + state.ifItems.length, + (index) => DraggableCard( + imagePath: + state.ifItems[index]['imagePath'] ?? '', + title: state.ifItems[index]['title'] ?? '', + deviceData: state.ifItems[index], + padding: const EdgeInsets.symmetric( + horizontal: 4, vertical: 8), + isFromThen: false, + isFromIf: true, + onRemove: () { + context.read().add( + RemoveDragCard( + index: index, isFromThen: false)); + }, + )), ), ], ), @@ -52,15 +64,52 @@ class IfContainer extends StatelessWidget { }, onWillAccept: (data) => data != null, onAccept: (data) async { + // final uniqueCustomId = const Uuid().v4(); + + // final mutableData = Map.from(data); + // mutableData['uniqueCustomId'] = uniqueCustomId; + + // if (!context.read().isTabToRun) { + // if (data['deviceId'] == 'tab_to_run') { + // context.read().add(AddToIfContainer(data, true)); + // } else { + // final result = + // await DeviceDialogHelper.showDeviceDialog(context, mutableData); + // if (result != null) { + // context + // .read() + // .add(AddToIfContainer(mutableData, false)); + // } else if (!['AC', '1G', '2G', '3G'] + // .contains(data['productType'])) { + // context + // .read() + // .add(AddToIfContainer(mutableData, false)); + // } + // } + //} + final uniqueCustomId = const Uuid().v4(); + + final mutableData = Map.from(data); + mutableData['uniqueCustomId'] = uniqueCustomId; + if (!context.read().isTabToRun) { - if (data['deviceId'] == 'tab_to_run') { - context.read().add(AddToIfContainer(data, true)); + if (mutableData['deviceId'] == 'tab_to_run') { + context + .read() + .add(AddToIfContainer(mutableData, true)); } else { - final result = await DeviceDialogHelper.showDeviceDialog(context, data); + final result = await DeviceDialogHelper.showDeviceDialog( + context, mutableData); + if (result != null) { - context.read().add(AddToIfContainer(result, false)); - } else if (!['AC', '1G', '2G', '3G'].contains(data['productType'])) { - context.read().add(AddToIfContainer(data, false)); + context + .read() + .add(AddToIfContainer(mutableData, false)); + } else if (!['AC', '1G', '2G', '3G'] + .contains(mutableData['productType'])) { + context + .read() + .add(AddToIfContainer(mutableData, false)); } } } diff --git a/lib/pages/routiens/widgets/routine_search_and_buttons.dart b/lib/pages/routiens/widgets/routine_search_and_buttons.dart index 66f2a3a0..fa0e2128 100644 --- a/lib/pages/routiens/widgets/routine_search_and_buttons.dart +++ b/lib/pages/routiens/widgets/routine_search_and_buttons.dart @@ -43,6 +43,7 @@ class RoutineSearchAndButtons extends StatelessWidget { boxDecoration: containerWhiteDecoration, elevation: 0, borderRadius: 15, + isRequired: true, width: 450, onChanged: (value) { context @@ -61,10 +62,8 @@ class RoutineSearchAndButtons extends StatelessWidget { onPressed: () async { final result = await SettingHelper.showSettingDialog( - context: context, - isAutomation: context - .read() - .isAutomation); + context: context, + ); if (result != null) { context .read() diff --git a/lib/pages/routiens/widgets/then_container.dart b/lib/pages/routiens/widgets/then_container.dart index 5d71e405..d6c9500f 100644 --- a/lib/pages/routiens/widgets/then_container.dart +++ b/lib/pages/routiens/widgets/then_container.dart @@ -30,19 +30,25 @@ class ThenContainer extends StatelessWidget { fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 16), Wrap( - spacing: 8, - runSpacing: 8, - children: state.thenItems - .map((item) => DraggableCard( - // key: Key(item['key']!), - imagePath: item['imagePath']!, - title: item['title']!, - deviceData: item, - padding: EdgeInsets.symmetric( - horizontal: 4, vertical: 8), - )) - .toList(), - ), + spacing: 8, + runSpacing: 8, + children: List.generate( + state.thenItems.length, + (index) => DraggableCard( + imagePath: + state.thenItems[index]['imagePath'] ?? '', + title: state.thenItems[index]['title'] ?? '', + deviceData: state.thenItems[index], + padding: const EdgeInsets.symmetric( + horizontal: 4, vertical: 8), + isFromThen: true, + isFromIf: false, + onRemove: () { + context.read().add( + RemoveDragCard( + index: index, isFromThen: true)); + }, + ))), ], ), ), diff --git a/lib/services/routines_api.dart b/lib/services/routines_api.dart index b137982d..abf5099e 100644 --- a/lib/services/routines_api.dart +++ b/lib/services/routines_api.dart @@ -1,3 +1,4 @@ +import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/routiens/models/create_scene/create_scene_model.dart'; import 'package:syncrow_web/pages/routiens/models/icon_model.dart'; import 'package:syncrow_web/pages/routiens/models/routine_model.dart'; @@ -11,6 +12,7 @@ class SceneApi { static Future> createScene( CreateSceneModel createSceneModel) async { try { + debugPrint('create scene model: ${createSceneModel.toMap()}'); final response = await _httpService.post( path: ApiEndpoints.createScene, body: createSceneModel.toMap(), @@ -19,8 +21,10 @@ class SceneApi { return json; }, ); + debugPrint('create scene response: $response'); return response; } catch (e) { + debugPrint(e.toString()); rethrow; } }