mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 17:47:28 +00:00
restrict_spaceMemberUser_and_change_SignUpModel
This commit is contained in:
@ -7,10 +7,10 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||||||
import 'package:onesignal_flutter/onesignal_flutter.dart';
|
import 'package:onesignal_flutter/onesignal_flutter.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/permission_model.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdown.dart';
|
import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdown.dart';
|
||||||
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
||||||
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
||||||
@ -30,23 +30,30 @@ import 'package:syncrow_app/services/api/profile_api.dart';
|
|||||||
import 'package:syncrow_app/services/api/spaces_api.dart';
|
import 'package:syncrow_app/services/api/spaces_api.dart';
|
||||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
part 'home_state.dart';
|
part 'home_state.dart';
|
||||||
|
|
||||||
class HomeCubit extends Cubit<HomeState> {
|
class HomeCubit extends Cubit<HomeState> {
|
||||||
HomeCubit._() : super(HomeInitial()) {
|
HomeCubit._() : super(HomeInitial()) {
|
||||||
// checkIfNotificationPermissionGranted();
|
// checkIfNotificationPermissionGranted();
|
||||||
fetchUserInfo();
|
fetchUserInfo().then(
|
||||||
if (selectedSpace == null) {
|
(value) {
|
||||||
fetchUnitsByUserId();
|
if (selectedSpace == null) {
|
||||||
// .then((value) {
|
fetchUnitsByUserId();
|
||||||
// if (selectedSpace != null) {
|
fetchPermissions();
|
||||||
// fetchRoomsByUnitId(selectedSpace!);
|
|
||||||
// }
|
// .then((value) {
|
||||||
// });
|
// if (selectedSpace != null) {
|
||||||
}
|
// fetchRoomsByUnitId(selectedSpace!);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
static UserModel? user;
|
static UserModel? user;
|
||||||
|
|
||||||
|
List<PermissionModel>? permissionModel = [];
|
||||||
|
|
||||||
static HomeCubit? _instance;
|
static HomeCubit? _instance;
|
||||||
static HomeCubit getInstance() {
|
static HomeCubit getInstance() {
|
||||||
// If an instance already exists, return it
|
// If an instance already exists, return it
|
||||||
@ -56,15 +63,87 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
Future fetchUserInfo() async {
|
Future fetchUserInfo() async {
|
||||||
try {
|
try {
|
||||||
|
emit(HomeLoading());
|
||||||
var uuid =
|
var uuid =
|
||||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
user = await ProfileApi().fetchUserInfo(uuid);
|
user = await ProfileApi().fetchUserInfo(uuid);
|
||||||
emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info
|
emit(HomeUserInfoLoaded(user!));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool manageSupSpace = false;
|
||||||
|
static bool manageScene = false;
|
||||||
|
static bool manageDeviceLocation = false;
|
||||||
|
static bool visitorPasswordManagement = false;
|
||||||
|
|
||||||
|
Future<void> fetchPermissions() async {
|
||||||
|
try {
|
||||||
|
emit(HomeLoading());
|
||||||
|
final response = await ProfileApi().fetchPermissions(user!.role!.uuid);
|
||||||
|
permissionModel = PermissionModel.fromJsonList(response);
|
||||||
|
hasViewPermission();
|
||||||
|
emit(PermissionsRoleLoaded(permissionModel!));
|
||||||
|
} catch (e) {
|
||||||
|
emit(HomeError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hasViewPermission() {
|
||||||
|
emit(HomeLoading());
|
||||||
|
|
||||||
|
manageSupSpace = hasPermission(
|
||||||
|
permissionModel!,
|
||||||
|
'SPACE_MANAGEMENT',
|
||||||
|
'MANAGE_SPACE',
|
||||||
|
'ASSIGN_USER_TO_SPACE',
|
||||||
|
);
|
||||||
|
manageScene = hasPermission(
|
||||||
|
permissionModel!,
|
||||||
|
'AUTOMATION_MANAGEMENT',
|
||||||
|
'MANAGE_SCENES',
|
||||||
|
'UPDATE',
|
||||||
|
);
|
||||||
|
manageDeviceLocation = hasPermission(
|
||||||
|
permissionModel!,
|
||||||
|
'DEVICE_MANAGEMENT',
|
||||||
|
'MANAGE_DEVICE',
|
||||||
|
'LOCATION_UPDATE',
|
||||||
|
);
|
||||||
|
visitorPasswordManagement = hasPermission(
|
||||||
|
permissionModel!,
|
||||||
|
'VISITOR_PASSWORD_MANAGEMENT',
|
||||||
|
'MANAGE_VISITOR_PASSWORD',
|
||||||
|
'VIEW',
|
||||||
|
);
|
||||||
|
emit(HomePermissionUpdated());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasPermission(List<PermissionModel> permissions, String mainTitle,
|
||||||
|
String subTitle, String finalTitle) {
|
||||||
|
try {
|
||||||
|
final mainOption = permissions.firstWhere(
|
||||||
|
(perm) => perm.title == mainTitle,
|
||||||
|
);
|
||||||
|
|
||||||
|
final subOption = mainOption.subOptions.firstWhere(
|
||||||
|
(sub) => sub.title == subTitle,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (subOption.subOptions == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final finalOption = subOption.subOptions!.firstWhere(
|
||||||
|
(finalSub) => finalSub.title == finalTitle,
|
||||||
|
);
|
||||||
|
return finalOption.isChecked == true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void emitSafe(HomeState newState) {
|
void emitSafe(HomeState newState) {
|
||||||
final cubit = this;
|
final cubit = this;
|
||||||
if (!cubit.isClosed) {
|
if (!cubit.isClosed) {
|
||||||
@ -89,7 +168,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
static HomeCubit get(context) => BlocProvider.of(context);
|
static HomeCubit get(context) => BlocProvider.of(context);
|
||||||
|
|
||||||
List<SpaceModel>? spaces;
|
List<SpaceModel>? spaces = [];
|
||||||
|
|
||||||
SpaceModel? selectedSpace;
|
SpaceModel? selectedSpace;
|
||||||
|
|
||||||
@ -261,6 +340,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
emitSafe(GetSpacesLoading());
|
emitSafe(GetSpacesLoading());
|
||||||
try {
|
try {
|
||||||
spaces = await SpacesAPI.getSpacesByUserId();
|
spaces = await SpacesAPI.getSpacesByUserId();
|
||||||
|
emitSafe(GetSpacesSuccess(spaces!));
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
emitSafe(GetSpacesError("No units found"));
|
emitSafe(GetSpacesError("No units found"));
|
||||||
return;
|
return;
|
||||||
@ -298,11 +378,13 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
var res = await SpacesAPI.activationCodeSpace(
|
var res = await SpacesAPI.activationCodeSpace(
|
||||||
activationCode: activationCode, userUuid: uuid);
|
activationCode: activationCode, userUuid: uuid);
|
||||||
|
|
||||||
if (res['success'] == true) {
|
if (res['success'] == true) {
|
||||||
fetchUserInfo();
|
fetchUserInfo();
|
||||||
fetchUnitsByUserId();
|
fetchUnitsByUserId();
|
||||||
}
|
}
|
||||||
emitSafe(GetSpacesSuccess(spaces!));
|
emitSafe(GetSpacesSuccess(spaces!));
|
||||||
|
|
||||||
return res['success'];
|
return res['success'];
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorMessage = e.response?.data['error']['message'];
|
final errorMessage = e.response?.data['error']['message'];
|
||||||
@ -378,6 +460,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
// ),
|
// ),
|
||||||
// onPressed: () {},
|
// onPressed: () {},
|
||||||
// ),
|
// ),
|
||||||
|
// HomeCubit.permissionModel!.scene!.visible == true
|
||||||
|
// ?
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.add,
|
Icons.add,
|
||||||
@ -413,7 +497,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
.read<CreateSceneBloc>()
|
.read<CreateSceneBloc>()
|
||||||
.add(const ClearTabToRunSetting());
|
.add(const ClearTabToRunSetting());
|
||||||
},
|
},
|
||||||
),
|
)
|
||||||
|
// : const SizedBox(),
|
||||||
// IconButton(
|
// IconButton(
|
||||||
// icon: const Icon(
|
// icon: const Icon(
|
||||||
// Icons.more_vert,
|
// Icons.more_vert,
|
||||||
@ -503,3 +588,28 @@ BottomNavigationBarItem defaultBottomNavBarItem(
|
|||||||
label: label,
|
label: label,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// class PermissionUtils {
|
||||||
|
// // Check if the "VIEW" permission exists in "MANAGE_SUBSPACE"
|
||||||
|
// static bool hasViewPermission(List<dynamic> permissions) {
|
||||||
|
// return _hasPermission(permissions, 'MANAGE_SUBSPACE', 'VIEW');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Generalized permission checker
|
||||||
|
// static bool _hasPermission(
|
||||||
|
// List<dynamic> permissions, String mainTitle, String subTitle) {
|
||||||
|
// final mainOption = permissions.firstWhere(
|
||||||
|
// (perm) => perm['title'] == mainTitle,
|
||||||
|
// orElse: () => null,
|
||||||
|
// );
|
||||||
|
// if (mainOption != null) {
|
||||||
|
// final subOption = mainOption['subOptions'].firstWhere(
|
||||||
|
// (sub) => sub['title'] == subTitle,
|
||||||
|
// orElse: () => null,
|
||||||
|
// );
|
||||||
|
// return subOption != null && subOption['isChecked'] == true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
@ -14,9 +14,9 @@ class HomeError extends HomeState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class HomeSuccess extends HomeState {}
|
class HomeSuccess extends HomeState {}
|
||||||
|
class ActivationSuccess extends HomeState {}
|
||||||
|
|
||||||
|
|
||||||
///specific states
|
|
||||||
//get spaces
|
|
||||||
class GetSpacesLoading extends HomeLoading {}
|
class GetSpacesLoading extends HomeLoading {}
|
||||||
|
|
||||||
class GetSpacesSuccess extends HomeSuccess {
|
class GetSpacesSuccess extends HomeSuccess {
|
||||||
@ -64,10 +64,16 @@ class RoomSelected extends HomeState {
|
|||||||
class RoomUnSelected extends HomeState {}
|
class RoomUnSelected extends HomeState {}
|
||||||
|
|
||||||
class NavChangePage extends HomeState {}
|
class NavChangePage extends HomeState {}
|
||||||
|
class HomePermissionUpdated extends HomeState {}
|
||||||
|
|
||||||
|
|
||||||
// Define new state classes
|
|
||||||
class HomeUserInfoLoaded extends HomeState {
|
class HomeUserInfoLoaded extends HomeState {
|
||||||
final UserModel user;
|
final UserModel user;
|
||||||
|
|
||||||
HomeUserInfoLoaded(this.user);
|
HomeUserInfoLoaded(this.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PermissionsRoleLoaded extends HomeState {
|
||||||
|
final List<PermissionModel> permissionModel;
|
||||||
|
PermissionsRoleLoaded(this.permissionModel);
|
||||||
|
}
|
||||||
|
39
lib/features/app_layout/model/permission_model.dart
Normal file
39
lib/features/app_layout/model/permission_model.dart
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
class PermissionModel {
|
||||||
|
final String title;
|
||||||
|
final List<PermissionAttributes> subOptions;
|
||||||
|
|
||||||
|
PermissionModel({required this.title, required this.subOptions});
|
||||||
|
|
||||||
|
factory PermissionModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return PermissionModel(
|
||||||
|
title: json['title'],
|
||||||
|
subOptions: (json['subOptions'] as List)
|
||||||
|
.map((e) => PermissionAttributes.fromJson(e))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<PermissionModel> fromJsonList(List<dynamic> jsonList) {
|
||||||
|
return jsonList.map((json) => PermissionModel.fromJson(json)).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PermissionAttributes {
|
||||||
|
final String title;
|
||||||
|
final List<PermissionAttributes>? subOptions;
|
||||||
|
final bool? isChecked;
|
||||||
|
|
||||||
|
PermissionAttributes({required this.title, this.subOptions, this.isChecked});
|
||||||
|
|
||||||
|
factory PermissionAttributes.fromJson(Map<String, dynamic> json) {
|
||||||
|
return PermissionAttributes(
|
||||||
|
title: json['title'],
|
||||||
|
isChecked: json['isChecked'],
|
||||||
|
subOptions: json['subOptions'] != null
|
||||||
|
? (json['subOptions'] as List)
|
||||||
|
.map((e) => PermissionAttributes.fromJson(e))
|
||||||
|
.toList()
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,10 @@ class AppLayout extends StatelessWidget {
|
|||||||
child: BlocBuilder<HomeCubit, HomeState>(
|
child: BlocBuilder<HomeCubit, HomeState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
appBar: HomeCubit.getInstance().spaces != null ? const DefaultAppBar() : null,
|
appBar: HomeCubit.getInstance().spaces != null &&
|
||||||
|
HomeCubit.getInstance().spaces!.isNotEmpty
|
||||||
|
? const DefaultAppBar()
|
||||||
|
: null,
|
||||||
bottomNavBar: const DefaultNavBar(),
|
bottomNavBar: const DefaultNavBar(),
|
||||||
child: const AppBody(),
|
child: const AppBody(),
|
||||||
);
|
);
|
||||||
|
@ -35,8 +35,10 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
actions: HomeCubit.appBarActions[
|
actions: HomeCubit.manageScene
|
||||||
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label],
|
? HomeCubit.appBarActions[
|
||||||
|
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label]
|
||||||
|
: null,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -221,6 +221,7 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
List<String> userFullName = fullName.split(' ');
|
List<String> userFullName = fullName.split(' ');
|
||||||
response = await AuthenticationAPI.signUp(
|
response = await AuthenticationAPI.signUp(
|
||||||
model: SignUpModel(
|
model: SignUpModel(
|
||||||
|
hasAcceptedAppAgreement: true,
|
||||||
email: email.toLowerCase(),
|
email: email.toLowerCase(),
|
||||||
password: signUpPassword,
|
password: signUpPassword,
|
||||||
firstName: userFullName[0],
|
firstName: userFullName[0],
|
||||||
|
@ -3,10 +3,12 @@ class SignUpModel {
|
|||||||
final String password;
|
final String password;
|
||||||
final String firstName;
|
final String firstName;
|
||||||
final String lastName;
|
final String lastName;
|
||||||
|
final bool hasAcceptedAppAgreement;
|
||||||
|
|
||||||
SignUpModel(
|
SignUpModel(
|
||||||
{required this.email,
|
{required this.email,
|
||||||
required this.password,
|
required this.password,
|
||||||
|
required this.hasAcceptedAppAgreement,
|
||||||
required this.firstName,
|
required this.firstName,
|
||||||
required this.lastName});
|
required this.lastName});
|
||||||
|
|
||||||
@ -15,7 +17,8 @@ class SignUpModel {
|
|||||||
email: json['email'],
|
email: json['email'],
|
||||||
password: json['password'],
|
password: json['password'],
|
||||||
firstName: json['firstName'],
|
firstName: json['firstName'],
|
||||||
lastName: json['lastName']);
|
lastName: json['lastName'],
|
||||||
|
hasAcceptedAppAgreement: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
@ -24,6 +27,7 @@ class SignUpModel {
|
|||||||
'password': password,
|
'password': password,
|
||||||
'firstName': firstName,
|
'firstName': firstName,
|
||||||
'lastName': lastName,
|
'lastName': lastName,
|
||||||
|
"hasAcceptedAppAgreement": hasAcceptedAppAgreement
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,11 @@ class UserModel {
|
|||||||
final String? timeZone;
|
final String? timeZone;
|
||||||
final String? regionUuid;
|
final String? regionUuid;
|
||||||
final bool? isAgreementAccepted;
|
final bool? isAgreementAccepted;
|
||||||
|
final bool? hasAcceptedWebAgreement;
|
||||||
|
final DateTime? webAgreementAcceptedAt;
|
||||||
|
final bool? hasAcceptedAppAgreement;
|
||||||
|
final DateTime? appAgreementAcceptedAt;
|
||||||
|
final Role? role;
|
||||||
|
|
||||||
UserModel({
|
UserModel({
|
||||||
required this.uuid,
|
required this.uuid,
|
||||||
@ -28,7 +33,11 @@ class UserModel {
|
|||||||
required this.isAgreementAccepted,
|
required this.isAgreementAccepted,
|
||||||
required this.regionName,
|
required this.regionName,
|
||||||
required this.timeZone,
|
required this.timeZone,
|
||||||
// required this.role,
|
required this.hasAcceptedWebAgreement,
|
||||||
|
required this.webAgreementAcceptedAt,
|
||||||
|
required this.hasAcceptedAppAgreement,
|
||||||
|
required this.appAgreementAcceptedAt,
|
||||||
|
required this.role,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory UserModel.fromJson(Map<String, dynamic> json) {
|
factory UserModel.fromJson(Map<String, dynamic> json) {
|
||||||
@ -44,6 +53,15 @@ class UserModel {
|
|||||||
regionName: json['region']?['regionName'],
|
regionName: json['region']?['regionName'],
|
||||||
timeZone: json['timeZone']?['timeZoneOffset'],
|
timeZone: json['timeZone']?['timeZoneOffset'],
|
||||||
regionUuid: json['region']?['uuid'],
|
regionUuid: json['region']?['uuid'],
|
||||||
|
hasAcceptedWebAgreement: json['hasAcceptedWebAgreement'],
|
||||||
|
webAgreementAcceptedAt: json['webAgreementAcceptedAt'] != null
|
||||||
|
? DateTime.parse(json['webAgreementAcceptedAt'])
|
||||||
|
: null,
|
||||||
|
hasAcceptedAppAgreement: json['hasAcceptedAppAgreement'],
|
||||||
|
appAgreementAcceptedAt: json['appAgreementAcceptedAt'] != null
|
||||||
|
? DateTime.parse(json['appAgreementAcceptedAt'])
|
||||||
|
: null,
|
||||||
|
role: json['role'] != null ? Role.fromJson(json['role']) : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +79,15 @@ class UserModel {
|
|||||||
regionUuid: null,
|
regionUuid: null,
|
||||||
regionName: tempJson['region']?['regionName'],
|
regionName: tempJson['region']?['regionName'],
|
||||||
timeZone: tempJson['timezone']?['timeZoneOffset'],
|
timeZone: tempJson['timezone']?['timeZoneOffset'],
|
||||||
|
hasAcceptedWebAgreement: tempJson['hasAcceptedWebAgreement'],
|
||||||
|
webAgreementAcceptedAt: tempJson['webAgreementAcceptedAt'] != null
|
||||||
|
? DateTime.parse(tempJson['webAgreementAcceptedAt'])
|
||||||
|
: null,
|
||||||
|
hasAcceptedAppAgreement: tempJson['hasAcceptedAppAgreement'],
|
||||||
|
appAgreementAcceptedAt: tempJson['appAgreementAcceptedAt'] != null
|
||||||
|
? DateTime.parse(tempJson['appAgreementAcceptedAt'])
|
||||||
|
: null,
|
||||||
|
role: tempJson['role'] != null ? Role.fromJson(tempJson['role']) : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +112,43 @@ class UserModel {
|
|||||||
'isAgreementAccepted': isAgreementAccepted,
|
'isAgreementAccepted': isAgreementAccepted,
|
||||||
'regionName': regionName,
|
'regionName': regionName,
|
||||||
'timeZone': timeZone,
|
'timeZone': timeZone,
|
||||||
|
'hasAcceptedWebAgreement': hasAcceptedWebAgreement,
|
||||||
|
'webAgreementAcceptedAt': webAgreementAcceptedAt?.toIso8601String(),
|
||||||
|
'hasAcceptedAppAgreement': hasAcceptedAppAgreement,
|
||||||
|
'appAgreementAcceptedAt': appAgreementAcceptedAt?.toIso8601String(),
|
||||||
|
'role': role?.toJson(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Role {
|
||||||
|
final String? uuid;
|
||||||
|
final DateTime? createdAt;
|
||||||
|
final DateTime? updatedAt;
|
||||||
|
final String? type;
|
||||||
|
|
||||||
|
Role({
|
||||||
|
required this.uuid,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Role.fromJson(Map<String, dynamic> json) {
|
||||||
|
return Role(
|
||||||
|
uuid: json['uuid'],
|
||||||
|
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null,
|
||||||
|
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : null,
|
||||||
|
type: json['type'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'uuid': uuid,
|
||||||
|
'createdAt': createdAt?.toIso8601String(),
|
||||||
|
'updatedAt': updatedAt?.toIso8601String(),
|
||||||
|
'type': type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,7 +433,9 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
seconds = event.seconds;
|
seconds = event.seconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: acId, code: 'countdown_time', value: event.duration),
|
deviceId: acId,
|
||||||
|
code: 'countdown_time',
|
||||||
|
value: event.duration),
|
||||||
acId);
|
acId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
|
@ -38,8 +38,10 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
|
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
|
||||||
return state is DeviceSettingLoadingState
|
return state is DeviceSettingLoadingState
|
||||||
? const Center(
|
? const Center(
|
||||||
child:
|
child: DefaultContainer(
|
||||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: CircularProgressIndicator()),
|
||||||
)
|
)
|
||||||
: RefreshIndicator(
|
: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
@ -55,15 +57,18 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.sosHomeIcon,
|
Assets.sosHomeIcon,
|
||||||
fit: BoxFit.fitHeight,
|
fit: BoxFit.fitHeight,
|
||||||
height: MediaQuery.of(context).size.height * 0.13,
|
height:
|
||||||
|
MediaQuery.of(context).size.height * 0.13,
|
||||||
))
|
))
|
||||||
: CircleAvatar(
|
: CircleAvatar(
|
||||||
radius: 55,
|
radius: 55,
|
||||||
backgroundColor: ColorsManager.graysColor,
|
backgroundColor: ColorsManager.graysColor,
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment:
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
@ -71,7 +76,10 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
? Assets.fourSceneIcon
|
? Assets.fourSceneIcon
|
||||||
: Assets.sixSceneIcon,
|
: Assets.sixSceneIcon,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
height: MediaQuery.of(context).size.height * 0.08,
|
height: MediaQuery.of(context)
|
||||||
|
.size
|
||||||
|
.height *
|
||||||
|
0.08,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -89,7 +97,8 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
IntrinsicWidth(
|
IntrinsicWidth(
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxWidth: 200),
|
constraints:
|
||||||
|
const BoxConstraints(maxWidth: 200),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
maxLength: 30,
|
maxLength: 30,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@ -122,7 +131,8 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
Assets.sosEditProfile,
|
Assets.sosEditProfile,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
height: MediaQuery.of(context).size.height * 0.02,
|
height: MediaQuery.of(context).size.height *
|
||||||
|
0.02,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -141,15 +151,17 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
bool? val = await Navigator.of(context).push(
|
if (HomeCubit.visitorPasswordManagement) {
|
||||||
MaterialPageRoute(
|
bool? val = await Navigator.of(context).push(
|
||||||
builder: (context) => LocationSettingPage(
|
MaterialPageRoute(
|
||||||
space: spaces!.first,
|
builder: (context) => LocationSettingPage(
|
||||||
deviceId: device?.uuid ?? '',
|
space: spaces!.first,
|
||||||
)),
|
deviceId: device?.uuid ?? '',
|
||||||
);
|
)),
|
||||||
if (val != null && val == true) {
|
);
|
||||||
_bloc.add(const DeviceSettingInitialInfo());
|
if (val != null && val == true) {
|
||||||
|
_bloc.add(const DeviceSettingInitialInfo());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -162,7 +174,8 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
child: BodyMedium(
|
child: BodyMedium(
|
||||||
text: _bloc.deviceInfo.subspace.subspaceName,
|
text: _bloc
|
||||||
|
.deviceInfo.subspace.subspaceName,
|
||||||
fontColor: ColorsManager.textGray,
|
fontColor: ColorsManager.textGray,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
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_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/members_management_view.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/members_management_view.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/smart_linkage_view.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/smart_linkage_view.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/temporary_password_page.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/temporary_password_page.dart';
|
||||||
@ -14,6 +15,8 @@ class DoorLockGrid extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final buttons = doorLockButtons(val: uuid);
|
||||||
|
|
||||||
return GridView.builder(
|
return GridView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
@ -23,14 +26,15 @@ class DoorLockGrid extends StatelessWidget {
|
|||||||
crossAxisSpacing: 10,
|
crossAxisSpacing: 10,
|
||||||
childAspectRatio: 1.75 / 1,
|
childAspectRatio: 1.75 / 1,
|
||||||
),
|
),
|
||||||
itemCount: 4,
|
itemCount: buttons.length,
|
||||||
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(val: uuid)[index]['page'] as Widget,
|
builder: (context) =>
|
||||||
|
doorLockButtons(val: uuid)[index]['page'] as Widget,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
@ -75,11 +79,12 @@ List<Map<String, dynamic>> doorLockButtons({val}) => [
|
|||||||
'image': Assets.assetsIconsDoorlockAssetsMembersManagement,
|
'image': Assets.assetsIconsDoorlockAssetsMembersManagement,
|
||||||
'page': const MembersManagementView(),
|
'page': const MembersManagementView(),
|
||||||
},
|
},
|
||||||
{
|
if (HomeCubit.manageDeviceLocation)
|
||||||
'title': 'Temporary Password',
|
{
|
||||||
'image': Assets.assetsIconsDoorlockAssetsTemporaryPassword,
|
'title': 'Temporary Password',
|
||||||
'page': TemporaryPasswordPage(deviceId: val),
|
'image': Assets.assetsIconsDoorlockAssetsTemporaryPassword,
|
||||||
},
|
'page': TemporaryPasswordPage(deviceId: val),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'title': 'Smart Linkage',
|
'title': 'Smart Linkage',
|
||||||
'image': Assets.assetsIconsDoorlockAssetsSmartLinkage,
|
'image': Assets.assetsIconsDoorlockAssetsSmartLinkage,
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/bloc/privacy_policy.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/bloc/user_agreement.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/view/widgets/join_home/join_home_view.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/view/widgets/manage_home/manage_home_view.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/view/widgets/securty/view/securty_view.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/services/api/profile_api.dart';
|
import 'package:syncrow_app/services/api/profile_api.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
part 'menu_state.dart';
|
part 'menu_state.dart';
|
||||||
|
|
||||||
@ -32,4 +42,143 @@ class MenuCubit extends Cubit<MenuState> {
|
|||||||
emit(MenuError(error.toString()));
|
emit(MenuError(error.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> menuSections = [
|
||||||
|
//Home Management
|
||||||
|
{
|
||||||
|
'title': 'Home Management',
|
||||||
|
'color': ColorsManager.primaryColor,
|
||||||
|
'buttons': [
|
||||||
|
// {
|
||||||
|
// 'title': 'Create a Unit',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsCreateHome,
|
||||||
|
// 'page': const CreateUnitView()
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
'title': 'Join a Unit',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsJoinAHome,
|
||||||
|
'page': const JoinHomeView()
|
||||||
|
},
|
||||||
|
if (HomeCubit.manageSupSpace)
|
||||||
|
{
|
||||||
|
'title': 'Manage Your Units',
|
||||||
|
'Icon':
|
||||||
|
Assets.assetsIconsMenuIconsHomeManagementIconsManageYourHome,
|
||||||
|
'page': const ManageHomeView()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
//General Settings
|
||||||
|
// {
|
||||||
|
// 'title': 'General Settings',
|
||||||
|
// 'color': const Color(0xFF023DFE),
|
||||||
|
// 'buttons': [
|
||||||
|
// {
|
||||||
|
// 'title': 'Voice Assistant',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsVoiceAssistant,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Temperature unit',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsTemperatureUnit,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Touch tone on panel',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsTouchTone,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Language',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsLanguage,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Network Diagnosis',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsNetworkDiagnosis,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Clear Cache',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsClearCach,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// //Messages Center
|
||||||
|
// {
|
||||||
|
// 'title': 'Messages Center',
|
||||||
|
// 'color': const Color(0xFF0088FF),
|
||||||
|
// 'buttons': [
|
||||||
|
// {
|
||||||
|
// 'title': 'Alerts',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsAlerts,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Messages',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsMessages,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'FAQs',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsFAQs,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Help & Feedback',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsHelpAndFeedback,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
//Security And Privacy
|
||||||
|
{
|
||||||
|
'title': 'Security And Privacy',
|
||||||
|
'color': const Color(0xFF8AB9FF),
|
||||||
|
'buttons': [
|
||||||
|
{
|
||||||
|
'title': 'Security',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsSecurityAndPrivacyIconsSecurty,
|
||||||
|
'page': const SecurtyView()
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// 'title': 'Privacy',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsSecurityAndPrivacyIconsPrivacy,
|
||||||
|
// 'page': const PrivacyView()
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
//Legal Information
|
||||||
|
{
|
||||||
|
'title': 'Legal Information',
|
||||||
|
'color': const Color(0xFF001B72),
|
||||||
|
'buttons': [
|
||||||
|
{
|
||||||
|
'title': 'About',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout,
|
||||||
|
'page': null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'Privacy Policy',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsPrivacyPolicy,
|
||||||
|
'page': const PrivacyPolicy()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'User Agreement',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsUserAgreement,
|
||||||
|
'page': const UserAgreement()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
Future<void> fetchMenuSections() async {
|
||||||
|
emit(MenuLoading());
|
||||||
|
try {
|
||||||
|
emit(MenuItemsLoaded(menuSections));
|
||||||
|
} catch (e) {
|
||||||
|
emit(MenuError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,11 @@ class MenuLoaded extends MenuState {
|
|||||||
MenuLoaded(this.userAgreementHtml);
|
MenuLoaded(this.userAgreementHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MenuItemsLoaded extends MenuState {
|
||||||
|
final List<Map<String, Object>> menuSections;
|
||||||
|
MenuItemsLoaded(this.menuSections);
|
||||||
|
}
|
||||||
class MenuError extends MenuState {
|
class MenuError extends MenuState {
|
||||||
final String message;
|
final String message;
|
||||||
|
|
||||||
|
@ -1,69 +1,62 @@
|
|||||||
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:flutter_dotenv/flutter_dotenv.dart';
|
|
||||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
|
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
|
||||||
import 'package:syncrow_app/features/menu/view/widgets/menu_list.dart';
|
import 'package:syncrow_app/features/menu/view/widgets/menu_list.dart';
|
||||||
import 'package:syncrow_app/features/menu/view/widgets/profile/profile_tab.dart';
|
import 'package:syncrow_app/features/menu/view/widgets/profile/profile_tab.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/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
|
||||||
|
|
||||||
class MenuView extends StatelessWidget {
|
class MenuView extends StatelessWidget {
|
||||||
const MenuView({super.key});
|
const MenuView({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (BuildContext context) => MenuCubit(),
|
create: (BuildContext context) => MenuCubit()..fetchMenuSections(),
|
||||||
child: BlocBuilder<MenuCubit, MenuState>(
|
child: BlocBuilder<MenuCubit, MenuState>(
|
||||||
builder: (context, state) {
|
builder: (context, menuState) {
|
||||||
return BlocBuilder<AuthCubit, AuthState>(
|
if (menuState is MenuLoading) {
|
||||||
builder: (context, state) {
|
return const Center(child: CircularProgressIndicator());
|
||||||
return SingleChildScrollView(
|
} else if (menuState is MenuError) {
|
||||||
physics: const BouncingScrollPhysics(),
|
return Center(child: Text(menuState.message));
|
||||||
child: Column(
|
} else if (menuState is MenuItemsLoaded) {
|
||||||
children: [
|
final sections = menuState.menuSections;
|
||||||
const ProfileTab(),
|
return SingleChildScrollView(
|
||||||
for (var section in menuSections)
|
physics: const BouncingScrollPhysics(),
|
||||||
MenuList(
|
child: Column(
|
||||||
section: section,
|
children: [
|
||||||
),
|
const ProfileTab(),
|
||||||
const SizedBox(
|
for (var section in sections) MenuList(section: section),
|
||||||
height: 15,
|
const SizedBox(height: 15),
|
||||||
),
|
InkWell(
|
||||||
BodyMedium(text: dotenv.env['ENV_NAME'] ?? ''),
|
onTap: () {
|
||||||
const SizedBox(
|
AuthCubit.get(context).logout();
|
||||||
height: 15,
|
},
|
||||||
),
|
child: Row(
|
||||||
InkWell(
|
children: [
|
||||||
onTap: () {
|
Expanded(
|
||||||
AuthCubit.get(context).logout();
|
child: DefaultContainer(
|
||||||
},
|
child: Center(
|
||||||
child: Row(
|
child: BodyLarge(
|
||||||
children: [
|
text: 'Logout',
|
||||||
Expanded(
|
style: context.bodyLarge.copyWith(
|
||||||
child: DefaultContainer(
|
color: Colors.red,
|
||||||
child: Center(
|
|
||||||
child: BodyLarge(
|
|
||||||
text: 'Logout',
|
|
||||||
style: context.bodyLarge.copyWith(
|
|
||||||
color: Colors.red,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
)
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
);
|
}
|
||||||
|
// Fallback in case no states match
|
||||||
|
return const SizedBox.shrink();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -36,34 +36,38 @@ class SceneItem extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DefaultContainer(
|
return DefaultContainer(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
if (HomeCubit.manageScene) {
|
||||||
if (disablePlayButton == false) {
|
context
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
.read<SmartSceneSelectBloc>()
|
||||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
.add(const SmartSceneClearEvent());
|
||||||
|
if (disablePlayButton == false) {
|
||||||
|
BlocProvider.of<CreateSceneBloc>(context).add(
|
||||||
|
FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
||||||
|
|
||||||
/// the state to set the scene type must be after the fetch
|
/// the state to set the scene type must be after the fetch
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
BlocProvider.of<CreateSceneBloc>(context)
|
||||||
.add(const SceneTypeEvent(CreateSceneEnum.tabToRun));
|
.add(const SceneTypeEvent(CreateSceneEnum.tabToRun));
|
||||||
} else {
|
} else {
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
BlocProvider.of<CreateSceneBloc>(context).add(
|
||||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: true));
|
FetchSceneTasksEvent(sceneId: scene.id, isAutomation: true));
|
||||||
|
|
||||||
/// the state to set the scene type must be after the fetch
|
/// the state to set the scene type must be after the fetch
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
BlocProvider.of<CreateSceneBloc>(context)
|
||||||
.add(const SceneTypeEvent(CreateSceneEnum.deviceStatusChanges));
|
.add(const SceneTypeEvent(CreateSceneEnum.deviceStatusChanges));
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.pushNamed(
|
||||||
|
context,
|
||||||
|
Routes.sceneTasksRoute,
|
||||||
|
arguments: SceneSettingsRouteArguments(
|
||||||
|
sceneType: disablePlayButton == false
|
||||||
|
? CreateSceneEnum.tabToRun.name
|
||||||
|
: CreateSceneEnum.deviceStatusChanges.name,
|
||||||
|
sceneId: scene.id,
|
||||||
|
sceneName: scene.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Navigator.pushNamed(
|
|
||||||
context,
|
|
||||||
Routes.sceneTasksRoute,
|
|
||||||
arguments: SceneSettingsRouteArguments(
|
|
||||||
sceneType: disablePlayButton == false
|
|
||||||
? CreateSceneEnum.tabToRun.name
|
|
||||||
: CreateSceneEnum.deviceStatusChanges.name,
|
|
||||||
sceneId: scene.id,
|
|
||||||
sceneName: scene.name,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@ -79,8 +83,11 @@ class SceneItem extends StatelessWidget {
|
|||||||
height: 32,
|
height: 32,
|
||||||
width: 32,
|
width: 32,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
errorBuilder: (context, error, stackTrace) =>
|
errorBuilder: (context, error, stackTrace) => Image.asset(
|
||||||
Image.asset(Assets.assetsIconsLogo, height: 32, width: 32, fit: BoxFit.fill),
|
Assets.assetsIconsLogo,
|
||||||
|
height: 32,
|
||||||
|
width: 32,
|
||||||
|
fit: BoxFit.fill),
|
||||||
),
|
),
|
||||||
if (disablePlayButton || scene.iconInBytes.isEmpty)
|
if (disablePlayButton || scene.iconInBytes.isEmpty)
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
@ -93,7 +100,9 @@ class SceneItem extends StatelessWidget {
|
|||||||
? IconButton(
|
? IconButton(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<SceneBloc>().add(SceneTrigger(scene.id, scene.name));
|
context
|
||||||
|
.read<SceneBloc>()
|
||||||
|
.add(SceneTrigger(scene.id, scene.name));
|
||||||
},
|
},
|
||||||
icon: isLoading
|
icon: isLoading
|
||||||
? const Center(
|
? const Center(
|
||||||
@ -115,11 +124,15 @@ class SceneItem extends StatelessWidget {
|
|||||||
activeColor: ColorsManager.primaryColor,
|
activeColor: ColorsManager.primaryColor,
|
||||||
value: scene.status == 'enable' ? true : false,
|
value: scene.status == 'enable' ? true : false,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<SceneBloc>().add(UpdateAutomationStatus(
|
context.read<SceneBloc>().add(
|
||||||
automationStatusUpdate: AutomationStatusUpdate(
|
UpdateAutomationStatus(
|
||||||
isEnable: value,
|
automationStatusUpdate:
|
||||||
spaceUuid: HomeCubit.getInstance().selectedSpace!.id),
|
AutomationStatusUpdate(
|
||||||
automationId: scene.id));
|
isEnable: value,
|
||||||
|
spaceUuid: HomeCubit.getInstance()
|
||||||
|
.selectedSpace!
|
||||||
|
.id),
|
||||||
|
automationId: scene.id));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -16,7 +16,7 @@ class CreateUnitWidget extends StatelessWidget {
|
|||||||
TextEditingController textEditingController = TextEditingController();
|
TextEditingController textEditingController = TextEditingController();
|
||||||
return BlocConsumer<HomeCubit, HomeState>(
|
return BlocConsumer<HomeCubit, HomeState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is ActivationError) {}
|
// if (state is ActivationError) {}
|
||||||
},
|
},
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
@ -96,7 +96,11 @@ class CreateUnitWidget extends StatelessWidget {
|
|||||||
textEditingController.text)) {
|
textEditingController.text)) {
|
||||||
CustomSnackBar.displaySnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
'Done successfully');
|
'Done successfully');
|
||||||
Navigator.of(context).pop();
|
Future.delayed(
|
||||||
|
const Duration(milliseconds: 500),
|
||||||
|
() {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
CustomSnackBar.displaySnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
'Wrong code!');
|
'Wrong code!');
|
||||||
@ -109,14 +113,14 @@ class CreateUnitWidget extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
state is ActivationError
|
// state is ActivationError
|
||||||
? Text(
|
// ? Text(
|
||||||
state.errMessage,
|
// state.errMessage,
|
||||||
style: const TextStyle(
|
// style: const TextStyle(
|
||||||
color: ColorsManager.red,
|
// color: ColorsManager.red,
|
||||||
fontWeight: FontWeight.w400),
|
// fontWeight: FontWeight.w400),
|
||||||
)
|
// )
|
||||||
: const SizedBox()
|
// : const SizedBox()
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -136,42 +140,42 @@ class CreateUnitWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return SizedBox(
|
// return SizedBox(
|
||||||
// width: MediaQuery.sizeOf(context).width,
|
// width: MediaQuery.sizeOf(context).width,
|
||||||
// height: MediaQuery.sizeOf(context).height,
|
// height: MediaQuery.sizeOf(context).height,
|
||||||
// child: Column(
|
// child: Column(
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
// children: [
|
// children: [
|
||||||
// SvgPicture.asset(
|
// SvgPicture.asset(
|
||||||
// Assets.noUnitsIconDashboard,
|
// Assets.noUnitsIconDashboard,
|
||||||
// width: 100,
|
// width: 100,
|
||||||
// height: 100,
|
// height: 100,
|
||||||
// ),
|
// ),
|
||||||
// const SizedBox(
|
// const SizedBox(
|
||||||
// height: 50,
|
// height: 50,
|
||||||
// ),
|
// ),
|
||||||
// Flexible(
|
// Flexible(
|
||||||
// child: GestureDetector(
|
// child: GestureDetector(
|
||||||
// onTap: () {
|
// onTap: () {
|
||||||
// Navigator.pushNamed(context, Routes.createUnit);
|
// Navigator.pushNamed(context, Routes.createUnit);
|
||||||
// },
|
// },
|
||||||
// child: Container(
|
// child: Container(
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 34, vertical: 14),
|
// padding: const EdgeInsets.symmetric(horizontal: 34, vertical: 14),
|
||||||
// decoration: ShapeDecoration(
|
// decoration: ShapeDecoration(
|
||||||
// color: const Color(0x99023DFE),
|
// color: const Color(0x99023DFE),
|
||||||
// shape: RoundedRectangleBorder(
|
// shape: RoundedRectangleBorder(
|
||||||
// borderRadius: BorderRadius.circular(20),
|
// borderRadius: BorderRadius.circular(20),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// child: const TitleMedium(
|
// child: const TitleMedium(
|
||||||
// text: 'Create a unit',
|
// text: 'Create a unit',
|
||||||
// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.white),
|
// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.white),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ],
|
// ],
|
||||||
// ),
|
// ),
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
@ -225,4 +225,7 @@ abstract class ApiEndpoints {
|
|||||||
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
||||||
static const String terms = '/terms';
|
static const String terms = '/terms';
|
||||||
static const String policy = '/policy';
|
static const String policy = '/policy';
|
||||||
|
static const String getPermission = '/permission/{roleUuid}';
|
||||||
|
|
||||||
|
///permission/roleUuid
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,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;
|
||||||
@ -97,7 +98,8 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> getPowerClampStatus(String deviceId) async {
|
static Future<Map<String, dynamic>> getPowerClampStatus(
|
||||||
|
String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId),
|
path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
@ -109,7 +111,9 @@ class DevicesAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> renamePass(
|
static Future<Map<String, dynamic>> renamePass(
|
||||||
{required String name, required String doorLockUuid, required String passwordId}) async {
|
{required String name,
|
||||||
|
required String doorLockUuid,
|
||||||
|
required String passwordId}) async {
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.put(
|
||||||
path: ApiEndpoints.renamePassword
|
path: ApiEndpoints.renamePassword
|
||||||
.replaceAll('{doorLockUuid}', doorLockUuid)
|
.replaceAll('{doorLockUuid}', doorLockUuid)
|
||||||
@ -144,7 +148,8 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future getSceneBySwitchName({String? deviceId, String? switchName}) async {
|
static Future getSceneBySwitchName(
|
||||||
|
{String? deviceId, String? switchName}) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.fourSceneByName
|
path: ApiEndpoints.fourSceneByName
|
||||||
.replaceAll('{deviceUuid}', deviceId!)
|
.replaceAll('{deviceUuid}', deviceId!)
|
||||||
@ -165,7 +170,11 @@ class DevicesAPI {
|
|||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId!),
|
path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId!),
|
||||||
body: jsonEncode(
|
body: jsonEncode(
|
||||||
{"switchName": switchName, "sceneUuid": sceneUuid, "spaceUuid": spaceUuid},
|
{
|
||||||
|
"switchName": switchName,
|
||||||
|
"sceneUuid": sceneUuid,
|
||||||
|
"spaceUuid": spaceUuid
|
||||||
|
},
|
||||||
),
|
),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
@ -185,7 +194,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)
|
||||||
@ -230,7 +240,9 @@ class DevicesAPI {
|
|||||||
if (json == null || json.isEmpty || json == []) {
|
if (json == null || json.isEmpty || json == []) {
|
||||||
return <DeviceModel>[];
|
return <DeviceModel>[];
|
||||||
}
|
}
|
||||||
return data.map<DeviceModel>((device) => DeviceModel.fromJson(device)).toList();
|
return data
|
||||||
|
.map<DeviceModel>((device) => DeviceModel.fromJson(device))
|
||||||
|
.toList();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -242,7 +254,8 @@ class DevicesAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
@ -264,7 +277,8 @@ class DevicesAPI {
|
|||||||
String deviceId,
|
String deviceId,
|
||||||
) async {
|
) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.getTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -275,7 +289,8 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future getOneTimePasswords(String deviceId) async {
|
static Future getOneTimePasswords(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.getOneTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -286,7 +301,8 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future getTimeLimitPasswords(String deviceId) async {
|
static Future getTimeLimitPasswords(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.getMultipleTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -311,10 +327,12 @@ class DevicesAPI {
|
|||||||
"invalidTime": invalidTime,
|
"invalidTime": invalidTime,
|
||||||
};
|
};
|
||||||
if (scheduleList != null) {
|
if (scheduleList != null) {
|
||||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
body["scheduleList"] =
|
||||||
|
scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||||
}
|
}
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.addTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
body: body,
|
body: body,
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => json,
|
expectedResponseModel: (json) => json,
|
||||||
@ -325,7 +343,8 @@ class DevicesAPI {
|
|||||||
static Future generateOneTimePassword({deviceId}) async {
|
static Future generateOneTimePassword({deviceId}) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.addOneTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -337,10 +356,12 @@ class DevicesAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async {
|
static Future generateMultiTimePassword(
|
||||||
|
{deviceId, effectiveTime, invalidTime}) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.addMultipleTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
@ -530,7 +551,9 @@ class DevicesAPI {
|
|||||||
String code,
|
String code,
|
||||||
) async {
|
) async {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getDeviceLogs.replaceAll('{uuid}', uuid).replaceAll('{code}', code),
|
path: ApiEndpoints.getDeviceLogs
|
||||||
|
.replaceAll('{uuid}', uuid)
|
||||||
|
.replaceAll('{code}', code),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return DeviceReport.fromJson(json);
|
return DeviceReport.fromJson(json);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:developer';
|
|
||||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
||||||
import 'package:syncrow_app/features/menu/model/region_model.dart';
|
import 'package:syncrow_app/features/menu/model/region_model.dart';
|
||||||
@ -95,6 +94,16 @@ class ProfileApi {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future fetchPermissions(roleId) async {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: ApiEndpoints.getPermission.replaceAll('{roleUuid}', roleId!),
|
||||||
|
showServerMessage: true,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
static Future<List<RegionModel>> fetchRegion() async {
|
static Future<List<RegionModel>> fetchRegion() async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getRegion,
|
path: ApiEndpoints.getRegion,
|
||||||
@ -117,7 +126,7 @@ class ProfileApi {
|
|||||||
return response as List<TimeZone>;
|
return response as List<TimeZone>;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future fetchUserAgreement() async {
|
Future fetchUserAgreement() async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.terms,
|
path: ApiEndpoints.terms,
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
@ -127,7 +136,7 @@ class ProfileApi {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future fetchPrivacyPolicy() async {
|
Future fetchPrivacyPolicy() async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.policy,
|
path: ApiEndpoints.policy,
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//ignore_for_file: constant_identifier_names
|
//ignore_for_file: constant_identifier_names
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/privacy_policy.dart';
|
import 'package:syncrow_app/features/menu/bloc/privacy_policy.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/user_agreement.dart';
|
import 'package:syncrow_app/features/menu/bloc/user_agreement.dart';
|
||||||
@ -677,134 +678,6 @@ K? getNextItem<K, V>(Map<K, V> map, V value) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Map<String, Object>> menuSections = [
|
|
||||||
//Home Management
|
|
||||||
{
|
|
||||||
'title': 'Home Management',
|
|
||||||
'color': ColorsManager.primaryColor,
|
|
||||||
'buttons': [
|
|
||||||
// {
|
|
||||||
// 'title': 'Create a Unit',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsCreateHome,
|
|
||||||
// 'page': const CreateUnitView()
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
'title': 'Join a Unit',
|
|
||||||
'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsJoinAHome,
|
|
||||||
'page': const JoinHomeView()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'title': 'Manage Your Units',
|
|
||||||
'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsManageYourHome,
|
|
||||||
'page': const ManageHomeView()
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
//General Settings
|
|
||||||
// {
|
|
||||||
// 'title': 'General Settings',
|
|
||||||
// 'color': const Color(0xFF023DFE),
|
|
||||||
// 'buttons': [
|
|
||||||
// {
|
|
||||||
// 'title': 'Voice Assistant',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsVoiceAssistant,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 'title': 'Temperature unit',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsTemperatureUnit,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 'title': 'Touch tone on panel',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsTouchTone,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 'title': 'Language',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsLanguage,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 'title': 'Network Diagnosis',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsNetworkDiagnosis,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 'title': 'Clear Cache',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsClearCach,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// //Messages Center
|
|
||||||
// {
|
|
||||||
// 'title': 'Messages Center',
|
|
||||||
// 'color': const Color(0xFF0088FF),
|
|
||||||
// 'buttons': [
|
|
||||||
// {
|
|
||||||
// 'title': 'Alerts',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsAlerts,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 'title': 'Messages',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsMessages,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 'title': 'FAQs',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsFAQs,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 'title': 'Help & Feedback',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsHelpAndFeedback,
|
|
||||||
// 'page': null
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
//Security And Privacy
|
|
||||||
{
|
|
||||||
'title': 'Security And Privacy',
|
|
||||||
'color': const Color(0xFF8AB9FF),
|
|
||||||
'buttons': [
|
|
||||||
{
|
|
||||||
'title': 'Security',
|
|
||||||
'Icon': Assets.assetsIconsMenuIconsSecurityAndPrivacyIconsSecurty,
|
|
||||||
'page': const SecurtyView()
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// 'title': 'Privacy',
|
|
||||||
// 'Icon': Assets.assetsIconsMenuIconsSecurityAndPrivacyIconsPrivacy,
|
|
||||||
// 'page': const PrivacyView()
|
|
||||||
// },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
//Legal Information
|
|
||||||
{
|
|
||||||
'title': 'Legal Information',
|
|
||||||
'color': const Color(0xFF001B72),
|
|
||||||
'buttons': [
|
|
||||||
{
|
|
||||||
'title': 'About',
|
|
||||||
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout,
|
|
||||||
'page': null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'title': 'Privacy Policy',
|
|
||||||
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsPrivacyPolicy,
|
|
||||||
'page': const PrivacyPolicy()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'title': 'User Agreement',
|
|
||||||
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsUserAgreement,
|
|
||||||
'page': const UserAgreement()
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
enum MemberRole {
|
enum MemberRole {
|
||||||
FamilyMember,
|
FamilyMember,
|
||||||
OtherMember,
|
OtherMember,
|
||||||
|
Reference in New Issue
Block a user