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:permission_handler/permission_handler.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/view/widgets/app_bar_home_dropdown.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/model/subspace_model.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/utils/helpers/snack_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
part 'home_state.dart';
|
||||
|
||||
class HomeCubit extends Cubit<HomeState> {
|
||||
HomeCubit._() : super(HomeInitial()) {
|
||||
// checkIfNotificationPermissionGranted();
|
||||
fetchUserInfo();
|
||||
fetchUserInfo().then(
|
||||
(value) {
|
||||
if (selectedSpace == null) {
|
||||
fetchUnitsByUserId();
|
||||
fetchPermissions();
|
||||
|
||||
// .then((value) {
|
||||
// if (selectedSpace != null) {
|
||||
// fetchRoomsByUnitId(selectedSpace!);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
static UserModel? user;
|
||||
|
||||
List<PermissionModel>? permissionModel = [];
|
||||
|
||||
static HomeCubit? _instance;
|
||||
static HomeCubit getInstance() {
|
||||
// If an instance already exists, return it
|
||||
@ -56,15 +63,87 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
|
||||
Future fetchUserInfo() async {
|
||||
try {
|
||||
emit(HomeLoading());
|
||||
var uuid =
|
||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||
user = await ProfileApi().fetchUserInfo(uuid);
|
||||
emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info
|
||||
emit(HomeUserInfoLoaded(user!));
|
||||
} catch (e) {
|
||||
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) {
|
||||
final cubit = this;
|
||||
if (!cubit.isClosed) {
|
||||
@ -89,7 +168,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
|
||||
static HomeCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
List<SpaceModel>? spaces;
|
||||
List<SpaceModel>? spaces = [];
|
||||
|
||||
SpaceModel? selectedSpace;
|
||||
|
||||
@ -261,6 +340,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
emitSafe(GetSpacesLoading());
|
||||
try {
|
||||
spaces = await SpacesAPI.getSpacesByUserId();
|
||||
emitSafe(GetSpacesSuccess(spaces!));
|
||||
} catch (failure) {
|
||||
emitSafe(GetSpacesError("No units found"));
|
||||
return;
|
||||
@ -298,11 +378,13 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||
var res = await SpacesAPI.activationCodeSpace(
|
||||
activationCode: activationCode, userUuid: uuid);
|
||||
|
||||
if (res['success'] == true) {
|
||||
fetchUserInfo();
|
||||
fetchUnitsByUserId();
|
||||
}
|
||||
emitSafe(GetSpacesSuccess(spaces!));
|
||||
|
||||
return res['success'];
|
||||
} on DioException catch (e) {
|
||||
final errorMessage = e.response?.data['error']['message'];
|
||||
@ -378,6 +460,8 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
// ),
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
// HomeCubit.permissionModel!.scene!.visible == true
|
||||
// ?
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
@ -413,7 +497,8 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
.read<CreateSceneBloc>()
|
||||
.add(const ClearTabToRunSetting());
|
||||
},
|
||||
),
|
||||
)
|
||||
// : const SizedBox(),
|
||||
// IconButton(
|
||||
// icon: const Icon(
|
||||
// Icons.more_vert,
|
||||
@ -503,3 +588,28 @@ BottomNavigationBarItem defaultBottomNavBarItem(
|
||||
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 ActivationSuccess extends HomeState {}
|
||||
|
||||
|
||||
///specific states
|
||||
//get spaces
|
||||
class GetSpacesLoading extends HomeLoading {}
|
||||
|
||||
class GetSpacesSuccess extends HomeSuccess {
|
||||
@ -64,10 +64,16 @@ class RoomSelected extends HomeState {
|
||||
class RoomUnSelected extends HomeState {}
|
||||
|
||||
class NavChangePage extends HomeState {}
|
||||
class HomePermissionUpdated extends HomeState {}
|
||||
|
||||
|
||||
// Define new state classes
|
||||
class HomeUserInfoLoaded extends HomeState {
|
||||
final UserModel 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>(
|
||||
builder: (context, state) {
|
||||
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(),
|
||||
child: const AppBody(),
|
||||
);
|
||||
|
@ -35,8 +35,10 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
)
|
||||
: null,
|
||||
),
|
||||
actions: HomeCubit.appBarActions[
|
||||
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label],
|
||||
actions: HomeCubit.manageScene
|
||||
? HomeCubit.appBarActions[
|
||||
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label]
|
||||
: null,
|
||||
));
|
||||
},
|
||||
);
|
||||
|
@ -221,6 +221,7 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
List<String> userFullName = fullName.split(' ');
|
||||
response = await AuthenticationAPI.signUp(
|
||||
model: SignUpModel(
|
||||
hasAcceptedAppAgreement: true,
|
||||
email: email.toLowerCase(),
|
||||
password: signUpPassword,
|
||||
firstName: userFullName[0],
|
||||
|
@ -3,10 +3,12 @@ class SignUpModel {
|
||||
final String password;
|
||||
final String firstName;
|
||||
final String lastName;
|
||||
final bool hasAcceptedAppAgreement;
|
||||
|
||||
SignUpModel(
|
||||
{required this.email,
|
||||
required this.password,
|
||||
required this.hasAcceptedAppAgreement,
|
||||
required this.firstName,
|
||||
required this.lastName});
|
||||
|
||||
@ -15,7 +17,8 @@ class SignUpModel {
|
||||
email: json['email'],
|
||||
password: json['password'],
|
||||
firstName: json['firstName'],
|
||||
lastName: json['lastName']);
|
||||
lastName: json['lastName'],
|
||||
hasAcceptedAppAgreement: true);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
@ -24,6 +27,7 @@ class SignUpModel {
|
||||
'password': password,
|
||||
'firstName': firstName,
|
||||
'lastName': lastName,
|
||||
"hasAcceptedAppAgreement": hasAcceptedAppAgreement
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ class UserModel {
|
||||
final String? timeZone;
|
||||
final String? regionUuid;
|
||||
final bool? isAgreementAccepted;
|
||||
final bool? hasAcceptedWebAgreement;
|
||||
final DateTime? webAgreementAcceptedAt;
|
||||
final bool? hasAcceptedAppAgreement;
|
||||
final DateTime? appAgreementAcceptedAt;
|
||||
final Role? role;
|
||||
|
||||
UserModel({
|
||||
required this.uuid,
|
||||
@ -28,7 +33,11 @@ class UserModel {
|
||||
required this.isAgreementAccepted,
|
||||
required this.regionName,
|
||||
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) {
|
||||
@ -44,6 +53,15 @@ class UserModel {
|
||||
regionName: json['region']?['regionName'],
|
||||
timeZone: json['timeZone']?['timeZoneOffset'],
|
||||
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,
|
||||
regionName: tempJson['region']?['regionName'],
|
||||
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,
|
||||
'regionName': regionName,
|
||||
'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;
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: acId, code: 'countdown_time', value: event.duration),
|
||||
deviceId: acId,
|
||||
code: 'countdown_time',
|
||||
value: event.duration),
|
||||
acId);
|
||||
|
||||
if (response['success'] ?? false) {
|
||||
|
@ -38,8 +38,10 @@ class SettingProfilePage extends StatelessWidget {
|
||||
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
|
||||
return state is DeviceSettingLoadingState
|
||||
? const Center(
|
||||
child:
|
||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||
child: DefaultContainer(
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: CircularProgressIndicator()),
|
||||
)
|
||||
: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
@ -55,15 +57,18 @@ class SettingProfilePage extends StatelessWidget {
|
||||
child: SvgPicture.asset(
|
||||
Assets.sosHomeIcon,
|
||||
fit: BoxFit.fitHeight,
|
||||
height: MediaQuery.of(context).size.height * 0.13,
|
||||
height:
|
||||
MediaQuery.of(context).size.height * 0.13,
|
||||
))
|
||||
: CircleAvatar(
|
||||
radius: 55,
|
||||
backgroundColor: ColorsManager.graysColor,
|
||||
child: ClipOval(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Center(
|
||||
child: SvgPicture.asset(
|
||||
@ -71,7 +76,10 @@ class SettingProfilePage extends StatelessWidget {
|
||||
? Assets.fourSceneIcon
|
||||
: Assets.sixSceneIcon,
|
||||
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: [
|
||||
IntrinsicWidth(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 200),
|
||||
constraints:
|
||||
const BoxConstraints(maxWidth: 200),
|
||||
child: TextFormField(
|
||||
maxLength: 30,
|
||||
style: const TextStyle(
|
||||
@ -122,7 +131,8 @@ class SettingProfilePage extends StatelessWidget {
|
||||
Assets.sosEditProfile,
|
||||
color: Colors.grey,
|
||||
fit: BoxFit.contain,
|
||||
height: MediaQuery.of(context).size.height * 0.02,
|
||||
height: MediaQuery.of(context).size.height *
|
||||
0.02,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -141,6 +151,7 @@ class SettingProfilePage extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
if (HomeCubit.visitorPasswordManagement) {
|
||||
bool? val = await Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => LocationSettingPage(
|
||||
@ -151,6 +162,7 @@ class SettingProfilePage extends StatelessWidget {
|
||||
if (val != null && val == true) {
|
||||
_bloc.add(const DeviceSettingInitialInfo());
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
@ -162,7 +174,8 @@ class SettingProfilePage extends StatelessWidget {
|
||||
children: [
|
||||
SizedBox(
|
||||
child: BodyMedium(
|
||||
text: _bloc.deviceInfo.subspace.subspaceName,
|
||||
text: _bloc
|
||||
.deviceInfo.subspace.subspaceName,
|
||||
fontColor: ColorsManager.textGray,
|
||||
),
|
||||
),
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.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/smart_linkage_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/temporary_password_page.dart';
|
||||
@ -14,6 +15,8 @@ class DoorLockGrid extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final buttons = doorLockButtons(val: uuid);
|
||||
|
||||
return GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
@ -23,14 +26,15 @@ class DoorLockGrid extends StatelessWidget {
|
||||
crossAxisSpacing: 10,
|
||||
childAspectRatio: 1.75 / 1,
|
||||
),
|
||||
itemCount: 4,
|
||||
itemCount: buttons.length,
|
||||
itemBuilder: (context, index) => DefaultContainer(
|
||||
onTap: () {
|
||||
//TODO: remove checking after adding the pages
|
||||
doorLockButtons()[index]['page'] != null
|
||||
? Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => doorLockButtons(val: uuid)[index]['page'] as Widget,
|
||||
builder: (context) =>
|
||||
doorLockButtons(val: uuid)[index]['page'] as Widget,
|
||||
),
|
||||
)
|
||||
: null;
|
||||
@ -75,6 +79,7 @@ List<Map<String, dynamic>> doorLockButtons({val}) => [
|
||||
'image': Assets.assetsIconsDoorlockAssetsMembersManagement,
|
||||
'page': const MembersManagementView(),
|
||||
},
|
||||
if (HomeCubit.manageDeviceLocation)
|
||||
{
|
||||
'title': 'Temporary Password',
|
||||
'image': Assets.assetsIconsDoorlockAssetsTemporaryPassword,
|
||||
|
@ -1,5 +1,15 @@
|
||||
import 'dart:ui';
|
||||
|
||||
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/utils/resource_manager/color_manager.dart';
|
||||
|
||||
part 'menu_state.dart';
|
||||
|
||||
@ -32,4 +42,143 @@ class MenuCubit extends Cubit<MenuState> {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
class MenuItemsLoaded extends MenuState {
|
||||
final List<Map<String, Object>> menuSections;
|
||||
MenuItemsLoaded(this.menuSections);
|
||||
}
|
||||
class MenuError extends MenuState {
|
||||
final String message;
|
||||
|
||||
|
@ -1,43 +1,35 @@
|
||||
import 'package:flutter/material.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/menu/bloc/menu_cubit.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/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_medium.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
class MenuView extends StatelessWidget {
|
||||
const MenuView({super.key});
|
||||
const MenuView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (BuildContext context) => MenuCubit(),
|
||||
create: (BuildContext context) => MenuCubit()..fetchMenuSections(),
|
||||
child: BlocBuilder<MenuCubit, MenuState>(
|
||||
builder: (context, state) {
|
||||
return BlocBuilder<AuthCubit, AuthState>(
|
||||
builder: (context, state) {
|
||||
builder: (context, menuState) {
|
||||
if (menuState is MenuLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (menuState is MenuError) {
|
||||
return Center(child: Text(menuState.message));
|
||||
} else if (menuState is MenuItemsLoaded) {
|
||||
final sections = menuState.menuSections;
|
||||
return SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
child: Column(
|
||||
children: [
|
||||
const ProfileTab(),
|
||||
for (var section in menuSections)
|
||||
MenuList(
|
||||
section: section,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
BodyMedium(text: dotenv.env['ENV_NAME'] ?? ''),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
for (var section in sections) MenuList(section: section),
|
||||
const SizedBox(height: 15),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
AuthCubit.get(context).logout();
|
||||
@ -58,12 +50,13 @@ class MenuView extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
// Fallback in case no states match
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -36,17 +36,20 @@ class SceneItem extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultContainer(
|
||||
onTap: () {
|
||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
||||
if (HomeCubit.manageScene) {
|
||||
context
|
||||
.read<SmartSceneSelectBloc>()
|
||||
.add(const SmartSceneClearEvent());
|
||||
if (disablePlayButton == false) {
|
||||
BlocProvider.of<CreateSceneBloc>(context)
|
||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
||||
BlocProvider.of<CreateSceneBloc>(context).add(
|
||||
FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
||||
|
||||
/// the state to set the scene type must be after the fetch
|
||||
BlocProvider.of<CreateSceneBloc>(context)
|
||||
.add(const SceneTypeEvent(CreateSceneEnum.tabToRun));
|
||||
} else {
|
||||
BlocProvider.of<CreateSceneBloc>(context)
|
||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: true));
|
||||
BlocProvider.of<CreateSceneBloc>(context).add(
|
||||
FetchSceneTasksEvent(sceneId: scene.id, isAutomation: true));
|
||||
|
||||
/// the state to set the scene type must be after the fetch
|
||||
BlocProvider.of<CreateSceneBloc>(context)
|
||||
@ -64,6 +67,7 @@ class SceneItem extends StatelessWidget {
|
||||
sceneName: scene.name,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -79,8 +83,11 @@ class SceneItem extends StatelessWidget {
|
||||
height: 32,
|
||||
width: 32,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (context, error, stackTrace) =>
|
||||
Image.asset(Assets.assetsIconsLogo, height: 32, width: 32, fit: BoxFit.fill),
|
||||
errorBuilder: (context, error, stackTrace) => Image.asset(
|
||||
Assets.assetsIconsLogo,
|
||||
height: 32,
|
||||
width: 32,
|
||||
fit: BoxFit.fill),
|
||||
),
|
||||
if (disablePlayButton || scene.iconInBytes.isEmpty)
|
||||
SvgPicture.asset(
|
||||
@ -93,7 +100,9 @@ class SceneItem extends StatelessWidget {
|
||||
? IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: () {
|
||||
context.read<SceneBloc>().add(SceneTrigger(scene.id, scene.name));
|
||||
context
|
||||
.read<SceneBloc>()
|
||||
.add(SceneTrigger(scene.id, scene.name));
|
||||
},
|
||||
icon: isLoading
|
||||
? const Center(
|
||||
@ -115,10 +124,14 @@ class SceneItem extends StatelessWidget {
|
||||
activeColor: ColorsManager.primaryColor,
|
||||
value: scene.status == 'enable' ? true : false,
|
||||
onChanged: (value) {
|
||||
context.read<SceneBloc>().add(UpdateAutomationStatus(
|
||||
automationStatusUpdate: AutomationStatusUpdate(
|
||||
context.read<SceneBloc>().add(
|
||||
UpdateAutomationStatus(
|
||||
automationStatusUpdate:
|
||||
AutomationStatusUpdate(
|
||||
isEnable: value,
|
||||
spaceUuid: HomeCubit.getInstance().selectedSpace!.id),
|
||||
spaceUuid: HomeCubit.getInstance()
|
||||
.selectedSpace!
|
||||
.id),
|
||||
automationId: scene.id));
|
||||
},
|
||||
),
|
||||
|
@ -16,7 +16,7 @@ class CreateUnitWidget extends StatelessWidget {
|
||||
TextEditingController textEditingController = TextEditingController();
|
||||
return BlocConsumer<HomeCubit, HomeState>(
|
||||
listener: (context, state) {
|
||||
if (state is ActivationError) {}
|
||||
// if (state is ActivationError) {}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return SingleChildScrollView(
|
||||
@ -96,7 +96,11 @@ class CreateUnitWidget extends StatelessWidget {
|
||||
textEditingController.text)) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
'Done successfully');
|
||||
Future.delayed(
|
||||
const Duration(milliseconds: 500),
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
} else {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
'Wrong code!');
|
||||
@ -109,14 +113,14 @@ class CreateUnitWidget extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
state is ActivationError
|
||||
? Text(
|
||||
state.errMessage,
|
||||
style: const TextStyle(
|
||||
color: ColorsManager.red,
|
||||
fontWeight: FontWeight.w400),
|
||||
)
|
||||
: const SizedBox()
|
||||
// state is ActivationError
|
||||
// ? Text(
|
||||
// state.errMessage,
|
||||
// style: const TextStyle(
|
||||
// color: ColorsManager.red,
|
||||
// fontWeight: FontWeight.w400),
|
||||
// )
|
||||
// : const SizedBox()
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -225,4 +225,7 @@ abstract class ApiEndpoints {
|
||||
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
||||
static const String terms = '/terms';
|
||||
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 {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
|
||||
path: ApiEndpoints.deviceFunctionsStatus
|
||||
.replaceAll('{deviceUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -97,7 +98,8 @@ class DevicesAPI {
|
||||
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(
|
||||
path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
@ -109,7 +111,9 @@ class DevicesAPI {
|
||||
}
|
||||
|
||||
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(
|
||||
path: ApiEndpoints.renamePassword
|
||||
.replaceAll('{doorLockUuid}', doorLockUuid)
|
||||
@ -144,7 +148,8 @@ class DevicesAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future getSceneBySwitchName({String? deviceId, String? switchName}) async {
|
||||
static Future getSceneBySwitchName(
|
||||
{String? deviceId, String? switchName}) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.fourSceneByName
|
||||
.replaceAll('{deviceUuid}', deviceId!)
|
||||
@ -165,7 +170,11 @@ class DevicesAPI {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId!),
|
||||
body: jsonEncode(
|
||||
{"switchName": switchName, "sceneUuid": sceneUuid, "spaceUuid": spaceUuid},
|
||||
{
|
||||
"switchName": switchName,
|
||||
"sceneUuid": sceneUuid,
|
||||
"spaceUuid": spaceUuid
|
||||
},
|
||||
),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
@ -185,7 +194,8 @@ class DevicesAPI {
|
||||
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(
|
||||
path: ApiEndpoints.devicesByGroupName
|
||||
.replaceAll('{unitUuid}', unitId)
|
||||
@ -230,7 +240,9 @@ class DevicesAPI {
|
||||
if (json == null || json.isEmpty || json == []) {
|
||||
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(
|
||||
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
||||
showServerMessage: false,
|
||||
@ -264,7 +277,8 @@ class DevicesAPI {
|
||||
String deviceId,
|
||||
) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.getTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -275,7 +289,8 @@ class DevicesAPI {
|
||||
|
||||
static Future getOneTimePasswords(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.getOneTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -286,7 +301,8 @@ class DevicesAPI {
|
||||
|
||||
static Future getTimeLimitPasswords(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.getMultipleTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -311,10 +327,12 @@ class DevicesAPI {
|
||||
"invalidTime": invalidTime,
|
||||
};
|
||||
if (scheduleList != null) {
|
||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||
body["scheduleList"] =
|
||||
scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||
}
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.addTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
body: body,
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => json,
|
||||
@ -325,7 +343,8 @@ class DevicesAPI {
|
||||
static Future generateOneTimePassword({deviceId}) async {
|
||||
try {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.addOneTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -337,10 +356,12 @@ class DevicesAPI {
|
||||
}
|
||||
}
|
||||
|
||||
static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async {
|
||||
static Future generateMultiTimePassword(
|
||||
{deviceId, effectiveTime, invalidTime}) async {
|
||||
try {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: true,
|
||||
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
||||
expectedResponseModel: (json) {
|
||||
@ -530,7 +551,9 @@ class DevicesAPI {
|
||||
String code,
|
||||
) async {
|
||||
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,
|
||||
expectedResponseModel: (json) {
|
||||
return DeviceReport.fromJson(json);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
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/menu/model/region_model.dart';
|
||||
@ -95,6 +94,16 @@ class ProfileApi {
|
||||
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 {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getRegion,
|
||||
|
@ -1,5 +1,6 @@
|
||||
//ignore_for_file: constant_identifier_names
|
||||
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/menu/bloc/privacy_policy.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;
|
||||
}
|
||||
|
||||
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 {
|
||||
FamilyMember,
|
||||
OtherMember,
|
||||
|
Reference in New Issue
Block a user