Success dialog and Failed dialog changes with VisitorPasswordDialog

This commit is contained in:
mohammad
2024-08-23 22:16:48 +03:00
parent f5a7441b3c
commit cf1a21e121
19 changed files with 792 additions and 785 deletions

View File

@ -2,6 +2,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:syncrow_web/pages/common/custom_dialog.dart';
import 'package:syncrow_web/pages/common/hour_picker_dialog.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart';
@ -9,9 +10,9 @@ import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
import 'package:syncrow_web/pages/visitor_password/model/schedule_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/assets.dart';
import 'package:syncrow_web/utils/snack_bar.dart';
class VisitorPasswordBloc
extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
@ -23,10 +24,8 @@ class VisitorPasswordBloc
on<ToggleDaySelectionEvent>(toggleDaySelection);
on<SelectDeviceEvent>(selectDevice);
on<UpdateFilteredDevicesEvent>(_onUpdateFilteredDevices);
on<OnlineOneTimePasswordEvent>(postOnlineOneTimePassword);
on<OnlineMultipleTimePasswordEvent>(postOnlineMultipleTimePassword);
on<OfflineMultipleTimePasswordEvent>(postOfflineMultipleTimePassword);
on<OfflineOneTimePasswordEvent>(postOfflineOneTimePassword);
on<SelectTimeEvent>(selectTimeOfLinePassword);
@ -58,16 +57,12 @@ class VisitorPasswordBloc
int? effectiveTimeTimeStamp;
int? expirationTimeTimeStamp;
int? repeatEffectiveTimeTimeStamp;
int? repeatExpirationTimeTimeStamp;
DateTime? startTime = DateTime.now();
DateTime? endTime;
String startTimeAccess = 'Start Time';
String endTimeAccess = 'End Time';
selectAccessType(
SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
accessTypeSelected = event.type;
@ -81,9 +76,9 @@ class VisitorPasswordBloc
}
Future<void> selectTimeVisitorPassword(
SelectTimeVisitorPassword event,
Emitter<VisitorPasswordState> emit,
) async {
SelectTimeVisitorPassword event,
Emitter<VisitorPasswordState> emit,
) async {
final DateTime? picked = await showDatePicker(
context: event.context,
initialDate: DateTime.now(),
@ -122,7 +117,8 @@ class VisitorPasswordBloc
timePicked.minute,
);
final selectedTimestamp = selectedDateTime.millisecondsSinceEpoch ~/ 1000;
final selectedTimestamp =
selectedDateTime.millisecondsSinceEpoch ~/ 1000;
if (event.isStart) {
if (expirationTimeTimeStamp != null &&
@ -133,9 +129,7 @@ class VisitorPasswordBloc
return;
}
effectiveTimeTimeStamp = selectedTimestamp;
startTimeAccess = selectedDateTime.toString().split('.').first;
startTimeAccess = selectedDateTime.toString().split('.').first;
} else {
if (effectiveTimeTimeStamp != null &&
selectedTimestamp < effectiveTimeTimeStamp!) {
@ -145,11 +139,8 @@ class VisitorPasswordBloc
return;
}
expirationTimeTimeStamp = selectedTimestamp;
endTimeAccess = selectedDateTime.toString().split('.').first;
endTimeAccess = selectedDateTime.toString().split('.').first;
}
emit(ChangeTimeState());
emit(VisitorPasswordInitial());
}
@ -201,10 +192,10 @@ class VisitorPasswordBloc
}
//online password
Future<void> postOnlineOneTimePassword(OnlineOneTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
try {
emit(LoadingInitialState());
generate7DigitNumber();
bool res = await AccessMangApi().postOnlineOneTime(
email: event.email,
@ -213,27 +204,37 @@ class VisitorPasswordBloc
passwordName: event.passwordName,
effectiveTime: effectiveTimeTimeStamp.toString(),
invalidTime: expirationTimeTimeStamp.toString());
if (res = true) {
Navigator.pop(event.context!);
if (res == true) {
emit(SuccessState());
} else {
throw Exception('Failed to create password');
}
emit(TableLoaded(data));
} catch (e) {
emit(FailedState(e.toString()));
Navigator.pop(event.context!);
stateDialog(
context: event.context!,
message: e.toString(),
title: 'Something Wrong');
}
}
Future<void> postOnlineMultipleTimePassword(
OnlineMultipleTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
try {
generate7DigitNumber();
bool res = await AccessMangApi().postOnlineMultipleTime(
emit(LoadingInitialState());
await generate7DigitNumber();
bool res = await AccessMangApi().postOnlineMultipleTime(
scheduleList: [
if (repeat)
Schedule(
effectiveTime: getTimeFromDateTimeString(expirationTime),
invalidTime: getTimeFromDateTimeString(effectiveTime).toString(),
invalidTime:
getTimeFromDateTimeString(effectiveTime).toString(),
workingDay: selectedDays,
),
],
@ -243,9 +244,11 @@ class VisitorPasswordBloc
email: event.email,
devicesUuid: selectedDevices,
passwordName: event.passwordName);
if(res==true){
Navigator.pop(event.context!);
if (res == true) {
emit(SuccessState());
emit(TableLoaded(data));
}
} catch (e) {
emit(FailedState(e.toString()));
}
@ -255,11 +258,16 @@ class VisitorPasswordBloc
Future<void> postOfflineOneTimePassword(OfflineOneTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
try {
generate7DigitNumber();
await AccessMangApi().postOffLineOneTime(
emit(LoadingInitialState());
await generate7DigitNumber();
bool res = await AccessMangApi().postOffLineOneTime(
email: event.email,
devicesUuid: selectedDevices,
passwordName: event.passwordName);
if (res == true) {
emit(SuccessState());
emit(TableLoaded(data));
}
} catch (e) {
emit(FailedState(e.toString()));
}
@ -269,15 +277,19 @@ class VisitorPasswordBloc
OfflineMultipleTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
try {
generate7DigitNumber();
await AccessMangApi().postOffLineMultipleTime(
email: event.email,
devicesUuid: selectedDevices,
passwordName: event.passwordName,
emit(LoadingInitialState());
await generate7DigitNumber();
bool res = await AccessMangApi().postOffLineMultipleTime(
email: event.email,
devicesUuid: selectedDevices,
passwordName: event.passwordName,
invalidTime: expirationTimeTimeStamp.toString(),
effectiveTime: effectiveTimeTimeStamp.toString(),
);
if (res == true) {
emit(SuccessState());
emit(TableLoaded(data));
}
} catch (e) {
emit(FailedState(e.toString()));
}
@ -300,13 +312,11 @@ class VisitorPasswordBloc
}
Future generate7DigitNumber() async {
emit(LoadingInitialState());
passwordController = '';
Random random = Random();
int min = 1000000;
int max = 9999999;
passwordController = (min + random.nextInt(max - min + 1)).toString();
emit(GeneratePasswordState());
return passwordController;
}
@ -319,12 +329,10 @@ class VisitorPasswordBloc
final deviceName = deviceNameController.text.toLowerCase();
final deviceId = deviceIdController.text.toLowerCase();
final unitName = unitNameController.text.toLowerCase();
final filteredData = data.where((device) {
final matchesDeviceName = device.name.toLowerCase().contains(deviceName);
final matchesDeviceId = device.uuid.toLowerCase().contains(deviceId);
// final matchesUnitName = device.unitName.toLowerCase().contains(unitName); // Assuming unitName is a property of the device
return matchesDeviceName && matchesDeviceId;
}).toList();
add(UpdateFilteredDevicesEvent(filteredData));
@ -334,7 +342,6 @@ class VisitorPasswordBloc
Stream<VisitorPasswordState> mapEventToState(
VisitorPasswordEvent event) async* {
if (event is FetchDevice) {
// Fetching logic...
} else if (event is UpdateFilteredDevicesEvent) {
yield TableLoaded(event.filteredData);
}
@ -347,10 +354,11 @@ class VisitorPasswordBloc
addDeviceToList(context) {
selectedDevices = selectedDeviceIds;
Navigator.of(context).pop(selectedDevices); // Close the dialog
Navigator.of(context).pop(selectedDevices);
}
Future<void> selectTimeOfLinePassword(SelectTimeEvent event, Emitter<VisitorPasswordState> emit) async {
Future<void> selectTimeOfLinePassword(
SelectTimeEvent event, Emitter<VisitorPasswordState> emit) async {
emit(ChangeTimeState());
final DateTime? picked = await showDatePicker(
context: event.context,
@ -416,11 +424,10 @@ class VisitorPasswordBloc
endTime = event.val;
}
}
DateTime? convertStringToDateTime(String dateTimeString) {
try {
// Define the input format. Adjust this pattern based on your input string format.
final DateFormat inputFormat = DateFormat('yyyy-MM-dd HH:mm:ss');
// Convert the string to a DateTime object.
DateTime dateTime = inputFormat.parse(dateTimeString);
return dateTime;
} catch (e) {
@ -432,8 +439,6 @@ class VisitorPasswordBloc
String getTimeFromDateTimeString(String dateTimeString) {
DateTime? dateTime = convertStringToDateTime(dateTimeString);
if (dateTime == null) return '';
// Extract the time component from the DateTime object.
return DateFormat('HH:mm').format(dateTime);
}
@ -444,4 +449,27 @@ class VisitorPasswordBloc
return null;
}
Future<void> stateDialog({
BuildContext? context,
String? message,
String? title,
dynamic actions,
}) {
return showCustomDialog(
context: context!,
message: message!,
iconPath: Assets.deviceNoteIcon,
title: title,
dialogHeight: 150,
actions: actions ??
<Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'),
),
],
);
}
}

View File

@ -77,11 +77,12 @@ class OnlineMultipleTimePasswordEvent extends VisitorPasswordEvent {
//offline password
class OfflineOneTimePasswordEvent extends VisitorPasswordEvent {
final BuildContext? context;
final String? email;
final String? passwordName;
const OfflineOneTimePasswordEvent({this.email,this.passwordName});
const OfflineOneTimePasswordEvent({this.email,this.passwordName,this.context});
@override
List<Object> get props => [email!,passwordName!,];
List<Object> get props => [email!,passwordName!,context!,];
}
class OfflineMultipleTimePasswordEvent extends VisitorPasswordEvent {
@ -89,11 +90,12 @@ class OfflineMultipleTimePasswordEvent extends VisitorPasswordEvent {
final String? passwordName;
final String? invalidTime;
final String? effectiveTime;
final BuildContext? context;
const OfflineMultipleTimePasswordEvent({this.email,this.passwordName,this.invalidTime,this.effectiveTime});
const OfflineMultipleTimePasswordEvent({this.context,this.email,this.passwordName,this.invalidTime,this.effectiveTime});
@override
List<Object> get props => [email!,passwordName!,invalidTime!,effectiveTime!];
List<Object> get props => [email!,passwordName!,invalidTime!,effectiveTime!,context!];
}

View File

@ -43,7 +43,7 @@ class LoadingInitialState extends VisitorPasswordState {}
class ChangeTimeState extends VisitorPasswordState {}
class TimeSelectedState extends VisitorPasswordState {}
class DeviceLoaded extends VisitorPasswordState {}
class GeneratePasswordState extends VisitorPasswordState {}
class SuccessState extends VisitorPasswordState {}
class FailedState extends VisitorPasswordState {
final String message;

View File

@ -12,7 +12,6 @@ import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/constants/const.dart';
import 'package:syncrow_web/utils/style.dart';
class AddDeviceDialog extends StatelessWidget {
const AddDeviceDialog({super.key});
@override
@ -54,7 +53,7 @@ class AddDeviceDialog extends StatelessWidget {
width: 15,
),
),
SizedBox(width: 10,),
const SizedBox(width: 10,),
Text('Only online accessible devices can be added',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
@ -63,13 +62,15 @@ class AddDeviceDialog extends StatelessWidget {
],
)
),
SizedBox(height: 20,),
const SizedBox(height: 20,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
textBaseline: TextBaseline.alphabetic,
children: [
Expanded(
flex: 2,
flex: 4,
child: CustomWebTextField(
controller: visitorBloc.deviceNameController,
isRequired: true,
@ -79,7 +80,7 @@ class AddDeviceDialog extends StatelessWidget {
),
const SizedBox(width: 10),
Expanded(
flex: 2,
flex: 4,
child: CustomWebTextField(
controller: visitorBloc.deviceIdController,
isRequired: true,
@ -89,7 +90,7 @@ class AddDeviceDialog extends StatelessWidget {
),
const SizedBox(width: 10),
Expanded(
flex: 2,
flex: 4,
child: CustomWebTextField(
controller: visitorBloc.unitNameController,
isRequired: true,
@ -97,67 +98,49 @@ class AddDeviceDialog extends StatelessWidget {
description: '',
),
),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 25),
Center(
child: Container(
height: 43,
width: 100,
decoration: containerDecoration,
child: Center(
child: DefaultButton(
onPressed: () {
visitorBloc.filterDevices(); // Call filter function
},
borderRadius: 9,
child: const Text('Search'),
),
Expanded(
flex: 2,
child: Container(
child: SizedBox(
width: size.width * 0.06,
child: Center(
child: DefaultButton(
onPressed: () {
visitorBloc.filterDevices();
},
borderRadius: 9,
child: const Text('Search'),
),
),
),
],
),
),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 25),
Center(
child: Container(
height: 43,
width: 100,
decoration: containerDecoration,
child: Center(
child: DefaultButton(
backgroundColor: ColorsManager.whiteColors,
borderRadius: 9,
child: Text(
'Reset',
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black),
),
onPressed: () {
visitorBloc.deviceNameController.clear();
visitorBloc.deviceIdController.clear();
visitorBloc.unitNameController.clear();
visitorBloc.add(FetchDevice()); // Reset to original list
},
),
),
Expanded(
flex: 2,
child: Container(
width: size.width * 0.06,
child: DefaultButton(
backgroundColor: ColorsManager.whiteColors,
borderRadius: 9,
child: Text('Reset',
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black),
),
onPressed: () {
visitorBloc.deviceNameController.clear();
visitorBloc.deviceIdController.clear();
visitorBloc.unitNameController.clear();
visitorBloc.add(FetchDevice()); // Reset to original list
},
),
],
),
),
)
],
),
const SizedBox(height: 20),
Expanded(
flex: 3,
child: state is TableLoaded
? DynamicTable(
cellDecoration: containerDecoration,

View File

@ -1,11 +1,10 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/pages/common/custom_web_textfield.dart';
import 'package:syncrow_web/pages/common/date_time_widget.dart';
import 'package:syncrow_web/pages/common/default_button.dart';
import 'package:syncrow_web/pages/common/info_dialog.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart';
@ -21,441 +20,517 @@ class VisitorPasswordDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
var text = Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13);
return BlocProvider(
create: (context) => VisitorPasswordBloc(),
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
builder: (BuildContext context, VisitorPasswordState state) {
child: BlocListener<VisitorPasswordBloc, VisitorPasswordState>(
listener: (context, state) {
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
bool isRepeat =
state is IsRepeatState ? state.repeat : visitorBloc.repeat;
return AlertDialog(
backgroundColor: Colors.white,
title: Text(
'Create visitor password',
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
fontWeight: FontWeight.w400,
fontSize: 24,
color: Colors.black),
),
content: SingleChildScrollView(
child: Form(
key: visitorBloc.forgetFormKey,
child: Padding(
padding: const EdgeInsets.all(5.0),
child: ListBody(
children: <Widget>[
Container(
child: Row(
children: [
Expanded(
flex: 2,
child: CustomWebTextField(
validator: visitorBloc.validate,
controller: visitorBloc.userNameController,
isRequired: true,
textFieldName: 'Name',
description: '',
),
),
const Spacer(),
Expanded(
flex: 2,
child: CustomWebTextField(
validator: visitorBloc.validateEmail,
controller: visitorBloc.emailController,
isRequired: true,
textFieldName: 'Email Address',
description:
'The password will be sent to the visitors email address.',
),
),
const Spacer(),
],
),
),
const SizedBox(
height: 15,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
if (state is SuccessState) {
visitorBloc.stateDialog(
context: context,
message: 'Password Created Successfully',
title: 'Send Success',
);
} else if (state is FailedState) {
visitorBloc.stateDialog(
context: context,
message: state.message,
title: 'Something Wrong',
);
}
},
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
builder: (BuildContext context, VisitorPasswordState state) {
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
bool isRepeat = state is IsRepeatState ? state.repeat : visitorBloc.repeat;
return AlertDialog(
backgroundColor: Colors.white,
title: Text(
'Create visitor password',
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
fontWeight: FontWeight.w400,
fontSize: 24,
color: Colors.black),
),
content:
state is LoadingInitialState ?const Center(child: CircularProgressIndicator()):
SingleChildScrollView(
child: Form(
key: visitorBloc.forgetFormKey,
child: Padding(
padding: const EdgeInsets.all(5.0),
child: ListBody(
children: <Widget>[
Container(
child: Row(
children: [
Text(
'* ',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Colors.red),
Expanded(
flex: 2,
child: CustomWebTextField(
validator: visitorBloc.validate,
controller: visitorBloc.userNameController,
isRequired: true,
textFieldName: 'Name',
description: '',
),
),
Text('Access Type',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13),),
const Spacer(),
Expanded(
flex: 2,
child: CustomWebTextField(
validator: visitorBloc.validateEmail,
controller: visitorBloc.emailController,
isRequired: true,
textFieldName: 'Email Address',
description:
'The password will be sent to the visitors email address.',
),
),
const Spacer(),
],
),
Row(
children: <Widget>[
SizedBox(
width: size.width * 0.15,
child: RadioListTile<String>(
title: Text('Online Password',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13),
),
value: 'Online Password',
groupValue: (state is PasswordTypeSelected)
? state.selectedType
: visitorBloc.accessTypeSelected,
onChanged: (String? value) {
if (value != null) {
print(value);
context
.read<VisitorPasswordBloc>()
.add(SelectPasswordType(value));
}
},
),
),
SizedBox(
width: size.width * 0.15,
child: RadioListTile<String>(
title: Text('Offline Password',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13),),
value: 'Offline Password',
groupValue: (state is PasswordTypeSelected)
? state.selectedType
: visitorBloc.accessTypeSelected,
onChanged: (String? value) {
if (value != null) {
context.read<VisitorPasswordBloc>()
.add(SelectPasswordType(value));
}
},
),
),
SizedBox(
width: size.width * 0.15,
child: RadioListTile<String>(
title: Text('Dynamic Password',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13),),
value: 'Dynamic Password',
groupValue: (state is PasswordTypeSelected)
? state.selectedType
: visitorBloc.accessTypeSelected,
onChanged: (String? value) {
if (value != null) {
context
.read<VisitorPasswordBloc>()
.add(SelectPasswordType(value));
visitorBloc.usageFrequencySelected = '';
}
},
),
),
],
),
Text(
'Only currently online devices can be selected. It is recommended to use when the device network is stable, and 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,
)
],
),
visitorBloc.accessTypeSelected == 'Dynamic Password'
? SizedBox()
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
),
const SizedBox(
height: 15,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Row(
children: [
Text(
'* ',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Colors.red),
),
Text('Usage Frequency',style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13),),
],
Text(
'* ',
style: Theme.of(context).textTheme
.bodyMedium!.copyWith(color: Colors.red),
),
Row(
children: <Widget>[
SizedBox(
width: 200,
child: RadioListTile<String>(
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,
onChanged: (String? value) {
if (value != null) {
context.read<VisitorPasswordBloc>()
.add(SelectUsageFrequency(value));
}
},
),
),
SizedBox(
width: 200,
child: RadioListTile<String>(
title: Text('Periodic',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13),),
value: 'Periodic',
groupValue: (state is UsageFrequencySelected)
? state.selectedFrequency
: visitorBloc.usageFrequencySelected,
onChanged: (String? value) {
if (value != null) {
context
.read<VisitorPasswordBloc>()
.add(SelectUsageFrequency(value));
}
},
),
),
],
),
Text('Within the validity period, each device can be unlocked only once.',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,fontSize: 9),
)
Text('Access Type',
style:text ),
],
),
const SizedBox(
height: 20,
),
if ((visitorBloc.usageFrequencySelected != 'One-Time' ||
visitorBloc.accessTypeSelected != 'Offline Password') &&
(visitorBloc.usageFrequencySelected != ''))
DateTimeWebWidget(
isTime: false,
isRequired: true,
title: 'Access Period',
size: size,
endTime: () {
visitorBloc.add(SelectTimeVisitorPassword(
context: context,
isStart: false,
isRepeat: false));
},
startTime: () {
visitorBloc.add(SelectTimeVisitorPassword(
context: context,
isStart: true,
isRepeat: false));
},
firstString: visitorBloc.startTimeAccess.toString(),
secondString: visitorBloc.endTimeAccess.toString(),
Row(
children: <Widget>[
SizedBox(
width: size.width * 0.15,
child: RadioListTile<String>(
title: Text('Online Password',
style: text,
),
value: 'Online Password',
groupValue: (state is PasswordTypeSelected)
? state.selectedType
: visitorBloc.accessTypeSelected,
onChanged: (String? value) {
if (value != null) {
context.read<VisitorPasswordBloc>()
.add(SelectPasswordType(value));
}
},
),
),
SizedBox(
width: size.width * 0.15,
child: RadioListTile<String>(
title: Text('Offline Password',
style:text ),
value: 'Offline Password',
groupValue: (state is PasswordTypeSelected)
? state.selectedType
: visitorBloc.accessTypeSelected,
onChanged: (String? value) {
if (value != null) {
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
}
},
),
),
SizedBox(
width: size.width * 0.15,
child: RadioListTile<String>(
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<VisitorPasswordBloc>()
.add(SelectPasswordType(value));
visitorBloc.usageFrequencySelected = '';
}
},
),
),
],
),
Text(
'Only currently online devices can be selected. It is recommended to use when the device network is stable, and 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,
)
],
),
const SizedBox(
height: 20,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'* ',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Colors.red),
),
Text('Access Devices',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13),),
],
visitorBloc.accessTypeSelected == 'Dynamic Password'
? const SizedBox()
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text('* ',
style: Theme.of(context).textTheme.bodyMedium!
.copyWith(color: Colors.red),
),
Text('Usage Frequency',style:text ,),
],
),
Row(
children: <Widget>[
SizedBox(
width: 200,
child: RadioListTile<String>(
title: Text('One-Time',
style:text ,),
value: 'One-Time',
groupValue:
(state is UsageFrequencySelected)
? state.selectedFrequency
: visitorBloc.usageFrequencySelected,
onChanged: (String? value) {
if (value != null) {
context.read<VisitorPasswordBloc>()
.add(SelectUsageFrequency(value));
}
},
),
),
SizedBox(
width: 200,
child: RadioListTile<String>(
title: Text('Periodic',
style: text),
value: 'Periodic',
groupValue: (state is UsageFrequencySelected)
? state.selectedFrequency
: visitorBloc.usageFrequencySelected,
onChanged: (String? value) {
if (value != null) {
context.read<VisitorPasswordBloc>()
.add(SelectUsageFrequency(value));
}
},
),
),
],
),
Text('Within the validity period, each device can be unlocked only once.',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,fontSize: 9),
)
],
),
const SizedBox(
height: 20,
),
if ((visitorBloc.usageFrequencySelected != 'One-Time' ||
visitorBloc.accessTypeSelected != 'Offline Password') &&
(visitorBloc.usageFrequencySelected != ''))
DateTimeWebWidget(
isTime: false,
isRequired: true,
title: 'Access Period',
size: size,
endTime: () {
visitorBloc.add(SelectTimeVisitorPassword(
context: context,
isStart: false,
isRepeat: false));
},
startTime: () {
visitorBloc.add(SelectTimeVisitorPassword(
context: context,
isStart: true,
isRepeat: false));
},
firstString: visitorBloc.startTimeAccess.toString(),
secondString: visitorBloc.endTimeAccess.toString(),
),
Text(
'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),),
const SizedBox(
height: 20,
),
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Online Password')
SizedBox(
width: 100,
child: Column(
children: [
Text('Repeat',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,fontSize: 13),),
Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: visitorBloc.repeat,
onChanged: (value) {
visitorBloc.add(ToggleRepeatEvent());
},
applyTheme: true,
),
),
],
const SizedBox(
height: 20,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text('* ',
style: Theme.of(context).textTheme.bodyMedium!
.copyWith(color: Colors.red),
),
Text('Access Devices',
style:text ,),
],
),
Text(
'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),),
const SizedBox(
height: 20,
),
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Online Password')
SizedBox(
width: 100,
child: Column(
children: [
Text('Repeat',
style:text),
Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: visitorBloc.repeat,
onChanged: (value) {
visitorBloc.add(ToggleRepeatEvent());
},
applyTheme: true,
),
),
],
),
),
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Online Password')
isRepeat ? const RepeatWidget() : const SizedBox(),
Container(
decoration: containerDecoration,
width: size.width * 0.08,
child: DefaultButton(
onPressed: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return const AddDeviceDialog();
},
).then((listDevice) {
if(listDevice!=null){
visitorBloc.selectedDevices = listDevice;
}
});
},
borderRadius: 8,
child: Text('+ Add Device',style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
color: ColorsManager.whiteColors,fontSize: 12),),
),
),
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Online Password')
isRepeat ? const RepeatWidget() : const SizedBox(),
Container(
decoration: containerDecoration,
width: size.width * 0.08,
child: DefaultButton(
onPressed: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return const AddDeviceDialog();
},
).then((listDevice) {
if(listDevice!=null){
print('selectedDevices==$listDevice');
visitorBloc.selectedDevices = listDevice;
],
),
],
),
),
),
),
actionsAlignment: MainAxisAlignment.center,
actions: <Widget>[
Container(
decoration: containerDecoration,
width: size.width * 0.2,
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.2,
child: DefaultButton(
onPressed: () {
if (visitorBloc.forgetFormKey.currentState!.validate()) {
if(visitorBloc.selectedDevices.isNotEmpty){
if(visitorBloc.effectiveTimeTimeStamp!=null&&visitorBloc.expirationTimeTimeStamp!=null) {
setPasswordFunction(context, size, visitorBloc);
}
else{
visitorBloc.stateDialog(context:
context,message: 'Please select Access Period to continue',title: 'Access Period');
}
}else{
visitorBloc.stateDialog(context:
context,message: 'Please select devices to continue',title: 'Select Devices');
}
}
},
borderRadius: 8,
child: Text('Ok', style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
color: ColorsManager.whiteColors,fontSize: 16),),
),
),
],
); },
),
),
}
});
);
}
},
borderRadius: 8,
child: Text('+ Add Device',style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
color: ColorsManager.whiteColors,fontSize: 12),),
Future<void> setPasswordFunction(
BuildContext context,
Size size,
VisitorPasswordBloc visitorBloc,
) {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
builder: (context, state) {
if (state is LoadingInitialState) {
// Show loading indicator while loading
return AlertDialog(
alignment: Alignment.center,
content: SizedBox(
height: size.height * 0.25,
child: Center(
child: CircularProgressIndicator(), // Display a loading spinner
),
),
);
}else{
return AlertDialog(
alignment: Alignment.center,
content: SizedBox(
height: size.height * 0.25,
child: Column(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
child: SvgPicture.asset(
Assets.deviceNoteIcon,
height: 35,
width: 35,
),
),
Text(
'Set Password',
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
fontSize: 30,
fontWeight: FontWeight.w400,
color: Colors.black,
),
),
],
),
const SizedBox(width: 15),
Text(
'This action will update all of the selected\n door locks passwords in the property.\n\nAre you sure you want to continue?',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400,
fontSize: 18,
),
),
],
),
),
),
),
actionsAlignment: MainAxisAlignment.center,
actions: <Widget>[
Container(
decoration: containerDecoration,
width: size.width * 0.2,
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),
actionsAlignment: MainAxisAlignment.center,
actions: <Widget>[
Container(
decoration: containerDecoration,
width: size.width * 0.1,
child: DefaultButton(
borderRadius: 8,
onPressed: () {
Navigator.of(context).pop();
},
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.2,
child: DefaultButton(
onPressed: () {
if (visitorBloc.forgetFormKey.currentState!.validate()) {
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();
},
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),
),
),
),
],
);
},
);
}
},
borderRadius: 8,
child: Text('Ok', style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
color: ColorsManager.whiteColors,fontSize: 16),),
),
),
],
);
},
),
Container(
decoration: containerDecoration,
width: size.width * 0.1,
child: DefaultButton(
borderRadius: 8,
onPressed: () {
Navigator.pop(context);
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(
'Ok',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
color: ColorsManager.whiteColors,
fontSize: 16,
),
),
),
),
],
);
}
},
);
},
);
}
}