forget password changes & bugs number 10 & 15-18

This commit is contained in:
mohammad
2024-09-02 10:16:28 +03:00
parent 3ff6937116
commit ddcdd4891a
12 changed files with 180 additions and 160 deletions

View File

@ -38,6 +38,7 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
HomeBloc.fetchUserInfo();
return MultiBlocProvider(
providers: [
BlocProvider(create: (context) => HomeBloc()),
@ -57,6 +58,7 @@ class MyApp extends StatelessWidget {
),
theme: myTheme,
routerConfig: _router,
));
)
);
}
}

View File

@ -38,12 +38,22 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
style: Theme.of(context).textTheme.headlineLarge,
),
),
centerBody: Text(
'Physical Access',
style: Theme.of(context)
.textTheme
.headlineMedium!
.copyWith(color: Colors.white),
centerBody: Wrap(
children: [
Padding(
padding: EdgeInsets.only(left: MediaQuery.of(context).size.width*0.09),
child: Align(
alignment: Alignment.bottomLeft,
child: Text(
'Physical Access',
style: Theme.of(context)
.textTheme
.headlineMedium!
.copyWith(color: Colors.white),
),
),
),
],
),
rightBody: const NavigateHomeGridView(),
scaffoldBody: BlocProvider(
@ -82,6 +92,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
const SizedBox(height: 20),
Expanded(
child: DynamicTable(
withSelectAll: false,
isEmpty: filteredData.isEmpty,
withCheckBox: false,
size: MediaQuery.of(context).size,
@ -113,8 +124,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
})));
}
Wrap _buildVisitorAdminPasswords(
BuildContext context, AccessBloc accessBloc) {
Wrap _buildVisitorAdminPasswords(BuildContext context, AccessBloc accessBloc) {
return Wrap(
spacing: 10,
runSpacing: 10,
@ -171,15 +181,14 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
width: 250,
child: CustomWebTextField(
controller: accessBloc.passwordName,
height: 38,
isRequired: true,
height: 43,
isRequired: false,
textFieldName: 'Name',
description: '',
),
),
const SizedBox(width: 15),
SizedBox(
height: 70,
child: DateTimeWebWidget(
icon: Assets.calendarIcon,
isRequired: false,

View File

@ -1,4 +1,5 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
@ -81,21 +82,25 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
_timer?.cancel();
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
emit(SuccessForgetState());
} else if (response == "You entered wrong otp") {
forgetValidate = 'Wrong one time password.';
emit(AuthInitialState());
} else if (response == "OTP expired") {
forgetValidate = 'One time password has been expired.';
emit(AuthInitialState());
}
} catch (failure) {
// forgetValidate='Invalid Credentials!';
emit(AuthInitialState());
// emit(FailureForgetState(error: failure.toString()));
}
on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
if(errorMessage=='this email is not registered'){
validate='Invalid Credentials!';
emit(AuthInitialState());
}else if (errorMessage == "You entered wrong otp") {
forgetValidate = 'Wrong one time password.';
emit(AuthInitialState());
} else if (errorMessage == "OTP expired") {
forgetValidate = 'One time password has been expired.';
emit(AuthInitialState());
}
}
}
//925207
String? validateCode(String? value) {
if (value == null || value.isEmpty) {
return 'Code is required';
@ -177,15 +182,15 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
emit(LoginInitial());
}
checkOtpCode(
ChangePasswordEvent event,
Emitter<AuthState> emit,
) async {
emit(LoadingForgetState());
await AuthenticationAPI.verifyOtp(
email: forgetEmailController.text, otpCode: forgetOtp.text);
emit(SuccessForgetState());
}
// checkOtpCode(
// ChangePasswordEvent event,
// Emitter<AuthState> emit,
// ) async {
// emit(LoadingForgetState());
// await AuthenticationAPI.verifyOtp(
// email: forgetEmailController.text, otpCode: forgetOtp.text);
// emit(SuccessForgetState());
// }
void _passwordVisible(PasswordVisibleEvent event, Emitter<AuthState> emit) {
emit(AuthLoading());

View File

@ -346,8 +346,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
if (forgetBloc
.forgetFormKey.currentState!
.validate()) {
forgetBloc
.add(ChangePasswordEvent());
forgetBloc.add(ChangePasswordEvent());
}
},
),
@ -355,12 +354,14 @@ class ForgetPasswordWebPage extends StatelessWidget {
],
),
const SizedBox(height: 10.0),
SizedBox(
child: Text(
forgetBloc.validate,
style: const TextStyle(
fontWeight: FontWeight.w700,
color: ColorsManager.red),
Center(
child: SizedBox(
child: Text(
forgetBloc.validate,
style: const TextStyle(
fontWeight: FontWeight.w700,
color: ColorsManager.red),
),
),
),
SizedBox(

View File

@ -10,6 +10,7 @@ class DynamicTable extends StatefulWidget {
final BoxDecoration? cellDecoration;
final Size size;
final bool withCheckBox;
final bool withSelectAll;
final bool isEmpty;
final void Function(bool?)? selectAll;
final void Function(int, bool, dynamic)? onRowSelected;
@ -21,6 +22,7 @@ class DynamicTable extends StatefulWidget {
required this.size,
required this.isEmpty,
required this.withCheckBox,
required this.withSelectAll,
this.headerDecoration,
this.cellDecoration,
this.selectAll,
@ -34,6 +36,7 @@ class DynamicTable extends StatefulWidget {
class _DynamicTableState extends State<DynamicTable> {
late List<bool> _selected;
bool _selectAll = false;
@override
void initState() {
@ -54,6 +57,17 @@ class _DynamicTableState extends State<DynamicTable> {
});
}
void _toggleSelectAll(bool? value) {
setState(() {
_selectAll = value ?? false;
_selected = List<bool>.filled(widget.data.length, _selectAll);
if (widget.selectAll != null) {
widget.selectAll!(_selectAll);
}
});
}
@override
Widget build(BuildContext context) {
return Container(
@ -148,7 +162,7 @@ class _DynamicTableState extends State<DynamicTable> {
),
child: Checkbox(
value: _selected.every((element) => element == true),
onChanged: null,
onChanged:widget.withSelectAll?_toggleSelectAll:null,
),
);
}

View File

@ -32,21 +32,19 @@ class CustomWebTextField extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (isRequired)
Row(
children: [
Text(
'* ',
if (isRequired)
Text('* ',
style: Theme.of(context)
.textTheme
.bodyMedium!
.textTheme.bodyMedium!
.copyWith(color: Colors.red),
),
Text(
textFieldName,
style: Theme.of(context)
.textTheme
.bodySmall!
.textTheme.bodySmall!
.copyWith(color: Colors.black, fontSize: 13),
),
],
@ -70,15 +68,17 @@ class CustomWebTextField extends StatelessWidget {
),
Container(
height: height ?? 35,
decoration: containerDecoration
.copyWith(color: const Color(0xFFF5F6F7), boxShadow: [
decoration: containerDecoration.copyWith(
color: const Color(0xFFF5F6F7),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 3,
offset: const Offset(1, 1), // changes position of shadow
),
]),
]
),
child: TextFormField(
validator: validator,
controller: controller,

View File

@ -51,71 +51,68 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
'Low Battery ($lowBatteryCount)',
];
return CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
padding: isLargeScreenSize(context)
? const EdgeInsets.all(30)
: const EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FilterWidget(
size: MediaQuery.of(context).size,
tabs: tabs,
selectedIndex: selectedIndex,
onTabChanged: (index) {
context
.read<DeviceManagementBloc>()
.add(SelectedFilterChanged(index));
},
),
const SizedBox(height: 20),
const DeviceSearchFilters(),
const SizedBox(height: 12),
Container(
height: 45,
width: 100,
decoration: containerDecoration,
child: Center(
child: DefaultButton(
onPressed: isControlButtonEnabled
? () {
final selectedDevice = context
.read<DeviceManagementBloc>()
.selectedDevices
.first;
showDialog(
context: context,
builder: (context) => DeviceControlDialog(
device: selectedDevice),
);
}
: null,
borderRadius: 9,
child: Text(
'Control',
style: TextStyle(
fontSize: 12,
color: isControlButtonEnabled
? Colors.white
: Colors.grey,
),
return Column(
children: [
Container(
padding: isLargeScreenSize(context)
? const EdgeInsets.all(30)
: const EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FilterWidget(
size: MediaQuery.of(context).size,
tabs: tabs,
selectedIndex: selectedIndex,
onTabChanged: (index) {
context.read<DeviceManagementBloc>()
.add(SelectedFilterChanged(index));
},
),
const SizedBox(height: 20),
const DeviceSearchFilters(),
const SizedBox(height: 12),
Container(
height: 45,
width: 100,
decoration: containerDecoration,
child: Center(
child: DefaultButton(
onPressed: isControlButtonEnabled
? () {
final selectedDevice = context
.read<DeviceManagementBloc>()
.selectedDevices.first;
showDialog(
context: context,
builder: (context) => DeviceControlDialog(
device: selectedDevice),
);
}
: null,
borderRadius: 9,
child: Text(
'Control',
style: TextStyle(
fontSize: 12,
color: isControlButtonEnabled
? Colors.white
: Colors.grey,
),
),
),
),
],
),
),
],
),
),
SliverFillRemaining(
Expanded(
child: Padding(
padding: isLargeScreenSize(context)
? const EdgeInsets.all(30)
: const EdgeInsets.all(15),
child: DynamicTable(
withSelectAll: false,
cellDecoration: containerDecoration,
onRowSelected: (index, isSelected, row) {
final selectedDevice = devicesToShow[index];

View File

@ -43,6 +43,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
try {
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
user = await HomeApi().fetchUserInfo(uuid);
} catch (e) {
return;
}

View File

@ -40,7 +40,7 @@ class AddDeviceDialog extends StatelessWidget {
fontSize: 24,
color: Colors.black),
),
content: Container(
content: SizedBox(
height: MediaQuery.of(context).size.height / 1.7,
width: MediaQuery.of(context).size.width / 2,
child: Padding(
@ -78,7 +78,7 @@ class AddDeviceDialog extends StatelessWidget {
),
],
)),
SizedBox(
const SizedBox(
height: 20,
),
const SizedBox(
@ -93,7 +93,7 @@ class AddDeviceDialog extends StatelessWidget {
flex: 4,
child: CustomWebTextField(
controller: visitorBloc.deviceNameController,
isRequired: true,
isRequired: false,
textFieldName: 'Device Name',
description: '',
),
@ -103,7 +103,7 @@ class AddDeviceDialog extends StatelessWidget {
flex: 4,
child: CustomWebTextField(
controller: visitorBloc.deviceIdController,
isRequired: true,
isRequired: false,
textFieldName: 'Device ID',
description: '',
),
@ -113,7 +113,7 @@ class AddDeviceDialog extends StatelessWidget {
flex: 4,
child: CustomWebTextField(
controller: visitorBloc.unitNameController,
isRequired: true,
isRequired: false,
textFieldName: 'Unit Name',
description: '',
),
@ -168,40 +168,40 @@ class AddDeviceDialog extends StatelessWidget {
flex: 3,
child: state is TableLoaded
? DynamicTable(
initialSelectedIds: selectedDeviceIds,
cellDecoration: containerDecoration,
isEmpty: visitorBloc.data.isEmpty,
selectAll: (p0) {
visitorBloc.selectedDeviceIds.clear();
for (var item in state.data) {
visitorBloc
.add(SelectDeviceEvent(item.uuid));
}
},
onRowSelected: (index, isSelected, row) {
final deviceId = state.data[index].uuid;
visitorBloc.add(SelectDeviceEvent(deviceId));
},
withCheckBox: true,
size: size * 0.5,
headers: const [
'Device Name',
'Device ID',
'Access Type',
'Unit Name',
'Status'
],
data: state.data.map((item) {
return [
item.name.toString(),
item.uuid.toString(),
item.productType.toString(),
'',
item.online.value.toString(),
];
}).toList(),
)
: const Center(child: CircularProgressIndicator()))
withSelectAll: true,
initialSelectedIds: selectedDeviceIds,
cellDecoration: containerDecoration,
isEmpty: visitorBloc.data.isEmpty,
selectAll: (p0) {
visitorBloc.selectedDeviceIds.clear();
for (var item in state.data) {
visitorBloc.add(SelectDeviceEvent(item.uuid));
}
},
onRowSelected: (index, isSelected, row) {
final deviceId = state.data[index].uuid;
visitorBloc.add(SelectDeviceEvent(deviceId));
},
withCheckBox: true,
size: size * 0.5,
headers: const [
'Device Name',
'Device ID',
'Access Type',
'Unit Name',
'Status'
],
data: state.data.map((item) {
return [
item.name.toString(),
item.uuid.toString(),
item.productType.toString(),
'',
item.online.value.toString(),
];
}).toList(),
) : const Center(child: CircularProgressIndicator()))
],
),
),

View File

@ -323,8 +323,7 @@ class VisitorPasswordDialog extends StatelessWidget {
: visitorBloc.usageFrequencySelected,
onChanged: (String? value) {
if (value != null) {
context
.read<VisitorPasswordBloc>()
context.read<VisitorPasswordBloc>()
.add(SelectUsageFrequency(value));
}
},
@ -344,7 +343,7 @@ class VisitorPasswordDialog extends StatelessWidget {
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
visitorBloc.accessTypeSelected == 'Offline Password')
Text(
'Within the validity period, there is no limit to the number of times each device can be unlocked.',
'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor, fontSize: 9),
),

View File

@ -25,7 +25,9 @@ class AuthenticationAPI {
path: ApiEndpoints.forgetPassword,
body: {"email": email, "password": password},
showServerMessage: true,
expectedResponseModel: (json) {});
expectedResponseModel: (json) {
print('json=$json');
});
return response;
}
@ -66,7 +68,6 @@ class AuthenticationAPI {
}
static Future verifyOtp({required String email, required String otpCode}) async {
try {
final response = await HTTPService().post(
path: ApiEndpoints.verifyOtp,
body: {"email": email, "type": "PASSWORD", "otpCode": otpCode},
@ -79,17 +80,7 @@ class AuthenticationAPI {
}
});
return response;
} on DioException catch (e) {
if (e.response != null) {
if (e.response!.statusCode == 400) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
return errorMessage;
}
} else {
debugPrint('Error: ${e.message}');
}
}
}
static Future<List<RegionModel>> fetchRegion() async {

View File

@ -8,6 +8,7 @@ class HomeApi {
path: ApiEndpoints.getUser.replaceAll('{userUuid}', userId!),
showServerMessage: true,
expectedResponseModel: (json) {
print('fetchUserInfo$json');
return UserModel.fromJson(json);
});
return response;