diff --git a/lib/pages/access_management/bloc/access_bloc.dart b/lib/pages/access_management/bloc/access_bloc.dart index fb66408a..94b0992f 100644 --- a/lib/pages/access_management/bloc/access_bloc.dart +++ b/lib/pages/access_management/bloc/access_bloc.dart @@ -107,26 +107,28 @@ class AccessBloc extends Bloc { Future _filterData(FilterDataEvent event, Emitter emit) async { emit(AccessLoaded()); try { + // Convert search text to lower case for case-insensitive search + final searchText = event.passwordName?.toLowerCase() ?? ''; + filteredData = data.where((item) { bool matchesCriteria = true; // Convert timestamp to DateTime and extract date component DateTime effectiveDate = - DateTime.fromMillisecondsSinceEpoch(int.parse(item.effectiveTime.toString()) * 1000) - .toUtc() - .toLocal(); + DateTime.fromMillisecondsSinceEpoch(int.parse(item.effectiveTime.toString()) * 1000) + .toUtc() + .toLocal(); DateTime invalidDate = - DateTime.fromMillisecondsSinceEpoch(int.parse(item.invalidTime.toString()) * 1000) - .toUtc() - .toLocal(); + DateTime.fromMillisecondsSinceEpoch(int.parse(item.invalidTime.toString()) * 1000) + .toUtc() + .toLocal(); DateTime effectiveDateOnly = - DateTime(effectiveDate.year, effectiveDate.month, effectiveDate.day); + DateTime(effectiveDate.year, effectiveDate.month, effectiveDate.day); DateTime invalidDateOnly = DateTime(invalidDate.year, invalidDate.month, invalidDate.day); - // Filter by password name - if (event.passwordName != null && event.passwordName!.isNotEmpty) { - final bool matchesName = - item.passwordName != null && item.passwordName.contains(event.passwordName); + // Filter by password name, making the search case-insensitive + if (searchText.isNotEmpty) { + final bool matchesName = item.passwordName.toString().toLowerCase().contains(searchText); if (!matchesName) { matchesCriteria = false; } @@ -135,7 +137,7 @@ class AccessBloc extends Bloc { // Filter by start date only if (event.startTime != null && event.endTime == null) { DateTime startDateOnly = - DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000).toUtc().toLocal(); + DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000).toUtc().toLocal(); startDateOnly = DateTime(startDateOnly.year, startDateOnly.month, startDateOnly.day); if (effectiveDateOnly.isBefore(startDateOnly)) { matchesCriteria = false; @@ -145,7 +147,7 @@ class AccessBloc extends Bloc { // Filter by end date only if (event.endTime != null && event.startTime == null) { DateTime endDateOnly = - DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000).toUtc().toLocal(); + DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000).toUtc().toLocal(); endDateOnly = DateTime(endDateOnly.year, endDateOnly.month, endDateOnly.day); if (invalidDateOnly.isAfter(endDateOnly)) { matchesCriteria = false; @@ -155,9 +157,9 @@ class AccessBloc extends Bloc { // Filter by both start date and end date if (event.startTime != null && event.endTime != null) { DateTime startDateOnly = - DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000).toUtc().toLocal(); + DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000).toUtc().toLocal(); DateTime endDateOnly = - DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000).toUtc().toLocal(); + DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000).toUtc().toLocal(); startDateOnly = DateTime(startDateOnly.year, startDateOnly.month, startDateOnly.day); endDateOnly = DateTime(endDateOnly.year, endDateOnly.month, endDateOnly.day); if (effectiveDateOnly.isBefore(startDateOnly) || invalidDateOnly.isAfter(endDateOnly)) { @@ -183,6 +185,8 @@ class AccessBloc extends Bloc { } } + + resetSearch(ResetSearch event, Emitter emit) async { emit(AccessLoaded()); startTime = 'Start Time'; diff --git a/lib/pages/access_management/model/password_model.dart b/lib/pages/access_management/model/password_model.dart index 8436ef56..50c03090 100644 --- a/lib/pages/access_management/model/password_model.dart +++ b/lib/pages/access_management/model/password_model.dart @@ -30,7 +30,7 @@ class PasswordModel { effectiveTime: json['effectiveTime'], passwordCreated: json['passwordCreated'], createdTime: json['createdTime'], - passwordName: json['passwordName'] ?? 'No name', // New field + passwordName: json['passwordName']??'No Name', passwordStatus: AccessStatusExtension.fromString(json['passwordStatus']), passwordType: AccessTypeExtension.fromString(json['passwordType']), deviceUuid: json['deviceUuid'], diff --git a/lib/pages/access_management/view/access_management.dart b/lib/pages/access_management/view/access_management.dart index 5652e2cd..0d4e3a19 100644 --- a/lib/pages/access_management/view/access_management.dart +++ b/lib/pages/access_management/view/access_management.dart @@ -27,8 +27,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { final isLargeScreen = isLargeScreenSize(context); final isSmallScreen = isSmallScreenSize(context); final isHalfMediumScreen = isHafMediumScreenSize(context); - final padding = - isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15); + final padding = isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15); return WebScaffold( enableMenuSideba: false, @@ -38,17 +37,23 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { style: Theme.of(context).textTheme.headlineLarge, ), ), - centerBody: Text( - 'Physical Access', - style: Theme.of(context) - .textTheme - .headlineMedium! - .copyWith(color: Colors.white), + centerBody: Wrap( + children: [ + Padding( + padding: EdgeInsets.only(left: MediaQuery.of(context).size.width * 0.09), + child: Align( + alignment: Alignment.bottomLeft, + child: Text( + 'Physical Access', + style: Theme.of(context).textTheme.headlineMedium!.copyWith(color: Colors.white), + ), + ), + ), + ], ), rightBody: const NavigateHomeGridView(), scaffoldBody: BlocProvider( - create: (BuildContext context) => - AccessBloc()..add(FetchTableData()), + create: (BuildContext context) => AccessBloc()..add(FetchTableData()), child: BlocConsumer( listener: (context, state) {}, builder: (context, state) { @@ -83,6 +88,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { Expanded( child: DynamicTable( uuidIndex: 1, + withSelectAll: true, isEmpty: filteredData.isEmpty, withCheckBox: false, size: MediaQuery.of(context).size, @@ -98,7 +104,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { ], data: filteredData.map((item) { return [ - item.passwordName.toString(), + item.passwordName, item.passwordType.value, ('${accessBloc.timestampToDate(item.effectiveTime)} - ${accessBloc.timestampToDate(item.invalidTime)}'), item.deviceUuid.toString(), @@ -114,8 +120,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { }))); } - Wrap _buildVisitorAdminPasswords( - BuildContext context, AccessBloc accessBloc) { + Wrap _buildVisitorAdminPasswords(BuildContext context, AccessBloc accessBloc) { return Wrap( spacing: 10, runSpacing: 10, @@ -141,8 +146,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { borderRadius: 8, child: Text( '+ Create Visitor Password ', - style: context.textTheme.titleSmall! - .copyWith(color: Colors.white, fontSize: 12), + style: context.textTheme.titleSmall!.copyWith(color: Colors.white, fontSize: 12), )), ), Container( @@ -154,8 +158,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { backgroundColor: ColorsManager.whiteColors, child: Text( 'Admin Password', - style: context.textTheme.titleSmall! - .copyWith(color: Colors.black, fontSize: 12), + style: context.textTheme.titleSmall!.copyWith(color: Colors.black, fontSize: 12), )), ), ], @@ -172,15 +175,14 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { width: 250, child: CustomWebTextField( controller: accessBloc.passwordName, - height: 38, - isRequired: true, + height: 43, + isRequired: false, textFieldName: 'Name', description: '', ), ), const SizedBox(width: 15), SizedBox( - height: 70, child: DateTimeWebWidget( icon: Assets.calendarIcon, isRequired: false, @@ -200,8 +202,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { SearchResetButtons( onSearch: () { accessBloc.add(FilterDataEvent( - selectedTabIndex: - BlocProvider.of(context).selectedIndex, + selectedTabIndex: BlocProvider.of(context).selectedIndex, passwordName: accessBloc.passwordName.text.toLowerCase(), startTime: accessBloc.effectiveTimeTimeStamp, endTime: accessBloc.expirationTimeTimeStamp)); @@ -246,8 +247,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { SearchResetButtons( onSearch: () { accessBloc.add(FilterDataEvent( - selectedTabIndex: - BlocProvider.of(context).selectedIndex, + selectedTabIndex: BlocProvider.of(context).selectedIndex, passwordName: accessBloc.passwordName.text.toLowerCase(), startTime: accessBloc.effectiveTimeTimeStamp, endTime: accessBloc.expirationTimeTimeStamp)); diff --git a/lib/pages/auth/bloc/auth_bloc.dart b/lib/pages/auth/bloc/auth_bloc.dart index ef433028..4e4a7b0e 100644 --- a/lib/pages/auth/bloc/auth_bloc.dart +++ b/lib/pages/auth/bloc/auth_bloc.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; @@ -81,21 +82,25 @@ class AuthBloc extends Bloc { _timer?.cancel(); emit(const TimerState(isButtonEnabled: true, remainingTime: 0)); emit(SuccessForgetState()); - } else if (response == "You entered wrong otp") { - forgetValidate = 'Wrong one time password.'; - emit(AuthInitialState()); - } else if (response == "OTP expired") { - forgetValidate = 'One time password has been expired.'; - emit(AuthInitialState()); } - } catch (failure) { - // forgetValidate='Invalid Credentials!'; - emit(AuthInitialState()); - // emit(FailureForgetState(error: failure.toString())); } + on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + if(errorMessage=='this email is not registered'){ + validate='Invalid Credentials!'; + emit(AuthInitialState()); + }else if (errorMessage == "You entered wrong otp") { + forgetValidate = 'Wrong one time password.'; + emit(AuthInitialState()); + } else if (errorMessage == "OTP expired") { + forgetValidate = 'One time password has been expired.'; + emit(AuthInitialState()); + } + + } } -//925207 String? validateCode(String? value) { if (value == null || value.isEmpty) { return 'Code is required'; @@ -178,15 +183,15 @@ class AuthBloc extends Bloc { emit(LoginInitial()); } - checkOtpCode( - ChangePasswordEvent event, - Emitter emit, - ) async { - emit(LoadingForgetState()); - await AuthenticationAPI.verifyOtp( - email: forgetEmailController.text, otpCode: forgetOtp.text); - emit(SuccessForgetState()); - } + // checkOtpCode( + // ChangePasswordEvent event, + // Emitter emit, + // ) async { + // emit(LoadingForgetState()); + // await AuthenticationAPI.verifyOtp( + // email: forgetEmailController.text, otpCode: forgetOtp.text); + // emit(SuccessForgetState()); + // } void _passwordVisible(PasswordVisibleEvent event, Emitter emit) { emit(AuthLoading()); diff --git a/lib/pages/auth/bloc/auth_event.dart b/lib/pages/auth/bloc/auth_event.dart index 0026554c..fa7e86b3 100644 --- a/lib/pages/auth/bloc/auth_event.dart +++ b/lib/pages/auth/bloc/auth_event.dart @@ -49,9 +49,13 @@ class UpdateTimerEvent extends AuthEvent { const UpdateTimerEvent({required this.remainingTime, required this.isButtonEnabled}); } -class ChangePasswordEvent extends AuthEvent {} +class ChangePasswordEvent extends AuthEvent { -class SendOtpEvent extends AuthEvent {} +} + +class SendOtpEvent extends AuthEvent { + +} class PasswordVisibleEvent extends AuthEvent { final bool? newValue; diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index 907569ee..efc580b3 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -1,3 +1,4 @@ +import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -148,44 +149,7 @@ class ForgetPasswordWebPage extends StatelessWidget { ), const SizedBox(height: 10), SizedBox( - child: DropdownButtonFormField( - validator: forgetBloc.validateRegion, - icon: const Icon( - Icons.keyboard_arrow_down_outlined, - ), - decoration: - textBoxDecoration()!.copyWith( - hintText: null, - ), - hint: SizedBox( - width: size.width * 0.12, - child: const Align( - alignment: Alignment.centerLeft, - child: Text( - 'Select your region/country', - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, - ), - ), - ), - isDense: true, - style: const TextStyle( - color: Colors.black), - items: forgetBloc.regionList! - .map((RegionModel region) { - return DropdownMenuItem( - value: region.id, - child: SizedBox( - width: size.width * 0.06, - child: Text(region.name)), - ); - }).toList(), - onChanged: (String? value) { - forgetBloc.add(SelectRegionEvent( - val: value!, - )); - }, - ), + child: _buildDropdownField(context, forgetBloc, size) ) ], ), @@ -208,11 +172,12 @@ class ForgetPasswordWebPage extends StatelessWidget { SizedBox( child: TextFormField( validator: forgetBloc.validateEmail, - controller: - forgetBloc.forgetEmailController, decoration: textBoxDecoration()! .copyWith( - hintText: 'Enter your email'), + hintText: 'Enter your email', + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400)), style: const TextStyle( color: Colors.black), ), @@ -244,13 +209,15 @@ class ForgetPasswordWebPage extends StatelessWidget { decoration: textBoxDecoration()!.copyWith( hintText: 'Enter Code', + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400), suffixIcon: SizedBox( width: 100, child: Center( child: InkWell( onTap: state is TimerState && - !state - .isButtonEnabled && + !state.isButtonEnabled && state.remainingTime != 1 ? null @@ -261,10 +228,8 @@ class ForgetPasswordWebPage extends StatelessWidget { child: Text( 'Get Code ${state is TimerState && !state.isButtonEnabled && state.remainingTime != 1 ? "(${forgetBloc.formattedTime(state.remainingTime)}) " : ""}', style: TextStyle( - color: state - is TimerState && - !state - .isButtonEnabled + color: state is TimerState && + !state.isButtonEnabled ? Colors.grey : ColorsManager .btnColor, @@ -278,8 +243,7 @@ class ForgetPasswordWebPage extends StatelessWidget { color: Colors.black), ), ), - if (forgetBloc.forgetValidate != - '') // Check if there is a validation message + if (forgetBloc.forgetValidate != '') // Check if there is a validation message Padding( padding: const EdgeInsets.only(top: 8.0), @@ -311,18 +275,16 @@ class ForgetPasswordWebPage extends StatelessWidget { const SizedBox(height: 10), SizedBox( child: TextFormField( - validator: - forgetBloc.passwordValidator, - keyboardType: - TextInputType.visiblePassword, - controller: forgetBloc - .forgetPasswordController, - decoration: - textBoxDecoration()!.copyWith( + validator: forgetBloc.passwordValidator, + keyboardType: TextInputType.visiblePassword, + controller: forgetBloc.forgetPasswordController, + decoration: textBoxDecoration()!.copyWith( hintText: 'At least 8 characters', + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400), ), - style: const TextStyle( - color: Colors.black), + style: const TextStyle(color: Colors.black), ), ), ], @@ -346,8 +308,7 @@ class ForgetPasswordWebPage extends StatelessWidget { if (forgetBloc .forgetFormKey.currentState! .validate()) { - forgetBloc - .add(ChangePasswordEvent()); + forgetBloc.add(ChangePasswordEvent()); } }, ), @@ -355,12 +316,14 @@ class ForgetPasswordWebPage extends StatelessWidget { ], ), const SizedBox(height: 10.0), - SizedBox( - child: Text( - forgetBloc.validate, - style: const TextStyle( - fontWeight: FontWeight.w700, - color: ColorsManager.red), + Center( + child: SizedBox( + child: Text( + forgetBloc.validate, + style: const TextStyle( + fontWeight: FontWeight.w700, + color: ColorsManager.red), + ), ), ), SizedBox( @@ -410,4 +373,109 @@ class ForgetPasswordWebPage extends StatelessWidget { ), )); } + Widget _buildDropdownField( + BuildContext context, AuthBloc loginBloc, Size size) { + final TextEditingController textEditingController = TextEditingController(); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Country/Region", + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontSize: 14, + fontWeight: FontWeight.w400, + ), + ), + const SizedBox(height: 10), + Container( + height: 50, + decoration: const BoxDecoration( + color: ColorsManager.boxColor, + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + width: size.width * 0.9, + child: DropdownButtonHideUnderline( + child: DropdownButton2( + style: TextStyle(color: Colors.black), + isExpanded: true, + hint: Text( + 'Select your region/country', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400, + ), + overflow: TextOverflow.ellipsis, + ), + items: loginBloc.regionList!.map((RegionModel region) { + return DropdownMenuItem( + value: region.id, // Use region.id as the value + child: Text( + region.name, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ); + }).toList(), + value: loginBloc.regionList!.any( + (region) => region.id == loginBloc.regionUuid,) + ? loginBloc.regionUuid + : null, + onChanged: (String? value) { + if (value != null) { + + loginBloc.add(SelectRegionEvent( + val: value, + )); + } + }, + buttonStyleData: const ButtonStyleData( + padding: EdgeInsets.symmetric(horizontal: 16), + height: 40, + width: double.infinity, + ), + dropdownStyleData: DropdownStyleData( + maxHeight: size.height * 0.70, + ), + menuItemStyleData: const MenuItemStyleData( + height: 40, + ), + dropdownSearchData: DropdownSearchData( + searchController: textEditingController, + searchInnerWidgetHeight: 50, + searchInnerWidget: Container( + height: 50, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + child: TextFormField( + style: const TextStyle(color: Colors.black), + controller: textEditingController, + decoration: textBoxDecoration()!.copyWith( + errorStyle: const TextStyle(height: 0), + contentPadding: const EdgeInsets.symmetric( + vertical: 12, + horizontal: 10, + ), + ), + ), + ), + searchMatchFn: (item, searchValue) { + // Use the item's child text (region name) for searching. + final regionName = (item.child as Text).data?.toLowerCase() ?? ''; + final search = searchValue.toLowerCase().trim(); + // Debugging print statement to ensure values are captured correctly. + // Return true if the region name contains the search term. + return regionName.contains(search); + }, + ), + onMenuStateChange: (isOpen) { + if (!isOpen) { + textEditingController.clear(); + } + }, + ), + ), + ), + ], + ); + } } diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index 1c638287..af211308 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -1,3 +1,4 @@ +import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -23,7 +24,8 @@ class LoginWebPage extends StatefulWidget { State createState() => _LoginWebPageState(); } -class _LoginWebPageState extends State with HelperResponsiveLayout { +class _LoginWebPageState extends State + with HelperResponsiveLayout { @override Widget build(BuildContext context) { return Scaffold( @@ -58,7 +60,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout _scrollController = ScrollController(); void _scrollToCenter() { - final double middlePosition = _scrollController.position.maxScrollExtent / 2; + final double middlePosition = + _scrollController.position.maxScrollExtent / 2; _scrollController.animateTo( middlePosition, duration: const Duration(seconds: 1), @@ -120,7 +123,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout const Spacer(), Expanded( flex: 2, - child: _buildLoginFormFields(context, loginBloc, size), + child: _buildLoginFormFields( + context, loginBloc, size), ), const Spacer(), ], @@ -131,12 +135,14 @@ class _LoginWebPageState extends State with HelperResponsiveLayout ), ), ), - if (state is AuthLoading) const Center(child: CircularProgressIndicator()) + if (state is AuthLoading) + const Center(child: CircularProgressIndicator()) ], ); } - Widget _buildLoginFormFields(BuildContext context, AuthBloc loginBloc, Size size) { + Widget _buildLoginFormFields( + BuildContext context, AuthBloc loginBloc, Size size) { return Container( decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), @@ -146,8 +152,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout child: Form( key: loginBloc.loginFormKey, child: Padding( - padding: - EdgeInsets.symmetric(horizontal: size.width * 0.02, vertical: size.width * 0.003), + padding: EdgeInsets.symmetric( + horizontal: size.width * 0.02, vertical: size.width * 0.003), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, @@ -175,88 +181,112 @@ class _LoginWebPageState extends State with HelperResponsiveLayout ); } - Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) { + + Widget _buildDropdownField( + BuildContext context, AuthBloc loginBloc, Size size) { + final TextEditingController textEditingController = TextEditingController(); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( "Country/Region", - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(fontSize: 14, fontWeight: FontWeight.w400), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontSize: 14, + fontWeight: FontWeight.w400, + ), ), const SizedBox(height: 10), - SizedBox( - width: size.width * 0.8, - child: LayoutBuilder( - builder: (context, constraints) { - return DropdownButtonFormField( - value: loginBloc.regionList!.any((region) => region.id == loginBloc.regionUuid) - ? loginBloc.regionUuid - : null, - validator: loginBloc.validateRegion, - icon: const Icon( - Icons.keyboard_arrow_down_outlined, - size: 20, + Container( + height: 50, + decoration: const BoxDecoration( + color: ColorsManager.boxColor, + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + width: size.width * 0.9, + child: DropdownButtonHideUnderline( + child: DropdownButton2( + style: TextStyle(color: Colors.black), + isExpanded: true, + hint: Text( + 'Select your region/country', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400, ), - decoration: textBoxDecoration()!.copyWith( - errorStyle: const TextStyle(height: 0), - contentPadding: const EdgeInsets.symmetric( - vertical: 12, - horizontal: 10, + overflow: TextOverflow.ellipsis, + ), + items: loginBloc.regionList!.map((RegionModel region) { + return DropdownMenuItem( + value: region.id, // Use region.id as the value + child: Text( + region.name, + overflow: TextOverflow.ellipsis, + maxLines: 1, ), - ), - hint: Text( - 'Select your region/country', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400), - overflow: TextOverflow.ellipsis, - ), - isDense: true, - style: const TextStyle(color: Colors.black), - items: loginBloc.regionList!.map((RegionModel region) { - return DropdownMenuItem( - value: region.id, - child: Container( - constraints: BoxConstraints(maxWidth: constraints.maxWidth - 40), - child: Text( - region.name, - overflow: TextOverflow.ellipsis, - maxLines: 1, + ); + }).toList(), + value: loginBloc.regionList!.any( + (region) => region.id == loginBloc.regionUuid,) + ? loginBloc.regionUuid + : null, + onChanged: (String? value) { + if (value != null) { + loginBloc.add(CheckEnableEvent()); + loginBloc.add(SelectRegionEvent(val: value)); + } + }, + buttonStyleData: const ButtonStyleData( + padding: EdgeInsets.symmetric(horizontal: 16), + height: 40, + width: double.infinity, + ), + dropdownStyleData: DropdownStyleData( + maxHeight: size.height * 0.70, + ), + menuItemStyleData: const MenuItemStyleData( + height: 40, + ), + dropdownSearchData: DropdownSearchData( + searchController: textEditingController, + searchInnerWidgetHeight: 50, + searchInnerWidget: Container( + height: 50, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + child: TextFormField( + style: const TextStyle(color: Colors.black), + controller: textEditingController, + decoration: textBoxDecoration()!.copyWith( + errorStyle: const TextStyle(height: 0), + contentPadding: const EdgeInsets.symmetric( + vertical: 12, + horizontal: 10, ), ), - ); - }).toList(), - onChanged: (String? value) { - loginBloc.add(CheckEnableEvent()); - loginBloc.add(SelectRegionEvent(val: value!)); + ), + ), + searchMatchFn: (item, searchValue) { + // Use the item's child text (region name) for searching. + final regionName = (item.child as Text).data?.toLowerCase() ?? ''; + final search = searchValue.toLowerCase().trim(); + // Debugging print statement to ensure values are captured correctly. + // Return true if the region name contains the search term. + return regionName.contains(search); }, - dropdownColor: Colors.white, - menuMaxHeight: size.height * 0.45, - selectedItemBuilder: (context) { - return loginBloc.regionList!.map((region) { - return Container( - constraints: BoxConstraints(maxWidth: constraints.maxWidth - 40), - child: Text( - region.name, - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ); - }).toList(); - }, - ); - }, + ), + onMenuStateChange: (isOpen) { + if (!isOpen) { + textEditingController.clear(); + } + }, + ), ), ), ], ); } + Widget _buildEmailField(BuildContext context, AuthBloc loginBloc) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -280,10 +310,9 @@ class _LoginWebPageState extends State with HelperResponsiveLayout decoration: textBoxDecoration()!.copyWith( errorStyle: const TextStyle(height: 0), hintText: 'Enter your email address', - hintStyle: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400)), + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400)), style: const TextStyle(color: Colors.black), ), ), @@ -315,17 +344,18 @@ class _LoginWebPageState extends State with HelperResponsiveLayout controller: loginBloc.loginPasswordController, decoration: textBoxDecoration()!.copyWith( hintText: 'At least 8 characters', - hintStyle: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400), + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, fontWeight: FontWeight.w400), suffixIcon: IconButton( onPressed: () { - loginBloc.add(PasswordVisibleEvent(newValue: loginBloc.obscureText)); + loginBloc.add( + PasswordVisibleEvent(newValue: loginBloc.obscureText)); }, icon: SizedBox( child: SvgPicture.asset( - loginBloc.obscureText ? Assets.visiblePassword : Assets.invisiblePassword, + loginBloc.obscureText + ? Assets.visiblePassword + : Assets.invisiblePassword, height: 15, width: 15, ), @@ -353,10 +383,10 @@ class _LoginWebPageState extends State with HelperResponsiveLayout }, child: Text( "Forgot Password?", - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.black, fontSize: 14, fontWeight: FontWeight.w400), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.black, + fontSize: 14, + fontWeight: FontWeight.w400), ), ), ], @@ -419,7 +449,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout ); } - Widget _buildSignInButton(BuildContext context, AuthBloc loginBloc, Size size) { + Widget _buildSignInButton( + BuildContext context, AuthBloc loginBloc, Size size) { return Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -460,7 +491,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout SizedBox( child: Text( loginBloc.validate, - style: const TextStyle(fontWeight: FontWeight.w700, color: ColorsManager.red), + style: const TextStyle( + fontWeight: FontWeight.w700, color: ColorsManager.red), ), ) ], diff --git a/lib/pages/common/custom_table.dart b/lib/pages/common/custom_table.dart index a1532b68..9d2fe949 100644 --- a/lib/pages/common/custom_table.dart +++ b/lib/pages/common/custom_table.dart @@ -5,11 +5,13 @@ import 'package:syncrow_web/utils/constants/assets.dart'; class DynamicTable extends StatefulWidget { final List headers; + final String? tableName; final List> data; final BoxDecoration? headerDecoration; final BoxDecoration? cellDecoration; final Size size; final bool withCheckBox; + final bool withSelectAll; final bool isEmpty; final void Function(bool?)? selectAll; final void Function(int, bool, dynamic)? onRowSelected; @@ -20,8 +22,10 @@ class DynamicTable extends StatefulWidget { required this.headers, required this.data, required this.size, + this.tableName, required this.isEmpty, required this.withCheckBox, + required this.withSelectAll, this.headerDecoration, this.cellDecoration, this.selectAll, @@ -36,6 +40,7 @@ class DynamicTable extends StatefulWidget { class _DynamicTableState extends State { late List _selected; + bool _selectAll = false; @override void initState() { @@ -71,6 +76,17 @@ class _DynamicTableState extends State { }); } + + void _toggleSelectAll(bool? value) { + setState(() { + _selectAll = value ?? false; + _selected = List.filled(widget.data.length, _selectAll); + if (widget.selectAll != null) { + widget.selectAll!(_selectAll); + } + }); + } + @override Widget build(BuildContext context) { return Container( @@ -108,7 +124,8 @@ class _DynamicTableState extends State { height: 15, ), Text( - 'No Devices', + // no password + widget.tableName=='AccessManagement'? 'No Password ' : 'No Devices', style: Theme.of(context) .textTheme .bodySmall! @@ -162,7 +179,7 @@ class _DynamicTableState extends State { ), child: Checkbox( value: _selected.every((element) => element == true), - onChanged: null, + onChanged:widget.withSelectAll?_toggleSelectAll:null, ), ); } diff --git a/lib/pages/common/text_field/custom_web_textfield.dart b/lib/pages/common/text_field/custom_web_textfield.dart index 926a20f5..756463e2 100644 --- a/lib/pages/common/text_field/custom_web_textfield.dart +++ b/lib/pages/common/text_field/custom_web_textfield.dart @@ -32,21 +32,19 @@ class CustomWebTextField extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (isRequired) + Row( children: [ - Text( - '* ', + if (isRequired) + Text('* ', style: Theme.of(context) - .textTheme - .bodyMedium! + .textTheme.bodyMedium! .copyWith(color: Colors.red), ), Text( textFieldName, style: Theme.of(context) - .textTheme - .bodySmall! + .textTheme.bodySmall! .copyWith(color: Colors.black, fontSize: 13), ), ], @@ -70,15 +68,17 @@ class CustomWebTextField extends StatelessWidget { ), Container( height: height ?? 35, - decoration: containerDecoration - .copyWith(color: const Color(0xFFF5F6F7), boxShadow: [ + decoration: containerDecoration.copyWith( + color: const Color(0xFFF5F6F7), + boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.3), spreadRadius: 2, blurRadius: 3, offset: const Offset(1, 1), // changes position of shadow ), - ]), + ] + ), child: TextFormField( validator: validator, controller: controller, diff --git a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart index 7f40bf37..ab2f07fc 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart @@ -55,71 +55,68 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { 'Low Battery ($lowBatteryCount)', ]; - return CustomScrollView( - slivers: [ - SliverToBoxAdapter( - child: Container( - padding: isLargeScreenSize(context) - ? const EdgeInsets.all(30) - : const EdgeInsets.all(15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - FilterWidget( - size: MediaQuery.of(context).size, - tabs: tabs, - selectedIndex: selectedIndex, - onTabChanged: (index) { - context - .read() - .add(SelectedFilterChanged(index)); - }, - ), - const SizedBox(height: 20), - const DeviceSearchFilters(), - const SizedBox(height: 12), - Container( - height: 45, - width: 100, - decoration: containerDecoration, - child: Center( - child: DefaultButton( - onPressed: isControlButtonEnabled - ? () { - final selectedDevice = context - .read() - .selectedDevices - .first; - showDialog( - context: context, - builder: (context) => DeviceControlDialog( - device: selectedDevice), - ); - } - : null, - borderRadius: 9, - child: Text( - 'Control', - style: TextStyle( - fontSize: 12, - color: isControlButtonEnabled - ? Colors.white - : Colors.grey, - ), + return Column( + children: [ + Container( + padding: isLargeScreenSize(context) + ? const EdgeInsets.all(30) + : const EdgeInsets.all(15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + FilterWidget( + size: MediaQuery.of(context).size, + tabs: tabs, + selectedIndex: selectedIndex, + onTabChanged: (index) { + context.read() + .add(SelectedFilterChanged(index)); + }, + ), + const SizedBox(height: 20), + const DeviceSearchFilters(), + const SizedBox(height: 12), + Container( + height: 45, + width: 100, + decoration: containerDecoration, + child: Center( + child: DefaultButton( + onPressed: isControlButtonEnabled + ? () { + final selectedDevice = context + .read() + .selectedDevices.first; + showDialog( + context: context, + builder: (context) => DeviceControlDialog( + device: selectedDevice), + ); + } + : null, + borderRadius: 9, + child: Text( + 'Control', + style: TextStyle( + fontSize: 12, + color: isControlButtonEnabled + ? Colors.white + : Colors.grey, ), ), ), ), - ], - ), + ), + ], ), ), - SliverFillRemaining( + Expanded( child: Padding( padding: isLargeScreenSize(context) ? const EdgeInsets.all(30) : const EdgeInsets.all(15), child: DynamicTable( + withSelectAll: false, cellDecoration: containerDecoration, onRowSelected: (index, isSelected, row) { final selectedDevice = devicesToShow[index]; diff --git a/lib/pages/visitor_password/bloc/visitor_password_bloc.dart b/lib/pages/visitor_password/bloc/visitor_password_bloc.dart index f1dbe47c..02f5ef0a 100644 --- a/lib/pages/visitor_password/bloc/visitor_password_bloc.dart +++ b/lib/pages/visitor_password/bloc/visitor_password_bloc.dart @@ -219,8 +219,8 @@ class VisitorPasswordBloc extends Bloc[ TextButton( onPressed: () { + Navigator.of(context).pop(true); }, child: const Text('OK'), diff --git a/lib/pages/visitor_password/view/add_device_dialog.dart b/lib/pages/visitor_password/view/add_device_dialog.dart index 38b08f6c..1a116b06 100644 --- a/lib/pages/visitor_password/view/add_device_dialog.dart +++ b/lib/pages/visitor_password/view/add_device_dialog.dart @@ -35,12 +35,12 @@ class AddDeviceDialog extends StatelessWidget { backgroundColor: Colors.white, title: Text( 'Add Accessible Device', - style: Theme.of(context).textTheme.headlineLarge!.copyWith( - fontWeight: FontWeight.w400, - fontSize: 24, - color: Colors.black), + style: Theme.of(context) + .textTheme + .headlineLarge! + .copyWith(fontWeight: FontWeight.w400, fontSize: 24, color: Colors.black), ), - content: Container( + content: SizedBox( height: MediaQuery.of(context).size.height / 1.7, width: MediaQuery.of(context).size.width / 2, child: Padding( @@ -68,17 +68,14 @@ class AddDeviceDialog extends StatelessWidget { ), Text( 'Only online accessible devices can be added', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - fontWeight: FontWeight.w400, - fontSize: 12, - color: ColorsManager.grayColor), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w400, + fontSize: 12, + color: ColorsManager.grayColor), ), ], )), - SizedBox( + const SizedBox( height: 20, ), const SizedBox( @@ -93,7 +90,7 @@ class AddDeviceDialog extends StatelessWidget { flex: 4, child: CustomWebTextField( controller: visitorBloc.deviceNameController, - isRequired: true, + isRequired: false, textFieldName: 'Device Name', description: '', ), @@ -103,7 +100,7 @@ class AddDeviceDialog extends StatelessWidget { flex: 4, child: CustomWebTextField( controller: visitorBloc.deviceIdController, - isRequired: true, + isRequired: false, textFieldName: 'Device ID', description: '', ), @@ -113,7 +110,7 @@ class AddDeviceDialog extends StatelessWidget { flex: 4, child: CustomWebTextField( controller: visitorBloc.unitNameController, - isRequired: true, + isRequired: false, textFieldName: 'Unit Name', description: '', ), @@ -155,8 +152,7 @@ class AddDeviceDialog extends StatelessWidget { visitorBloc.deviceNameController.clear(); visitorBloc.deviceIdController.clear(); visitorBloc.unitNameController.clear(); - visitorBloc.add( - FetchDevice()); // Reset to original list + visitorBloc.add(FetchDevice()); // Reset to original list }, ), ), @@ -168,14 +164,15 @@ class AddDeviceDialog extends StatelessWidget { flex: 3, child: state is TableLoaded ? DynamicTable( + uuidIndex: 1, + withSelectAll: true, initialSelectedIds: selectedDeviceIds, cellDecoration: containerDecoration, isEmpty: visitorBloc.data.isEmpty, selectAll: (p0) { visitorBloc.selectedDeviceIds.clear(); for (var item in state.data) { - visitorBloc - .add(SelectDeviceEvent(item.uuid)); + visitorBloc.add(SelectDeviceEvent(item.uuid)); } }, onRowSelected: (index, isSelected, row) { @@ -184,7 +181,6 @@ class AddDeviceDialog extends StatelessWidget { }, withCheckBox: true, size: size * 0.5, - uuidIndex: 1, headers: const [ 'Device Name', 'Device ID', diff --git a/lib/pages/visitor_password/view/visitor_password_dialog.dart b/lib/pages/visitor_password/view/visitor_password_dialog.dart index 591b6ff6..ad11b30f 100644 --- a/lib/pages/visitor_password/view/visitor_password_dialog.dart +++ b/lib/pages/visitor_password/view/visitor_password_dialog.dart @@ -87,7 +87,8 @@ class VisitorPasswordDialog extends StatelessWidget { ], )) .then((v) { - Navigator.of(context).pop(); + Navigator.of(context).pop(true); + }); } else if (state is FailedState) { visitorBloc.stateDialog( @@ -211,28 +212,28 @@ class VisitorPasswordDialog extends StatelessWidget { }, ), ), - SizedBox( - width: size.width * 0.12, - child: RadioListTile( - contentPadding: EdgeInsets.zero, - title: Text( - 'Dynamic Password', - style: text, - ), - value: 'Dynamic Password', - groupValue: (state is PasswordTypeSelected) - ? state.selectedType - : visitorBloc.accessTypeSelected, - onChanged: (String? value) { - if (value != null) { - context - .read() - .add(SelectPasswordType(value)); - visitorBloc.usageFrequencySelected = ''; - } - }, - ), - ), + // SizedBox( + // width: size.width * 0.12, + // child: RadioListTile( + // contentPadding: EdgeInsets.zero, + // title: Text( + // 'Dynamic Password', + // style: text, + // ), + // value: 'Dynamic Password', + // groupValue: (state is PasswordTypeSelected) + // ? state.selectedType + // : visitorBloc.accessTypeSelected, + // onChanged: (String? value) { + // if (value != null) { + // context + // .read() + // .add(SelectPasswordType(value)); + // visitorBloc.usageFrequencySelected = ''; + // } + // }, + // ), + // ), ], )), const Spacer( @@ -256,14 +257,14 @@ class VisitorPasswordDialog extends StatelessWidget { color: ColorsManager.grayColor, fontSize: 9), ), - if (visitorBloc.accessTypeSelected == 'Dynamic Password') - Text( - 'Quick and short-acting password, only valid within 5 minutes after creation, the system randomly generates a digital password.', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.grayColor, - fontSize: 9), - ), + // if (visitorBloc.accessTypeSelected == 'Dynamic Password') + // Text( + // 'Quick and short-acting password, only valid within 5 minutes after creation, the system randomly generates a digital password.', + // style: Theme.of(context).textTheme.bodySmall!.copyWith( + // fontWeight: FontWeight.w400, + // color: ColorsManager.grayColor, + // fontSize: 9), + // ), const SizedBox( height: 20, ) @@ -323,8 +324,7 @@ class VisitorPasswordDialog extends StatelessWidget { : visitorBloc.usageFrequencySelected, onChanged: (String? value) { if (value != null) { - context - .read() + context.read() .add(SelectUsageFrequency(value)); } }, @@ -344,7 +344,7 @@ class VisitorPasswordDialog extends StatelessWidget { if (visitorBloc.usageFrequencySelected == 'One-Time' && visitorBloc.accessTypeSelected == 'Offline Password') Text( - 'Within the validity period, there is no limit to the number of times each device can be unlocked.', + 'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours', style: Theme.of(context).textTheme.bodySmall!.copyWith( color: ColorsManager.grayColor, fontSize: 9), ), @@ -380,11 +380,9 @@ class VisitorPasswordDialog extends StatelessWidget { endTime: () { if (visitorBloc.usageFrequencySelected == 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') { - visitorBloc.add( - SelectTimeEvent(context: context, isEffective: false)); + visitorBloc.add(SelectTimeEvent(context: context, isEffective: false)); } else { - visitorBloc.add(SelectTimeVisitorPassword( - context: context, isStart: false, isRepeat: false)); + visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false, isRepeat: false)); } }, startTime: () { @@ -398,13 +396,11 @@ class VisitorPasswordDialog extends StatelessWidget { } }, firstString: (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == 'Offline Password') + 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') ? visitorBloc.effectiveTime : visitorBloc.startTimeAccess.toString(), secondString: (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == 'Offline Password') + 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') ? visitorBloc.expirationTime : visitorBloc.endTimeAccess.toString(), icon: Assets.calendarIcon), @@ -528,9 +524,20 @@ class VisitorPasswordDialog extends StatelessWidget { if (visitorBloc.usageFrequencySelected == 'One-Time' && visitorBloc.accessTypeSelected == 'Offline Password') { setPasswordFunction(context, size, visitorBloc); - } else if (visitorBloc.accessTypeSelected == 'Dynamic Password') { - setPasswordFunction(context, size, visitorBloc); - } else { + } else if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Offline Password') { + if (visitorBloc.expirationTime != 'End Time' && + visitorBloc.effectiveTime != 'Start Time' ) { + setPasswordFunction(context, size, visitorBloc); + }else{ + visitorBloc.stateDialog( + context: context, + message: 'Please select Access Period to continue', + title: 'Access Period'); + } + } else if( + visitorBloc.endTimeAccess.toString()!='End Time' + &&visitorBloc.startTimeAccess.toString()!='Start Time') { if (visitorBloc.effectiveTimeTimeStamp != null && visitorBloc.expirationTimeTimeStamp != null) { if (isRepeat == true) { @@ -554,6 +561,11 @@ class VisitorPasswordDialog extends StatelessWidget { message: 'Please select Access Period to continue', title: 'Access Period'); } + }else{ + visitorBloc.stateDialog( + context: context, + message: 'Please select Access Period to continue', + title: 'Access Period'); } } else { visitorBloc.stateDialog( @@ -563,57 +575,6 @@ class VisitorPasswordDialog extends StatelessWidget { } } }, - - // onPressed: () { - // if (visitorBloc.forgetFormKey.currentState!.validate()) { - // if (visitorBloc.selectedDevices.isNotEmpty) { - // switch (visitorBloc.usageFrequencySelected) { - // case 'One-Time': - // if (visitorBloc.accessTypeSelected == 'Offline Password') { - // setPasswordFunction(context, size, visitorBloc); - // } else { - // visitorBloc.stateDialog( - // context: context, - // message: 'Invalid combination of Access Type and Usage Frequency.', - // title: 'Error', - // ); - // } - // break; - // default: - // if (visitorBloc.effectiveTimeTimeStamp != null && visitorBloc.expirationTimeTimeStamp != null) { - // if (isRepeat) { - // if (visitorBloc.expirationTime != 'End Time' && - // visitorBloc.effectiveTime != 'Start Time' && - // visitorBloc.selectedDays.isNotEmpty) { - // setPasswordFunction(context, size, visitorBloc); - // } else { - // visitorBloc.stateDialog( - // context: context, - // message: 'Please select days and fill start time and end time to continue', - // title: 'Access Period', - // ); - // } - // } else { - // setPasswordFunction(context, size, visitorBloc); - // } - // } else { - // visitorBloc.stateDialog( - // context: context, - // message: 'Please select Access Period to continue', - // title: 'Access Period', - // ); - // } - // break; - // } - // } else { - // visitorBloc.stateDialog( - // context: context, - // message: 'Please select devices to continue', - // title: 'Select Devices', - // ); - // } - // } - // }, borderRadius: 8, child: Text( 'Ok', @@ -723,39 +684,39 @@ class VisitorPasswordDialog extends StatelessWidget { borderRadius: 8, onPressed: () { Navigator.pop(context); - if (visitorBloc.accessTypeSelected == 'Dynamic Password') { - } else { - 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( - context: context, - 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(), - )); - } + 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( + context: context, + 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( diff --git a/lib/services/access_mang_api.dart b/lib/services/access_mang_api.dart index 3309e253..b99b75a9 100644 --- a/lib/services/access_mang_api.dart +++ b/lib/services/access_mang_api.dart @@ -22,7 +22,6 @@ class AccessMangApi { ); return response; } catch (e) { - debugPrint('Error fetching visitor passwords: $e'); return []; } } @@ -42,7 +41,6 @@ class AccessMangApi { ); return response; } catch (e) { - debugPrint('Error fetching $e'); return []; } } diff --git a/lib/services/auth_api.dart b/lib/services/auth_api.dart index 6573f3ad..a09fa7ba 100644 --- a/lib/services/auth_api.dart +++ b/lib/services/auth_api.dart @@ -25,7 +25,8 @@ class AuthenticationAPI { path: ApiEndpoints.forgetPassword, body: {"email": email, "password": password}, showServerMessage: true, - expectedResponseModel: (json) {}); + expectedResponseModel: (json) { + }); return response; } @@ -52,21 +53,17 @@ class AuthenticationAPI { return cooldown; } } else { - debugPrint('Error: ${e.response!.statusCode} - ${e.response!.statusMessage}'); return 1; } } else { - debugPrint('Error: ${e.message}'); return 1; } } catch (e) { - debugPrint('Unexpected Error: $e'); return 1; } } static Future verifyOtp({required String email, required String otpCode}) async { - try { final response = await HTTPService().post( path: ApiEndpoints.verifyOtp, body: {"email": email, "type": "PASSWORD", "otpCode": otpCode}, @@ -79,17 +76,7 @@ class AuthenticationAPI { } }); return response; - } on DioException catch (e) { - if (e.response != null) { - if (e.response!.statusCode == 400) { - final errorData = e.response!.data; - String errorMessage = errorData['message']; - return errorMessage; - } - } else { - debugPrint('Error: ${e.message}'); - } - } + } static Future> fetchRegion() async { diff --git a/pubspec.lock b/pubspec.lock index 9a9cd6a8..3da608f2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -89,6 +89,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + dropdown_button2: + dependency: "direct main" + description: + name: dropdown_button2 + sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1 + url: "https://pub.dev" + source: hosted + version: "2.3.9" + dropdown_search: + dependency: "direct main" + description: + name: dropdown_search + sha256: "55106e8290acaa97ed15bea1fdad82c3cf0c248dd410e651f5a8ac6870f783ab" + url: "https://pub.dev" + source: hosted + version: "5.0.6" equatable: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index a8e96a9b..ea0138ea 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,9 +43,11 @@ dependencies: get_it: ^7.6.7 flutter_secure_storage: ^9.2.2 shared_preferences: ^2.3.0 + dropdown_button2: ^2.3.9 data_table_2: ^2.5.15 go_router: intl: ^0.19.0 + dropdown_search: ^5.0.6 dev_dependencies: flutter_test: