mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
Bug fixes, and added a logout button
This commit is contained in:
@ -31,8 +31,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
|
|
||||||
////////////////////////////// forget password //////////////////////////////////
|
////////////////////////////// forget password //////////////////////////////////
|
||||||
final TextEditingController forgetEmailController = TextEditingController();
|
final TextEditingController forgetEmailController = TextEditingController();
|
||||||
final TextEditingController forgetPasswordController =
|
final TextEditingController forgetPasswordController = TextEditingController();
|
||||||
TextEditingController();
|
|
||||||
final TextEditingController forgetOtp = TextEditingController();
|
final TextEditingController forgetOtp = TextEditingController();
|
||||||
final forgetFormKey = GlobalKey<FormState>();
|
final forgetFormKey = GlobalKey<FormState>();
|
||||||
late bool checkValidate = false;
|
late bool checkValidate = false;
|
||||||
@ -41,15 +40,13 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
int _remainingTime = 0;
|
int _remainingTime = 0;
|
||||||
List<RegionModel>? regionList = [RegionModel(name: 'name', id: 'id')];
|
List<RegionModel>? regionList = [RegionModel(name: 'name', id: 'id')];
|
||||||
|
|
||||||
Future<void> _onStartTimer(
|
Future<void> _onStartTimer(StartTimerEvent event, Emitter<AuthState> emit) async {
|
||||||
StartTimerEvent event, Emitter<AuthState> emit) async {
|
|
||||||
if (_validateInputs(emit)) return;
|
if (_validateInputs(emit)) return;
|
||||||
if (_timer != null && _timer!.isActive) {
|
if (_timer != null && _timer!.isActive) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_remainingTime = 1;
|
_remainingTime = 1;
|
||||||
add(UpdateTimerEvent(
|
add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
|
||||||
remainingTime: _remainingTime, isButtonEnabled: false));
|
|
||||||
_remainingTime = (await AuthenticationAPI.sendOtp(
|
_remainingTime = (await AuthenticationAPI.sendOtp(
|
||||||
email: forgetEmailController.text, regionUuid: regionUuid))!;
|
email: forgetEmailController.text, regionUuid: regionUuid))!;
|
||||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||||
@ -58,8 +55,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true));
|
add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true));
|
||||||
} else {
|
} else {
|
||||||
add(UpdateTimerEvent(
|
add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
|
||||||
remainingTime: _remainingTime, isButtonEnabled: false));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -69,36 +65,32 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
|
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changePassword(
|
Future<void> changePassword(ChangePasswordEvent event, Emitter<AuthState> emit) async {
|
||||||
ChangePasswordEvent event, Emitter<AuthState> emit) async {
|
|
||||||
try {
|
try {
|
||||||
emit(LoadingForgetState());
|
emit(LoadingForgetState());
|
||||||
var response = await AuthenticationAPI.verifyOtp(
|
var response = await AuthenticationAPI.verifyOtp(
|
||||||
email: forgetEmailController.text, otpCode: forgetOtp.text);
|
email: forgetEmailController.text, otpCode: forgetOtp.text);
|
||||||
if (response == true) {
|
if (response == true) {
|
||||||
await AuthenticationAPI.forgetPassword(
|
await AuthenticationAPI.forgetPassword(
|
||||||
password: forgetPasswordController.text,
|
password: forgetPasswordController.text, email: forgetEmailController.text);
|
||||||
email: forgetEmailController.text);
|
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
|
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
|
||||||
emit(SuccessForgetState());
|
emit(SuccessForgetState());
|
||||||
}
|
}
|
||||||
|
} 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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String? validateCode(String? value) {
|
String? validateCode(String? value) {
|
||||||
@ -109,9 +101,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onUpdateTimer(UpdateTimerEvent event, Emitter<AuthState> emit) {
|
void _onUpdateTimer(UpdateTimerEvent event, Emitter<AuthState> emit) {
|
||||||
emit(TimerState(
|
emit(TimerState(isButtonEnabled: event.isButtonEnabled, remainingTime: event.remainingTime));
|
||||||
isButtonEnabled: event.isButtonEnabled,
|
|
||||||
remainingTime: event.remainingTime));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////// login /////////////////////////////////////
|
///////////////////////////////////// login /////////////////////////////////////
|
||||||
@ -142,9 +132,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
|
|
||||||
token = await AuthenticationAPI.loginWithEmail(
|
token = await AuthenticationAPI.loginWithEmail(
|
||||||
model: LoginWithEmailModel(
|
model: LoginWithEmailModel(
|
||||||
email: event.username,
|
email: event.username, password: event.password, regionUuid: event.regionUuid),
|
||||||
password: event.password,
|
|
||||||
regionUuid: event.regionUuid),
|
|
||||||
);
|
);
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
validate = 'Invalid Credentials!';
|
validate = 'Invalid Credentials!';
|
||||||
@ -154,8 +142,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
|
|
||||||
if (token.accessTokenIsNotEmpty) {
|
if (token.accessTokenIsNotEmpty) {
|
||||||
FlutterSecureStorage storage = const FlutterSecureStorage();
|
FlutterSecureStorage storage = const FlutterSecureStorage();
|
||||||
await storage.write(
|
await storage.write(key: Token.loginAccessTokenKey, value: token.accessToken);
|
||||||
key: Token.loginAccessTokenKey, value: token.accessToken);
|
|
||||||
const FlutterSecureStorage().write(
|
const FlutterSecureStorage().write(
|
||||||
key: UserModel.userUuidKey,
|
key: UserModel.userUuidKey,
|
||||||
value: Token.decodeToken(token.accessToken)['uuid'].toString());
|
value: Token.decodeToken(token.accessToken)['uuid'].toString());
|
||||||
@ -310,14 +297,12 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
static Future<String> getTokenAndValidate() async {
|
static Future<String> getTokenAndValidate() async {
|
||||||
try {
|
try {
|
||||||
const storage = FlutterSecureStorage();
|
const storage = FlutterSecureStorage();
|
||||||
final firstLaunch = await SharedPreferencesHelper.readBoolFromSP(
|
final firstLaunch =
|
||||||
StringsManager.firstLaunch) ??
|
await SharedPreferencesHelper.readBoolFromSP(StringsManager.firstLaunch) ?? true;
|
||||||
true;
|
|
||||||
if (firstLaunch) {
|
if (firstLaunch) {
|
||||||
storage.deleteAll();
|
storage.deleteAll();
|
||||||
}
|
}
|
||||||
await SharedPreferencesHelper.saveBoolToSP(
|
await SharedPreferencesHelper.saveBoolToSP(StringsManager.firstLaunch, false);
|
||||||
StringsManager.firstLaunch, false);
|
|
||||||
final value = await storage.read(key: Token.loginAccessTokenKey) ?? '';
|
final value = await storage.read(key: Token.loginAccessTokenKey) ?? '';
|
||||||
if (value.isEmpty) {
|
if (value.isEmpty) {
|
||||||
return 'Token not found';
|
return 'Token not found';
|
||||||
@ -369,9 +354,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
final String formattedTime = [
|
final String formattedTime = [
|
||||||
if (days > 0) '${days}d', // Append 'd' for days
|
if (days > 0) '${days}d', // Append 'd' for days
|
||||||
if (days > 0 || hours > 0)
|
if (days > 0 || hours > 0)
|
||||||
hours
|
hours.toString().padLeft(2, '0'), // Show hours if there are days or hours
|
||||||
.toString()
|
|
||||||
.padLeft(2, '0'), // Show hours if there are days or hours
|
|
||||||
minutes.toString().padLeft(2, '0'),
|
minutes.toString().padLeft(2, '0'),
|
||||||
seconds.toString().padLeft(2, '0'),
|
seconds.toString().padLeft(2, '0'),
|
||||||
].join(':');
|
].join(':');
|
||||||
@ -409,4 +392,9 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
forgetValidate = '';
|
forgetValidate = '';
|
||||||
emit(LoginInitial());
|
emit(LoginInitial());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static logout() {
|
||||||
|
const storage = FlutterSecureStorage();
|
||||||
|
storage.deleteAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
|
|
||||||
Future<void> showCustomDialog({
|
Future<void> showCustomDialog({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
@ -13,7 +12,7 @@ Future<void> showCustomDialog({
|
|||||||
double? iconWidth,
|
double? iconWidth,
|
||||||
VoidCallback? onOkPressed,
|
VoidCallback? onOkPressed,
|
||||||
bool barrierDismissible = false,
|
bool barrierDismissible = false,
|
||||||
required actions,
|
required List<Widget> actions,
|
||||||
}) {
|
}) {
|
||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -21,59 +20,43 @@ Future<void> showCustomDialog({
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
final size = MediaQuery.of(context).size;
|
final size = MediaQuery.of(context).size;
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
height: dialogHeight ?? size.height * 0.15,
|
height: dialogHeight ?? size.height * 0.15,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
if (iconPath != null)
|
if (iconPath != null)
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
iconPath,
|
iconPath,
|
||||||
height: iconHeight ?? 35,
|
height: iconHeight ?? 35,
|
||||||
width: iconWidth ?? 35,
|
width: iconWidth ?? 35,
|
||||||
),
|
),
|
||||||
if (title != null)
|
if (title != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.headlineLarge!
|
||||||
|
.copyWith(fontSize: 20, fontWeight: FontWeight.w400, color: Colors.black),
|
||||||
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
message,
|
||||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.black),
|
||||||
fontSize: 20,
|
textAlign: TextAlign.center,
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color: Colors.black),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
if (widget != null) Expanded(child: widget)
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
],
|
||||||
child: Text(
|
|
||||||
message,
|
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodyMedium!
|
|
||||||
.copyWith(color: Colors.black),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if(widget!=null)
|
|
||||||
Expanded(child:widget)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
actionsAlignment: MainAxisAlignment.center,
|
|
||||||
actions: <Widget>[
|
|
||||||
TextButton(
|
|
||||||
onPressed: onOkPressed ?? () => Navigator.of(context).pop(),
|
|
||||||
child: Text(
|
|
||||||
'OK',
|
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 16),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
actionsAlignment: MainAxisAlignment.center,
|
||||||
);
|
actions: actions);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,14 @@ import 'package:syncrow_web/services/devices_mang_api.dart';
|
|||||||
part 'device_managment_event.dart';
|
part 'device_managment_event.dart';
|
||||||
part 'device_managment_state.dart';
|
part 'device_managment_state.dart';
|
||||||
|
|
||||||
class DeviceManagementBloc
|
class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementState> {
|
||||||
extends Bloc<DeviceManagementEvent, DeviceManagementState> {
|
|
||||||
int _selectedIndex = 0;
|
int _selectedIndex = 0;
|
||||||
List<AllDevicesModel> _devices = [];
|
List<AllDevicesModel> _devices = [];
|
||||||
int _onlineCount = 0;
|
int _onlineCount = 0;
|
||||||
int _offlineCount = 0;
|
int _offlineCount = 0;
|
||||||
int _lowBatteryCount = 0;
|
int _lowBatteryCount = 0;
|
||||||
List<AllDevicesModel> _selectedDevices = [];
|
List<AllDevicesModel> _selectedDevices = [];
|
||||||
|
String productName = '';
|
||||||
|
|
||||||
DeviceManagementBloc() : super(DeviceManagementInitial()) {
|
DeviceManagementBloc() : super(DeviceManagementInitial()) {
|
||||||
on<FetchDevices>(_onFetchDevices);
|
on<FetchDevices>(_onFetchDevices);
|
||||||
@ -23,8 +23,7 @@ class DeviceManagementBloc
|
|||||||
on<SelectDevice>(_onSelectDevice);
|
on<SelectDevice>(_onSelectDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchDevices(
|
Future<void> _onFetchDevices(FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
||||||
FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
|
||||||
emit(DeviceManagementLoading());
|
emit(DeviceManagementLoading());
|
||||||
try {
|
try {
|
||||||
final devices = await DevicesManagementApi().fetchDevices();
|
final devices = await DevicesManagementApi().fetchDevices();
|
||||||
@ -44,8 +43,7 @@ class DeviceManagementBloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onFilterDevices(
|
void _onFilterDevices(FilterDevices event, Emitter<DeviceManagementState> emit) async {
|
||||||
FilterDevices event, Emitter<DeviceManagementState> emit) {
|
|
||||||
if (_devices.isNotEmpty) {
|
if (_devices.isNotEmpty) {
|
||||||
final filteredDevices = _devices.where((device) {
|
final filteredDevices = _devices.where((device) {
|
||||||
switch (event.filter) {
|
switch (event.filter) {
|
||||||
@ -65,20 +63,20 @@ class DeviceManagementBloc
|
|||||||
onlineCount: _onlineCount,
|
onlineCount: _onlineCount,
|
||||||
offlineCount: _offlineCount,
|
offlineCount: _offlineCount,
|
||||||
lowBatteryCount: _lowBatteryCount,
|
lowBatteryCount: _lowBatteryCount,
|
||||||
selectedDevice:
|
selectedDevice: _selectedDevices.isNotEmpty ? _selectedDevices.first : null,
|
||||||
_selectedDevices.isNotEmpty ? _selectedDevices.first : null,
|
|
||||||
));
|
));
|
||||||
|
if (productName.isNotEmpty) {
|
||||||
|
add(SearchDevices(productName: productName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSelectedFilterChanged(
|
void _onSelectedFilterChanged(SelectedFilterChanged event, Emitter<DeviceManagementState> emit) {
|
||||||
SelectedFilterChanged event, Emitter<DeviceManagementState> emit) {
|
|
||||||
_selectedIndex = event.selectedIndex;
|
_selectedIndex = event.selectedIndex;
|
||||||
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
|
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSelectDevice(
|
void _onSelectDevice(SelectDevice event, Emitter<DeviceManagementState> emit) {
|
||||||
SelectDevice event, Emitter<DeviceManagementState> emit) {
|
|
||||||
final selectedUuid = event.selectedDevice.uuid;
|
final selectedUuid = event.selectedDevice.uuid;
|
||||||
|
|
||||||
if (_selectedDevices.any((device) => device.uuid == selectedUuid)) {
|
if (_selectedDevices.any((device) => device.uuid == selectedUuid)) {
|
||||||
@ -113,10 +111,8 @@ class DeviceManagementBloc
|
|||||||
void _calculateDeviceCounts() {
|
void _calculateDeviceCounts() {
|
||||||
_onlineCount = _devices.where((device) => device.online == true).length;
|
_onlineCount = _devices.where((device) => device.online == true).length;
|
||||||
_offlineCount = _devices.where((device) => device.online == false).length;
|
_offlineCount = _devices.where((device) => device.online == false).length;
|
||||||
_lowBatteryCount = _devices
|
_lowBatteryCount =
|
||||||
.where((device) =>
|
_devices.where((device) => device.batteryLevel != null && device.batteryLevel! < 20).length;
|
||||||
device.batteryLevel != null && device.batteryLevel! < 20)
|
|
||||||
.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getFilterFromIndex(int index) {
|
String _getFilterFromIndex(int index) {
|
||||||
@ -132,18 +128,20 @@ class DeviceManagementBloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSearchDevices(
|
void _onSearchDevices(SearchDevices event, Emitter<DeviceManagementState> emit) {
|
||||||
SearchDevices event, Emitter<DeviceManagementState> emit) {
|
|
||||||
// If the search fields are all empty, restore the last filtered devices
|
// If the search fields are all empty, restore the last filtered devices
|
||||||
if ((event.community == null || event.community!.isEmpty) &&
|
if ((event.community == null || event.community!.isEmpty) &&
|
||||||
(event.unitName == null || event.unitName!.isEmpty) &&
|
(event.unitName == null || event.unitName!.isEmpty) &&
|
||||||
(event.productName == null || event.productName!.isEmpty)) {
|
(event.productName == null || event.productName!.isEmpty)) {
|
||||||
|
productName = '';
|
||||||
// If the current state is filtered, re-emit the filtered state
|
// If the current state is filtered, re-emit the filtered state
|
||||||
if (state is DeviceManagementFiltered) {
|
if (state is DeviceManagementFiltered) {
|
||||||
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
|
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
productName = event.productName ?? '';
|
||||||
|
|
||||||
List<AllDevicesModel> devicesToSearch = _devices;
|
List<AllDevicesModel> devicesToSearch = _devices;
|
||||||
|
|
||||||
if (state is DeviceManagementFiltered) {
|
if (state is DeviceManagementFiltered) {
|
||||||
@ -157,32 +155,19 @@ class DeviceManagementBloc
|
|||||||
final filteredDevices = devicesToSearch.where((device) {
|
final filteredDevices = devicesToSearch.where((device) {
|
||||||
final matchesCommunity = event.community == null ||
|
final matchesCommunity = event.community == null ||
|
||||||
event.community!.isEmpty ||
|
event.community!.isEmpty ||
|
||||||
(device.room?.name
|
(device.room?.name?.toLowerCase().contains(event.community!.toLowerCase()) ?? false);
|
||||||
?.toLowerCase()
|
|
||||||
.contains(event.community!.toLowerCase()) ??
|
|
||||||
false);
|
|
||||||
final matchesUnit = event.unitName == null ||
|
final matchesUnit = event.unitName == null ||
|
||||||
event.unitName!.isEmpty ||
|
event.unitName!.isEmpty ||
|
||||||
(device.unit?.name
|
(device.unit?.name?.toLowerCase().contains(event.unitName!.toLowerCase()) ?? false);
|
||||||
?.toLowerCase()
|
|
||||||
.contains(event.unitName!.toLowerCase()) ??
|
|
||||||
false);
|
|
||||||
final matchesProductName = event.productName == null ||
|
final matchesProductName = event.productName == null ||
|
||||||
event.productName!.isEmpty ||
|
event.productName!.isEmpty ||
|
||||||
(device.name
|
(device.name?.toLowerCase().contains(event.productName!.toLowerCase()) ?? false);
|
||||||
?.toLowerCase()
|
|
||||||
.contains(event.productName!.toLowerCase()) ??
|
|
||||||
false);
|
|
||||||
final matchesDeviceName = event.productName == null ||
|
final matchesDeviceName = event.productName == null ||
|
||||||
event.productName!.isEmpty ||
|
event.productName!.isEmpty ||
|
||||||
(device.categoryName
|
(device.categoryName?.toLowerCase().contains(event.productName!.toLowerCase()) ??
|
||||||
?.toLowerCase()
|
|
||||||
.contains(event.productName!.toLowerCase()) ??
|
|
||||||
false);
|
false);
|
||||||
|
|
||||||
return matchesCommunity &&
|
return matchesCommunity && matchesUnit && (matchesProductName || matchesDeviceName);
|
||||||
matchesUnit &&
|
|
||||||
(matchesProductName || matchesDeviceName);
|
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
emit(DeviceManagementFiltered(
|
emit(DeviceManagementFiltered(
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
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:go_router/go_router.dart';
|
||||||
|
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/custom_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_state.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_state.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
class WebAppBar extends StatefulWidget {
|
class WebAppBar extends StatefulWidget {
|
||||||
@ -128,6 +133,57 @@ class _WebAppBarState extends State<WebAppBar> with HelperResponsiveLayout {
|
|||||||
'${user.firstName} ${user.lastName}',
|
'${user.firstName} ${user.lastName}',
|
||||||
style: Theme.of(context).textTheme.bodyLarge,
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
showCustomDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: true,
|
||||||
|
title: 'Logout',
|
||||||
|
message: 'Are you sure you want to logout?',
|
||||||
|
actions: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
AuthBloc.logout();
|
||||||
|
context.go(RoutesConst.auth);
|
||||||
|
},
|
||||||
|
child: DefaultButton(
|
||||||
|
child: Text(
|
||||||
|
'Ok',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(fontSize: 12, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
context.pop();
|
||||||
|
},
|
||||||
|
child: DefaultButton(
|
||||||
|
child: Text(
|
||||||
|
'Cancel',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(fontSize: 12, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Icon(
|
||||||
|
Icons.logout,
|
||||||
|
color: ColorsManager.whiteColors,
|
||||||
|
),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user