mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-10-23 10:47:55 +00:00
door lock
This commit is contained in:
@@ -6,6 +6,7 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/offline_password_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/offline_temporary_password.dart';
|
import 'package:syncrow_app/features/devices/model/offline_temporary_password.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/smart_door_model.dart';
|
import 'package:syncrow_app/features/devices/model/smart_door_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
@@ -14,15 +15,17 @@ import 'package:syncrow_app/features/devices/model/temporary_password_model.dart
|
|||||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
late SmartDoorModel deviceStatus;
|
late SmartDoorModel deviceStatus;
|
||||||
static String pageType = '';
|
|
||||||
bool isSavingPassword = false;
|
bool isSavingPassword = false;
|
||||||
|
|
||||||
SmartDoorBloc({required this.deviceId}) : super(InitialState()) {
|
SmartDoorBloc({required this.deviceId}) : super(InitialState()) {
|
||||||
on<InitialEvent>(_fetchSmartDoorStatus);
|
on<InitialEvent>(_fetchSmartDoorStatus);
|
||||||
on<InitialPasswordsPage>(getTemporaryPasswords);
|
on<InitialPasswordsPage>(getTemporaryPasswords);
|
||||||
|
on<InitialOneTimePassword>(getOneTimePasswords);
|
||||||
|
on<InitialTimeLimitPassword>(getTimeLimitPasswords);
|
||||||
on<UpdateLockEvent>(_updateLock);
|
on<UpdateLockEvent>(_updateLock);
|
||||||
on<SavePasswordEvent>(savePassword);
|
on<SavePasswordEvent>(savePassword);
|
||||||
on<ToggleRepeatEvent>(toggleRepeat);
|
on<ToggleRepeatEvent>(toggleRepeat);
|
||||||
@@ -49,7 +52,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
DateTime? startTime;
|
DateTime? startTime;
|
||||||
DateTime? endTime;
|
DateTime? endTime;
|
||||||
List<TemporaryPassword>? temporaryPasswords = [];
|
List<TemporaryPassword>? temporaryPasswords = [];
|
||||||
List<TemporaryPassword>? oneTimePasswords = [];
|
List<OfflinePasswordModel>? oneTimePasswords = [];
|
||||||
|
List<OfflinePasswordModel>? timeLimitPasswords = [];
|
||||||
|
|
||||||
Future generate7DigitNumber(GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
Future generate7DigitNumber(GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
@@ -72,8 +76,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
ApiResponse pass= ApiResponse.fromJson(res);
|
ApiResponse pass= ApiResponse.fromJson(res);
|
||||||
passwordController.text =pass.data.offlineTempPassword;
|
passwordController.text =pass.data.offlineTempPassword;
|
||||||
passwordId=pass.data.offlineTempPasswordId;
|
passwordId=pass.data.offlineTempPasswordId;
|
||||||
emit(const GeneratePasswordOneTimestate(generated: true));
|
emit(const GeneratePasswordOneTimestate(generated: true));
|
||||||
|
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
emit(FailedState(errorMessage: _.toString()));
|
emit(FailedState(errorMessage: _.toString()));
|
||||||
}finally {
|
}finally {
|
||||||
@@ -100,9 +103,12 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
void _renamePassword(RenamePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
void _renamePassword(RenamePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
|
print('==4444${passwordNameController.text}');
|
||||||
|
print('==1==${deviceId}');
|
||||||
|
print('==4444${passwordId}');
|
||||||
var response = await DevicesAPI.renamePass(
|
var response = await DevicesAPI.renamePass(
|
||||||
name:passwordNameController.text ,
|
name:passwordNameController.text ,
|
||||||
deviceId:deviceId ,
|
doorLockUuid:deviceId ,
|
||||||
passwordId:passwordId
|
passwordId:passwordId
|
||||||
);
|
);
|
||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||||
@@ -115,14 +121,37 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
void getTemporaryPasswords(InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
|
void getTemporaryPasswords(InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
print('deviceId=$deviceId');
|
var response = await DevicesAPI.getTemporaryPasswords(deviceId, );
|
||||||
pageType = event.type!;
|
|
||||||
var response = await DevicesAPI.getTemporaryPasswords(deviceId, pageType);
|
|
||||||
if (response is List) {
|
if (response is List) {
|
||||||
temporaryPasswords = response.map((item) => TemporaryPassword.fromJson(item)).toList();
|
temporaryPasswords = response.map((item) => TemporaryPassword.fromJson(item)).toList();
|
||||||
} else if (response is Map && response.containsKey('data')) {
|
} else if (response is Map && response.containsKey('data')) {
|
||||||
temporaryPasswords =
|
temporaryPasswords = (response['data'] as List).map((item) => TemporaryPassword.fromJson(item)).toList();
|
||||||
(response['data'] as List).map((item) => TemporaryPassword.fromJson(item)).toList();
|
}
|
||||||
|
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getOneTimePasswords(InitialOneTimePassword event, Emitter<SmartDoorState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
var response = await DevicesAPI.getOneTimePasswords(deviceId);
|
||||||
|
if (response is List) {
|
||||||
|
oneTimePasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList();
|
||||||
|
}
|
||||||
|
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getTimeLimitPasswords(InitialTimeLimitPassword event, Emitter<SmartDoorState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
var response = await DevicesAPI.getTimeLimitPasswords(deviceId);
|
||||||
|
if (response is List) {
|
||||||
|
timeLimitPasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList();
|
||||||
}
|
}
|
||||||
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -166,8 +195,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Future<void> selectTime(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
|
Future<void> selectTime(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
emit(ChangeTimeState());
|
emit(ChangeTimeState());
|
||||||
final DateTime? picked = await showDatePicker(
|
final DateTime? picked = await showDatePicker(
|
||||||
@@ -241,7 +268,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
isSavingPassword = true;
|
isSavingPassword = true;
|
||||||
emit(LoadingSaveState());
|
emit(LoadingSaveState());
|
||||||
var res = await DevicesAPI.createPassword(
|
var res = await DevicesAPI.createPassword(
|
||||||
pageType: pageType,
|
|
||||||
deviceId: deviceId,
|
deviceId: deviceId,
|
||||||
effectiveTime: effectiveTimeTimeStamp.toString(),
|
effectiveTime: effectiveTimeTimeStamp.toString(),
|
||||||
invalidTime: expirationTimeTimeStamp.toString(),
|
invalidTime: expirationTimeTimeStamp.toString(),
|
||||||
@@ -267,7 +293,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> generateAndSavePasswordTimeLimited (GenerateAndSavePasswordTimeLimitEvent event, Emitter<SmartDoorState> emit) async {
|
Future<void> generateAndSavePasswordTimeLimited (GenerateAndSavePasswordTimeLimitEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
if (_validateInputs() || isSavingPassword) return;
|
if (timeLimitValidate() || isSavingPassword) return;
|
||||||
try {
|
try {
|
||||||
isSavingPassword = true;
|
isSavingPassword = true;
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
@@ -280,22 +306,20 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||||
emit(const GeneratePasswordOneTimestate(generated: true));
|
emit(const GeneratePasswordOneTimestate(generated: true));
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
print(_);
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
isSavingPassword = false;
|
isSavingPassword = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Future<void> deletePassword(DeletePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
Future<void> deletePassword(DeletePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
var response =
|
var response =
|
||||||
await DevicesAPI.deletePassword(deviceId: deviceId, passwordId: event.passwordId)
|
await DevicesAPI.deletePassword(deviceId: deviceId, passwordId: event.passwordId)
|
||||||
.then((value) async {
|
.then((value) async {
|
||||||
add(InitialPasswordsPage(type: pageType));
|
add(InitialPasswordsPage());
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(errorMessage: e.toString()));
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
@@ -303,15 +327,15 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool _validateInputs() {
|
bool _validateInputs() {
|
||||||
if (passwordController.text.length < 7 && pageType=='Online Password') {
|
if (passwordController.text.length < 7 ) {
|
||||||
CustomSnackBar.displaySnackBar('Password less than 7');
|
CustomSnackBar.displaySnackBar('Password less than 7');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (passwordController.text.isEmpty && pageType=='Online Password') {
|
if (passwordController.text.isEmpty) {
|
||||||
CustomSnackBar.displaySnackBar('Password required');
|
CustomSnackBar.displaySnackBar('Password required');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (passwordNameController.text.isEmpty && pageType=='Online Password') {
|
if (passwordNameController.text.isEmpty ) {
|
||||||
CustomSnackBar.displaySnackBar('Password name required');
|
CustomSnackBar.displaySnackBar('Password name required');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -329,7 +353,18 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool timeLimitValidate() {
|
||||||
|
|
||||||
|
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
||||||
|
CustomSnackBar.displaySnackBar('Select effective time');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (expirationTime == 'Select Time' || expirationTimeTimeStamp == null) {
|
||||||
|
CustomSnackBar.displaySnackBar('Select expiration time');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
List<Map<String, String>> days = [
|
List<Map<String, String>> days = [
|
||||||
{"day": "Sun", "key": "Sun"},
|
{"day": "Sun", "key": "Sun"},
|
||||||
@@ -352,6 +387,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
emit(ChangeTimeState());
|
emit(ChangeTimeState());
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTimeOnly(DateTime? dateTime) {
|
String getTimeOnly(DateTime? dateTime) {
|
||||||
if (dateTime == null) return '';
|
if (dateTime == null) return '';
|
||||||
return DateFormat('HH:mm').format(dateTime);
|
return DateFormat('HH:mm').format(dateTime);
|
||||||
|
|||||||
@@ -9,11 +9,9 @@ abstract class SmartDoorEvent extends Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InitialEvent extends SmartDoorEvent {}
|
class InitialEvent extends SmartDoorEvent {}
|
||||||
class InitialPasswordsPage extends SmartDoorEvent {
|
class InitialPasswordsPage extends SmartDoorEvent {}
|
||||||
final String? type;
|
|
||||||
const InitialPasswordsPage({ this.type});
|
|
||||||
}
|
|
||||||
class InitialOneTimePassword extends SmartDoorEvent {}
|
class InitialOneTimePassword extends SmartDoorEvent {}
|
||||||
|
class InitialTimeLimitPassword extends SmartDoorEvent {}
|
||||||
|
|
||||||
class UpdateLockEvent extends SmartDoorEvent {
|
class UpdateLockEvent extends SmartDoorEvent {
|
||||||
final bool value;
|
final bool value;
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class OfflinePasswordModel {
|
||||||
|
final dynamic gmtCreate;
|
||||||
|
final dynamic gmtExpired;
|
||||||
|
final dynamic gmtStart;
|
||||||
|
final bool hasClearPwd;
|
||||||
|
final String optUid;
|
||||||
|
final String pwd;
|
||||||
|
final dynamic pwdId;
|
||||||
|
final String pwdName;
|
||||||
|
final String pwdTypeCode;
|
||||||
|
final String revokedPwdName;
|
||||||
|
final dynamic status;
|
||||||
|
|
||||||
|
OfflinePasswordModel({
|
||||||
|
required this.gmtCreate,
|
||||||
|
required this.gmtExpired,
|
||||||
|
required this.gmtStart,
|
||||||
|
required this.hasClearPwd,
|
||||||
|
required this.optUid,
|
||||||
|
required this.pwd,
|
||||||
|
required this.pwdId,
|
||||||
|
required this.pwdName,
|
||||||
|
required this.pwdTypeCode,
|
||||||
|
required this.revokedPwdName,
|
||||||
|
required this.status,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Factory method to create a Password from a JSON map
|
||||||
|
factory OfflinePasswordModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return OfflinePasswordModel(
|
||||||
|
gmtCreate: json['gmtCreate'],
|
||||||
|
gmtExpired: json['gmtExpired'],
|
||||||
|
gmtStart: json['gmtStart'],
|
||||||
|
hasClearPwd: json['hasClearPwd'],
|
||||||
|
optUid: json['optUid'],
|
||||||
|
pwd: json['pwd'],
|
||||||
|
pwdId: json['pwdId'],
|
||||||
|
pwdName: json['pwdName'],
|
||||||
|
pwdTypeCode: json['pwdTypeCode'],
|
||||||
|
revokedPwdName: json['revokedPwdName'],
|
||||||
|
status: json['status'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to convert a Password object to a JSON map
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'gmtCreate': gmtCreate,
|
||||||
|
'gmtExpired': gmtExpired,
|
||||||
|
'gmtStart': gmtStart,
|
||||||
|
'hasClearPwd': hasClearPwd,
|
||||||
|
'optUid': optUid,
|
||||||
|
'pwd': pwd,
|
||||||
|
'pwdId': pwdId,
|
||||||
|
'pwdName': pwdName,
|
||||||
|
'pwdTypeCode': pwdTypeCode,
|
||||||
|
'revokedPwdName': revokedPwdName,
|
||||||
|
'status': status,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@@ -12,12 +10,12 @@ import 'package:syncrow_app/features/devices/view/widgets/smart_door/repeat_widg
|
|||||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/door_lock_button.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
|
|
||||||
class OfflineOneTimePasswordPage extends StatelessWidget {
|
class OfflineOneTimePasswordPage extends StatelessWidget {
|
||||||
final String? deviceId;
|
final String? deviceId;
|
||||||
final String? type;
|
final String? type;
|
||||||
@@ -102,8 +100,7 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
|
|||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
})
|
}) :[
|
||||||
:[
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -158,8 +155,7 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.of(context).size.width / 2.6,
|
width: MediaQuery.of(context).size.width / 2.6,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: BlocProvider.of<SmartDoorBloc>(context)
|
controller: BlocProvider.of<SmartDoorBloc>(context).passwordNameController,
|
||||||
.passwordNameController,
|
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
hintText: 'Enter The Name',
|
hintText: 'Enter The Name',
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
@@ -191,22 +187,26 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
|
|||||||
Center(
|
Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: MediaQuery.of(context).size.width/1.5,
|
width: MediaQuery.of(context).size.width/1.5,
|
||||||
child: DefaultButton(
|
child: DoorLockButton(
|
||||||
isDone: generated,
|
isDone: generated,
|
||||||
isLoading: smartDoorBloc.isSavingPassword ,
|
isLoading: smartDoorBloc.isSavingPassword ,
|
||||||
borderRadius: 30,
|
borderRadius: 30,
|
||||||
backgroundColor:ColorsManager.primaryColor ,
|
backgroundColor:ColorsManager.primaryColor ,
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
if(generated==false){
|
if(generated==false){
|
||||||
smartDoorBloc.add(GenerateAndSavePasswordOneTimeEvent(context: context));
|
smartDoorBloc.add(GenerateAndSavePasswordOneTimeEvent(context: context));
|
||||||
|
await Clipboard.setData(
|
||||||
|
ClipboardData(text: smartDoorBloc.passwordController.text)
|
||||||
|
);
|
||||||
}else{
|
}else{
|
||||||
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
||||||
smartDoorBloc.add(RenamePasswordEvent());
|
smartDoorBloc.add(RenamePasswordEvent());
|
||||||
}
|
}
|
||||||
Navigator.pop(context);
|
Navigator.of(context).pop(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: const BodyMedium(
|
child: const BodyMedium(
|
||||||
|
|
||||||
text: 'Obtain Password',
|
text: 'Obtain Password',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontColor: Colors.white,
|
fontColor: Colors.white,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/offline_password_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
|
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
@@ -7,13 +8,15 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
class DoorDialog extends StatefulWidget {
|
class DoorDialog extends StatefulWidget {
|
||||||
final String title;
|
final String? title;
|
||||||
final TemporaryPassword value;
|
final TemporaryPassword? temporaryPassword;
|
||||||
|
final OfflinePasswordModel? offline;
|
||||||
|
|
||||||
const DoorDialog({
|
const DoorDialog({
|
||||||
super.key,
|
super.key,
|
||||||
required this.title,
|
this.title,
|
||||||
required this.value,
|
this.offline,
|
||||||
|
this.temporaryPassword,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -28,16 +31,18 @@ class DoorDialogState extends State<DoorDialog> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final effectiveTime = widget.temporaryPassword?.effectiveTime ??int.parse( widget.offline?.gmtStart);
|
||||||
|
final invalidTime = widget.temporaryPassword?.invalidTime ?? int.parse(widget.offline?.gmtExpired);
|
||||||
|
|
||||||
final DateTime effectiveDateTime =
|
final DateTime effectiveDateTime =
|
||||||
DateTime.fromMillisecondsSinceEpoch(widget.value.effectiveTime * 1000, isUtc: false);
|
DateTime.fromMillisecondsSinceEpoch(effectiveTime! * 1000, isUtc: false);
|
||||||
String formattedDateEffectiveTime = DateFormat('yyyy-MM-dd').format(effectiveDateTime);
|
String formattedDateEffectiveTime = DateFormat('yyyy-MM-dd').format(effectiveDateTime);
|
||||||
String formattedTimeEffectiveTime = DateFormat('HH:mm:ss').format(effectiveDateTime);
|
String formattedTimeEffectiveTime = DateFormat('hh:mm a').format(effectiveDateTime);
|
||||||
|
|
||||||
final DateTime expiredDateTime =
|
final DateTime expiredDateTime =
|
||||||
DateTime.fromMillisecondsSinceEpoch(widget.value.invalidTime * 1000, isUtc: false);
|
DateTime.fromMillisecondsSinceEpoch(invalidTime! * 1000, isUtc: false);
|
||||||
String formattedDateExpiredDateTime = DateFormat('yyyy-MM-dd').format(expiredDateTime);
|
String formattedDateExpiredDateTime = DateFormat('yyyy-MM-dd').format(expiredDateTime);
|
||||||
String formattedTimeExpiredDateTime = DateFormat('HH:mm:ss').format(expiredDateTime);
|
String formattedTimeExpiredDateTime = DateFormat('hh:mm a').format(expiredDateTime);
|
||||||
|
|
||||||
return Dialog(
|
return Dialog(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -49,7 +54,7 @@ class DoorDialogState extends State<DoorDialog> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
BodyMedium(
|
BodyMedium(
|
||||||
text: widget.title,
|
text: widget.title ?? '',
|
||||||
style: context.bodyMedium.copyWith(
|
style: context.bodyMedium.copyWith(
|
||||||
color: ColorsManager.primaryColorWithOpacity,
|
color: ColorsManager.primaryColorWithOpacity,
|
||||||
fontWeight: FontsManager.extraBold,
|
fontWeight: FontsManager.extraBold,
|
||||||
@@ -111,7 +116,8 @@ class DoorDialogState extends State<DoorDialog> {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
color: ColorsManager.greyColor,
|
color: ColorsManager.greyColor,
|
||||||
),
|
),
|
||||||
Row(
|
widget.temporaryPassword?.effectiveTime!=null?
|
||||||
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
InkWell(
|
InkWell(
|
||||||
@@ -130,7 +136,7 @@ class DoorDialogState extends State<DoorDialog> {
|
|||||||
width: 1,
|
width: 1,
|
||||||
color: ColorsManager.greyColor,
|
color: ColorsManager.greyColor,
|
||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pop(context, 'delete');
|
Navigator.pop(context, 'delete');
|
||||||
},
|
},
|
||||||
@@ -142,6 +148,27 @@ class DoorDialogState extends State<DoorDialog> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
):
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 50,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: BodyMedium(
|
||||||
|
text: 'Cancel',
|
||||||
|
style: context.bodyMedium.copyWith(color: ColorsManager.greyColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
),
|
||||||
|
|
||||||
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -9,15 +9,16 @@ import 'package:syncrow_app/features/devices/view/widgets/smart_door/repeat_widg
|
|||||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/door_lock_button.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
class OfflineTimeLimitPasswordPage extends StatelessWidget {
|
class CreateOfflineTimeLimitPasswordPage extends StatelessWidget {
|
||||||
final String? deviceId;
|
final String? deviceId;
|
||||||
final String? type;
|
final String? type;
|
||||||
const OfflineTimeLimitPasswordPage({super.key, this.deviceId, this.type});
|
const CreateOfflineTimeLimitPasswordPage({super.key, this.deviceId, this.type});
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
bool isRepeat = false;
|
bool isRepeat = false;
|
||||||
@@ -253,21 +254,23 @@ class OfflineTimeLimitPasswordPage extends StatelessWidget {
|
|||||||
Center(
|
Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: MediaQuery.of(context).size.width / 1.5,
|
width: MediaQuery.of(context).size.width / 1.5,
|
||||||
child: DefaultButton(
|
child: DoorLockButton(
|
||||||
isDone: generated,
|
isDone: generated,
|
||||||
isLoading: smartDoorBloc.isSavingPassword,
|
isLoading: smartDoorBloc.isSavingPassword,
|
||||||
borderRadius: 30,
|
borderRadius: 30,
|
||||||
backgroundColor: ColorsManager.primaryColor,
|
backgroundColor: ColorsManager.primaryColor,
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
if (generated == false) {
|
if (generated == false) {
|
||||||
smartDoorBloc.add(
|
smartDoorBloc.add(
|
||||||
GenerateAndSavePasswordTimeLimitEvent(
|
GenerateAndSavePasswordTimeLimitEvent(context: context));
|
||||||
context: context));
|
await Clipboard.setData(
|
||||||
|
ClipboardData(text: smartDoorBloc.passwordController.text)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
||||||
smartDoorBloc.add(RenamePasswordEvent());
|
smartDoorBloc.add(RenamePasswordEvent());
|
||||||
}
|
}
|
||||||
Navigator.pop(context);
|
Navigator.of(context).pop(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: const BodyMedium(
|
child: const BodyMedium(
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/offline_one_time_password_page.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_dialog.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
|
class OnetimePasswordPage extends StatelessWidget {
|
||||||
|
final String? deviceId;
|
||||||
|
const OnetimePasswordPage({super.key, this.deviceId,});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialOneTimePassword( )),
|
||||||
|
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state is FailedState) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(state.errorMessage),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
builder: (context, state) {
|
||||||
|
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||||
|
return DefaultScaffold(
|
||||||
|
title: 'Passwords',
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(builder: (context) => OfflineOneTimePasswordPage(deviceId: deviceId, )
|
||||||
|
)).then((result) {
|
||||||
|
if(result!=null){
|
||||||
|
smartDoorBloc.add(InitialOneTimePassword());
|
||||||
|
smartDoorBloc.add(InitialOneTimePassword());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.add)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
return state is LoadingInitialState
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: Center(
|
||||||
|
child: smartDoorBloc.oneTimePasswords!.isNotEmpty
|
||||||
|
? ListView.builder(
|
||||||
|
itemCount: smartDoorBloc.oneTimePasswords!.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(5.0),
|
||||||
|
child: DefaultContainer(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||||
|
child: ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
leading: SvgPicture.asset(Assets.timeLimitedPasswordIcon),
|
||||||
|
title: BodyMedium(
|
||||||
|
text: 'Password Name: ${smartDoorBloc.oneTimePasswords![index].pwdName}',
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
final result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return DoorDialog(
|
||||||
|
title: 'Password Information',
|
||||||
|
offline: smartDoorBloc.oneTimePasswords![index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
},
|
||||||
|
trailing: const Icon(
|
||||||
|
Icons.arrow_forward_ios,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
) : Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(Assets.noValidPasswords),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
const BodyMedium(text: 'No Valid Passwords')
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/onetime_password_page.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/timelimited_password_page.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/view_temporary_password.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/view_temporary_password.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
@@ -90,7 +92,7 @@ class TemporaryPasswordPage extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ViewTemporaryPassword(deviceId:deviceId,type:'One-Time'),));
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => OnetimePasswordPage(deviceId:deviceId,),));
|
||||||
},
|
},
|
||||||
trailing: const Icon(
|
trailing: const Icon(
|
||||||
Icons.arrow_forward_ios,
|
Icons.arrow_forward_ios,
|
||||||
@@ -108,7 +110,7 @@ class TemporaryPasswordPage extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ViewTemporaryPassword(deviceId:deviceId,type:'Time-Limited'),));
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => TimeLimitedPasswordPage(deviceId:deviceId,),));
|
||||||
},
|
},
|
||||||
trailing: const Icon(
|
trailing: const Icon(
|
||||||
Icons.arrow_forward_ios,
|
Icons.arrow_forward_ios,
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/offline_timeLimit_password_page.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
import 'door_dialog.dart';
|
||||||
|
|
||||||
|
class TimeLimitedPasswordPage extends StatelessWidget {
|
||||||
|
final String? deviceId;
|
||||||
|
const TimeLimitedPasswordPage({super.key, this.deviceId});
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialTimeLimitPassword()),
|
||||||
|
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state is FailedState) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(state.errorMessage),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
builder: (context, state) {
|
||||||
|
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||||
|
return DefaultScaffold(
|
||||||
|
title: 'Passwords',
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(builder: (context) => CreateOfflineTimeLimitPasswordPage(deviceId: deviceId,)
|
||||||
|
)).then((result) {
|
||||||
|
if (result != null) {
|
||||||
|
smartDoorBloc.add(InitialTimeLimitPassword());
|
||||||
|
smartDoorBloc.add(InitialTimeLimitPassword());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.add)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
return state is LoadingInitialState
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: Center(
|
||||||
|
child: smartDoorBloc.timeLimitPasswords!.isNotEmpty
|
||||||
|
? ListView.builder(
|
||||||
|
itemCount: smartDoorBloc.timeLimitPasswords!.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(5.0),
|
||||||
|
child: DefaultContainer(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||||
|
child: ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
leading: SvgPicture.asset(Assets.timeLimitedPasswordIcon),
|
||||||
|
title: BodyMedium(
|
||||||
|
text: 'Password Name: ${smartDoorBloc.timeLimitPasswords![index].pwdName}',
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
final result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return DoorDialog(
|
||||||
|
title: 'Password Information',
|
||||||
|
offline: smartDoorBloc.timeLimitPasswords![index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
trailing: const Icon(
|
||||||
|
Icons.arrow_forward_ios,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
) : Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(Assets.noValidPasswords),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
const BodyMedium(text: 'No Valid Passwords')
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,6 @@ import 'package:flutter_svg/svg.dart';
|
|||||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/offline_one_time_password_page.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/offline_timeLimit_password_page.dart';
|
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
@@ -22,7 +20,7 @@ class ViewTemporaryPassword extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialPasswordsPage(type:type )),
|
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialPasswordsPage( )),
|
||||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is FailedState) {
|
if (state is FailedState) {
|
||||||
@@ -43,15 +41,10 @@ class ViewTemporaryPassword extends StatelessWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(builder: (context) =>
|
MaterialPageRoute(builder: (context) =>
|
||||||
type=='One-Time' ?
|
CreateTemporaryPassword(deviceId: deviceId, type: type))).then((result) {
|
||||||
OfflineOneTimePasswordPage(deviceId: deviceId, type: type)
|
|
||||||
: type=='Time-Limited' ?
|
|
||||||
OfflineTimeLimitPasswordPage(deviceId: deviceId, type: type)
|
|
||||||
:
|
|
||||||
CreateTemporaryPassword(deviceId: deviceId, type: type),
|
|
||||||
)).then((result) {
|
|
||||||
if (result != null && result) {
|
if (result != null && result) {
|
||||||
smartDoorBloc.add(InitialPasswordsPage(type:type ));
|
smartDoorBloc.add(InitialPasswordsPage());
|
||||||
|
smartDoorBloc.add(InitialPasswordsPage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -85,7 +78,7 @@ class ViewTemporaryPassword extends StatelessWidget {
|
|||||||
builder: (context) {
|
builder: (context) {
|
||||||
return DoorDialog(
|
return DoorDialog(
|
||||||
title: 'Password Information',
|
title: 'Password Information',
|
||||||
value: smartDoorBloc.temporaryPasswords![index],
|
temporaryPassword: smartDoorBloc.temporaryPasswords![index],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ class DefaultButton extends StatelessWidget {
|
|||||||
final double? padding;
|
final double? padding;
|
||||||
final bool isDone;
|
final bool isDone;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
|
|
||||||
final TextStyle? customTextStyle;
|
final TextStyle? customTextStyle;
|
||||||
|
|
||||||
final ButtonStyle? customButtonStyle;
|
final ButtonStyle? customButtonStyle;
|
||||||
@@ -91,12 +90,14 @@ class DefaultButton extends StatelessWidget {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: isDone
|
:
|
||||||
? const Icon(
|
|
||||||
Icons.check_circle_outline,
|
|
||||||
color: Colors.white,
|
isDone
|
||||||
)
|
? const Icon(
|
||||||
: child,
|
Icons.check_circle_outline,
|
||||||
|
color: Colors.white,
|
||||||
|
) :child ,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
|
class DoorLockButton extends StatelessWidget {
|
||||||
|
const DoorLockButton({
|
||||||
|
super.key,
|
||||||
|
this.enabled = true,
|
||||||
|
this.onPressed,
|
||||||
|
required this.child,
|
||||||
|
this.isSecondary = false,
|
||||||
|
this.isLoading = false,
|
||||||
|
this.isDone = false,
|
||||||
|
this.customTextStyle,
|
||||||
|
this.customButtonStyle,
|
||||||
|
this.backgroundColor,
|
||||||
|
this.foregroundColor,
|
||||||
|
this.borderRadius,
|
||||||
|
this.height,
|
||||||
|
this.padding,
|
||||||
|
});
|
||||||
|
|
||||||
|
final void Function()? onPressed;
|
||||||
|
final Widget child;
|
||||||
|
final double? height;
|
||||||
|
final bool isSecondary;
|
||||||
|
final double? borderRadius;
|
||||||
|
final bool enabled;
|
||||||
|
final double? padding;
|
||||||
|
final bool isDone;
|
||||||
|
final bool isLoading;
|
||||||
|
final TextStyle? customTextStyle;
|
||||||
|
|
||||||
|
final ButtonStyle? customButtonStyle;
|
||||||
|
|
||||||
|
final Color? backgroundColor;
|
||||||
|
|
||||||
|
final Color? foregroundColor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ElevatedButton(
|
||||||
|
onPressed: enabled ? onPressed : null,
|
||||||
|
style: isSecondary
|
||||||
|
? null
|
||||||
|
: customButtonStyle ??
|
||||||
|
ButtonStyle(
|
||||||
|
textStyle: MaterialStateProperty.all(
|
||||||
|
customTextStyle ??
|
||||||
|
context.bodyMedium.copyWith(
|
||||||
|
fontSize: 16,
|
||||||
|
color: foregroundColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
foregroundColor: MaterialStateProperty.all(
|
||||||
|
isSecondary
|
||||||
|
? Colors.black
|
||||||
|
: enabled
|
||||||
|
? foregroundColor ?? Colors.white
|
||||||
|
: Colors.black,
|
||||||
|
),
|
||||||
|
backgroundColor: MaterialStateProperty.resolveWith<Color>(
|
||||||
|
(Set<MaterialState> states) {
|
||||||
|
return enabled
|
||||||
|
? backgroundColor ?? ColorsManager.primaryColor
|
||||||
|
: Colors.grey;
|
||||||
|
}),
|
||||||
|
shape: MaterialStateProperty.all(
|
||||||
|
RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(borderRadius ?? 20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
fixedSize: MaterialStateProperty.all(
|
||||||
|
const Size.fromHeight(50),
|
||||||
|
),
|
||||||
|
padding: MaterialStateProperty.all(
|
||||||
|
EdgeInsets.all(padding ?? 10),
|
||||||
|
),
|
||||||
|
minimumSize: MaterialStateProperty.all(
|
||||||
|
const Size.fromHeight(50),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SizedBox(
|
||||||
|
height: height ?? 50,
|
||||||
|
child: Center(
|
||||||
|
child: isLoading
|
||||||
|
? const SizedBox.square(
|
||||||
|
dimension: 24,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: isDone
|
||||||
|
? const Text('Done') :child ,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -153,5 +153,5 @@ abstract class ApiEndpoints {
|
|||||||
|
|
||||||
//multiple-time offline
|
//multiple-time offline
|
||||||
static const String deleteTemporaryPassword =
|
static const String deleteTemporaryPassword =
|
||||||
'$baseUrl/door-lock/temporary-password/{doorLockUuid}/{passwordId}';
|
'$baseUrl/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:developer';
|
||||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
@@ -72,10 +73,12 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future<Map<String, dynamic>> renamePass({
|
static Future<Map<String, dynamic>> renamePass({
|
||||||
required String name,
|
required String name,
|
||||||
required String deviceId,
|
required String doorLockUuid,
|
||||||
required String passwordId}) async {
|
required String passwordId}) async {
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.put(
|
||||||
path: ApiEndpoints.renamePassword.replaceAll('{deviceUuid}', deviceId).replaceAll('{passwordId}', passwordId),
|
path: ApiEndpoints.renamePassword
|
||||||
|
.replaceAll('{doorLockUuid}', doorLockUuid)
|
||||||
|
.replaceAll('{passwordId}', passwordId),
|
||||||
body: {
|
body: {
|
||||||
"name": name
|
"name": name
|
||||||
},
|
},
|
||||||
@@ -155,10 +158,9 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future getTemporaryPasswords(String deviceId, pageType) async {
|
static Future getTemporaryPasswords(String deviceId, ) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path:
|
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@@ -167,35 +169,50 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
//create password
|
static Future getOneTimePasswords(String deviceId) async {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
log('==============$json');
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future getTimeLimitPasswords(String deviceId) async {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
print('00000000$json');
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create password
|
||||||
static Future createPassword({
|
static Future createPassword({
|
||||||
required String name,
|
required String name,
|
||||||
required String password,
|
required String password,
|
||||||
required String effectiveTime,
|
required String effectiveTime,
|
||||||
required String invalidTime,
|
required String invalidTime,
|
||||||
required String deviceId,
|
required String deviceId,
|
||||||
required String pageType,
|
List<Schedule>? scheduleList,}) async {
|
||||||
List<Schedule>? scheduleList,
|
|
||||||
}) async {
|
|
||||||
String endpointPath;
|
|
||||||
if (pageType == 'Online Password') {
|
|
||||||
endpointPath = ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId);
|
|
||||||
} else if (pageType == 'One-Time') {
|
|
||||||
endpointPath = ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId);
|
|
||||||
} else {
|
|
||||||
endpointPath = ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId);
|
|
||||||
}
|
|
||||||
Map<String, dynamic> body = {
|
Map<String, dynamic> body = {
|
||||||
"name": name,
|
"name": name,
|
||||||
"password": password,
|
"password": password,
|
||||||
"effectiveTime": effectiveTime,
|
"effectiveTime": effectiveTime,
|
||||||
"invalidTime": invalidTime,
|
"invalidTime": invalidTime,
|
||||||
};
|
};
|
||||||
if (pageType == 'Online Password' && scheduleList != null) {
|
if (scheduleList != null) {
|
||||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||||
}
|
}
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: endpointPath,
|
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
body: body,
|
body: body,
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => json,
|
expectedResponseModel: (json) => json,
|
||||||
@@ -209,6 +226,7 @@ class DevicesAPI {
|
|||||||
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
|
print('generateOneTimePassword=${json}');
|
||||||
return json;
|
return json;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -250,4 +268,6 @@ class DevicesAPI {
|
|||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user