mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
visitor password api
This commit is contained in:
@ -1,14 +1,19 @@
|
||||
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/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/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/snack_bar.dart';
|
||||
|
||||
// Define the BLoC
|
||||
class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
||||
class VisitorPasswordBloc
|
||||
extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
||||
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
|
||||
on<SelectUsageFrequency>(selectUsageFrequency);
|
||||
on<FetchDevice>(_onFetchDevice);
|
||||
@ -17,25 +22,25 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
on<SelectTimeVisitorPassword>(selectTimeVisitorPassword);
|
||||
on<ToggleRepeatEvent>(toggleRepeat);
|
||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||
on<SelectDeviceEvent>(selectDevice);
|
||||
on<OnlineOneTimePasswordEvent>(postOnlineOneTimePassword);
|
||||
on<OnlineMultipleTimePasswordEvent>(postOnlineMultipleTimePassword);
|
||||
}
|
||||
final TextEditingController userNameController = TextEditingController();
|
||||
final TextEditingController emailController = TextEditingController();
|
||||
|
||||
|
||||
|
||||
final TextEditingController deviceNameController = TextEditingController();
|
||||
final TextEditingController deviceIdController = TextEditingController();
|
||||
final TextEditingController unitNameController = TextEditingController();
|
||||
final TextEditingController virtualAddressController = TextEditingController();
|
||||
|
||||
List<DeviceModel> data=[];
|
||||
List<DeviceModel> data = [];
|
||||
List<String> selectedDeviceIds = ['909e052c-6934-48f3-b22d-67ee04ad7265'];
|
||||
final forgetFormKey = GlobalKey<FormState>();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
String accessTypeSelected='Offline Password';
|
||||
String usageFrequencySelected='One-Time';
|
||||
String accessTypeSelected = 'Online Password';
|
||||
String usageFrequencySelected = 'One-Time';
|
||||
String passwordController = '';
|
||||
|
||||
bool repeat = false;
|
||||
|
||||
@ -45,18 +50,24 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
String startTime = 'Start Time';
|
||||
String endTime = 'End Time';
|
||||
|
||||
selectAccessType(SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
|
||||
accessTypeSelected=event.type;
|
||||
emit(PasswordTypeSelected(event.type));
|
||||
DateTime? repeatStartTime=DateTime.now();
|
||||
DateTime? repeatEndTime;
|
||||
|
||||
selectAccessType(
|
||||
SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
|
||||
accessTypeSelected = event.type;
|
||||
emit(PasswordTypeSelected(event.type));
|
||||
}
|
||||
|
||||
selectUsageFrequency(SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
|
||||
usageFrequencySelected=event.usageType;
|
||||
emit(UsageFrequencySelected(event.usageType));
|
||||
selectUsageFrequency(
|
||||
SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
|
||||
usageFrequencySelected = event.usageType;
|
||||
emit(UsageFrequencySelected(event.usageType));
|
||||
}
|
||||
|
||||
|
||||
Future<void> selectTimeVisitorPassword(SelectTimeVisitorPassword event, Emitter<VisitorPasswordState> emit) async {
|
||||
Future<void> selectTimeVisitorPassword(
|
||||
SelectTimeVisitorPassword event,
|
||||
Emitter<VisitorPasswordState> emit) async {
|
||||
final DateTime? picked = await showDatePicker(
|
||||
context: event.context,
|
||||
initialDate: DateTime.now(),
|
||||
@ -67,7 +78,6 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
final TimeOfDay? timePicked = await showTimePicker(
|
||||
context: event.context,
|
||||
initialTime: TimeOfDay.now(),
|
||||
|
||||
builder: (context, child) {
|
||||
return Theme(
|
||||
data: ThemeData.light().copyWith(
|
||||
@ -94,43 +104,57 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
timePicked.minute,
|
||||
);
|
||||
final selectedTimestamp = DateTime(
|
||||
selectedDateTime.year,
|
||||
selectedDateTime.month,
|
||||
selectedDateTime.day,
|
||||
selectedDateTime.hour,
|
||||
selectedDateTime.minute,
|
||||
).millisecondsSinceEpoch ~/ 1000; // Divide by 1000 to remove milliseconds
|
||||
selectedDateTime.year,
|
||||
selectedDateTime.month,
|
||||
selectedDateTime.day,
|
||||
selectedDateTime.hour,
|
||||
selectedDateTime.minute,
|
||||
).millisecondsSinceEpoch ~/
|
||||
1000; // Divide by 1000 to remove milliseconds
|
||||
if (event.isStart) {
|
||||
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 {
|
||||
startTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||
startTime = selectedDateTime
|
||||
.toString()
|
||||
.split('.')
|
||||
.first; // Remove seconds and milliseconds
|
||||
effectiveTimeTimeStamp = selectedTimestamp;
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
|
||||
} else {
|
||||
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
|
||||
if (effectiveTimeTimeStamp != null &&
|
||||
selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
'Expiration Time cannot be earlier than Effective Time.');
|
||||
} else {
|
||||
endTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||
endTime = selectedDateTime
|
||||
.toString()
|
||||
.split('.')
|
||||
.first; // Remove seconds and milliseconds
|
||||
expirationTimeTimeStamp = selectedTimestamp;
|
||||
}
|
||||
emit(VisitorPasswordInitial());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit(AccessInitial());
|
||||
// emit(TableLoaded(data));
|
||||
}
|
||||
|
||||
|
||||
bool toggleRepeat(ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
|
||||
bool toggleRepeat(
|
||||
ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
|
||||
emit(LoadingInitialState());
|
||||
repeat = !repeat;
|
||||
emit(IsRepeatState(repeat: repeat));
|
||||
return repeat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<Map<String, String>> days = [
|
||||
{"day": "Sun", "key": "Sun"},
|
||||
{"day": "Mon", "key": "Mon"},
|
||||
@ -143,7 +167,10 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
|
||||
List<String> selectedDays = [];
|
||||
|
||||
Future<void> toggleDaySelection(ToggleDaySelectionEvent event, Emitter<VisitorPasswordState> emit,)async {
|
||||
Future<void> toggleDaySelection(
|
||||
ToggleDaySelectionEvent event,
|
||||
Emitter<VisitorPasswordState> emit,
|
||||
) async {
|
||||
emit(LoadingInitialState());
|
||||
if (selectedDays.contains(event.key)) {
|
||||
selectedDays.remove(event.key);
|
||||
@ -152,17 +179,90 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
}
|
||||
//Add Accessible Device
|
||||
|
||||
Future<void> _onFetchDevice(
|
||||
FetchDevice event, Emitter<VisitorPasswordState> emit) async {
|
||||
try {
|
||||
emit(DeviceLoaded());
|
||||
data = await AccessMangApi().fetchDevices();
|
||||
data = await AccessMangApi().fetchDevices();
|
||||
emit(TableLoaded(data));
|
||||
} catch (e) {
|
||||
emit(FailedState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> postOnlineOneTimePassword(
|
||||
OnlineOneTimePasswordEvent event,
|
||||
Emitter<VisitorPasswordState> emit) async {
|
||||
try {
|
||||
// emit(DeviceLoaded());
|
||||
await AccessMangApi().postOnlineOneTime(
|
||||
email: event.email,
|
||||
devicesUuid: selectedDeviceIds,
|
||||
passwordName: event.passwordName);
|
||||
// emit(TableLoaded(data));
|
||||
} catch (e) {
|
||||
emit(FailedState(e.toString()));
|
||||
}
|
||||
}
|
||||
Future<void> postOnlineMultipleTimePassword(
|
||||
OnlineMultipleTimePasswordEvent event,
|
||||
Emitter<VisitorPasswordState> emit) async {
|
||||
try {
|
||||
generate7DigitNumber();
|
||||
// emit(DeviceLoaded());
|
||||
await AccessMangApi().postOnlineMultipleTime(
|
||||
scheduleList:[
|
||||
if (repeat)
|
||||
Schedule(
|
||||
effectiveTime: getTimeOnly(repeatStartTime),
|
||||
invalidTime: getTimeOnly(repeatEndTime).toString(),
|
||||
workingDay: selectedDays,
|
||||
),
|
||||
] ,
|
||||
password: passwordController,
|
||||
invalidTime:event.invalidTime ,
|
||||
effectiveTime:event.effectiveTime ,
|
||||
email: event.email,
|
||||
devicesUuid: selectedDeviceIds,
|
||||
passwordName: event.passwordName
|
||||
);
|
||||
// emit(TableLoaded(data));
|
||||
} catch (e) {
|
||||
emit(FailedState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void selectDevice(
|
||||
SelectDeviceEvent event, Emitter<VisitorPasswordState> emit) {
|
||||
if (selectedDeviceIds.contains(event.deviceId)) {
|
||||
selectedDeviceIds.remove(event.deviceId);
|
||||
} else {
|
||||
selectedDeviceIds.add(event.deviceId);
|
||||
}
|
||||
print(selectedDeviceIds);
|
||||
}
|
||||
|
||||
String? validate(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Field is required';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
String getTimeOnly(DateTime? dateTime) {
|
||||
if (dateTime == null) return '';
|
||||
return DateFormat('HH:mm').format(dateTime);
|
||||
}
|
||||
}
|
||||
|
@ -47,4 +47,32 @@ class ToggleDaySelectionEvent extends VisitorPasswordEvent {
|
||||
|
||||
|
||||
class ToggleRepeatEvent extends VisitorPasswordEvent {}
|
||||
class GeneratePasswordEvent extends VisitorPasswordEvent {}
|
||||
|
||||
class FetchDevice extends VisitorPasswordEvent {}
|
||||
|
||||
class OnlineOneTimePasswordEvent extends VisitorPasswordEvent {
|
||||
final String? email;
|
||||
final String? passwordName;
|
||||
|
||||
const OnlineOneTimePasswordEvent({this.email,this.passwordName});
|
||||
|
||||
@override
|
||||
List<Object> get props => [email!,passwordName!,];
|
||||
}
|
||||
class OnlineMultipleTimePasswordEvent extends VisitorPasswordEvent {
|
||||
final String? email;
|
||||
final String? passwordName;
|
||||
final String? invalidTime;
|
||||
final String? effectiveTime;
|
||||
|
||||
const OnlineMultipleTimePasswordEvent({this.email,this.passwordName,this.invalidTime,this.effectiveTime});
|
||||
|
||||
@override
|
||||
List<Object> get props => [email!,passwordName!,invalidTime!,effectiveTime!];
|
||||
}
|
||||
|
||||
class SelectDeviceEvent extends VisitorPasswordEvent {
|
||||
final String deviceId;
|
||||
const SelectDeviceEvent(this.deviceId);
|
||||
}
|
@ -44,6 +44,7 @@ class IsRepeatState extends VisitorPasswordState {
|
||||
class LoadingInitialState extends VisitorPasswordState {}
|
||||
class ChangeTimeState extends VisitorPasswordState {}
|
||||
class DeviceLoaded extends VisitorPasswordState {}
|
||||
class GeneratePasswordState extends VisitorPasswordState {}
|
||||
class FailedState extends VisitorPasswordState {
|
||||
final String message;
|
||||
|
||||
@ -59,4 +60,9 @@ class TableLoaded extends VisitorPasswordState {
|
||||
|
||||
@override
|
||||
List<Object> get props => [data];
|
||||
}
|
||||
|
||||
class DeviceSelectionUpdated extends VisitorPasswordState {
|
||||
final List<String> selectedDeviceIds;
|
||||
const DeviceSelectionUpdated(this.selectedDeviceIds);
|
||||
}
|
27
lib/pages/visitor_password/model/schedule_model.dart
Normal file
27
lib/pages/visitor_password/model/schedule_model.dart
Normal file
@ -0,0 +1,27 @@
|
||||
class Schedule {
|
||||
final String effectiveTime;
|
||||
final String invalidTime;
|
||||
final List<String> workingDay;
|
||||
|
||||
Schedule({
|
||||
required this.effectiveTime,
|
||||
required this.invalidTime,
|
||||
required this.workingDay,
|
||||
});
|
||||
|
||||
factory Schedule.fromJson(Map<String, dynamic> json) {
|
||||
return Schedule(
|
||||
effectiveTime: json['effectiveTime'],
|
||||
invalidTime: json['invalidTime'],
|
||||
workingDay: List<String>.from(json['workingDay']),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'effectiveTime': effectiveTime,
|
||||
'invalidTime': invalidTime,
|
||||
'workingDay': workingDay,
|
||||
};
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ import '../../common/custom_table.dart';
|
||||
|
||||
class AddDeviceDialog extends StatelessWidget {
|
||||
const AddDeviceDialog({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
@ -138,41 +137,42 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Container(
|
||||
child: Expanded(
|
||||
child: state is TableLoaded
|
||||
? Container(
|
||||
decoration: containerDecoration,
|
||||
child: DynamicTable(
|
||||
size: size*0.5,
|
||||
headers: ['Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status'],
|
||||
data: state.data.map((item) {
|
||||
return [
|
||||
item.name.toString(),
|
||||
item.uuid.toString(),
|
||||
item.productType.toString(),
|
||||
'',
|
||||
item.online.toString(),
|
||||
// item.categoryName.toString(),
|
||||
// accessBloc.timestampToDateTime(item.effectiveTime).toString(),
|
||||
// accessBloc.timestampToDateTime(item.invalidTime).toString(),
|
||||
// item.deviceUuid.toString(),
|
||||
// item.passwordCreated != null ? accessBloc.timestampToDateTime(item.passwordCreated).toString() : 'no data',
|
||||
// item.passwordStatus.toString(),
|
||||
];
|
||||
}).toList(),
|
||||
),
|
||||
)
|
||||
// TableWidget(size: size, headers: ['Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status', 'Virtual Address',], data: [], bloc: bloc)
|
||||
: const Center(child: CircularProgressIndicator())),
|
||||
)
|
||||
const SizedBox(height: 20),
|
||||
Expanded(
|
||||
child: state is TableLoaded
|
||||
? Container(
|
||||
decoration: containerDecoration,
|
||||
child: DynamicTable(
|
||||
selectAll: (p0) {
|
||||
visitorBloc.selectedDeviceIds.clear();
|
||||
for (var item in state.data) {
|
||||
visitorBloc.add(SelectDeviceEvent(item.uuid));
|
||||
}
|
||||
},
|
||||
onRowCheckboxChanged: (index, isSelected) {
|
||||
final deviceId = state.data[index].uuid; // Adjust as per your actual data structure
|
||||
visitorBloc.add(SelectDeviceEvent(deviceId));
|
||||
},
|
||||
withCheckBox: true,
|
||||
size: size*0.5,
|
||||
headers: const [ 'Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status'],
|
||||
data: state.data.map((item) {
|
||||
return [
|
||||
item.name.toString(),
|
||||
item.uuid.toString(),
|
||||
item.productType.toString(),
|
||||
'',
|
||||
item.online.toString(),
|
||||
];
|
||||
}).toList(),
|
||||
),
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator()))
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -195,9 +195,14 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.2,
|
||||
child: const DefaultButton(
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(); // Close the dialog
|
||||
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('Ok'),
|
||||
),
|
||||
|
@ -27,238 +27,246 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
backgroundColor: Colors.white,
|
||||
title: const Text('Create visitor password'),
|
||||
content: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
child: Form(
|
||||
key: visitorBloc.forgetFormKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.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.validate,
|
||||
controller: visitorBloc.emailController,
|
||||
isRequired: true,
|
||||
textFieldName: 'Email Address',
|
||||
description: 'The password will be sent to the visitor’s email address.',
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20,),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CustomWebTextField(
|
||||
controller: visitorBloc.userNameController,
|
||||
isRequired: true,
|
||||
textFieldName: 'Name',
|
||||
description: '',
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Access Type'),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CustomWebTextField(
|
||||
controller: visitorBloc.emailController,
|
||||
isRequired: true,
|
||||
textFieldName: 'Email Address',
|
||||
description: 'The password will be sent to the visitor’s email address.',
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
|
||||
SizedBox(
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Online Password'),
|
||||
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: const Text('Offline Password'),
|
||||
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: const Text('Dynamic Password'),
|
||||
value: 'Dynamic Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
const 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'),
|
||||
SizedBox(height: 20,)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20,),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Access Type'),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Offline Password'),
|
||||
value: 'Offline Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||
SizedBox():
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Online Password'),
|
||||
value: 'Online Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
const Text('Usage Frequency'),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('One-Time'),
|
||||
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: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Dynamic Password'),
|
||||
value: 'Dynamic Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Periodic'),
|
||||
value: 'Periodic',
|
||||
groupValue: (state is UsageFrequencySelected)
|
||||
? state.selectedFrequency
|
||||
: visitorBloc.usageFrequencySelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectUsageFrequency(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const 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'),
|
||||
SizedBox(height: 20,)
|
||||
],
|
||||
),
|
||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||
SizedBox():
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Usage Frequency'),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('One-Time'),
|
||||
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: const Text('Periodic'),
|
||||
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.')
|
||||
],
|
||||
),
|
||||
Text('Within the validity period, each device can be unlocked only once.')
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 20,),
|
||||
const SizedBox(height: 20,),
|
||||
|
||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||
SizedBox():
|
||||
DateTimeWebWidget(
|
||||
isRequired: true,
|
||||
title: 'Access Period',
|
||||
size: size,
|
||||
endTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false));
|
||||
},
|
||||
startTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
||||
},
|
||||
firstString: visitorBloc.startTime,
|
||||
secondString: visitorBloc.endTime,
|
||||
),
|
||||
const SizedBox(height: 20,),
|
||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||
SizedBox():
|
||||
DateTimeWebWidget(
|
||||
isRequired: true,
|
||||
title: 'Access Period',
|
||||
size: size,
|
||||
endTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false));
|
||||
},
|
||||
startTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
||||
},
|
||||
firstString: visitorBloc.startTime,
|
||||
secondString: visitorBloc.endTime,
|
||||
),
|
||||
const SizedBox(height: 20,),
|
||||
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Access Devices'),
|
||||
],
|
||||
),
|
||||
const Text('Within the validity period, each device can be unlocked only once.'),
|
||||
const SizedBox(height: 20,),
|
||||
visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Offline Password'?
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Text('Repeat'),
|
||||
trailing: Transform.scale(
|
||||
scale: .8,
|
||||
child: CupertinoSwitch(
|
||||
value: visitorBloc.repeat,
|
||||
onChanged: (value) {
|
||||
visitorBloc.add(ToggleRepeatEvent());
|
||||
},
|
||||
applyTheme: true,
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Access Devices'),
|
||||
],
|
||||
),
|
||||
const Text('Within the validity period, each device can be unlocked only once.'),
|
||||
const SizedBox(height: 20,),
|
||||
if(visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Online Password')
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Text('Repeat'),
|
||||
trailing: Transform.scale(
|
||||
scale: .8,
|
||||
child: CupertinoSwitch(
|
||||
value: visitorBloc.repeat,
|
||||
onChanged: (value) {
|
||||
visitorBloc.add(ToggleRepeatEvent());
|
||||
},
|
||||
applyTheme: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
):const SizedBox(),
|
||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.1,
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return const AddDeviceDialog();
|
||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.1,
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return const AddDeviceDialog();
|
||||
|
||||
},
|
||||
);
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('+ Add Device'),
|
||||
},
|
||||
);
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('+ Add Device'),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -282,7 +290,36 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.2,
|
||||
child: const DefaultButton(
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
if(visitorBloc.forgetFormKey.currentState!.validate()){
|
||||
if(visitorBloc.usageFrequencySelected=='One-Time'&&visitorBloc.accessTypeSelected=='Online Password'){
|
||||
visitorBloc.add(OnlineOneTimePasswordEvent(
|
||||
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=='Periodic'&&visitorBloc.accessTypeSelected=='Online Password') {
|
||||
visitorBloc.add(OnlineMultipleTimePasswordEvent(
|
||||
passwordName:visitorBloc.userNameController.text ,
|
||||
email: visitorBloc.emailController.text,
|
||||
effectiveTime:visitorBloc.effectiveTimeTimeStamp.toString() ,
|
||||
invalidTime:visitorBloc.expirationTimeTimeStamp.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('Ok'),
|
||||
),
|
||||
|
Reference in New Issue
Block a user