merged with dev and access_bugs and solved conflicts

This commit is contained in:
Abdullah Alassaf
2024-08-28 14:50:47 +03:00
30 changed files with 1326 additions and 1207 deletions

View File

@ -1,4 +1,5 @@
import 'dart:math';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
@ -7,14 +8,14 @@ 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';
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
import 'package:syncrow_web/pages/visitor_password/model/failed_operation.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> {
class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
on<SelectUsageFrequency>(selectUsageFrequency);
on<FetchDevice>(_onFetchDevice);
@ -37,8 +38,7 @@ class VisitorPasswordBloc
final TextEditingController deviceNameController = TextEditingController();
final TextEditingController deviceIdController = TextEditingController();
final TextEditingController unitNameController = TextEditingController();
final TextEditingController virtualAddressController =
TextEditingController();
final TextEditingController virtualAddressController = TextEditingController();
List<String> selectedDevices = [];
List<DeviceModel> data = [];
@ -62,15 +62,13 @@ class VisitorPasswordBloc
String startTimeAccess = 'Start Time';
String endTimeAccess = 'End Time';
selectAccessType(
SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
PasswordStatus? passwordStatus;
selectAccessType(SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
accessTypeSelected = event.type;
emit(PasswordTypeSelected(event.type));
}
selectUsageFrequency(
SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
selectUsageFrequency(SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
usageFrequencySelected = event.usageType;
emit(UsageFrequencySelected(event.usageType));
}
@ -117,12 +115,10 @@ class VisitorPasswordBloc
timePicked.minute,
);
final selectedTimestamp =
selectedDateTime.millisecondsSinceEpoch ~/ 1000;
final selectedTimestamp = selectedDateTime.millisecondsSinceEpoch ~/ 1000;
if (event.isStart) {
if (expirationTimeTimeStamp != null &&
selectedTimestamp > expirationTimeTimeStamp!) {
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Effective Time cannot be later than Expiration Time.',
);
@ -131,8 +127,7 @@ class VisitorPasswordBloc
effectiveTimeTimeStamp = selectedTimestamp;
startTimeAccess = selectedDateTime.toString().split('.').first;
} else {
if (effectiveTimeTimeStamp != null &&
selectedTimestamp < effectiveTimeTimeStamp!) {
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Expiration Time cannot be earlier than Effective Time.',
);
@ -147,8 +142,7 @@ class VisitorPasswordBloc
}
}
bool toggleRepeat(
ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
bool toggleRepeat(ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
emit(LoadingInitialState());
repeat = !repeat;
emit(IsRepeatState(repeat: repeat));
@ -180,8 +174,7 @@ class VisitorPasswordBloc
emit(ChangeTimeState());
}
Future<void> _onFetchDevice(
FetchDevice event, Emitter<VisitorPasswordState> emit) async {
Future<void> _onFetchDevice(FetchDevice event, Emitter<VisitorPasswordState> emit) async {
try {
emit(DeviceLoaded());
data = await AccessMangApi().fetchDevices();
@ -192,48 +185,43 @@ class VisitorPasswordBloc
}
//online password
Future<void> postOnlineOneTimePassword(OnlineOneTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
Future<void> postOnlineOneTimePassword(
OnlineOneTimePasswordEvent event, Emitter<VisitorPasswordState> emit) async {
try {
emit(LoadingInitialState());
generate7DigitNumber();
bool res = await AccessMangApi().postOnlineOneTime(
var res = await AccessMangApi().postOnlineOneTime(
email: event.email,
password: passwordController,
devicesUuid: selectedDevices,
passwordName: event.passwordName,
effectiveTime: effectiveTimeTimeStamp.toString(),
invalidTime: expirationTimeTimeStamp.toString());
if (res == true) {
if (res['statusCode'] == 201) {
passwordStatus = PasswordStatus.fromJson(res['data']);
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');
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
print('errorMessage==$errorData');
emit(FailedState(errorMessage.toString()));
}
}
Future<void> postOnlineMultipleTimePassword(
OnlineMultipleTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
OnlineMultipleTimePasswordEvent event, Emitter<VisitorPasswordState> emit) async {
try {
emit(LoadingInitialState());
await generate7DigitNumber();
bool res = await AccessMangApi().postOnlineMultipleTime(
var res = await AccessMangApi().postOnlineMultipleTime(
scheduleList: [
if (repeat)
Schedule(
effectiveTime: getTimeFromDateTimeString(expirationTime),
invalidTime:
getTimeFromDateTimeString(effectiveTime).toString(),
invalidTime: getTimeFromDateTimeString(effectiveTime).toString(),
workingDay: selectedDays,
),
],
@ -243,79 +231,66 @@ class VisitorPasswordBloc
email: event.email,
devicesUuid: selectedDevices,
passwordName: event.passwordName);
if (res == true) {
if (res['statusCode'] == 201) {
passwordStatus = PasswordStatus.fromJson(res['data']);
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');
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
print('errorMessage==$errorData');
emit(FailedState(errorMessage.toString()));
}
}
//offline password
Future<void> postOfflineOneTimePassword(OfflineOneTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
Future<void> postOfflineOneTimePassword(
OfflineOneTimePasswordEvent event, Emitter<VisitorPasswordState> emit) async {
try {
emit(LoadingInitialState());
await generate7DigitNumber();
bool res = await AccessMangApi().postOffLineOneTime(
email: event.email,
devicesUuid: selectedDevices,
passwordName: event.passwordName);
if (res == true) {
var res = await AccessMangApi().postOffLineOneTime(
email: event.email, devicesUuid: selectedDevices, passwordName: event.passwordName);
if (res['statusCode'] == 201) {
passwordStatus = PasswordStatus.fromJson(res['data']);
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');
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
print('errorMessage==$errorData');
emit(FailedState(errorMessage.toString()));
}
}
Future<void> postOfflineMultipleTimePassword(
OfflineMultipleTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
OfflineMultipleTimePasswordEvent event, Emitter<VisitorPasswordState> emit) async {
try {
emit(LoadingInitialState());
await generate7DigitNumber();
bool res = await AccessMangApi().postOffLineMultipleTime(
var res = await AccessMangApi().postOffLineMultipleTime(
email: event.email,
devicesUuid: selectedDevices,
passwordName: event.passwordName,
invalidTime: expirationTimeTimeStamp.toString(),
effectiveTime: effectiveTimeTimeStamp.toString(),
);
if (res == true) {
if (res['statusCode'] == 201) {
passwordStatus = PasswordStatus.fromJson(res['data']);
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');
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
print('errorMessage==$errorData');
emit(FailedState(errorMessage.toString()));
}
}
void selectDevice(
SelectDeviceEvent event, Emitter<VisitorPasswordState> emit) {
void selectDevice(SelectDeviceEvent event, Emitter<VisitorPasswordState> emit) {
if (selectedDeviceIds.contains(event.deviceId)) {
selectedDeviceIds.remove(event.deviceId);
} else {
@ -358,8 +333,7 @@ class VisitorPasswordBloc
}
@override
Stream<VisitorPasswordState> mapEventToState(
VisitorPasswordEvent event) async* {
Stream<VisitorPasswordState> mapEventToState(VisitorPasswordEvent event) async* {
if (event is FetchDevice) {
} else if (event is UpdateFilteredDevicesEvent) {
yield TableLoaded(event.filteredData);
@ -407,27 +381,20 @@ class VisitorPasswordBloc
).millisecondsSinceEpoch ~/
1000; // Divide by 1000 to remove milliseconds
if (event.isEffective) {
if (expirationTimeTimeStamp != null &&
selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Effective Time cannot be later than Expiration Time.');
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
} else {
effectiveTime = selectedDateTime
.toString()
.split('.')
.first; // Remove seconds and milliseconds
effectiveTime =
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
effectiveTimeTimeStamp = selectedTimestamp;
}
} else {
if (effectiveTimeTimeStamp != null &&
selectedTimestamp < effectiveTimeTimeStamp!) {
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Expiration Time cannot be earlier than Effective Time.');
} else {
expirationTime = selectedDateTime
.toString()
.split('.')
.first; // Remove seconds and milliseconds
expirationTime =
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
expirationTimeTimeStamp = selectedTimestamp;
}
}
@ -468,23 +435,26 @@ class VisitorPasswordBloc
return null;
}
Future<void> stateDialog({
Future stateDialog({
BuildContext? context,
String? message,
String? title,
dynamic actions,
Widget? widgeta,
}) {
return showCustomDialog(
barrierDismissible: false,
context: context!,
message: message!,
iconPath: Assets.deviceNoteIcon,
title: title,
dialogHeight: 150,
widget: widgeta,
dialogHeight: MediaQuery.of(context).size.height * 0.3,
actions: actions ??
<Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pop(true);
},
child: const Text('OK'),
),

View File

@ -1,6 +1,6 @@
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/constants/const.dart';
import 'package:syncrow_web/utils/enum/device_types.dart';
import 'package:syncrow_web/utils/constants/app_enum.dart';
class DeviceModel {
dynamic productUuid;
@ -54,8 +54,7 @@ class DeviceModel {
if (type == DeviceType.LightBulb) {
tempIcon = Assets.lightBulb;
} else if (type == DeviceType.CeilingSensor ||
type == DeviceType.WallSensor) {
} else if (type == DeviceType.CeilingSensor || type == DeviceType.WallSensor) {
tempIcon = Assets.sensors;
} else if (type == DeviceType.AC) {
tempIcon = Assets.ac;

View File

@ -0,0 +1,124 @@
class FailedOperation {
final bool success;
final dynamic deviceUuid;
final dynamic error;
FailedOperation({
required this.success,
required this.deviceUuid,
required this.error,
});
factory FailedOperation.fromJson(Map<String, dynamic> json) {
return FailedOperation(
success: json['success'],
deviceUuid: json['deviceUuid'],
error: json['error'],
);
}
Map<String, dynamic> toJson() {
return {
'success': success,
'deviceUuid': deviceUuid,
'error': error,
};
}
}
class SuccessOperation {
final bool success;
// final Result result;
final String deviceUuid;
SuccessOperation({
required this.success,
// required this.result,
required this.deviceUuid,
});
factory SuccessOperation.fromJson(Map<String, dynamic> json) {
return SuccessOperation(
success: json['success'],
// result: Result.fromJson(json['result']),
deviceUuid: json['deviceUuid'],
);
}
Map<String, dynamic> toJson() {
return {
'success': success,
// 'result': result.toJson(),
'deviceUuid': deviceUuid,
};
}
}
// class Result {
// final dynamic effectiveTime;
// final dynamic invalidTime;
// final dynamic offlineTempPassword;
// final dynamic offlineTempPasswordId;
// final dynamic offlineTempPasswordName;
//
// Result({
// required this.effectiveTime,
// required this.invalidTime,
// required this.offlineTempPassword,
// required this.offlineTempPasswordId,
// required this.offlineTempPasswordName,
// });
//
// factory Result.fromJson(Map<String, dynamic> json) {
// return Result(
// effectiveTime: json['effective_time'],
// invalidTime: json['invalid_time'],
// offlineTempPassword: json['offline_temp_password'].toString(),
// offlineTempPasswordId: json['offline_temp_password_id'],
// offlineTempPasswordName: json['offline_temp_password_name'],
// );
// }
//
// Map<String, dynamic> toJson() {
// return {
// 'effective_time': effectiveTime,
// 'invalid_time': invalidTime,
// 'offline_temp_password': offlineTempPassword,
// 'offline_temp_password_id': offlineTempPasswordId,
// 'offline_temp_password_name': offlineTempPasswordName,
// };
// }
// }
class PasswordStatus {
final List<SuccessOperation> successOperations;
final List<FailedOperation> failedOperations;
PasswordStatus({
required this.successOperations,
required this.failedOperations,
});
factory PasswordStatus.fromJson(Map<String, dynamic> json) {
return PasswordStatus(
successOperations: (json['successOperations'] as List)
.map((i) => SuccessOperation.fromJson(i))
.toList(),
failedOperations: (json['failedOperations'] as List)
.map((i) => FailedOperation.fromJson(i))
.toList(),
);
}
Map<String, dynamic> toJson() {
return {
'successOperations': successOperations.map((e) => e.toJson()).toList(),
'failedOperations': failedOperations.map((e) => e.toJson()).toList(),
};
}
}

View File

@ -9,7 +9,7 @@ import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.d
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/constants/const.dart';
import 'package:syncrow_web/utils/constants/app_enum.dart';
import 'package:syncrow_web/utils/style.dart';
class AddDeviceDialog extends StatelessWidget {

View File

@ -20,21 +20,75 @@ 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);
var text = Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black, fontSize: 13);
return BlocProvider(
create: (context) => VisitorPasswordBloc(),
child: BlocListener<VisitorPasswordBloc, VisitorPasswordState>(
listener: (context, state) {
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
if (state is SuccessState) {
visitorBloc.stateDialog(
context: context,
message: 'Password Created Successfully',
title: 'Send Success',
);
visitorBloc
.stateDialog(
context: context,
message: 'Password Created Successfully',
title: 'Send Success',
widgeta: Column(
children: [
if (visitorBloc.passwordStatus!.failedOperations.isNotEmpty)
Column(
children: [
const Text('Failed Devises'),
SizedBox(
width: 200,
height: 50,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: visitorBloc.passwordStatus!.failedOperations.length,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.all(5),
decoration: containerDecoration,
height: 45,
child: Center(
child: Text(visitorBloc
.passwordStatus!.failedOperations[index].deviceUuid)),
);
},
),
),
],
),
if (visitorBloc.passwordStatus!.successOperations.isNotEmpty)
Column(
children: [
const Text('Success Devises'),
SizedBox(
width: 200,
height: 50,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: visitorBloc.passwordStatus!.successOperations.length,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.all(5),
decoration: containerDecoration,
height: 45,
child: Center(
child: Text(visitorBloc.passwordStatus!
.successOperations[index].deviceUuid)),
);
},
),
),
],
),
],
))
.then((v) {
Navigator.of(context).pop();
});
} else if (state is FailedState) {
visitorBloc.stateDialog(
context: context,
@ -46,16 +100,15 @@ class VisitorPasswordDialog extends StatelessWidget {
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
builder: (BuildContext context, VisitorPasswordState state) {
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
bool isRepeat =
state is IsRepeatState ? state.repeat : visitorBloc.repeat;
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),
style: Theme.of(context)
.textTheme
.headlineLarge!
.copyWith(fontWeight: FontWeight.w400, fontSize: 24, color: Colors.black),
),
content: state is LoadingInitialState
? const Center(child: CircularProgressIndicator())
@ -73,8 +126,7 @@ class VisitorPasswordDialog extends StatelessWidget {
flex: 2,
child: CustomWebTextField(
validator: visitorBloc.validate,
controller:
visitorBloc.userNameController,
controller: visitorBloc.userNameController,
isRequired: true,
textFieldName: 'Name',
description: '',
@ -116,95 +168,111 @@ class VisitorPasswordDialog extends StatelessWidget {
),
Row(
children: <Widget>[
Flexible(
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
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));
}
},
),
),
Flexible(
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
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));
}
},
),
),
Flexible(
child: RadioListTile<String>(
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<VisitorPasswordBloc>()
.add(SelectPasswordType(
value));
visitorBloc
.usageFrequencySelected = '';
}
},
),
Expanded(
flex: 2,
child: Row(
children: [
SizedBox(
width: size.width * 0.12,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
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.12,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
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.12,
child: RadioListTile<String>(
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<VisitorPasswordBloc>()
.add(SelectPasswordType(value));
visitorBloc.usageFrequencySelected = '';
}
},
),
),
],
)),
const Spacer(
flex: 2,
),
],
),
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),
),
if (visitorBloc.accessTypeSelected == 'Online Password')
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),
),
if (visitorBloc.accessTypeSelected == 'Offline Password')
Text(
'Unaffected by the online status of the device, you can select online or offline device, and 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,
)
],
),
visitorBloc.accessTypeSelected ==
'Dynamic Password'
visitorBloc.accessTypeSelected == 'Dynamic Password'
? const SizedBox()
: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
@ -223,7 +291,8 @@ class VisitorPasswordDialog extends StatelessWidget {
),
Row(
children: <Widget>[
Flexible(
SizedBox(
width: size.width * 0.12,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
title: Text(
@ -231,88 +300,113 @@ class VisitorPasswordDialog extends StatelessWidget {
style: text,
),
value: 'One-Time',
groupValue: (state
is UsageFrequencySelected)
groupValue: (state is UsageFrequencySelected)
? state.selectedFrequency
: visitorBloc
.usageFrequencySelected,
: visitorBloc.usageFrequencySelected,
onChanged: (String? value) {
if (value != null) {
context
.read<
VisitorPasswordBloc>()
.add(
SelectUsageFrequency(
value));
.read<VisitorPasswordBloc>()
.add(SelectUsageFrequency(value));
}
},
),
),
Flexible(
SizedBox(
width: size.width * 0.12,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
title: Text('Periodic',
style: text),
title: Text('Periodic', style: text),
value: 'Periodic',
groupValue: (state
is UsageFrequencySelected)
groupValue: (state is UsageFrequencySelected)
? state.selectedFrequency
: visitorBloc
.usageFrequencySelected,
: visitorBloc.usageFrequencySelected,
onChanged: (String? value) {
if (value != null) {
context
.read<
VisitorPasswordBloc>()
.add(
SelectUsageFrequency(
value));
.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),
)
//One-Time
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
visitorBloc.accessTypeSelected == 'Online Password')
Text(
'Within the validity period, each device can be unlocked only once.',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor, fontSize: 9),
),
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.',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor, fontSize: 9),
),
// Periodic
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Offline Password')
Text(
'Within the validity period, there is no limit to the number of times each device can be unlocked, and it should be used at least once within 24 hours after the entry into force.',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor, fontSize: 9),
),
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Online Password')
Text(
'Within the validity period, there is no limit to the number of times each device can be unlocked.',
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') &&
if ((visitorBloc.usageFrequencySelected != 'One-Time' ||
visitorBloc.accessTypeSelected != 'Offline Password') &&
(visitorBloc.usageFrequencySelected != ''))
DateTimeWebWidget(
isRequired: true,
title: 'Access Period',
size: size,
endTime: () {
visitorBloc.add(SelectTimeVisitorPassword(
context: context,
isStart: false,
isRepeat: false));
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Offline Password') {
visitorBloc.add(
SelectTimeEvent(context: context, isEffective: false));
} else {
visitorBloc.add(SelectTimeVisitorPassword(
context: context, isStart: false, isRepeat: false));
}
},
startTime: () {
visitorBloc.add(SelectTimeVisitorPassword(
context: context,
isStart: true,
isRepeat: false));
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Offline Password') {
visitorBloc.add(
SelectTimeEvent(context: context, isEffective: true));
} else {
visitorBloc.add(SelectTimeVisitorPassword(
context: context, isStart: true, isRepeat: false));
}
},
firstString:
visitorBloc.startTimeAccess.toString(),
secondString:
visitorBloc.endTimeAccess.toString(),
firstString: (visitorBloc.usageFrequencySelected ==
'Periodic' &&
visitorBloc.accessTypeSelected == 'Offline Password')
? visitorBloc.effectiveTime
: visitorBloc.startTimeAccess.toString(),
secondString: (visitorBloc.usageFrequencySelected ==
'Periodic' &&
visitorBloc.accessTypeSelected == 'Offline Password')
? visitorBloc.expirationTime
: visitorBloc.endTimeAccess.toString(),
icon: Assets.calendarIcon),
const SizedBox(
height: 20,
@ -337,21 +431,16 @@ class VisitorPasswordDialog extends StatelessWidget {
),
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),
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')
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Online Password')
SizedBox(
width: 100,
child: Column(
@ -362,8 +451,7 @@ class VisitorPasswordDialog extends StatelessWidget {
child: CupertinoSwitch(
value: visitorBloc.repeat,
onChanged: (value) {
visitorBloc
.add(ToggleRepeatEvent());
visitorBloc.add(ToggleRepeatEvent());
},
applyTheme: true,
),
@ -371,13 +459,9 @@ class VisitorPasswordDialog extends StatelessWidget {
],
),
),
if (visitorBloc.usageFrequencySelected ==
'Periodic' &&
visitorBloc.accessTypeSelected ==
'Online Password')
isRepeat
? const RepeatWidget()
: const SizedBox(),
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == 'Online Password')
isRepeat ? const RepeatWidget() : const SizedBox(),
Container(
decoration: containerDecoration,
width: size.width / 9,
@ -388,28 +472,22 @@ class VisitorPasswordDialog extends StatelessWidget {
barrierDismissible: false,
builder: (BuildContext context) {
return AddDeviceDialog(
selectedDeviceIds:
visitorBloc.selectedDevices,
selectedDeviceIds: visitorBloc.selectedDevices,
);
},
).then((listDevice) {
if (listDevice != null) {
visitorBloc.selectedDevices =
listDevice;
visitorBloc.selectedDevices = listDevice;
}
});
},
borderRadius: 8,
child: Text(
'+ Add Device',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
fontWeight: FontWeight.w400,
color:
ColorsManager.whiteColors,
fontSize: 12),
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
color: ColorsManager.whiteColors,
fontSize: 12),
),
),
),
@ -447,15 +525,36 @@ class VisitorPasswordDialog extends StatelessWidget {
onPressed: () {
if (visitorBloc.forgetFormKey.currentState!.validate()) {
if (visitorBloc.selectedDevices.isNotEmpty) {
if (visitorBloc.effectiveTimeTimeStamp != null &&
visitorBloc.expirationTimeTimeStamp != null) {
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
visitorBloc.accessTypeSelected == 'Offline Password') {
setPasswordFunction(context, size, visitorBloc);
} else if (visitorBloc.accessTypeSelected == 'Dynamic Password') {
print('objectobjectobjectobject');
setPasswordFunction(context, size, visitorBloc);
} else {
visitorBloc.stateDialog(
context: context,
message:
'Please select Access Period to continue',
title: 'Access Period');
if (visitorBloc.effectiveTimeTimeStamp != null &&
visitorBloc.expirationTimeTimeStamp != null) {
if (isRepeat == true) {
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');
}
}
} else {
visitorBloc.stateDialog(
@ -465,6 +564,57 @@ 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',
@ -501,8 +651,7 @@ class VisitorPasswordDialog extends StatelessWidget {
content: SizedBox(
height: size.height * 0.25,
child: Center(
child:
CircularProgressIndicator(), // Display a loading spinner
child: CircularProgressIndicator(), // Display a loading spinner
),
),
);
@ -526,10 +675,7 @@ class VisitorPasswordDialog extends StatelessWidget {
),
Text(
'Set Password',
style: Theme.of(context)
.textTheme
.headlineLarge!
.copyWith(
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
fontSize: 30,
fontWeight: FontWeight.w400,
color: Colors.black,
@ -578,47 +724,39 @@ class VisitorPasswordDialog extends StatelessWidget {
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(),
));
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(),
));
}
}
},
child: Text(