mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-09 22:57:21 +00:00
add device filter and select time repeat widget
This commit is contained in:
@ -59,7 +59,7 @@ class MyApp extends StatelessWidget {
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
||||
useMaterial3: true, // Enable Material 3
|
||||
),
|
||||
// home: VisitorPasswordDialog()
|
||||
// home: AddDeviceDialog()
|
||||
home:isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||
));
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ class AccessManagementPage extends StatelessWidget {
|
||||
? DynamicTable(
|
||||
withCheckBox: false,
|
||||
size: size,
|
||||
// cellDecoration: containerDecoration,
|
||||
cellDecoration: containerDecoration,
|
||||
headers: const [
|
||||
'Name',
|
||||
'Access Type',
|
||||
|
@ -155,7 +155,7 @@ class _DynamicTableState extends State<DynamicTable> {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
height: 80,
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
|
@ -72,7 +72,10 @@ class CustomWebTextField extends StatelessWidget {
|
||||
controller: controller,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: textBoxDecoration()!
|
||||
.copyWith(hintText: 'Please enter'),
|
||||
.copyWith(
|
||||
errorStyle: const TextStyle(height: 0), // Hide the error text space
|
||||
|
||||
hintText: 'Please enter'),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
74
lib/pages/common/info_dialog.dart
Normal file
74
lib/pages/common/info_dialog.dart
Normal file
@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class InfoDialog extends StatelessWidget {
|
||||
final String title;
|
||||
final String content;
|
||||
final Size? size;
|
||||
final List<Widget>? actions;
|
||||
|
||||
InfoDialog({
|
||||
required this.title,
|
||||
required this.content,
|
||||
this.actions,
|
||||
this.size,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Text(
|
||||
content,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 18),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
actionsAlignment: MainAxisAlignment.center,
|
||||
actions: actions ??
|
||||
<Widget>[
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ class VisitorPasswordBloc
|
||||
on<ToggleRepeatEvent>(toggleRepeat);
|
||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||
on<SelectDeviceEvent>(selectDevice);
|
||||
on<UpdateFilteredDevicesEvent>(_onUpdateFilteredDevices);
|
||||
|
||||
on<OnlineOneTimePasswordEvent>(postOnlineOneTimePassword);
|
||||
on<OnlineMultipleTimePasswordEvent>(postOnlineMultipleTimePassword);
|
||||
@ -39,6 +40,8 @@ class VisitorPasswordBloc
|
||||
final TextEditingController unitNameController = TextEditingController();
|
||||
final TextEditingController virtualAddressController = TextEditingController();
|
||||
|
||||
|
||||
|
||||
List<DeviceModel> data = [];
|
||||
List<String> selectedDeviceIds = [];
|
||||
|
||||
@ -55,11 +58,18 @@ class VisitorPasswordBloc
|
||||
int? effectiveTimeTimeStamp;
|
||||
int? expirationTimeTimeStamp;
|
||||
|
||||
int? repeatEffectiveTimeTimeStamp;
|
||||
int? repeatExpirationTimeTimeStamp;
|
||||
|
||||
String startTime = 'Start Time';
|
||||
String endTime = 'End Time';
|
||||
|
||||
DateTime? repeatStartTime=DateTime.now();
|
||||
DateTime? repeatEndTime;
|
||||
|
||||
String repeatStartTime = 'Start Time';
|
||||
String repeatEndTime = 'End Time';
|
||||
|
||||
// DateTime? repeatStartTime=DateTime.now();
|
||||
// DateTime? repeatEndTime;
|
||||
|
||||
selectAccessType(
|
||||
SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
|
||||
@ -80,7 +90,7 @@ class VisitorPasswordBloc
|
||||
context: event.context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2015, 8),
|
||||
lastDate: DateTime(2101),
|
||||
lastDate: DateTime(3101),
|
||||
);
|
||||
if (picked != null) {
|
||||
final TimeOfDay? timePicked = await showTimePicker(
|
||||
@ -120,33 +130,34 @@ class VisitorPasswordBloc
|
||||
).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
|
||||
if(event.isRepeat==true)
|
||||
{repeatStartTime = selectedDateTime.toString().split('.').first;}
|
||||
|
||||
else // Remove seconds and milliseconds
|
||||
{startTime = selectedDateTime.toString().split('.').first;}
|
||||
effectiveTimeTimeStamp = selectedTimestamp;
|
||||
emit(ChangeTimeState());
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
|
||||
} else {
|
||||
if (effectiveTimeTimeStamp != null &&
|
||||
selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
'Expiration Time cannot be earlier than Effective Time.');
|
||||
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
|
||||
} else {
|
||||
endTime = selectedDateTime
|
||||
.toString()
|
||||
.split('.')
|
||||
.first; // Remove seconds and milliseconds
|
||||
if(event.isRepeat==true)
|
||||
{repeatEndTime = selectedDateTime.toString().split('.').first;}
|
||||
else
|
||||
{endTime = selectedDateTime.toString().split('.').first;}
|
||||
expirationTimeTimeStamp = selectedTimestamp;
|
||||
}
|
||||
emit(VisitorPasswordInitial());
|
||||
emit(ChangeTimeState());
|
||||
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
|
||||
emit(VisitorPasswordInitial());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,12 +236,12 @@ class VisitorPasswordBloc
|
||||
// emit(DeviceLoaded());
|
||||
await AccessMangApi().postOnlineMultipleTime(
|
||||
scheduleList:[
|
||||
if (repeat)
|
||||
Schedule(
|
||||
effectiveTime: getTimeOnly(repeatStartTime),
|
||||
invalidTime: getTimeOnly(repeatEndTime).toString(),
|
||||
workingDay: selectedDays,
|
||||
),
|
||||
// if (repeat)
|
||||
// Schedule(
|
||||
// effectiveTime: getTimeOnly(repeatStartTime),
|
||||
// invalidTime: getTimeOnly(repeatEndTime).toString(),
|
||||
// workingDay: selectedDays,
|
||||
// ),
|
||||
] ,
|
||||
password: passwordController,
|
||||
invalidTime:event.invalidTime ,
|
||||
@ -297,7 +308,7 @@ class VisitorPasswordBloc
|
||||
|
||||
String? validate(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Field is required';
|
||||
return '';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -317,4 +328,34 @@ class VisitorPasswordBloc
|
||||
if (dateTime == null) return '';
|
||||
return DateFormat('HH:mm').format(dateTime);
|
||||
}
|
||||
|
||||
|
||||
void filterDevices() {
|
||||
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();
|
||||
// emit(TableLoaded(filteredData));
|
||||
|
||||
add(UpdateFilteredDevicesEvent(filteredData));
|
||||
}
|
||||
@override
|
||||
Stream<VisitorPasswordState> mapEventToState(VisitorPasswordEvent event) async* {
|
||||
if (event is FetchDevice) {
|
||||
// Fetching logic...
|
||||
} else if (event is UpdateFilteredDevicesEvent) {
|
||||
yield TableLoaded(event.filteredData);
|
||||
}
|
||||
}
|
||||
|
||||
void _onUpdateFilteredDevices(UpdateFilteredDevicesEvent event, Emitter<VisitorPasswordState> emit) {
|
||||
emit(TableLoaded(event.filteredData));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
|
||||
|
||||
abstract class VisitorPasswordEvent extends Equatable {
|
||||
const VisitorPasswordEvent();
|
||||
@ -28,11 +29,12 @@ class SelectUsageFrequency extends VisitorPasswordEvent {
|
||||
class SelectTimeVisitorPassword extends VisitorPasswordEvent {
|
||||
final BuildContext context;
|
||||
final bool isStart;
|
||||
final bool isRepeat;
|
||||
|
||||
const SelectTimeVisitorPassword({ required this.context,required this.isStart});
|
||||
const SelectTimeVisitorPassword({ required this.context,required this.isStart,required this.isRepeat});
|
||||
|
||||
@override
|
||||
List<Object> get props => [context,isStart];
|
||||
List<Object> get props => [context,isStart,isRepeat];
|
||||
}
|
||||
|
||||
|
||||
@ -96,4 +98,21 @@ class OfflineMultipleTimePasswordEvent extends VisitorPasswordEvent {
|
||||
class SelectDeviceEvent extends VisitorPasswordEvent {
|
||||
final String deviceId;
|
||||
const SelectDeviceEvent(this.deviceId);
|
||||
}
|
||||
|
||||
class FilterDataEvent extends VisitorPasswordEvent {
|
||||
final String? passwordName;
|
||||
final int? startTime;
|
||||
final int? endTime;
|
||||
|
||||
const FilterDataEvent({
|
||||
this.passwordName,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
});
|
||||
}
|
||||
class UpdateFilteredDevicesEvent extends VisitorPasswordEvent {
|
||||
final List<DeviceModel> filteredData;
|
||||
|
||||
UpdateFilteredDevicesEvent(this.filteredData);
|
||||
}
|
@ -16,9 +16,7 @@ class VisitorPasswordInitial extends VisitorPasswordState {}
|
||||
|
||||
class PasswordTypeSelected extends VisitorPasswordState {
|
||||
final String selectedType;
|
||||
|
||||
const PasswordTypeSelected(this.selectedType);
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedType];
|
||||
}
|
||||
@ -45,19 +43,17 @@ class LoadingInitialState extends VisitorPasswordState {}
|
||||
class ChangeTimeState extends VisitorPasswordState {}
|
||||
class DeviceLoaded extends VisitorPasswordState {}
|
||||
class GeneratePasswordState extends VisitorPasswordState {}
|
||||
|
||||
class FailedState extends VisitorPasswordState {
|
||||
final String message;
|
||||
|
||||
FailedState(this.message);
|
||||
|
||||
const FailedState(this.message);
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
class TableLoaded extends VisitorPasswordState {
|
||||
final List<DeviceModel> data;
|
||||
|
||||
const TableLoaded(this.data);
|
||||
|
||||
@override
|
||||
List<Object> get props => [data];
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
|
||||
|
||||
import 'package:syncrow_web/utils/constants/const.dart';
|
||||
|
||||
class DeviceModel {
|
||||
dynamic productUuid;
|
||||
dynamic productType;
|
||||
@ -15,7 +17,7 @@ class DeviceModel {
|
||||
dynamic lon;
|
||||
dynamic model;
|
||||
dynamic name;
|
||||
dynamic online;
|
||||
DeviseStatus online;
|
||||
dynamic ownerId;
|
||||
dynamic sub;
|
||||
dynamic timeZone;
|
||||
@ -62,7 +64,7 @@ class DeviceModel {
|
||||
lon: json['lon'] ,
|
||||
model: json['model'] ,
|
||||
name: json['name'],
|
||||
online: json['online'],
|
||||
online: OnlineTypeExtension.fromString(json['online']),
|
||||
ownerId: json['ownerId'] ,
|
||||
sub: json['sub'],
|
||||
timeZone: json['timeZone'],
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
@ -10,6 +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/style.dart';
|
||||
|
||||
|
||||
@ -34,13 +34,13 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: size.width,
|
||||
padding: EdgeInsets.all(15),
|
||||
decoration:containerDecoration.copyWith(
|
||||
color: ColorsManager.worningColor,
|
||||
border: Border.all(color: Color(0xffFFD22F)),
|
||||
boxShadow: []
|
||||
),
|
||||
width: size.width,
|
||||
padding: EdgeInsets.all(15),
|
||||
decoration:containerDecoration.copyWith(
|
||||
color: ColorsManager.worningColor,
|
||||
border: Border.all(color: Color(0xffFFD22F)),
|
||||
boxShadow: []
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
@ -73,7 +73,7 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CustomWebTextField(
|
||||
controller: visitorBloc.deviceNameController,
|
||||
controller: visitorBloc.deviceIdController,
|
||||
isRequired: true,
|
||||
textFieldName: 'Device ID',
|
||||
description: '',
|
||||
@ -103,7 +103,7 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
child: Center(
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
// Your search function here
|
||||
visitorBloc.filterDevices(); // Call filter function
|
||||
},
|
||||
borderRadius: 9,
|
||||
child: const Text('Search'),
|
||||
@ -133,6 +133,12 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
'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
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -145,7 +151,7 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
const SizedBox(height: 20),
|
||||
Expanded(
|
||||
child: state is TableLoaded
|
||||
? Container(
|
||||
? Container(
|
||||
decoration: containerDecoration,
|
||||
child: DynamicTable(
|
||||
selectAll: (p0) {
|
||||
@ -160,14 +166,14 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
},
|
||||
withCheckBox: true,
|
||||
size: size*0.5,
|
||||
headers: const [ 'Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status'],
|
||||
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(),
|
||||
item.online.value.toString(),
|
||||
];
|
||||
}).toList(),
|
||||
),
|
||||
@ -195,13 +201,11 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.2,
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(); // Close the dialog
|
||||
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('Ok'),
|
||||
@ -211,5 +215,6 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -20,29 +20,6 @@ class RepeatWidget extends StatelessWidget {
|
||||
final smartDoorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: DateTimeWebWidget(
|
||||
isRequired: true,
|
||||
title: 'Access Period',
|
||||
size: size,
|
||||
endTime: () {
|
||||
smartDoorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false));
|
||||
},
|
||||
startTime: () {
|
||||
smartDoorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
||||
},
|
||||
firstString: smartDoorBloc.startTime,
|
||||
secondString: smartDoorBloc.endTime,
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Container(
|
||||
width: size.width * 0.8,
|
||||
height: size.height * 0.06, // Adjust height as needed
|
||||
@ -72,6 +49,29 @@ class RepeatWidget extends StatelessWidget {
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: DateTimeWebWidget(
|
||||
isRequired: false,
|
||||
title: '',
|
||||
size: size,
|
||||
endTime: () {
|
||||
smartDoorBloc.add(SelectTimeVisitorPassword(
|
||||
isRepeat: true,
|
||||
context: context, isStart: false
|
||||
));
|
||||
},
|
||||
startTime: () {
|
||||
smartDoorBloc.add(SelectTimeVisitorPassword(
|
||||
isRepeat: true,
|
||||
context: context, isStart: true
|
||||
));
|
||||
},
|
||||
firstString: smartDoorBloc.repeatStartTime.toString(),
|
||||
secondString: smartDoorBloc.repeatEndTime.toString(),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
|
||||
],
|
||||
|
@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.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';
|
||||
@ -79,7 +80,6 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
|
||||
SizedBox(
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
@ -90,6 +90,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
print(value);
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
@ -106,6 +107,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
print(value);
|
||||
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
@ -123,6 +126,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
visitorBloc.usageFrequencySelected='';
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -130,7 +134,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
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,)
|
||||
const SizedBox(height: 20,)
|
||||
],
|
||||
),
|
||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||
@ -162,6 +166,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
: visitorBloc.usageFrequencySelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
print(value);
|
||||
|
||||
context.read<VisitorPasswordBloc>().add(SelectUsageFrequency(value));
|
||||
}
|
||||
},
|
||||
@ -185,27 +191,28 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
|
||||
Text('Within the validity period, each device can be unlocked only once.')
|
||||
const Text('Within the validity period, each device can be unlocked only once.')
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 20,),
|
||||
|
||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||
SizedBox():
|
||||
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));
|
||||
visitorBloc.add(SelectTimeVisitorPassword(
|
||||
context: context, isStart: false,isRepeat:false));
|
||||
},
|
||||
startTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
||||
visitorBloc.add(SelectTimeVisitorPassword(
|
||||
context: context, isStart: true,isRepeat:false));
|
||||
},
|
||||
firstString: visitorBloc.startTime,
|
||||
secondString: visitorBloc.endTime,
|
||||
),
|
||||
|
||||
const SizedBox(height: 20,),
|
||||
|
||||
Column(
|
||||
@ -243,7 +250,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||
if(visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Online Password')
|
||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.1,
|
||||
@ -254,7 +262,6 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return const AddDeviceDialog();
|
||||
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -293,39 +300,79 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
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=='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()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return InfoDialog(
|
||||
size: size,
|
||||
title: 'Set Password',
|
||||
content: 'This action will update all of the selected\n door locks passwords in the property.\n\nAre you sure you want to continue?',
|
||||
|
||||
actions: [
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.1,
|
||||
child: DefaultButton(
|
||||
borderRadius: 8,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(); // Close the dialog
|
||||
},
|
||||
backgroundColor: Colors.white,
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: Theme.of(context).textTheme.bodyMedium!,
|
||||
),
|
||||
),
|
||||
),
|
||||
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(
|
||||
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: const Text(
|
||||
'Ok',
|
||||
),
|
||||
),
|
||||
),
|
||||
],);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('Ok'),
|
||||
|
@ -42,3 +42,38 @@ extension AccessTypeExtension on AccessType {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum DeviseStatus {
|
||||
online,
|
||||
offline,
|
||||
}
|
||||
|
||||
extension OnlineTypeExtension on DeviseStatus {
|
||||
String get value {
|
||||
switch (this) {
|
||||
case DeviseStatus.online:
|
||||
return "Online";
|
||||
case DeviseStatus.offline:
|
||||
return "Offline";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static DeviseStatus fromString(bool value) {
|
||||
switch (value) {
|
||||
case false:
|
||||
return DeviseStatus.offline;
|
||||
case true:
|
||||
return DeviseStatus.online;
|
||||
default:
|
||||
throw ArgumentError("Invalid access type: $value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user