mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 01:35:23 +00:00
CreateTemporaryPassword
This commit is contained in:
@ -1,68 +1,30 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:day_picker/model/day_in_week.dart';
|
import 'package:day_picker/model/day_in_week.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
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/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';
|
||||||
|
import 'package:syncrow_app/features/devices/model/create_temporary_password_model.dart';
|
||||||
|
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';
|
||||||
|
|
||||||
class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
late SmartDoorModel deviceStatus;
|
late SmartDoorModel deviceStatus;
|
||||||
TextEditingController passwordController = TextEditingController();
|
static String pageType = '';
|
||||||
TextEditingController passwordNameController = TextEditingController();
|
|
||||||
String effectiveTime = 'Select Time';
|
|
||||||
int? effectiveTimeTimeStamp;
|
|
||||||
String expirationTime = 'Select Time';
|
|
||||||
int? expirationTimeTimeStamp;
|
|
||||||
bool repeat = false;
|
|
||||||
bool isStartEndTime = true;
|
|
||||||
List<String>? selectedDay;
|
|
||||||
|
|
||||||
DateTime? startTime;
|
|
||||||
DateTime? endTime ;
|
|
||||||
|
|
||||||
|
|
||||||
changeTime(val,isStartEndTime){
|
|
||||||
emit(LoadingInitialState());
|
|
||||||
if(isStartEndTime==true){
|
|
||||||
startTime=val;
|
|
||||||
}else{
|
|
||||||
endTime=val;
|
|
||||||
}
|
|
||||||
emit(changeTimeState());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool repeatFunction() {
|
|
||||||
emit(LoadingInitialState());
|
|
||||||
repeat = !repeat;
|
|
||||||
emit(IsRepeatState());
|
|
||||||
return repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool isStartEndTimeFun(val) {
|
|
||||||
emit(LoadingInitialState());
|
|
||||||
isStartEndTime = val;
|
|
||||||
emit(IsStartEndState());
|
|
||||||
return isStartEndTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SmartDoorBloc({required this.deviceId}) : super(InitialState()) {
|
SmartDoorBloc({required this.deviceId}) : super(InitialState()) {
|
||||||
on<InitialEvent>(_fetchSmartDoorStatus);
|
on<InitialEvent>(_fetchSmartDoorStatus);
|
||||||
|
on<InitialPasswordsPage>(getTemporaryPasswords);
|
||||||
on<UpdateLockEvent>(_updateLock);
|
on<UpdateLockEvent>(_updateLock);
|
||||||
}
|
}
|
||||||
|
void _fetchSmartDoorStatus(InitialEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
void _fetchSmartDoorStatus(
|
|
||||||
InitialEvent event, Emitter<SmartDoorState> emit) async {
|
|
||||||
emit(LoadingInitialState());
|
|
||||||
try {
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
var response = await DevicesAPI.getDeviceStatus(deviceId);
|
var response = await DevicesAPI.getDeviceStatus(deviceId);
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
@ -76,6 +38,64 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getTemporaryPasswords(InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
pageType=event.type!;
|
||||||
|
var response = await DevicesAPI.getTemporaryPasswords(deviceId,pageType);
|
||||||
|
if (response is List) {
|
||||||
|
temporaryPasswords = response.map((item) => TemporaryPassword.fromJson(item)).toList();
|
||||||
|
} else if (response is Map && response.containsKey('data')) {
|
||||||
|
temporaryPasswords = (response['data'] as List).map((item) => TemporaryPassword.fromJson(item)).toList();
|
||||||
|
} else {
|
||||||
|
throw Exception("Unexpected response format");
|
||||||
|
}
|
||||||
|
emit(TemporaryPasswordsLoadedState( temporaryPassword: temporaryPasswords!));
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEditingController passwordController = TextEditingController();
|
||||||
|
TextEditingController passwordNameController = TextEditingController();
|
||||||
|
String effectiveTime = 'Select Time';
|
||||||
|
int? effectiveTimeTimeStamp;
|
||||||
|
String expirationTime ='Select Time';
|
||||||
|
int? expirationTimeTimeStamp;
|
||||||
|
bool repeat = false;
|
||||||
|
bool isStartEndTime = true;
|
||||||
|
List<String>? selectedDay;
|
||||||
|
DateTime? startTime;
|
||||||
|
DateTime? endTime;
|
||||||
|
List<TemporaryPassword>? temporaryPasswords=[];
|
||||||
|
List<TemporaryPassword>? oneTimePasswords=[];
|
||||||
|
|
||||||
|
changeTime(val, isStartEndTime) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
if (isStartEndTime == true) {
|
||||||
|
startTime = val;
|
||||||
|
} else {
|
||||||
|
endTime = val;
|
||||||
|
}
|
||||||
|
emit(changeTimeState());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool toggleRepeat() {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
repeat = !repeat;
|
||||||
|
emit(IsRepeatState());
|
||||||
|
return repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setStartEndTime(bool val) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
isStartEndTime = val;
|
||||||
|
emit(IsStartEndState());
|
||||||
|
return isStartEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void _updateLock(UpdateLockEvent event, Emitter<SmartDoorState> emit) async {
|
void _updateLock(UpdateLockEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
emit(LoadingNewSate(smartDoorModel: deviceStatus));
|
emit(LoadingNewSate(smartDoorModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
@ -97,8 +117,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
passwordController.clear();
|
passwordController.clear();
|
||||||
Random random = Random();
|
Random random = Random();
|
||||||
int min = 1000000; // Minimum 7-digit number
|
int min = 1000000;
|
||||||
int max = 9999999; // Maximum 7-digit number
|
int max = 9999999;
|
||||||
passwordController.text = (min + random.nextInt(max - min + 1)).toString();
|
passwordController.text = (min + random.nextInt(max - min + 1)).toString();
|
||||||
emit(GeneratePasswordState());
|
emit(GeneratePasswordState());
|
||||||
}
|
}
|
||||||
@ -124,34 +144,18 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
timePicked.minute,
|
timePicked.minute,
|
||||||
);
|
);
|
||||||
if (isEffective) {
|
if (isEffective) {
|
||||||
if (expirationTimeTimeStamp != null &&
|
if (expirationTimeTimeStamp != null && selectedDateTime.millisecondsSinceEpoch > expirationTimeTimeStamp!) {
|
||||||
selectedDateTime.millisecondsSinceEpoch >
|
_showSnackBar(context, 'Effective Time cannot be later than Expiration Time.');
|
||||||
expirationTimeTimeStamp!) {
|
|
||||||
// Show error message
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
const SnackBar(
|
|
||||||
content: Text(
|
|
||||||
'Effective Time cannot be later than Expiration Time.'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
effectiveTime = selectedDateTime.toString();
|
effectiveTime = selectedDateTime.toString();
|
||||||
effectiveTimeTimeStamp = selectedDateTime.millisecondsSinceEpoch;
|
effectiveTimeTimeStamp = selectedDateTime.millisecondsSinceEpoch;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (effectiveTimeTimeStamp != null &&
|
if (effectiveTimeTimeStamp != null && selectedDateTime.millisecondsSinceEpoch < effectiveTimeTimeStamp!) {
|
||||||
selectedDateTime.millisecondsSinceEpoch <
|
_showSnackBar(context, 'Expiration Time cannot be earlier than Effective Time.');
|
||||||
effectiveTimeTimeStamp!) {
|
|
||||||
// Show error message
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
const SnackBar(
|
|
||||||
content: Text(
|
|
||||||
'Expiration Time cannot be earlier than Effective Time.'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
expirationTime = selectedDateTime.toString();
|
expirationTime = selectedDateTime.toString();
|
||||||
expirationTimeTimeStamp = selectedDateTime.millisecondsSinceEpoch;
|
expirationTimeTimeStamp = selectedDateTime.millisecondsSinceEpoch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit(TimeSelectedState());
|
emit(TimeSelectedState());
|
||||||
@ -160,74 +164,98 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> saveFunction(BuildContext context,) async {
|
Future<void> savePassword(BuildContext context) async {
|
||||||
if (passwordController.text.isEmpty) {
|
if (_validateInputs(context)) return;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
try {
|
||||||
const SnackBar(
|
emit(LoadingInitialState());
|
||||||
content: Text('Password name required'),
|
var response = await DevicesAPI.createPassword(
|
||||||
backgroundColor: Colors.red,
|
pageType: pageType,
|
||||||
),
|
deviceId: deviceId,
|
||||||
|
effectiveTime: effectiveTimeTimeStamp.toString(),
|
||||||
|
invalidTime: expirationTimeTimeStamp.toString(),
|
||||||
|
name: passwordNameController.text,
|
||||||
|
password: passwordController.text,
|
||||||
|
scheduleList: [
|
||||||
|
if (repeat)
|
||||||
|
Schedule(
|
||||||
|
effectiveTime: getTimeOnly(startTime),
|
||||||
|
invalidTime: getTimeOnly(endTime).toString(),
|
||||||
|
workingDay: selectedDay!,
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
return;
|
add(InitialPasswordsPage(type: pageType));
|
||||||
}
|
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
||||||
if (passwordNameController.text.isEmpty) {
|
Navigator.pop(context);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
Navigator.pop(context);
|
||||||
const SnackBar(
|
} catch (e) {
|
||||||
content: Text('Password name required'),
|
emit(FailedState(errorMessage: 'Failed to save password: $e'));
|
||||||
backgroundColor: Colors.red,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
const SnackBar(
|
|
||||||
content: Text('Select effective time'),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (expirationTime == 'Select Time' || expirationTimeTimeStamp == null) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
const SnackBar(
|
|
||||||
content: Text('Select expiration time'),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void deletePassword(BuildContext context, passwordId) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
var response = await DevicesAPI.deletePassword(
|
||||||
|
deviceId: deviceId,
|
||||||
|
passwordId: passwordId
|
||||||
|
).then((value) async {
|
||||||
|
add(InitialPasswordsPage(type: pageType));
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool _validateInputs(BuildContext context) {
|
||||||
|
|
||||||
|
if (passwordController.text.isEmpty) {
|
||||||
|
_showSnackBar(context, 'Password required');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (passwordNameController.text.isEmpty) {
|
||||||
|
_showSnackBar(context, 'Password name required');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
||||||
|
_showSnackBar(context, 'Select effective time');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (expirationTime == 'Select Time' || expirationTimeTimeStamp == null) {
|
||||||
|
_showSnackBar(context, 'Select expiration time');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(repeat==true&&(endTime==null||startTime==null||selectedDay==null)){
|
||||||
|
_showSnackBar(context, 'Start Time and End time and the days required ');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showSnackBar(BuildContext context, String message) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(message),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
List<DayInWeek> days = [
|
List<DayInWeek> days = [
|
||||||
DayInWeek(
|
DayInWeek("Sun", dayKey: 'Sun'),
|
||||||
"Sun",
|
DayInWeek("Mon", dayKey: 'Mon'),
|
||||||
dayKey: 'Sun',
|
DayInWeek("Tue", dayKey: 'Tue'),
|
||||||
),
|
DayInWeek("Wed", dayKey: 'Wed'),
|
||||||
DayInWeek(
|
DayInWeek("Thu", dayKey: 'Thu'),
|
||||||
"Mon",
|
DayInWeek("Fri", dayKey: 'Fri'),
|
||||||
dayKey: 'Mon',
|
DayInWeek("Sat", dayKey: 'Sat'),
|
||||||
),
|
|
||||||
DayInWeek(
|
|
||||||
"Tue",
|
|
||||||
isSelected: true,
|
|
||||||
dayKey: 'Tue'
|
|
||||||
),
|
|
||||||
DayInWeek(
|
|
||||||
"Wed",
|
|
||||||
dayKey: 'Wed',
|
|
||||||
),
|
|
||||||
DayInWeek(
|
|
||||||
"Thu",
|
|
||||||
dayKey: 'Thu',
|
|
||||||
),
|
|
||||||
DayInWeek(
|
|
||||||
"Fri",
|
|
||||||
dayKey: 'Fri',
|
|
||||||
),
|
|
||||||
DayInWeek(
|
|
||||||
"Sat",
|
|
||||||
dayKey: 'Sat',
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
String getTimeOnly(DateTime? dateTime) {
|
||||||
|
if (dateTime == null) return '';
|
||||||
|
return DateFormat('HH:mm').format(dateTime);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,11 @@ abstract class SmartDoorEvent extends Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InitialEvent extends SmartDoorEvent {}
|
class InitialEvent extends SmartDoorEvent {}
|
||||||
|
class InitialPasswordsPage extends SmartDoorEvent {
|
||||||
|
final String? type;
|
||||||
|
const InitialPasswordsPage({ this.type});
|
||||||
|
}
|
||||||
|
class InitialOneTimePassword extends SmartDoorEvent {}
|
||||||
|
|
||||||
class UpdateLockEvent extends SmartDoorEvent {
|
class UpdateLockEvent extends SmartDoorEvent {
|
||||||
final bool value;
|
final bool value;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.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/temporary_password_model.dart';
|
||||||
|
|
||||||
class SmartDoorState extends Equatable {
|
class SmartDoorState extends Equatable {
|
||||||
const SmartDoorState();
|
const SmartDoorState();
|
||||||
@ -44,3 +45,7 @@ class IsStartEndState extends SmartDoorState{}
|
|||||||
class changeStartTimeState extends SmartDoorState{}
|
class changeStartTimeState extends SmartDoorState{}
|
||||||
class changeEndTimeState extends SmartDoorState{}
|
class changeEndTimeState extends SmartDoorState{}
|
||||||
class changeTimeState extends SmartDoorState{}
|
class changeTimeState extends SmartDoorState{}
|
||||||
|
class TemporaryPasswordsLoadedState extends SmartDoorState{
|
||||||
|
final List<TemporaryPassword> temporaryPassword;
|
||||||
|
const TemporaryPasswordsLoadedState({required this.temporaryPassword});
|
||||||
|
}
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CreateTemporaryPasswordModel{
|
||||||
|
final String name;
|
||||||
|
late final String password;
|
||||||
|
late final String effectiveTime;
|
||||||
|
late final String invalidTime;
|
||||||
|
List<Schedule>? scheduleList;
|
||||||
|
|
||||||
|
CreateTemporaryPasswordModel({
|
||||||
|
required this.name,
|
||||||
|
required this.password,
|
||||||
|
required this.effectiveTime,
|
||||||
|
required this.invalidTime,
|
||||||
|
this.scheduleList,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory CreateTemporaryPasswordModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return CreateTemporaryPasswordModel(
|
||||||
|
name: json['name'],
|
||||||
|
password: json['password'],
|
||||||
|
effectiveTime: json['effectiveTime'],
|
||||||
|
invalidTime: json['invalidTime'],
|
||||||
|
scheduleList: (json['scheduleList'] as List)
|
||||||
|
.map((i) => Schedule.fromJson(i))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'name': name,
|
||||||
|
'password': password,
|
||||||
|
'effectiveTime': effectiveTime,
|
||||||
|
'invalidTime': invalidTime,
|
||||||
|
'scheduleList': scheduleList!.map((i) => i.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
37
lib/features/devices/model/temporary_password_model.dart
Normal file
37
lib/features/devices/model/temporary_password_model.dart
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
class TemporaryPassword {
|
||||||
|
final int effectiveTime;
|
||||||
|
final int id;
|
||||||
|
final int invalidTime;
|
||||||
|
final String name;
|
||||||
|
final int phase;
|
||||||
|
final String phone;
|
||||||
|
final int sn;
|
||||||
|
final String timeZone;
|
||||||
|
final int type;
|
||||||
|
|
||||||
|
TemporaryPassword({
|
||||||
|
required this.effectiveTime,
|
||||||
|
required this.id,
|
||||||
|
required this.invalidTime,
|
||||||
|
required this.name,
|
||||||
|
required this.phase,
|
||||||
|
required this.phone,
|
||||||
|
required this.sn,
|
||||||
|
required this.timeZone,
|
||||||
|
required this.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TemporaryPassword.fromJson(Map<String, dynamic> json) {
|
||||||
|
return TemporaryPassword(
|
||||||
|
effectiveTime: json['effectiveTime'],
|
||||||
|
id: json['id'],
|
||||||
|
invalidTime: json['invalidTime'],
|
||||||
|
name: json['name'],
|
||||||
|
phase: json['phase'],
|
||||||
|
phone: json['phone'] ?? '',
|
||||||
|
sn: json['sn'],
|
||||||
|
timeZone: json['timeZone'] ?? '',
|
||||||
|
type: json['type'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -240,8 +240,7 @@ class CeilingSensorInterface extends StatelessWidget {
|
|||||||
padding:
|
padding:
|
||||||
const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
|
const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (ceilingSensorButtons()[index]['title'] ==
|
if (ceilingSensorButtons()[index]['title'] == 'Sensitivity') {
|
||||||
'Sensitivity') {
|
|
||||||
final result = await showDialog(
|
final result = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
@ -11,21 +11,18 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
|
|||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:time_picker_spinner/time_picker_spinner.dart';
|
import 'package:time_picker_spinner/time_picker_spinner.dart';
|
||||||
|
|
||||||
class CreateTemporaryPassword extends StatefulWidget {
|
class CreateTemporaryPassword extends StatelessWidget {
|
||||||
const CreateTemporaryPassword({super.key});
|
final String? deviceId;
|
||||||
|
|
||||||
@override
|
const CreateTemporaryPassword({super.key,this.deviceId});
|
||||||
State<CreateTemporaryPassword> createState() =>
|
|
||||||
_CreateTemporaryPasswordState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (BuildContext context) => SmartDoorBloc(deviceId: ''),
|
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
|
||||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
|
print(state);
|
||||||
if (state is FailedState) {
|
if (state is FailedState) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
@ -34,18 +31,22 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, builder: (context, state) {
|
|
||||||
|
|
||||||
|
}, builder: (context, state) {
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
title: 'Create Password',
|
title: 'Create Password',
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
BlocProvider.of<SmartDoorBloc>(context).saveFunction(context);
|
BlocProvider.of<SmartDoorBloc>(context).savePassword(context);
|
||||||
},
|
},
|
||||||
child: const Text('Save'))
|
child: const Text('Save'))
|
||||||
],
|
],
|
||||||
child: SingleChildScrollView(
|
child: state is LoadingInitialState?
|
||||||
child: Column(
|
const Center(child: CircularProgressIndicator()): SingleChildScrollView(
|
||||||
|
child:
|
||||||
|
Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -64,8 +65,7 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
fontColor: ColorsManager.grayColor,
|
fontColor: ColorsManager.grayColor,
|
||||||
),
|
),
|
||||||
DefaultContainer(
|
DefaultContainer(
|
||||||
padding:
|
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||||
const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -125,8 +125,7 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
width: MediaQuery.of(context).size.width / 2,
|
width: MediaQuery.of(context).size.width / 2,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller:
|
controller:
|
||||||
BlocProvider.of<SmartDoorBloc>(context)
|
BlocProvider.of<SmartDoorBloc>(context).passwordNameController,
|
||||||
.passwordNameController,
|
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Enter The Name'),
|
labelText: 'Enter The Name'),
|
||||||
)),
|
)),
|
||||||
@ -146,8 +145,8 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
.selectTime(context, isEffective: true);
|
.selectTime(context, isEffective: true);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
BlocProvider.of<SmartDoorBloc>(context)
|
BlocProvider.of<SmartDoorBloc>(context).effectiveTime
|
||||||
.effectiveTime),
|
),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
@ -194,7 +193,7 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
BlocProvider.of<SmartDoorBloc>(context).repeat,
|
BlocProvider.of<SmartDoorBloc>(context).repeat,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
BlocProvider.of<SmartDoorBloc>(context)
|
BlocProvider.of<SmartDoorBloc>(context)
|
||||||
.repeatFunction();
|
.toggleRepeat();
|
||||||
},
|
},
|
||||||
applyTheme: true,
|
applyTheme: true,
|
||||||
)),
|
)),
|
||||||
@ -217,14 +216,14 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
children: [
|
children: [
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<SmartDoorBloc>(context).isStartEndTimeFun(true);
|
BlocProvider.of<SmartDoorBloc>(context).setStartEndTime(true);
|
||||||
},
|
},
|
||||||
child: BodyMedium(text: 'Start',fontColor:BlocProvider.of<SmartDoorBloc>(context).isStartEndTime==false? Colors.black:Colors.blue,fontSize: 18,),
|
child: BodyMedium(text: 'Start',fontColor:BlocProvider.of<SmartDoorBloc>(context).isStartEndTime==false? Colors.black:Colors.blue,fontSize: 18,),
|
||||||
),
|
),
|
||||||
|
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<SmartDoorBloc>(context).isStartEndTimeFun(false);
|
BlocProvider.of<SmartDoorBloc>(context).setStartEndTime(false);
|
||||||
},
|
},
|
||||||
child: BodyMedium(text: 'End',fontColor:BlocProvider.of<SmartDoorBloc>(context).isStartEndTime? Colors.black:Colors.blue,fontSize: 18,),
|
child: BodyMedium(text: 'End',fontColor:BlocProvider.of<SmartDoorBloc>(context).isStartEndTime? Colors.black:Colors.blue,fontSize: 18,),
|
||||||
)
|
)
|
||||||
@ -234,10 +233,10 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
const Divider(),
|
const Divider(),
|
||||||
Container(
|
Container(
|
||||||
height: 80,
|
height: 80,
|
||||||
child: BlocProvider.of<SmartDoorBloc>(context).isStartEndTime?
|
child:
|
||||||
Container(
|
Container(
|
||||||
height: 90,
|
height: 90,
|
||||||
child: TimePickerSpinner(
|
child:BlocProvider.of<SmartDoorBloc>(context).isStartEndTime? TimePickerSpinner(
|
||||||
time:
|
time:
|
||||||
BlocProvider.of<SmartDoorBloc>(context).startTime,
|
BlocProvider.of<SmartDoorBloc>(context).startTime,
|
||||||
is24HourMode: false,
|
is24HourMode: false,
|
||||||
@ -248,30 +247,24 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
highlightedTextStyle: const TextStyle(
|
highlightedTextStyle: const TextStyle(
|
||||||
fontSize: 30, color: Colors.blue),
|
fontSize: 30, color: Colors.blue),
|
||||||
onTimeChange: (time) {
|
onTimeChange: (time) {
|
||||||
BlocProvider.of<SmartDoorBloc>(context).startTime=time;
|
|
||||||
BlocProvider.of<SmartDoorBloc>(context).changeTime(time, BlocProvider.of<SmartDoorBloc>(context).isStartEndTime);
|
BlocProvider.of<SmartDoorBloc>(context).changeTime(time, BlocProvider.of<SmartDoorBloc>(context).isStartEndTime);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
): Container(
|
||||||
|
child: TimePickerSpinner(
|
||||||
|
time: BlocProvider.of<SmartDoorBloc>(context).endTime,
|
||||||
|
is24HourMode: false,
|
||||||
|
itemHeight: 40,
|
||||||
|
normalTextStyle: const TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
),
|
||||||
|
highlightedTextStyle: const TextStyle(
|
||||||
|
fontSize: 30, color: Colors.blue),
|
||||||
|
onTimeChange: (time) {
|
||||||
|
BlocProvider.of<SmartDoorBloc>(context).changeTime(time, BlocProvider.of<SmartDoorBloc>(context).isStartEndTime);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
):
|
)
|
||||||
TimePickerSpinner(
|
|
||||||
time: BlocProvider.of<SmartDoorBloc>(context).endTime,
|
|
||||||
is24HourMode: false,
|
|
||||||
itemHeight: 40,
|
|
||||||
normalTextStyle: const TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
),
|
|
||||||
highlightedTextStyle: const TextStyle(
|
|
||||||
fontSize: 24, color: Colors.blue),
|
|
||||||
onTimeChange: (time) {
|
|
||||||
setState(() {
|
|
||||||
BlocProvider.of<SmartDoorBloc>(context).endTime=time;
|
|
||||||
BlocProvider.of<SmartDoorBloc>(context).changeTime(time, BlocProvider.of<SmartDoorBloc>(context).isStartEndTime);
|
|
||||||
|
|
||||||
// dateTime = time;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
@ -288,9 +281,7 @@ class _CreateTemporaryPasswordState extends State<CreateTemporaryPassword> {
|
|||||||
borderRadius: BorderRadius.circular(30.0),
|
borderRadius: BorderRadius.circular(30.0),
|
||||||
color: Colors.white),
|
color: Colors.white),
|
||||||
onSelect: (values) {
|
onSelect: (values) {
|
||||||
print(values);
|
BlocProvider.of<SmartDoorBloc>(context).selectedDay = values;
|
||||||
BlocProvider.of<SmartDoorBloc>(context)
|
|
||||||
.selectedDay = values;
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
135
lib/features/devices/view/widgets/smart_door/door_dialog.dart
Normal file
135
lib/features/devices/view/widgets/smart_door/door_dialog.dart
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_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/title_medium.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.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/font_manager.dart';
|
||||||
|
|
||||||
|
class DoorDialog extends StatefulWidget {
|
||||||
|
final String title;
|
||||||
|
final TemporaryPassword value;
|
||||||
|
|
||||||
|
const DoorDialog({
|
||||||
|
super.key,
|
||||||
|
required this.title,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
DoorDialogState createState() => DoorDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class DoorDialogState extends State<DoorDialog> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final DateTime effectiveDateTime =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(widget.value.effectiveTime);
|
||||||
|
final DateTime expiredDateTime =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(widget.value.invalidTime);
|
||||||
|
final DateFormat formatter = DateFormat('HH:mm');
|
||||||
|
return Dialog(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.only(top: 20),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
BodyMedium(
|
||||||
|
text: widget.title,
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.primaryColorWithOpacity,
|
||||||
|
fontWeight: FontsManager.extraBold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 15,
|
||||||
|
horizontal: 50,
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
height: 1,
|
||||||
|
width: double.infinity,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(15.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
const Text('Effective Time :'),
|
||||||
|
Text(formatter.format(effectiveDateTime)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
const Text('Expired Time :'),
|
||||||
|
Text(formatter.format(expiredDateTime)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 1,
|
||||||
|
width: double.infinity,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: BodyMedium(
|
||||||
|
text: 'Cancel',
|
||||||
|
style: context.bodyMedium
|
||||||
|
.copyWith(color: ColorsManager.greyColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 50,
|
||||||
|
width: 1,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context, 'delete');
|
||||||
|
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: BodyMedium(
|
||||||
|
text: 'Delete Password',
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.primaryColorWithOpacity),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -10,9 +10,9 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart
|
|||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
|
||||||
class DoorLockGrid extends StatelessWidget {
|
class DoorLockGrid extends StatelessWidget {
|
||||||
const DoorLockGrid({
|
String uuid;
|
||||||
super.key,
|
DoorLockGrid({
|
||||||
});
|
super.key,required this.uuid});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -29,10 +29,10 @@ class DoorLockGrid extends StatelessWidget {
|
|||||||
itemBuilder: (context, index) => DefaultContainer(
|
itemBuilder: (context, index) => DefaultContainer(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
//TODO: remove checking after adding the pages
|
//TODO: remove checking after adding the pages
|
||||||
doorLockButtons[index]['page'] != null
|
doorLockButtons()[index]['page'] != null
|
||||||
? Navigator.of(context).push(
|
? Navigator.of(context).push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => doorLockButtons[index]['page'] as Widget,
|
builder: (context) => doorLockButtons(val: uuid)[index]['page'] as Widget,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
@ -44,7 +44,7 @@ class DoorLockGrid extends StatelessWidget {
|
|||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxHeight: 46, maxWidth: 50),
|
constraints: const BoxConstraints(maxHeight: 46, maxWidth: 50),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
doorLockButtons[index]['image'] as String,
|
doorLockButtons()[index]['image'] as String,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
@ -53,7 +53,7 @@ class DoorLockGrid extends StatelessWidget {
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
child: BodySmall(
|
child: BodySmall(
|
||||||
text: doorLockButtons[index]['title'] as String,
|
text: doorLockButtons()[index]['title'] as String,
|
||||||
// doorLockButtons.keys.elementAt(index),
|
// doorLockButtons.keys.elementAt(index),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
@ -66,7 +66,7 @@ class DoorLockGrid extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Map<String, dynamic>> doorLockButtons = [
|
List<Map<String, dynamic>> doorLockButtons({val}) => [
|
||||||
{
|
{
|
||||||
'title': 'Unlocking Records',
|
'title': 'Unlocking Records',
|
||||||
'image': Assets.assetsIconsDoorlockAssetsUnlockingRecords,
|
'image': Assets.assetsIconsDoorlockAssetsUnlockingRecords,
|
||||||
@ -80,7 +80,7 @@ List<Map<String, dynamic>> doorLockButtons = [
|
|||||||
{
|
{
|
||||||
'title': 'Temporary Password',
|
'title': 'Temporary Password',
|
||||||
'image': Assets.assetsIconsDoorlockAssetsTemporaryPassword,
|
'image': Assets.assetsIconsDoorlockAssetsTemporaryPassword,
|
||||||
'page':const TemporaryPasswordPage() ,
|
'page': TemporaryPasswordPage(deviceId:val) ,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Smart Linkage',
|
'title': 'Smart Linkage',
|
||||||
|
@ -111,7 +111,7 @@ class DoorInterface extends StatelessWidget {
|
|||||||
doorLock: doorLock,
|
doorLock: doorLock,
|
||||||
smartDoorModel: smartDoorModel,
|
smartDoorModel: smartDoorModel,
|
||||||
),
|
),
|
||||||
const DoorLockGrid(),
|
DoorLockGrid( uuid: doorLock.uuid!, ),
|
||||||
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -9,14 +9,10 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
|
|||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class TemporaryPasswordPage extends StatefulWidget {
|
class TemporaryPasswordPage extends StatelessWidget {
|
||||||
const TemporaryPasswordPage({super.key});
|
final String? deviceId;
|
||||||
|
const TemporaryPasswordPage({super.key,this.deviceId});
|
||||||
|
|
||||||
@override
|
|
||||||
State<TemporaryPasswordPage> createState() => _TemporaryPasswordPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _TemporaryPasswordPageState extends State<TemporaryPasswordPage> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
@ -50,48 +46,15 @@ class _TemporaryPasswordPageState extends State<TemporaryPasswordPage> {
|
|||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const ViewTemporaryPassword(),));
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ViewTemporaryPassword(deviceId:deviceId,type:'Online Password'),));
|
||||||
},
|
},
|
||||||
trailing: const Icon(
|
trailing: const Icon(
|
||||||
|
|
||||||
Icons.arrow_forward_ios,
|
Icons.arrow_forward_ios,
|
||||||
color: ColorsManager.greyColor,
|
color: ColorsManager.greyColor,
|
||||||
size: 15,
|
size: 15,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Row(
|
|
||||||
// children: [
|
|
||||||
// Expanded(
|
|
||||||
// child: Row(
|
|
||||||
// children: [
|
|
||||||
// SizedBox(
|
|
||||||
// width: 45,
|
|
||||||
// height: 40,
|
|
||||||
// child: SvgPicture.asset(
|
|
||||||
// Assets.timeLimitedPasswordIcon),
|
|
||||||
// ),
|
|
||||||
// const SizedBox(width: 15),
|
|
||||||
// const Expanded(
|
|
||||||
// child:
|
|
||||||
// BodyMedium(
|
|
||||||
// text: 'Time-Limited Password',
|
|
||||||
// fontWeight: FontWeight.normal,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// const Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
// children: [
|
|
||||||
// Icon(
|
|
||||||
// Icons.arrow_forward_ios,
|
|
||||||
// color: ColorsManager.greyColor,
|
|
||||||
// size: 15,
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -123,96 +86,35 @@ class _TemporaryPasswordPageState extends State<TemporaryPasswordPage> {
|
|||||||
text: 'One-Time Password',
|
text: 'One-Time Password',
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
),
|
),
|
||||||
onTap: () {},
|
onTap: () {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ViewTemporaryPassword(deviceId:deviceId,type:'One-Time'),));
|
||||||
|
|
||||||
|
},
|
||||||
trailing: const Icon(
|
trailing: const Icon(
|
||||||
Icons.arrow_forward_ios,
|
Icons.arrow_forward_ios,
|
||||||
color: ColorsManager.greyColor,
|
color: ColorsManager.greyColor,
|
||||||
size: 15,
|
size: 15,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Row(
|
|
||||||
// children: [
|
|
||||||
// Expanded(
|
|
||||||
// child: Row(
|
|
||||||
// children: [
|
|
||||||
// SizedBox(
|
|
||||||
// width: 45,
|
|
||||||
// height: 40,
|
|
||||||
// child: SvgPicture.asset(
|
|
||||||
// Assets.oneTimePassword),
|
|
||||||
// ),
|
|
||||||
// const SizedBox(width: 15),
|
|
||||||
// const Expanded(
|
|
||||||
// child: BodyMedium(
|
|
||||||
// text: 'One-Time Password',
|
|
||||||
// fontWeight: FontWeight.normal,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// const Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
// children: [
|
|
||||||
// Icon(
|
|
||||||
// Icons.arrow_forward_ios,
|
|
||||||
// color: ColorsManager.greyColor,
|
|
||||||
// size: 15,
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
const Divider( ),
|
const Divider( ),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
leading: SvgPicture.asset(
|
leading: SvgPicture.asset(
|
||||||
Assets.timeLimitedPassword),
|
Assets.timeLimitedPassword),
|
||||||
title: BodyMedium(
|
title: const BodyMedium(
|
||||||
text: 'Time-Limited Password',
|
text: 'Time-Limited Password',
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
),
|
),
|
||||||
onTap: () {},
|
onTap: () {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ViewTemporaryPassword(deviceId:deviceId,type:'Time-Limited'),));
|
||||||
|
},
|
||||||
trailing: const Icon(
|
trailing: const Icon(
|
||||||
Icons.arrow_forward_ios,
|
Icons.arrow_forward_ios,
|
||||||
color: ColorsManager.greyColor,
|
color: ColorsManager.greyColor,
|
||||||
size: 15,
|
size: 15,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Row(
|
|
||||||
// children: [
|
|
||||||
// Expanded(
|
|
||||||
// child: Row(
|
|
||||||
// children: [
|
|
||||||
// SizedBox(
|
|
||||||
// width: 45,
|
|
||||||
// height: 40,
|
|
||||||
// child: SvgPicture.asset(
|
|
||||||
// Assets.timeLimitedPassword),
|
|
||||||
//
|
|
||||||
// ),
|
|
||||||
// const SizedBox(width: 15),
|
|
||||||
// const Expanded(
|
|
||||||
// child: BodyMedium(
|
|
||||||
// text: 'Time-Limited Password',
|
|
||||||
// fontWeight: FontWeight.normal,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// const Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
// children: [
|
|
||||||
// Icon(
|
|
||||||
// Icons.arrow_forward_ios,
|
|
||||||
// color: ColorsManager.greyColor,
|
|
||||||
// size: 15,
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
],)
|
],)
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,45 +1,112 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/svg.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/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';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'create_temporary_password.dart';
|
import 'create_temporary_password.dart';
|
||||||
|
import 'door_dialog.dart';
|
||||||
|
|
||||||
class ViewTemporaryPassword extends StatelessWidget {
|
class ViewTemporaryPassword extends StatelessWidget {
|
||||||
const ViewTemporaryPassword({super.key});
|
final String? deviceId;
|
||||||
|
final String? type;
|
||||||
|
const ViewTemporaryPassword({super.key, this.deviceId, this.type});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DefaultScaffold(
|
return BlocProvider(
|
||||||
title: 'Passwords',
|
create: (BuildContext context) =>
|
||||||
actions: [
|
SmartDoorBloc(deviceId: deviceId!)..add(InitialPasswordsPage(type:type )),
|
||||||
IconButton(
|
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||||
onPressed: () {
|
listener: (context, state) {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const CreateTemporaryPassword(),));
|
if (state is FailedState) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
},
|
SnackBar(
|
||||||
icon: const Icon(Icons.add)
|
content: Text(state.errorMessage),
|
||||||
)
|
backgroundColor: Colors.red,
|
||||||
],
|
),
|
||||||
child: Container(
|
);
|
||||||
child: Center(
|
}
|
||||||
child:Column(
|
}, builder: (context, state) {
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
return DefaultScaffold(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
title: 'Passwords',
|
||||||
children: [
|
actions: [
|
||||||
SvgPicture.asset(
|
IconButton(
|
||||||
Assets.noValidPasswords
|
onPressed: () {
|
||||||
),
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
const SizedBox(height: 10,),
|
builder: (context) =>
|
||||||
const BodyMedium(text: 'No Valid Passwords')
|
CreateTemporaryPassword(deviceId: deviceId),
|
||||||
],
|
));
|
||||||
),
|
},
|
||||||
),
|
icon: const Icon(Icons.add))
|
||||||
)
|
],
|
||||||
);;
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||||
|
return state is LoadingInitialState
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: Center(
|
||||||
|
child: smartDoorBloc.temporaryPasswords!.isNotEmpty
|
||||||
|
? ListView.builder(
|
||||||
|
itemCount: smartDoorBloc.temporaryPasswords!.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.temporaryPasswords![index].name}',
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
final result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return DoorDialog(
|
||||||
|
title: 'Password Information',
|
||||||
|
value: smartDoorBloc.temporaryPasswords![index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if(result=='delete'){
|
||||||
|
smartDoorBloc.deletePassword(context, smartDoorBloc.temporaryPasswords![index].id.toString());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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')
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,4 +111,24 @@ abstract class ApiEndpoints {
|
|||||||
static const String editDevicePermission = '$baseUrl/device-permission/edit/{userId}';
|
static const String editDevicePermission = '$baseUrl/device-permission/edit/{userId}';
|
||||||
|
|
||||||
static const String assignDeviceToRoom = '$baseUrl/device/room';
|
static const String assignDeviceToRoom = '$baseUrl/device/room';
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////Door Lock //////////////////////
|
||||||
|
//online
|
||||||
|
static const String addTemporaryPassword = '$baseUrl/door-lock/temporary-password/online/{doorLockUuid}';
|
||||||
|
static const String getTemporaryPassword = '$baseUrl/door-lock/temporary-password/online/{doorLockUuid}';
|
||||||
|
|
||||||
|
|
||||||
|
//one-time offline
|
||||||
|
static const String addOneTimeTemporaryPassword = '$baseUrl/door-lock/temporary-password/offline/one-time/{doorLockUuid}';
|
||||||
|
static const String getOneTimeTemporaryPassword = '$baseUrl/door-lock/temporary-password/offline/one-time/{doorLockUuid}';
|
||||||
|
|
||||||
|
//multiple-time offline
|
||||||
|
static const String addMultipleTimeTemporaryPassword = '$baseUrl/door-lock/temporary-password/offline/multiple-time/{doorLockUuid}';
|
||||||
|
static const String getMultipleTimeTemporaryPassword = '$baseUrl/door-lock/temporary-password/offline/multiple-time/{doorLockUuid}';
|
||||||
|
|
||||||
|
//multiple-time offline
|
||||||
|
static const String deleteTemporaryPassword = '$baseUrl/door-lock/temporary-password/{doorLockUuid}/{passwordId}';
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
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';
|
||||||
@ -6,6 +7,8 @@ import 'package:syncrow_app/features/devices/model/device_model.dart';
|
|||||||
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
||||||
import 'package:syncrow_app/services/api/http_service.dart';
|
import 'package:syncrow_app/services/api/http_service.dart';
|
||||||
|
|
||||||
|
import '../../features/devices/model/create_temporary_password_model.dart';
|
||||||
|
|
||||||
class DevicesAPI {
|
class DevicesAPI {
|
||||||
static final HTTPService _httpService = HTTPService();
|
static final HTTPService _httpService = HTTPService();
|
||||||
|
|
||||||
@ -58,7 +61,8 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
|
path: ApiEndpoints.deviceFunctionsStatus
|
||||||
|
.replaceAll('{deviceUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -67,7 +71,8 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDeviceByGroupName(String unitId, String groupName) async {
|
static Future<List<DeviceModel>> getDeviceByGroupName(
|
||||||
|
String unitId, String groupName) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.devicesByGroupName
|
path: ApiEndpoints.devicesByGroupName
|
||||||
.replaceAll('{unitUuid}', unitId)
|
.replaceAll('{unitUuid}', unitId)
|
||||||
@ -106,7 +111,8 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
|
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
||||||
|
String gatewayId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
@ -123,4 +129,79 @@ class DevicesAPI {
|
|||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future getTemporaryPasswords(String deviceId, pageType) async {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: pageType == 'One-Time'
|
||||||
|
? ApiEndpoints.getOneTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId)
|
||||||
|
: pageType == 'Online Password'
|
||||||
|
? ApiEndpoints.getTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId)
|
||||||
|
: ApiEndpoints.getMultipleTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create password
|
||||||
|
static Future createPassword({
|
||||||
|
required String name,
|
||||||
|
required String password,
|
||||||
|
required String effectiveTime,
|
||||||
|
required String invalidTime,
|
||||||
|
required String deviceId,
|
||||||
|
required String pageType,
|
||||||
|
List<Schedule>? scheduleList,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
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 = {
|
||||||
|
"name": name,
|
||||||
|
"password": password,
|
||||||
|
"effectiveTime": effectiveTime,
|
||||||
|
"invalidTime": invalidTime,
|
||||||
|
};
|
||||||
|
if (pageType == 'Online Password' && scheduleList != null) {
|
||||||
|
body["scheduleList"] =
|
||||||
|
scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||||
|
}
|
||||||
|
final response = await _httpService.post(
|
||||||
|
path: endpointPath,
|
||||||
|
body: body,
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) => json,
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Future<Map<String, dynamic>> deletePassword(
|
||||||
|
{required String passwordId, required String deviceId}) async {
|
||||||
|
final response = await _httpService.delete(
|
||||||
|
path: ApiEndpoints.deleteTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId)
|
||||||
|
.replaceAll('{passwordId}', passwordId),
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user