CreateTemporaryPassword

This commit is contained in:
mohammad
2024-06-30 11:54:14 +03:00
parent babaada63f
commit 578b9586d2
5 changed files with 87 additions and 55 deletions

View File

@ -3,6 +3,7 @@ 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:intl/intl.dart';
import 'package:pin_code_fields/pin_code_fields.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';
@ -11,6 +12,7 @@ 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/create_temporary_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/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> { class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
final String deviceId; final String deviceId;
@ -22,7 +24,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
on<InitialPasswordsPage>(getTemporaryPasswords); 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 {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
var response = await DevicesAPI.getDeviceStatus(deviceId); var response = await DevicesAPI.getDeviceStatus(deviceId);
@ -38,21 +41,25 @@ 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());
pageType=event.type!; pageType = event.type!;
var response = await DevicesAPI.getTemporaryPasswords(deviceId,pageType); 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 = (response['data'] as List).map((item) => TemporaryPassword.fromJson(item)).toList(); temporaryPasswords = (response['data'] as List)
.map((item) => TemporaryPassword.fromJson(item))
.toList();
} else { } else {
throw Exception("Unexpected response format"); throw Exception("Unexpected response format");
} }
emit(TemporaryPasswordsLoadedState( temporaryPassword: temporaryPasswords!)); emit(TemporaryPasswordsLoadedState(
temporaryPassword: temporaryPasswords!));
} catch (e) { } catch (e) {
print(e);
emit(FailedState(errorMessage: e.toString())); emit(FailedState(errorMessage: e.toString()));
} }
} }
@ -61,15 +68,15 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
TextEditingController passwordNameController = TextEditingController(); TextEditingController passwordNameController = TextEditingController();
String effectiveTime = 'Select Time'; String effectiveTime = 'Select Time';
int? effectiveTimeTimeStamp; int? effectiveTimeTimeStamp;
String expirationTime ='Select Time'; String expirationTime = 'Select Time';
int? expirationTimeTimeStamp; int? expirationTimeTimeStamp;
bool repeat = false; bool repeat = false;
bool isStartEndTime = true; bool isStartEndTime = true;
List<String>? selectedDay; List<String>? selectedDay;
DateTime? startTime; DateTime? startTime;
DateTime? endTime; DateTime? endTime;
List<TemporaryPassword>? temporaryPasswords=[]; List<TemporaryPassword>? temporaryPasswords = [];
List<TemporaryPassword>? oneTimePasswords=[]; List<TemporaryPassword>? oneTimePasswords = [];
changeTime(val, isStartEndTime) { changeTime(val, isStartEndTime) {
emit(LoadingInitialState()); emit(LoadingInitialState());
@ -95,7 +102,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
return isStartEndTime; 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 {
@ -123,7 +129,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
emit(GeneratePasswordState()); emit(GeneratePasswordState());
} }
Future<void> selectTime(BuildContext context, {required bool isEffective}) async { Future<void> selectTime(BuildContext context,
{required bool isEffective}) async {
final DateTime? picked = await showDatePicker( final DateTime? picked = await showDatePicker(
context: context, context: context,
initialDate: DateTime.now(), initialDate: DateTime.now(),
@ -144,18 +151,24 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
timePicked.minute, timePicked.minute,
); );
if (isEffective) { if (isEffective) {
if (expirationTimeTimeStamp != null && selectedDateTime.millisecondsSinceEpoch > expirationTimeTimeStamp!) { if (expirationTimeTimeStamp != null &&
_showSnackBar(context, 'Effective Time cannot be later than Expiration Time.'); selectedDateTime.millisecondsSinceEpoch >
expirationTimeTimeStamp!) {
_showSnackBar(context,
'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 && selectedDateTime.millisecondsSinceEpoch < effectiveTimeTimeStamp!) { if (effectiveTimeTimeStamp != null &&
_showSnackBar(context, 'Expiration Time cannot be earlier than Effective Time.'); selectedDateTime.millisecondsSinceEpoch <
effectiveTimeTimeStamp!) {
_showSnackBar(context,
'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());
@ -163,11 +176,10 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
} }
} }
Future<void> savePassword(BuildContext context) async { Future<void> savePassword(BuildContext context) async {
if (_validateInputs(context)) return; if (_validateInputs(context)) return;
try { try {
emit(LoadingInitialState()); emit(LoadingSaveState());
var response = await DevicesAPI.createPassword( var response = await DevicesAPI.createPassword(
pageType: pageType, pageType: pageType,
deviceId: deviceId, deviceId: deviceId,
@ -175,7 +187,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
invalidTime: expirationTimeTimeStamp.toString(), invalidTime: expirationTimeTimeStamp.toString(),
name: passwordNameController.text, name: passwordNameController.text,
password: passwordController.text, password: passwordController.text,
scheduleList: [ scheduleList: [
if (repeat) if (repeat)
Schedule( Schedule(
effectiveTime: getTimeOnly(startTime), effectiveTime: getTimeOnly(startTime),
@ -183,24 +195,22 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
workingDay: selectedDay!, workingDay: selectedDay!,
), ),
], ],
); ).then((value)async {
add(InitialPasswordsPage(type: pageType)); add(InitialPasswordsPage(type: pageType));
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!)); },);
Navigator.pop(context); CustomSnackBar.displaySnackBar('Save Successfully');
Navigator.pop(context); emit(SaveState());
} catch (e) { } catch (e) {
emit(FailedState(errorMessage: 'Failed to save password: $e')); emit(FailedState(errorMessage: 'Failed to save password: $e'));
} }
} }
void deletePassword(BuildContext context, passwordId) async { void deletePassword(BuildContext context, passwordId) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
var response = await DevicesAPI.deletePassword( var response = await DevicesAPI.deletePassword(
deviceId: deviceId, deviceId: deviceId, passwordId: passwordId)
passwordId: passwordId .then((value) async {
).then((value) async {
add(InitialPasswordsPage(type: pageType)); add(InitialPasswordsPage(type: pageType));
}); });
} catch (e) { } catch (e) {
@ -208,9 +218,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
} }
} }
bool _validateInputs(BuildContext context) { bool _validateInputs(BuildContext context) {
if (passwordController.text.isEmpty) { if (passwordController.text.isEmpty) {
_showSnackBar(context, 'Password required'); _showSnackBar(context, 'Password required');
return true; return true;
@ -227,7 +235,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
_showSnackBar(context, 'Select expiration time'); _showSnackBar(context, 'Select expiration time');
return true; return true;
} }
if(repeat==true&&(endTime==null||startTime==null||selectedDay==null)){ if (repeat == true &&
(endTime == null || startTime == null || selectedDay == null)) {
_showSnackBar(context, 'Start Time and End time and the days required '); _showSnackBar(context, 'Start Time and End time and the days required ');
return true; return true;
} }
@ -246,7 +255,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
List<DayInWeek> days = [ List<DayInWeek> days = [
DayInWeek("S", dayKey: 'Sun'), DayInWeek("S", dayKey: 'Sun'),
DayInWeek("M", dayKey: 'Mon'), DayInWeek("M", dayKey: 'Mon'),
DayInWeek("T", dayKey: 'Tue'), DayInWeek("T", dayKey: 'Tue'),
DayInWeek("W", dayKey: 'Wed'), DayInWeek("W", dayKey: 'Wed'),
DayInWeek("T", dayKey: 'Thu'), DayInWeek("T", dayKey: 'Thu'),
DayInWeek("F", dayKey: 'Fri'), DayInWeek("F", dayKey: 'Fri'),

View File

@ -45,6 +45,8 @@ 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 SaveState extends SmartDoorState{}
class LoadingSaveState extends SmartDoorState{}
class TemporaryPasswordsLoadedState extends SmartDoorState{ class TemporaryPasswordsLoadedState extends SmartDoorState{
final List<TemporaryPassword> temporaryPassword; final List<TemporaryPassword> temporaryPassword;
const TemporaryPasswordsLoadedState({required this.temporaryPassword}); const TemporaryPasswordsLoadedState({required this.temporaryPassword});

View File

@ -4,25 +4,27 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:pin_code_fields/pin_code_fields.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_state.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_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_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:time_picker_spinner/time_picker_spinner.dart'; import 'package:time_picker_spinner/time_picker_spinner.dart';
class CreateTemporaryPassword extends StatelessWidget { class CreateTemporaryPassword extends StatelessWidget {
final String? deviceId; final String? deviceId;
final String? type;
const CreateTemporaryPassword({super.key,this.deviceId}); const CreateTemporaryPassword({super.key,this.deviceId, this.type});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (BuildContext context) => SmartDoorBloc(deviceId: 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(
@ -31,18 +33,30 @@ class CreateTemporaryPassword extends StatelessWidget {
), ),
); );
} }
},
builder: (context, state) {
}, builder: (context, state) {
return DefaultScaffold( return DefaultScaffold(
title: 'Create Password', appBar: AppBar(
actions: [ backgroundColor: Colors.transparent,
TextButton( centerTitle: true,
onPressed: () { title: const BodyLarge(
BlocProvider.of<SmartDoorBloc>(context).savePassword(context); text: 'Create Password' ,
}, fontColor: ColorsManager.primaryColor,
child: const Text('Save')) fontWeight: FontsManager.bold,
], ),
leading: IconButton(onPressed: () {
Navigator.of(context).pop('UpdatePage');
}, icon: Icon(Icons.arrow_back)),
actions: [
TextButton(
onPressed: () {
BlocProvider.of<SmartDoorBloc>(context).savePassword(context);
SmartDoorBloc(deviceId: deviceId!).add(InitialPasswordsPage(type:type ));
},
child: const Text('Save'))
],
),
child: state is LoadingInitialState? child: state is LoadingInitialState?
const Center(child: CircularProgressIndicator()): SingleChildScrollView( const Center(child: CircularProgressIndicator()): SingleChildScrollView(
child: child:
@ -70,7 +84,8 @@ class CreateTemporaryPassword extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: PinCodeTextField( child: PinCodeTextField(
keyboardType: TextInputType.phone, autoDisposeControllers: false,
keyboardType: TextInputType.phone,
length: 7, length: 7,
enabled: true, enabled: true,
obscureText: false, obscureText: false,

View File

@ -24,6 +24,7 @@ class ViewTemporaryPassword extends StatelessWidget {
SmartDoorBloc(deviceId: deviceId!)..add(InitialPasswordsPage(type:type )), SmartDoorBloc(deviceId: deviceId!)..add(InitialPasswordsPage(type:type )),
child: BlocConsumer<SmartDoorBloc, SmartDoorState>( child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
listener: (context, state) { listener: (context, state) {
print('=======4${state}');
if (state is FailedState) { if (state is FailedState) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
@ -33,21 +34,25 @@ class ViewTemporaryPassword extends StatelessWidget {
); );
} }
}, builder: (context, state) { }, builder: (context, state) {
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
return DefaultScaffold( return DefaultScaffold(
title: 'Passwords', title: 'Passwords',
actions: [ actions: [
IconButton( IconButton(
onPressed: () { onPressed: () {
Navigator.of(context).push(MaterialPageRoute( Navigator.of(context).push(MaterialPageRoute(
builder: (context) => builder: (context) => CreateTemporaryPassword(deviceId: deviceId, type: type),
CreateTemporaryPassword(deviceId: deviceId), )).then((result) {
)); if (result != null) {
smartDoorBloc.add(InitialPasswordsPage(type:type )); }
});
}, },
icon: const Icon(Icons.add)) icon: const Icon(Icons.add))
], ],
child: Builder( child: Builder(
builder: (context) { builder: (context) {
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
return state is LoadingInitialState return state is LoadingInitialState
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: Center( : Center(

View File

@ -30,7 +30,8 @@ class ManageHomeView extends StatelessWidget {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: List.generate( children:
List.generate(
spaces.length, spaces.length,
(index) { (index) {
if (index == spaces.length - 1) { if (index == spaces.length - 1) {