From f5a7441b3c2af02525bff97868d42363a70320db Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 22 Aug 2024 16:52:41 +0300 Subject: [PATCH] tap filter --- assets/images/empty_table.svg | 23 ++ .../access_management/bloc/access_bloc.dart | 97 +++++-- .../access_management/bloc/access_event.dart | 6 + .../model/password_model.dart | 20 +- .../view/access_management.dart | 147 +++-------- lib/pages/auth/bloc/auth_bloc.dart | 1 - lib/pages/auth/view/login_web_page.dart | 3 +- lib/pages/common/custom_table.dart | 32 ++- lib/pages/common/date_time_widget.dart | 5 +- lib/pages/home/bloc/home_bloc.dart | 2 +- lib/pages/home/view/home_card.dart | 18 +- .../bloc/visitor_password_bloc.dart | 18 +- .../view/add_device_dialog.dart | 4 +- .../view/visitor_password_dialog.dart | 236 +++++++----------- lib/utils/constants/assets.dart | 1 + lib/utils/constants/const.dart | 38 ++- 16 files changed, 333 insertions(+), 318 deletions(-) create mode 100644 assets/images/empty_table.svg diff --git a/assets/images/empty_table.svg b/assets/images/empty_table.svg new file mode 100644 index 00000000..24ac359d --- /dev/null +++ b/assets/images/empty_table.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/pages/access_management/bloc/access_bloc.dart b/lib/pages/access_management/bloc/access_bloc.dart index f586c56f..5b406add 100644 --- a/lib/pages/access_management/bloc/access_bloc.dart +++ b/lib/pages/access_management/bloc/access_bloc.dart @@ -5,23 +5,25 @@ import 'package:syncrow_web/pages/access_management/bloc/access_state.dart'; import 'package:syncrow_web/pages/access_management/model/password_model.dart'; import 'package:syncrow_web/services/access_mang_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/constants/const.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; class AccessBloc extends Bloc { AccessBloc() : super((AccessInitial())) { on(_onFetchTableData); - on(selectFilterTap); + // on(selectFilterTap); on(selectTime); on(_filterData); on(resetSearch); + on(onTabChanged); } - String startTime = 'Start Time'; - String endTime = 'End Time'; + String startTime = 'Start Date'; + String endTime = 'End Date'; int? effectiveTimeTimeStamp; int? expirationTimeTimeStamp; TextEditingController passwordName= TextEditingController(); - List filteredData = []; // To store filtered data + List filteredData = []; List data=[]; Future _onFetchTableData( @@ -29,11 +31,26 @@ class AccessBloc extends Bloc { try { emit(AccessLoaded()); data = await AccessMangApi().fetchVisitorPassword(); - emit(TableLoaded(data)); + filteredData= data; + updateTabsCount(); + emit(TableLoaded(data)); } catch (e) { emit(FailedState(e.toString())); } } + void updateTabsCount() { + // Count occurrences based on the type field + int toBeEffectiveCount = data.where((item) => item.passwordStatus.value== 'To Be Effective').length; + int effectiveCount = data.where((item) => item.passwordStatus.value == 'Effective').length; + int expiredCount = data.where((item) => item.passwordStatus.value == 'Expired').length; + + // Update tab labels with counts + tabs[1] = 'To Be Effective ($toBeEffectiveCount)'; + tabs[2] = 'Effective ($effectiveCount)'; + tabs[3] = 'Expired ($expiredCount)'; + } + + int selectedIndex = 0; @@ -49,9 +66,8 @@ class AccessBloc extends Bloc { try { emit(AccessLoaded()); selectedIndex= event.selectedIndex; - emit(AccessInitial()); + emit(AccessInitial()); emit(TableLoaded(data)); - } catch (e) { emit(FailedState( e.toString())); return; @@ -60,6 +76,7 @@ class AccessBloc extends Bloc { Future selectTime(SelectTime event, Emitter emit) async { + final DateTime? picked = await showDatePicker( context: event.context, initialDate: DateTime.now(), @@ -120,27 +137,27 @@ class AccessBloc extends Bloc { } } } - emit(AccessInitial()); - emit(TableLoaded(data)); + emit(ChangeTimeState()); } + Future _filterData(FilterDataEvent event, Emitter emit) async { emit(AccessLoaded()); try { - // Filter the data based on the provided criteria filteredData = data.where((item) { bool matchesCriteria = true; - // Check if the password name should be used for filtering + + // Filter by password name if provided if (event.passwordName != null && event.passwordName!.isNotEmpty) { - final bool matchesName = item.passwodName != null && - item.passwodName.contains(event.passwordName); + final bool matchesName = item.passwordName != null && + item.passwordName.contains(event.passwordName); if (!matchesName) { matchesCriteria = false; } } - // Check if the time range should be used for filtering + + // Filter by date range if provided if (event.startTime != null && event.endTime != null) { - // Ensure effectiveTime and invalidTime are treated as integers final int? effectiveTime = int.tryParse(item.effectiveTime.toString()); final int? invalidTime = int.tryParse(item.invalidTime.toString()); if (effectiveTime == null || invalidTime == null) { @@ -153,22 +170,31 @@ class AccessBloc extends Bloc { } } } + + // Filter by tab selection + if (event.selectedTabIndex == 1 && item.passwordStatus.value != 'To Be Effective') { + matchesCriteria = false; + } else if (event.selectedTabIndex == 2 && item.passwordStatus.value != 'Effective') { + matchesCriteria = false; + } else if (event.selectedTabIndex == 3 && item.passwordStatus.value != 'Expired') { + matchesCriteria = false; + } + return matchesCriteria; }).toList(); - print('Filtered data: $filteredData'); emit(TableLoaded(filteredData)); } catch (e) { - print('Error occurred during filtering: $e'); + emit(FailedState(e.toString())); } } - // ResetSearch + resetSearch(ResetSearch event, Emitter emit) async{ emit(AccessLoaded()); startTime = 'Start Time'; endTime = 'End Time'; passwordName.clear(); + selectedIndex=0; add(FetchTableData()); - } String timestampToDate(dynamic timestamp) { @@ -176,5 +202,38 @@ class AccessBloc extends Bloc { return "${dateTime.year}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.day.toString().padLeft(2, '0')}"; } + Future onTabChanged(TabChangedEvent event, Emitter emit) async { + try { + emit(AccessLoaded()); + selectedIndex = event.selectedIndex; + // Apply filtering based on selected tab + switch (selectedIndex) { + case 0: // All + filteredData = data; + break; + case 1: // To Be Effective + filteredData = data.where((item) => item.passwordStatus.value == "To Be Effective").toList(); + break; + case 2: // Effective + filteredData = data.where((item) => item.passwordStatus.value == "Effective").toList(); + + break; + case 3: // Expired + filteredData = data.where((item) => item.passwordStatus.value == "Expired").toList(); + break; + default: + filteredData = data; + } + add(FilterDataEvent( + selectedTabIndex: selectedIndex, // Pass the selected tab index + passwordName: passwordName.text.toLowerCase(), + startTime: effectiveTimeTimeStamp, + endTime: expirationTimeTimeStamp + )); + emit(TableLoaded(filteredData)); + } catch (e) { + emit(FailedState(e.toString())); + } + } } diff --git a/lib/pages/access_management/bloc/access_event.dart b/lib/pages/access_management/bloc/access_event.dart index 3a64a11a..f2f631b4 100644 --- a/lib/pages/access_management/bloc/access_event.dart +++ b/lib/pages/access_management/bloc/access_event.dart @@ -31,10 +31,16 @@ class FilterDataEvent extends AccessEvent { final String? passwordName; final int? startTime; final int? endTime; + final int selectedTabIndex; // Add this field const FilterDataEvent({ this.passwordName, this.startTime, this.endTime, + required this.selectedTabIndex, // Initialize this field + }); } + + + diff --git a/lib/pages/access_management/model/password_model.dart b/lib/pages/access_management/model/password_model.dart index acd3e13a..584e9b7e 100644 --- a/lib/pages/access_management/model/password_model.dart +++ b/lib/pages/access_management/model/password_model.dart @@ -6,8 +6,8 @@ class PasswordModel { final dynamic effectiveTime; final dynamic passwordCreated; final dynamic createdTime; - final dynamic passwodName; // New field - final dynamic passwordStatus; + final dynamic passwordName; // New field + final AccessStatus passwordStatus; final AccessType passwordType; final dynamic deviceUuid; @@ -17,8 +17,8 @@ class PasswordModel { this.effectiveTime, this.passwordCreated, this.createdTime, - this.passwodName, // New field - this.passwordStatus, + this.passwordName, // New field + required this.passwordStatus, required this.passwordType, this.deviceUuid, }); @@ -30,9 +30,9 @@ class PasswordModel { effectiveTime: json['effectiveTime'], passwordCreated: json['passwordCreated'], createdTime: json['createdTime'], - passwodName: json['passwodName']??'No name', // New field - passwordStatus: json['passwordStatus'], - passwordType:AccessTypeExtension.fromString(json['passwordType']) , + passwordName: json['passwordName']??'No name', // New field + passwordStatus:AccessStatusExtension.fromString(json['passwordStatus']), + passwordType:AccessTypeExtension.fromString(json['passwordType']), deviceUuid: json['deviceUuid'], ); } @@ -44,13 +44,11 @@ class PasswordModel { 'effectiveTime': effectiveTime, 'passwordCreated': passwordCreated, 'createdTime': createdTime, - 'passwodName': passwodName, // New field + 'passwodName': passwordName, // New field 'passwordStatus': passwordStatus, 'passwordType': passwordType, 'deviceUuid': deviceUuid, }; } - List parsePasswordList(List jsonList) { - return jsonList.map((json) => PasswordModel.fromJson(json)).toList(); - } + } diff --git a/lib/pages/access_management/view/access_management.dart b/lib/pages/access_management/view/access_management.dart index e202194f..38fb545e 100644 --- a/lib/pages/access_management/view/access_management.dart +++ b/lib/pages/access_management/view/access_management.dart @@ -38,14 +38,13 @@ class AccessManagementPage extends StatelessWidget { ], scaffoldBody: BlocProvider(create: (BuildContext context) => AccessBloc()..add(FetchTableData()), child: BlocConsumer(listener: (context, state) { - if (state is FailedState) { - // CustomSnackBar.displaySnackBar( - // state.errorMessage - // ); - } + }, builder: (context, state) { final accessBloc = BlocProvider.of(context); - return Container( + final filteredData = accessBloc.filteredData; + return state is AccessLoaded? + const Center(child: CircularProgressIndicator()): + Container( padding: EdgeInsets.all(30), height: size.height, width: size.width, @@ -61,35 +60,34 @@ class AccessManagementPage extends StatelessWidget { itemCount: BlocProvider.of(context).tabs.length, shrinkWrap: true, itemBuilder: (context, index) { - final isSelected = index == - BlocProvider.of(context).selectedIndex; + final isSelected = index == BlocProvider.of(context).selectedIndex; return InkWell( onTap: () { BlocProvider.of(context).add(TabChangedEvent(index)); }, child: Container( decoration: BoxDecoration( - color: ColorsManager.boxColor, - border: Border.all( - color: isSelected ? Colors.blue : Colors.transparent, - width: 2.0,), - borderRadius: index == 0 - ? const BorderRadius.only( - topLeft: Radius.circular(10), - bottomLeft: Radius.circular(10)) - : index == 3 - ? const BorderRadius.only( - topRight: Radius.circular(10), - bottomRight: Radius.circular(10)) - : null), - padding: const EdgeInsets.only(left: 10,right: 10), + color: ColorsManager.boxColor, + border: Border.all( + color: isSelected ? Colors.blue : Colors.transparent, + width: 2.0, + ), + borderRadius: index == 0 + ? const BorderRadius.only( + topLeft: Radius.circular(10), + bottomLeft: Radius.circular(10)) + : index == 3 + ? const BorderRadius.only( + topRight: Radius.circular(10), + bottomRight: Radius.circular(10)) + : null, + ), + padding: const EdgeInsets.only(left: 10, right: 10), child: Center( child: Text( BlocProvider.of(context).tabs[index], style: TextStyle( - color: isSelected - ? Colors.blue - : Colors.black, + color: isSelected ? Colors.blue : Colors.black, ), ), ), @@ -105,12 +103,15 @@ class AccessManagementPage extends StatelessWidget { Row( children: [ Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text('Name'), + Text('Name', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.black,fontSize: 13),), + const SizedBox(height: 5,), Container( + height:size.height * 0.053, width: size.width * 0.15, decoration: containerDecoration, child: TextFormField( @@ -118,7 +119,8 @@ class AccessManagementPage extends StatelessWidget { style: const TextStyle(color: Colors.black), decoration: textBoxDecoration()! .copyWith(hintText: 'Please enter'), - )), + ) + ), ], ), const SizedBox( @@ -152,6 +154,7 @@ class AccessManagementPage extends StatelessWidget { child: DefaultButton( onPressed: () { accessBloc.add(FilterDataEvent( + selectedTabIndex: BlocProvider.of(context).selectedIndex, // Pass the selected tab index passwordName: accessBloc.passwordName.text.toLowerCase(), startTime: accessBloc.effectiveTimeTimeStamp, endTime: accessBloc.expirationTimeTimeStamp @@ -234,8 +237,8 @@ class AccessManagementPage extends StatelessWidget { height: 20, ), Expanded( - child: state is TableLoaded - ? DynamicTable( + child: DynamicTable( + isEmpty: filteredData.isEmpty , withCheckBox: false, size: size, cellDecoration: containerDecoration, @@ -243,102 +246,30 @@ class AccessManagementPage extends StatelessWidget { 'Name', 'Access Type', 'Access Period', - 'Device Id', + 'Accessible Device', 'Authorizer', 'Authorization Date & Time', 'Access Status' ], - data: state.data.map((item) { + data: filteredData.map((item) { return [ - item.passwodName.toString(), + item.passwordName.toString(), item.passwordType.value, ('${accessBloc.timestampToDate(item.effectiveTime)} - ${accessBloc.timestampToDate(item.invalidTime)}'), item.deviceUuid.toString(), '', '', - '' + item.passwordStatus.value ]; }).toList(), ) - : const Center(child: CircularProgressIndicator()), + // : const Center(child: CircularProgressIndicator()), ) - ], ), ); }))); } - - - // Container TableWidget(Size size, TableLoaded state,AccessBloc accessBloc) { - // return Container( - // decoration: containerDecoration, - // width: size.width, - // child: Padding( - // padding: const EdgeInsets.all(10.0), - // child: ListView( - // scrollDirection: Axis.horizontal, - // children: [ - // Container( - // width: size.width, - // height: size.height, - // child: Column( - // children: [ - // Container( - // color: ColorsManager.boxColor, - // child: Row( - // children: [ - // _buildTableHeaderCell('Password name'), - // _buildTableHeaderCell(' Password Type'), - // _buildTableHeaderCell('Start Time'), - // _buildTableHeaderCell('End Time'), - // _buildTableHeaderCell('Device Id'), - // // _buildTableHeaderCell('Authorization Source'), - // // _buildTableHeaderCell('Authorizer'), - // _buildTableHeaderCell('Password Created'), - // // _buildTableHeaderCell('Access Status'), - // _buildTableHeaderCell('Password Status'), - // ], - // ), - // ), - // Expanded( - // child: Container( - // width: size.width, - // color: ColorsManager.whiteColors, - // child: ListView( - // shrinkWrap: true, - // children: [ - // Column( - // children: state.data.map((item) { - // return Row( - // children: [ - // _buildTableCell(item.passwodName), - // _buildTableCell(item.passwordType), - // - // _buildTableCell(accessBloc.timestampToDateTime(item.effectiveTime).toString()), - // _buildTableCell(accessBloc.timestampToDateTime(item.invalidTime).toString()), - // _buildTableCell(item.deviceUuid.toString()), - // // _buildTableCell(item.authorizationSource), - // // _buildTableCell(item.authorizer), - // _buildTableCell(item.passwordCreated!=null?accessBloc.timestampToDateTime(item.passwordCreated).toString():'no data'), - // // _buildTableCell(item.accessStatus), - // _buildTableCell(item.passwordStatus.toString()), - // ], - // ); - // }).toList(), - // ), - // ], - // ), - // ), - // ), - // ], - // ), - // ), - // ], - // ), - // ), - // ); - // } } diff --git a/lib/pages/auth/bloc/auth_bloc.dart b/lib/pages/auth/bloc/auth_bloc.dart index 2cc1a033..125c2817 100644 --- a/lib/pages/auth/bloc/auth_bloc.dart +++ b/lib/pages/auth/bloc/auth_bloc.dart @@ -159,7 +159,6 @@ class AuthBloc extends Bloc { loginPasswordController.clear(); emit(LoginSuccess()); } else { - emit(const LoginFailure(error: 'Something went wrong')); } } else { diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index b819669e..d8b22d38 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -166,8 +166,7 @@ class _LoginWebPageState extends State { return DropdownMenuItem( value: region.id, child: SizedBox( - width: size.width*0.06, - + width: size.width*0.08, child: Text(region.name)), ); }).toList(), diff --git a/lib/pages/common/custom_table.dart b/lib/pages/common/custom_table.dart index 86f34124..b7aa71a5 100644 --- a/lib/pages/common/custom_table.dart +++ b/lib/pages/common/custom_table.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; class DynamicTable extends StatefulWidget { final List headers; @@ -8,6 +10,7 @@ class DynamicTable extends StatefulWidget { final BoxDecoration? cellDecoration; final Size size; final bool withCheckBox; + final bool isEmpty; final void Function(bool?)? selectAll; final void Function(int, bool?)? onRowCheckboxChanged; @@ -16,6 +19,7 @@ class DynamicTable extends StatefulWidget { required this.headers, required this.data, required this.size, + required this.isEmpty, required this.withCheckBox, this.headerDecoration, this.cellDecoration, @@ -63,7 +67,8 @@ class _DynamicTableState extends State { decoration: widget.cellDecoration, child: Padding( padding: const EdgeInsets.all(10.0), - child: ListView( + child: + ListView( scrollDirection: Axis.horizontal, children: [ SizedBox( @@ -83,6 +88,29 @@ class _DynamicTableState extends State { ], ), ), + widget.isEmpty? + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + children: [ + SvgPicture.asset( + Assets.emptyTable + ), + SizedBox(height: 15,), + Text('No Passwords',style: Theme.of(context).textTheme.bodySmall!.copyWith(color:ColorsManager.grayColor ),) + ], + ), + ], + ), + ], + ), + ): Expanded( child: Container( color: Colors.white, @@ -164,7 +192,7 @@ class _DynamicTableState extends State { alignment: Alignment.centerLeft, child: Text( content, - style: const TextStyle(color: Colors.black, fontSize: 12), + style: const TextStyle(color: Colors.black, fontSize: 10,fontWeight: FontWeight.w400), ), ), ); diff --git a/lib/pages/common/date_time_widget.dart b/lib/pages/common/date_time_widget.dart index 39dc582c..55d5b9a9 100644 --- a/lib/pages/common/date_time_widget.dart +++ b/lib/pages/common/date_time_widget.dart @@ -42,11 +42,12 @@ class DateTimeWebWidget extends StatelessWidget { .bodyMedium! .copyWith(color: Colors.red), ), - Text(title??'' , style: Theme.of(context).textTheme.bodySmall!.copyWith( + Text(title??'' , + style: Theme.of(context).textTheme.bodySmall!.copyWith( color: Colors.black,fontSize: 13),), ], ), - SizedBox(height: 8,), + const SizedBox(height: 8,), Container( width: size.width * 0.25, padding: EdgeInsets.all(10), diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index db233d3c..ebcc6b4e 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -67,7 +67,7 @@ class HomeBloc extends Bloc { color: null, ), HomeItemModel( - title: 'Space\nManagement', + title: 'Space Management', icon: Assets.spaseManagementIcon, active: true, onPress: (context) { diff --git a/lib/pages/home/view/home_card.dart b/lib/pages/home/view/home_card.dart index 287bb4f4..ce152c1c 100644 --- a/lib/pages/home/view/home_card.dart +++ b/lib/pages/home/view/home_card.dart @@ -37,14 +37,16 @@ class HomeCard extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - FittedBox( - fit: BoxFit.scaleDown, - child: Text( - name, - style: const TextStyle( - fontSize: 20, - color: Colors.white, - fontWeight: FontWeight.bold, + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + name, + style: const TextStyle( + fontSize: 20, + color: Colors.white, + fontWeight: FontWeight.bold, + ), ), ), ), diff --git a/lib/pages/visitor_password/bloc/visitor_password_bloc.dart b/lib/pages/visitor_password/bloc/visitor_password_bloc.dart index 65d82dda..ff3b57e4 100644 --- a/lib/pages/visitor_password/bloc/visitor_password_bloc.dart +++ b/lib/pages/visitor_password/bloc/visitor_password_bloc.dart @@ -11,9 +11,7 @@ import 'package:syncrow_web/services/access_mang_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; -List selectedDevices = []; -// Define the BLoC class VisitorPasswordBloc extends Bloc { VisitorPasswordBloc() : super(VisitorPasswordInitial()) { @@ -42,12 +40,12 @@ class VisitorPasswordBloc final TextEditingController unitNameController = TextEditingController(); final TextEditingController virtualAddressController = TextEditingController(); + List selectedDevices = []; List data = []; List selectedDeviceIds = []; - String effectiveTime = 'Select Time'; - - String expirationTime = 'Select Time'; + String effectiveTime = 'Start Time'; + String expirationTime = 'End Time'; final forgetFormKey = GlobalKey(); @@ -69,8 +67,6 @@ class VisitorPasswordBloc String startTimeAccess = 'Start Time'; String endTimeAccess = 'End Time'; - // DateTime? repeatStartTime=DateTime.now(); - // DateTime? repeatEndTime; selectAccessType( SelectPasswordType event, Emitter emit) { @@ -210,9 +206,6 @@ class VisitorPasswordBloc Emitter emit) async { try { generate7DigitNumber(); - - print('selectedDevices$selectedDevices'); - // emit(DeviceLoaded()); bool res = await AccessMangApi().postOnlineOneTime( email: event.email, password: passwordController, @@ -225,6 +218,7 @@ class VisitorPasswordBloc } emit(TableLoaded(data)); } catch (e) { + emit(FailedState(e.toString())); } } @@ -351,9 +345,9 @@ class VisitorPasswordBloc emit(TableLoaded(event.filteredData)); } - addDeviceToList() { + addDeviceToList(context) { selectedDevices = selectedDeviceIds; - print(selectedDevices); + Navigator.of(context).pop(selectedDevices); // Close the dialog } Future selectTimeOfLinePassword(SelectTimeEvent event, Emitter emit) async { diff --git a/lib/pages/visitor_password/view/add_device_dialog.dart b/lib/pages/visitor_password/view/add_device_dialog.dart index 7f9ca94e..9d7be636 100644 --- a/lib/pages/visitor_password/view/add_device_dialog.dart +++ b/lib/pages/visitor_password/view/add_device_dialog.dart @@ -161,6 +161,7 @@ class AddDeviceDialog extends StatelessWidget { child: state is TableLoaded ? DynamicTable( cellDecoration: containerDecoration, + isEmpty:visitorBloc.data.isEmpty, selectAll: (p0) { visitorBloc.selectedDeviceIds.clear(); for (var item in state.data) { @@ -211,8 +212,7 @@ class AddDeviceDialog extends StatelessWidget { width: size.width * 0.2, child: DefaultButton( onPressed: () { - visitorBloc.addDeviceToList(); - Navigator.of(context).pop(); // Close the dialog + visitorBloc.addDeviceToList(context); }, borderRadius: 8, child: Text('Ok'), diff --git a/lib/pages/visitor_password/view/visitor_password_dialog.dart b/lib/pages/visitor_password/view/visitor_password_dialog.dart index 9998ec3e..1f7e3a14 100644 --- a/lib/pages/visitor_password/view/visitor_password_dialog.dart +++ b/lib/pages/visitor_password/view/visitor_password_dialog.dart @@ -128,10 +128,7 @@ class VisitorPasswordDialog extends StatelessWidget { : visitorBloc.accessTypeSelected, onChanged: (String? value) { if (value != null) { - print(value); - - context - .read() + context.read() .add(SelectPasswordType(value)); } }, @@ -192,22 +189,18 @@ class VisitorPasswordDialog extends StatelessWidget { SizedBox( width: 200, child: RadioListTile( - title: Text('One-Time',style: Theme.of(context).textTheme.bodySmall!.copyWith( + title: Text('One-Time', + style: Theme.of(context).textTheme.bodySmall!.copyWith( color: Colors.black,fontSize: 13),), value: 'One-Time', groupValue: (state is UsageFrequencySelected) ? state.selectedFrequency - : visitorBloc - .usageFrequencySelected, + : visitorBloc.usageFrequencySelected, onChanged: (String? value) { if (value != null) { - print(value); - - context - .read() - .add(SelectUsageFrequency( - value)); + context.read() + .add(SelectUsageFrequency(value)); } }, ), @@ -219,17 +212,14 @@ class VisitorPasswordDialog extends StatelessWidget { style: Theme.of(context).textTheme.bodySmall!.copyWith( color: Colors.black,fontSize: 13),), value: 'Periodic', - groupValue: - (state is UsageFrequencySelected) + groupValue: (state is UsageFrequencySelected) ? state.selectedFrequency - : visitorBloc - .usageFrequencySelected, + : visitorBloc.usageFrequencySelected, onChanged: (String? value) { if (value != null) { context .read() - .add(SelectUsageFrequency( - value)); + .add(SelectUsageFrequency(value)); } }, ), @@ -238,7 +228,8 @@ class VisitorPasswordDialog extends StatelessWidget { ), Text('Within the validity period, each device can be unlocked only once.', style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.grayColor,fontSize: 9),) + color: ColorsManager.grayColor,fontSize: 9), + ) ], ), const SizedBox( @@ -288,7 +279,7 @@ class VisitorPasswordDialog extends StatelessWidget { ], ), Text( - 'Within the validity period, each device can be unlocked only once.', + 'Within the validity period, each device can be unlocked only once.', style: Theme.of(context).textTheme.bodySmall!.copyWith( fontWeight: FontWeight.w400, color: ColorsManager.grayColor,fontSize: 9),), @@ -326,13 +317,20 @@ class VisitorPasswordDialog extends StatelessWidget { width: size.width * 0.08, child: DefaultButton( onPressed: () { - showDialog( + showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return const AddDeviceDialog(); }, - ); + ).then((listDevice) { + if(listDevice!=null){ + print('selectedDevices==$listDevice'); + visitorBloc.selectedDevices = listDevice; + + } + }); + }, borderRadius: 8, child: Text('+ Add Device',style: Theme.of(context).textTheme.bodySmall!.copyWith( @@ -371,135 +369,81 @@ class VisitorPasswordDialog extends StatelessWidget { width: size.width * 0.2, child: DefaultButton( onPressed: () { - print(selectedDevices); if (visitorBloc.forgetFormKey.currentState!.validate()) { - if (selectedDevices.toString() != '[]') { - showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return InfoDialog( - size: size, - title: 'Set Password', - content: - 'This action will update all of the selected\n door locks passwords in the property.\n\nAre you sure you want to continue?', - actions: [ - Container( - decoration: containerDecoration, - width: size.width * 0.1, - child: DefaultButton( - borderRadius: 8, - onPressed: () { - Navigator.of(context) - .pop(); // Close the dialog - }, - backgroundColor: Colors.white, - child: Text( - 'Cancel', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.blackColor,fontSize: 16), - ), - ), - ), - Container( - decoration: containerDecoration, - width: size.width * 0.1, - child: DefaultButton( - borderRadius: 8, - onPressed: () { - if (visitorBloc.usageFrequencySelected == 'One-Time' && - visitorBloc.accessTypeSelected == 'Online Password') { - visitorBloc.add( - OnlineOneTimePasswordEvent( - context: context, - passwordName: visitorBloc.userNameController.text, - email: visitorBloc.emailController.text)); - } else if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Online Password') { - visitorBloc.add(OnlineMultipleTimePasswordEvent( - passwordName: visitorBloc.userNameController.text, - email: visitorBloc.emailController.text, - effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(), - invalidTime: visitorBloc.expirationTimeTimeStamp.toString())); - } else if (visitorBloc.usageFrequencySelected == 'One-Time' && - visitorBloc.accessTypeSelected == 'Offline Password') { - visitorBloc.add(OfflineOneTimePasswordEvent( - passwordName: visitorBloc.userNameController.text, - email: visitorBloc.emailController.text, - )); - } else if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Offline Password') { - visitorBloc.add( - OfflineMultipleTimePasswordEvent( - passwordName: visitorBloc.userNameController.text, - email: visitorBloc.emailController.text, - effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(), - invalidTime: visitorBloc.expirationTimeTimeStamp.toString())); - } - }, - child: Text('Ok', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.whiteColors,fontSize: 16), - ), - ), - ), - ], - ); - }, - ); - } else { - showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return AlertDialog( - alignment: Alignment.center, - content: SizedBox( - height: size!.height * 0.15, - child: Column( - children: [ - SizedBox( - child: SvgPicture.asset( - Assets.deviceNoteIcon, - height: 35, - width: 35, - ), - ), - - const SizedBox( - width: 15, - ), - Text( - 'Please select devices to continue', - style: Theme.of(context) - .textTheme - .headlineLarge! - .copyWith( - fontSize: 20, - fontWeight: FontWeight.w400, - color: Colors.black), - ), - ], - ), - ), - actionsAlignment: MainAxisAlignment.center, - actions: [ - TextButton( + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return InfoDialog( + size: size, + title: 'Set Password', + content: + 'This action will update all of the selected\n door locks passwords in the property.\n\nAre you sure you want to continue?', + actions: [ + Container( + decoration: containerDecoration, + width: size.width * 0.1, + child: DefaultButton( + borderRadius: 8, onPressed: () { Navigator.of(context).pop(); }, - child: Text('OK', + backgroundColor: Colors.white, + child: Text( + 'Cancel', style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.whiteColors,fontSize: 16),), + fontWeight: FontWeight.w400, + color: ColorsManager.blackColor,fontSize: 16), + ), ), - ], - ); - }, - ); - } + ), + Container( + decoration: containerDecoration, + width: size.width * 0.1, + child: DefaultButton( + borderRadius: 8, + onPressed: () { + if (visitorBloc.usageFrequencySelected == 'One-Time' && + visitorBloc.accessTypeSelected == 'Online Password') { + visitorBloc.add( + OnlineOneTimePasswordEvent( + context: context, + passwordName: visitorBloc.userNameController.text, + email: visitorBloc.emailController.text)); + } else if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Online Password') { + visitorBloc.add(OnlineMultipleTimePasswordEvent( + passwordName: visitorBloc.userNameController.text, + email: visitorBloc.emailController.text, + effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(), + invalidTime: visitorBloc.expirationTimeTimeStamp.toString())); + } else if (visitorBloc.usageFrequencySelected == 'One-Time' && + visitorBloc.accessTypeSelected == 'Offline Password') { + visitorBloc.add(OfflineOneTimePasswordEvent( + passwordName: visitorBloc.userNameController.text, + email: visitorBloc.emailController.text, + )); + } else if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Offline Password') { + visitorBloc.add( + OfflineMultipleTimePasswordEvent( + passwordName: visitorBloc.userNameController.text, + email: visitorBloc.emailController.text, + effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(), + invalidTime: visitorBloc.expirationTimeTimeStamp.toString())); + } + }, + child: Text('Ok', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.whiteColors,fontSize: 16), + ), + ), + ), + ], + ); + }, + ); } }, borderRadius: 8, diff --git a/lib/utils/constants/assets.dart b/lib/utils/constants/assets.dart index 62f991fe..f4a2859e 100644 --- a/lib/utils/constants/assets.dart +++ b/lib/utils/constants/assets.dart @@ -26,4 +26,5 @@ class Assets { static const String calendarIcon = "assets/images/calendar_icon.svg"; static const String deviceNoteIcon = "assets/images/device_note.svg"; static const String timeIcon = "assets/images/time_icon.svg"; + static const String emptyTable = "assets/images/empty_table.svg"; } diff --git a/lib/utils/constants/const.dart b/lib/utils/constants/const.dart index 7afa399d..77beff69 100644 --- a/lib/utils/constants/const.dart +++ b/lib/utils/constants/const.dart @@ -1,6 +1,4 @@ - - enum AccessType { onlineOnetime, onlineMultiple, @@ -43,8 +41,6 @@ extension AccessTypeExtension on AccessType { - - enum DeviseStatus { online, offline, @@ -74,6 +70,40 @@ extension OnlineTypeExtension on DeviseStatus { } +enum AccessStatus { + expired , + effective , + toBeEffective, +} + +extension AccessStatusExtension on AccessStatus { + String get value { + switch (this) { + case AccessStatus.expired: + return "Expired"; + case AccessStatus.effective: + return "Effective" ; + case AccessStatus.toBeEffective: + return "To be effective"; + + } + } + + static AccessStatus fromString(String value) { + switch (value) { + case "EXPIRED" : + return AccessStatus.expired; + case "EFFECTIVE" : + return AccessStatus.effective; + case "TO_BE_EFFECTIVE": + return AccessStatus.toBeEffective; + default: + throw ArgumentError("Invalid access type: $value"); + } + } +} + +