Compare commits

...
13 Commits
Author SHA1 Message Date
hannathkadher 9cb62795a6 Merge branch 'dev' of https://github.com/SyncrowIOT/web into SP-1246 2025-04-03 10:17:06 +04:00
hannathkadher a034202d76 updated endpoints 2025-04-03 10:14:24 +04:00
mohammadnemer1 869799f08e Merge pull request #126 from SyncrowIOT/fix_routine_popup
Refactor routine creation UI for improved code organization
2025-03-27 15:06:38 +03:00
mohammad 573e7b42ed Refactor routine creation UI for improved code organization 2025-03-27 15:04:33 +03:00
Faris Armoush 5bf5120883 Merge pull request #124 from SyncrowIOT/SP-1271-Fix-Deployment
SP-1271-Fix-Deployment
2025-03-27 13:45:59 +03:00
fkarmoush f307aaff9d Removed the usage of spacing property because the GitHub action doesnt support the version that has it, so instead opted for using Padding. 2025-03-27 11:08:57 +03:00
Faris Armoush aea18fb293 Merge pull request #123 from SyncrowIOT/SP-1271-FE-Remove-Community-Field-from-Device-Management-Screen
Sp 1271 fe remove community field from device management screen
2025-03-26 12:57:16 +03:00
fkarmoush 835dfe8785 Rename controller variables in DeviceSearchFilters to be private to control access control. 2025-03-26 12:40:25 +03:00
fkarmoush f670ae78aa Refactor device search filters layout for improved code organization and to remove any code duplication. 2025-03-26 12:39:51 +03:00
fkarmoush d3128a9c9c Refactor search button callback for improved readability 2025-03-26 12:37:03 +03:00
fkarmoush b65f172f9d Removed memory leak bug from DeviceSearchFilters widget. 2025-03-26 12:36:26 +03:00
fkarmoush dad18b77de Removed community filter field from DeviceSearchFilters. 2025-03-26 12:35:04 +03:00
Abdullah Alassaf 77a9aa2f19 Added include spaces to the communites api 2025-03-26 04:29:33 +03:00
12 changed files with 430 additions and 326 deletions
@@ -2,14 +2,17 @@ import 'package:flutter/foundation.dart';
class FactoryResetModel { class FactoryResetModel {
final List<String> devicesUuid; final List<String> devicesUuid;
final String operationType;
FactoryResetModel({ FactoryResetModel({
required this.devicesUuid, required this.devicesUuid,
this.operationType = "RESET",
}); });
factory FactoryResetModel.fromJson(Map<String, dynamic> json) { factory FactoryResetModel.fromJson(Map<String, dynamic> json) {
return FactoryResetModel( return FactoryResetModel(
devicesUuid: List<String>.from(json['devicesUuid']), devicesUuid: List<String>.from(json['devicesUuid']),
operationType: "RESET",
); );
} }
@@ -12,77 +12,95 @@ class DeviceSearchFilters extends StatefulWidget {
State<DeviceSearchFilters> createState() => _DeviceSearchFiltersState(); State<DeviceSearchFilters> createState() => _DeviceSearchFiltersState();
} }
class _DeviceSearchFiltersState extends State<DeviceSearchFilters> with HelperResponsiveLayout { class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
final TextEditingController communityController = TextEditingController(); with HelperResponsiveLayout {
final TextEditingController unitNameController = TextEditingController(); late final TextEditingController _unitNameController;
final TextEditingController productNameController = TextEditingController(); late final TextEditingController _productNameController;
@override
void initState() {
_unitNameController = TextEditingController();
_productNameController = TextEditingController();
super.initState();
}
@override
void dispose() {
_unitNameController.dispose();
_productNameController.dispose();
super.dispose();
}
List<Widget> get _widgets => [
_buildSearchField(
"Space Name",
_unitNameController,
200,
),
_buildSearchField(
"Device Name / Product Name",
_productNameController,
300,
),
_buildSearchResetButtons(),
];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return isExtraLargeScreenSize(context) if (isExtraLargeScreenSize(context)) {
? Row( return Row(
children: [ children: _widgets.map(
_buildSearchField("Community", communityController, 200), (e) {
const SizedBox(width: 20), return Padding(
_buildSearchField("Space Name", unitNameController, 200), padding: const EdgeInsets.symmetric(vertical: 10),
const SizedBox(width: 20), child: e,
_buildSearchField("Device Name / Product Name", productNameController, 300), );
const SizedBox(width: 20), },
_buildSearchResetButtons(), ).toList(),
], );
) }
: Wrap(
spacing: 20, return Wrap(
runSpacing: 10, spacing: 20,
children: [ runSpacing: 10,
_buildSearchField( children: _widgets,
"Community", );
communityController,
200,
),
_buildSearchField("Space Name", unitNameController, 200),
_buildSearchField(
"Device Name / Product Name",
productNameController,
300,
),
_buildSearchResetButtons(),
],
);
} }
Widget _buildSearchField(String title, TextEditingController controller, double width) { Widget _buildSearchField(
return Container( String title,
child: StatefulTextField( TextEditingController controller,
title: title, double width,
width: width, ) {
elevation: 2, return StatefulTextField(
controller: controller, title: title,
onSubmitted: () { width: width,
context.read<DeviceManagementBloc>().add(SearchDevices( elevation: 2,
productName: productNameController.text, controller: controller,
unitName: unitNameController.text, onSubmitted: () {
community: communityController.text, final searchDevicesEvent = SearchDevices(
searchField: true)); productName: _productNameController.text,
}, unitName: _unitNameController.text,
onChanged: (p0) {}, searchField: true,
), );
context.read<DeviceManagementBloc>().add(searchDevicesEvent);
},
onChanged: (p0) {},
); );
} }
Widget _buildSearchResetButtons() { Widget _buildSearchResetButtons() {
return SearchResetButtons( return SearchResetButtons(
onSearch: () { onSearch: () => context.read<DeviceManagementBloc>().add(
context.read<DeviceManagementBloc>().add(SearchDevices( SearchDevices(
community: communityController.text, unitName: _unitNameController.text,
unitName: unitNameController.text, productName: _productNameController.text,
productName: productNameController.text, searchField: true,
searchField: true)); ),
}, ),
onReset: () { onReset: () {
communityController.clear(); _unitNameController.clear();
unitNameController.clear(); _productNameController.clear();
productNameController.clear();
context.read<DeviceManagementBloc>() context.read<DeviceManagementBloc>()
..add(ResetFilters()) ..add(ResetFilters())
..add(FetchDevices(context)); ..add(FetchDevices(context));
@@ -1,16 +1,16 @@
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/style.dart';
class CommunityDropdown extends StatelessWidget { class CommunityDropdown extends StatelessWidget {
final String? selectedValue; final String? selectedValue;
final Function(String?) onChanged; final Function(String?) onChanged;
final TextEditingController _searchController = TextEditingController();
const CommunityDropdown({ CommunityDropdown({
Key? key, Key? key,
required this.selectedValue, required this.selectedValue,
required this.onChanged, required this.onChanged,
@@ -34,59 +34,125 @@ class CommunityDropdown extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
BlocBuilder<SpaceTreeBloc, SpaceTreeState>( BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
builder: (context, state) { builder: (context, state) {
List<CommunityModel> communities = state.isSearching
? state.filteredCommunity
: state.communityList;
return SizedBox( return SizedBox(
child: DropdownButtonFormField<String>( child: Container(
dropdownColor: ColorsManager.whiteColors, decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: DropdownButton2<String>(
underline: SizedBox(),
value: selectedValue, value: selectedValue,
items: communities.map((community) { items: state.communityList.map((community) {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
value: community.uuid, value: community.uuid,
child: Text(' ${community.name}'), child: Text(
' ${community.name}',
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
); );
}).toList(), }).toList(),
onChanged: onChanged, onChanged: onChanged,
icon: const SizedBox.shrink(), style: TextStyle(color: Colors.black),
borderRadius: const BorderRadius.all(Radius.circular(10)),
hint: Padding( hint: Padding(
padding: EdgeInsets.only(left: 10), padding: EdgeInsets.only(left: 10),
child: Text( child: Text(
"Please Select", " Please Select",
style: Theme.of(context).textTheme.bodySmall!.copyWith( style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.textGray, color: ColorsManager.textGray,
), ),
), ),
), ),
decoration: inputTextFormDeco().copyWith( customButton: Container(
contentPadding: EdgeInsets.zero, height: 45,
suffixIcon: Container( decoration: BoxDecoration(
padding: EdgeInsets.zero, border:
width: 70, Border.all(color: ColorsManager.textGray, width: 1.0),
height: 45, borderRadius: BorderRadius.circular(10),
decoration: BoxDecoration( ),
color: Colors.grey[100], child: Row(
borderRadius: const BorderRadius.only( mainAxisAlignment: MainAxisAlignment.spaceBetween,
bottomRight: Radius.circular(10), children: [
topRight: Radius.circular(10), Expanded(
flex: 5,
child: Text(
selectedValue != null
? " ${state.communityList.firstWhere((element) => element.uuid == selectedValue).name}"
: ' Please Select',
style:
Theme.of(context).textTheme.bodySmall!.copyWith(
color: selectedValue != null
? Colors.black
: ColorsManager.textGray,
),
overflow: TextOverflow.ellipsis,
),
), ),
border: Border.all( Expanded(
color: ColorsManager.textGray, child: Container(
width: 1.0, decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
height: 45,
child: const Icon(
Icons.keyboard_arrow_down,
color: ColorsManager.textGray,
),
),
), ),
), ],
child: const Center( ),
child: Icon( ),
Icons.keyboard_arrow_down, dropdownStyleData: DropdownStyleData(
color: ColorsManager.textGray, maxHeight: MediaQuery.of(context).size.height * 0.4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
),
dropdownSearchData: DropdownSearchData(
searchController: _searchController,
searchInnerWidgetHeight: 50,
searchInnerWidget: Container(
height: 50,
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
child: TextFormField(
style: const TextStyle(color: Colors.black),
controller: _searchController,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 12,
),
hintText: 'Search for community...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
), ),
), ),
), ),
searchMatchFn: (item, searchValue) {
final communityName =
(item.child as Text).data?.toLowerCase() ?? '';
return communityName
.contains(searchValue.toLowerCase().trim());
},
),
onMenuStateChange: (isOpen) {
if (!isOpen) {
_searchController.clear();
}
},
menuItemStyleData: const MenuItemStyleData(
height: 40,
), ),
), ),
); ));
}, },
), ),
], ],
@@ -62,28 +62,34 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const Divider(), const Divider(),
CommunityDropdown( Padding(
selectedValue: _selectedCommunity, padding: const EdgeInsets.only(left: 15, right: 15),
onChanged: (String? newValue) { child: CommunityDropdown(
setState(() { selectedValue: _selectedCommunity,
_selectedCommunity = newValue; onChanged: (String? newValue) {
_selectedSpace = null; setState(() {
}); _selectedCommunity = newValue;
if (newValue != null) { _selectedSpace = null;
_fetchSpaces(newValue); });
} if (newValue != null) {
}, _fetchSpaces(newValue);
}
},
),
), ),
const SizedBox(height: 16), const SizedBox(height: 5),
SpaceDropdown( Padding(
hintMessage: spaceHint, padding: const EdgeInsets.only(left: 15, right: 15),
spaces: spaces, child: SpaceDropdown(
selectedValue: _selectedSpace, hintMessage: spaceHint,
onChanged: (String? newValue) { spaces: spaces,
setState(() { selectedValue: _selectedSpace,
_selectedSpace = newValue; onChanged: (String? newValue) {
}); setState(() {
}, _selectedSpace = newValue;
});
},
),
), ),
const Divider(), const Divider(),
Row( Row(
@@ -96,7 +102,6 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
), ),
child: TextButton( child: TextButton(
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text( child: Text(
@@ -139,6 +144,7 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
), ),
], ],
), ),
SizedBox(height: 10),
], ],
), ),
); );
@@ -1,7 +1,8 @@
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/style.dart';
class SpaceDropdown extends StatelessWidget { class SpaceDropdown extends StatelessWidget {
final List<SpaceModel> spaces; final List<SpaceModel> spaces;
@@ -33,62 +34,108 @@ class SpaceDropdown extends StatelessWidget {
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
DropdownButtonFormField<String>( SizedBox(
value: selectedValue, child: Container(
items: spaces.map((space) { decoration: BoxDecoration(
return DropdownMenuItem<String>( borderRadius: BorderRadius.circular(10),
value: space.uuid,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
' ${space.name}',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 12,
color: ColorsManager.blackColor,
),
),
Text(
' ${space.lastThreeParents}',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 12,
),
),
],
));
}).toList(),
onChanged: onChanged,
icon: const SizedBox.shrink(),
borderRadius: const BorderRadius.all(Radius.circular(10)),
hint: Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
hintMessage,
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.textGray,
),
), ),
), child: DropdownButton2<String>(
decoration: inputTextFormDeco().copyWith( underline: const SizedBox(),
contentPadding: EdgeInsets.zero, value: selectedValue,
suffixIcon: Container( items: spaces.map((space) {
width: 70, return DropdownMenuItem<String>(
height: 45, value: space.uuid,
decoration: BoxDecoration( child: Column(
color: Colors.grey[200], crossAxisAlignment: CrossAxisAlignment.start,
borderRadius: const BorderRadius.only( mainAxisAlignment: MainAxisAlignment.start,
bottomRight: Radius.circular(10), children: [
topRight: Radius.circular(10), Text(
), ' ${space.name}',
border: Border.all( style:
color: ColorsManager.textGray, Theme.of(context).textTheme.bodyMedium!.copyWith(
width: 1.0, fontSize: 12,
color: ColorsManager.blackColor,
),
),
Text(
' ${space.lastThreeParents}',
style:
Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 12,
),
),
],
),
);
}).toList(),
onChanged: onChanged,
style: TextStyle(color: Colors.black),
hint: Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
hintMessage,
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.textGray,
),
), ),
), ),
child: const Icon( customButton: Container(
Icons.keyboard_arrow_down, height: 45,
color: ColorsManager.textGray, decoration: BoxDecoration(
border:
Border.all(color: ColorsManager.textGray, width: 1.0),
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 5,
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
selectedValue != null
? spaces
.firstWhere((e) => e.uuid == selectedValue)
.name
: hintMessage,
style:
Theme.of(context).textTheme.bodySmall!.copyWith(
color: selectedValue != null
? Colors.black
: ColorsManager.textGray,
),
overflow: TextOverflow.ellipsis,
),
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
height: 45,
child: const Icon(
Icons.keyboard_arrow_down,
color: ColorsManager.textGray,
),
),
),
],
),
),
dropdownStyleData: DropdownStyleData(
maxHeight: MediaQuery.of(context).size.height * 0.4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
),
menuItemStyleData: const MenuItemStyleData(
height: 60,
), ),
), ),
), ),
@@ -33,8 +33,6 @@ class _RoutinesViewState extends State<RoutinesView> {
communityID: communityId, spaceID: spaceId)); communityID: communityId, spaceID: spaceId));
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
routineBloc.add(const CreateNewRoutineViewEvent(createRoutineView: true)); routineBloc.add(const CreateNewRoutineViewEvent(createRoutineView: true));
await Future.delayed(const Duration(milliseconds:500));
_bloc.add(const ResetSelectedEvent());
} }
@override @override
+47 -70
View File
@@ -28,11 +28,10 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
try { try {
final updatedCommunity = event.updatedCommunity; final updatedCommunity = event.updatedCommunity;
final updatedCommunities = final updatedCommunities = List<CommunityModel>.from(state.communityList);
List<CommunityModel>.from(state.communityList);
final index = updatedCommunities final index =
.indexWhere((community) => community.uuid == updatedCommunity.uuid); updatedCommunities.indexWhere((community) => community.uuid == updatedCommunity.uuid);
if (index != -1) { if (index != -1) {
updatedCommunities[index] = updatedCommunity; updatedCommunities[index] = updatedCommunity;
@@ -51,47 +50,41 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
final projectUuid = await ProjectManager.getProjectUUID() ?? ''; final projectUuid = await ProjectManager.getProjectUUID() ?? '';
List<CommunityModel> communities = List<CommunityModel> communities =
await CommunitySpaceManagementApi().fetchCommunities(projectUuid); await CommunitySpaceManagementApi().fetchCommunities(projectUuid, includeSpaces: true);
List<CommunityModel> updatedCommunities = await Future.wait( // List<CommunityModel> updatedCommunities = await Future.wait(
communities.map((community) async { // communities.map((community) async {
List<SpaceModel> spaces = await CommunitySpaceManagementApi() // List<SpaceModel> spaces =
.getSpaceHierarchy(community.uuid, projectUuid); // await CommunitySpaceManagementApi().getSpaceHierarchy(community.uuid, projectUuid);
return CommunityModel( // return CommunityModel(
uuid: community.uuid, // uuid: community.uuid,
createdAt: community.createdAt, // createdAt: community.createdAt,
updatedAt: community.updatedAt, // updatedAt: community.updatedAt,
name: community.name, // name: community.name,
description: community.description, // description: community.description,
spaces: spaces, // spaces: spaces,
region: community.region, // region: community.region,
); // );
}).toList(), // }).toList(),
); // );
emit(state.copyWith( emit(state.copyWith(communitiesList: communities, expandedCommunity: [], expandedSpaces: []));
communitiesList: updatedCommunities,
expandedCommunity: [],
expandedSpaces: []));
} catch (e) { } catch (e) {
emit(SpaceTreeErrorState('Error loading communities and spaces: $e')); emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
} }
} }
void _onCommunityAdded( void _onCommunityAdded(OnCommunityAdded event, Emitter<SpaceTreeState> emit) async {
OnCommunityAdded event, Emitter<SpaceTreeState> emit) async {
final updatedCommunities = List<CommunityModel>.from(state.communityList); final updatedCommunities = List<CommunityModel>.from(state.communityList);
updatedCommunities.add(event.newCommunity); updatedCommunities.add(event.newCommunity);
emit(state.copyWith(communitiesList: updatedCommunities)); emit(state.copyWith(communitiesList: updatedCommunities));
} }
_onCommunityExpanded( _onCommunityExpanded(OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async {
OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async {
try { try {
List<String> updatedExpandedCommunityList = List<String> updatedExpandedCommunityList = List.from(state.expandedCommunities);
List.from(state.expandedCommunities);
if (updatedExpandedCommunityList.contains(event.communityId)) { if (updatedExpandedCommunityList.contains(event.communityId)) {
updatedExpandedCommunityList.remove(event.communityId); updatedExpandedCommunityList.remove(event.communityId);
@@ -123,19 +116,14 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
} }
} }
_onCommunitySelected( _onCommunitySelected(OnCommunitySelected event, Emitter<SpaceTreeState> emit) async {
OnCommunitySelected event, Emitter<SpaceTreeState> emit) async {
try { try {
List<String> updatedSelectedCommunities = List<String> updatedSelectedCommunities =
List.from(state.selectedCommunities.toSet().toList()); List.from(state.selectedCommunities.toSet().toList());
List<String> updatedSelectedSpaces = List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
List.from(state.selectedSpaces.toSet().toList()); List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
List<String> updatedSoldChecks = Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces);
List.from(state.soldCheck.toSet().toList()); List<String> selectedSpacesInCommunity = communityAndSpaces[event.communityId] ?? [];
Map<String, List<String>> communityAndSpaces =
Map.from(state.selectedCommunityAndSpaces);
List<String> selectedSpacesInCommunity =
communityAndSpaces[event.communityId] ?? [];
List<String> childrenIds = _getAllChildIds(event.children); List<String> childrenIds = _getAllChildIds(event.children);
@@ -168,15 +156,11 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
try { try {
List<String> updatedSelectedCommunities = List<String> updatedSelectedCommunities =
List.from(state.selectedCommunities.toSet().toList()); List.from(state.selectedCommunities.toSet().toList());
List<String> updatedSelectedSpaces = List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
List.from(state.selectedSpaces.toSet().toList()); List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
List<String> updatedSoldChecks = Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces);
List.from(state.soldCheck.toSet().toList());
Map<String, List<String>> communityAndSpaces =
Map.from(state.selectedCommunityAndSpaces);
List<String> selectedSpacesInCommunity = List<String> selectedSpacesInCommunity = communityAndSpaces[event.communityModel.uuid] ?? [];
communityAndSpaces[event.communityModel.uuid] ?? [];
List<String> childrenIds = _getAllChildIds(event.children); List<String> childrenIds = _getAllChildIds(event.children);
bool isChildSelected = false; bool isChildSelected = false;
@@ -199,11 +183,9 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
selectedSpacesInCommunity.addAll(childrenIds); selectedSpacesInCommunity.addAll(childrenIds);
} }
List<String> spaces = List<String> spaces = _getThePathToChild(event.communityModel.uuid, event.spaceId);
_getThePathToChild(event.communityModel.uuid, event.spaceId);
for (String space in spaces) { for (String space in spaces) {
if (!updatedSelectedSpaces.contains(space) && if (!updatedSelectedSpaces.contains(space) && !updatedSoldChecks.contains(space)) {
!updatedSoldChecks.contains(space)) {
updatedSoldChecks.add(space); updatedSoldChecks.add(space);
} }
} }
@@ -226,9 +208,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
updatedSoldChecks.remove(event.spaceId); updatedSoldChecks.remove(event.spaceId);
List<String> parents = List<String> parents =
_getThePathToChild(event.communityModel.uuid, event.spaceId) _getThePathToChild(event.communityModel.uuid, event.spaceId).toSet().toList();
.toSet()
.toList();
if (updatedSelectedSpaces.isEmpty) { if (updatedSelectedSpaces.isEmpty) {
updatedSoldChecks.removeWhere(parents.contains); updatedSoldChecks.removeWhere(parents.contains);
@@ -236,8 +216,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
} else { } else {
// Check if any parent has selected children // Check if any parent has selected children
for (String space in parents) { for (String space in parents) {
if (!_noChildrenSelected( if (!_noChildrenSelected(event.communityModel, space, updatedSelectedSpaces, parents)) {
event.communityModel, space, updatedSelectedSpaces, parents)) {
updatedSoldChecks.remove(space); updatedSoldChecks.remove(space);
} }
} }
@@ -262,8 +241,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
} }
} }
_noChildrenSelected(CommunityModel community, String spaceId, _noChildrenSelected(
List<String> selectedSpaces, List<String> parents) { CommunityModel community, String spaceId, List<String> selectedSpaces, List<String> parents) {
if (selectedSpaces.contains(spaceId)) { if (selectedSpaces.contains(spaceId)) {
return true; return true;
} }
@@ -290,11 +269,10 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
// Filter communities and expand only those that match the query // Filter communities and expand only those that match the query
filteredCommunity = communities.where((community) { filteredCommunity = communities.where((community) {
final containsQueryInCommunity = community.name final containsQueryInCommunity =
.toLowerCase() community.name.toLowerCase().contains(event.searchQuery.toLowerCase());
.contains(event.searchQuery.toLowerCase()); final containsQueryInSpaces =
final containsQueryInSpaces = community.spaces.any( community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase()));
(space) => _containsQuery(space, event.searchQuery.toLowerCase()));
return containsQueryInCommunity || containsQueryInSpaces; return containsQueryInCommunity || containsQueryInSpaces;
}).toList(); }).toList();
@@ -347,8 +325,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
// Helper function to determine if any space or its children match the search query // Helper function to determine if any space or its children match the search query
bool _containsQuery(SpaceModel space, String query) { bool _containsQuery(SpaceModel space, String query) {
final matchesSpace = space.name.toLowerCase().contains(query); final matchesSpace = space.name.toLowerCase().contains(query);
final matchesChildren = space.children.any((child) => final matchesChildren =
_containsQuery(child, query)); // Recursive check for children space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
return matchesSpace || matchesChildren; return matchesSpace || matchesChildren;
} }
@@ -371,8 +349,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
return children; return children;
} }
bool _anySpacesSelectedInCommunity(CommunityModel community, bool _anySpacesSelectedInCommunity(
List<String> selectedSpaces, List<String> partialCheckedList) { CommunityModel community, List<String> selectedSpaces, List<String> partialCheckedList) {
bool result = false; bool result = false;
List<String> ids = _getAllChildIds(community.spaces); List<String> ids = _getAllChildIds(community.spaces);
for (var id in ids) { for (var id in ids) {
@@ -401,8 +379,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
return ids; return ids;
} }
List<String> _getAllParentsIds( List<String> _getAllParentsIds(SpaceModel child, String spaceId, List<String> listIds) {
SpaceModel child, String spaceId, List<String> listIds) {
List<String> ids = listIds; List<String> ids = listIds;
ids.add(child.uuid ?? ''); ids.add(child.uuid ?? '');
@@ -194,9 +194,10 @@ class VisitorPasswordBloc
emit(DeviceLoaded()); emit(DeviceLoaded());
final projectUuid = await ProjectManager.getProjectUUID() ?? ''; final projectUuid = await ProjectManager.getProjectUUID() ?? '';
data = await AccessMangApi().fetchDevices(projectUuid); data = await AccessMangApi().fetchDoorLockDeviceList(projectUuid);
emit(TableLoaded(data)); emit(TableLoaded(data));
} catch (e) { } catch (e) {
print("error: $e");
emit(FailedState(e.toString())); emit(FailedState(e.toString()));
} }
} }
+31 -13
View File
@@ -6,13 +6,23 @@ import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/constants/api_const.dart';
class AccessMangApi { class AccessMangApi {
AccessMangApi() {
_validateEndpoints();
}
void _validateEndpoints() {
if (!ApiEndpoints.getDevices.contains('{projectId}')) {
throw Exception("Endpoint 'getDevices' must contain '{projectId}' placeholder.");
}
}
Future<List<PasswordModel>> fetchVisitorPassword(String projectId) async { Future<List<PasswordModel>> fetchVisitorPassword(String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.visitorPassword.replaceAll('{projectId}', projectId), path: ApiEndpoints.visitorPassword,
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<dynamic> jsonData = json; List<dynamic> jsonData = json['data'] ?? [];
List<PasswordModel> passwordList = jsonData.map((jsonItem) { List<PasswordModel> passwordList = jsonData.map((jsonItem) {
return PasswordModel.fromJson(jsonItem); return PasswordModel.fromJson(jsonItem);
}).toList(); }).toList();
@@ -25,17 +35,22 @@ class AccessMangApi {
} }
} }
Future fetchDevices(String projectId) async { Future fetchDoorLockDeviceList(String projectId) async {
try { try {
// The endpoint structure is already validated during initialization.
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getDevices.replaceAll('{projectId}', projectId), path: ApiEndpoints.getDevices.replaceAll('{projectId}', projectId),
queryParameters: {
'deviceType': 'DOOR_LOCK',
},
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<dynamic> jsonData = json; List<dynamic> jsonData = json['data'] ?? [];
List<DeviceModel> passwordList = jsonData.map((jsonItem) { List<DeviceModel> deviceList = jsonData.map((jsonItem) {
return DeviceModel.fromJson(jsonItem); return DeviceModel.fromJson(jsonItem);
}).toList(); }).toList();
return passwordList; return deviceList;
}, },
); );
return response; return response;
@@ -52,14 +67,15 @@ class AccessMangApi {
String? invalidTime, String? invalidTime,
List<String>? devicesUuid}) async { List<String>? devicesUuid}) async {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.sendOnlineOneTime, path: ApiEndpoints.visitorPassword,
body: jsonEncode({ body: jsonEncode({
"email": email, "email": email,
"passwordName": passwordName, "passwordName": passwordName,
"password": password, "password": password,
"devicesUuid": devicesUuid, "devicesUuid": devicesUuid,
"effectiveTime": effectiveTime, "effectiveTime": effectiveTime,
"invalidTime": invalidTime "invalidTime": invalidTime,
"operationType": "ONLINE_ONE_TIME",
}), }),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
@@ -84,13 +100,13 @@ class AccessMangApi {
"password": password, "password": password,
"effectiveTime": effectiveTime, "effectiveTime": effectiveTime,
"invalidTime": invalidTime, "invalidTime": invalidTime,
"operationType": "ONLINE_MULTIPLE_TIME",
}; };
if (scheduleList != null) { if (scheduleList != null) {
body["scheduleList"] = body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
scheduleList.map((schedule) => schedule.toJson()).toList();
} }
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.sendOnlineMultipleTime, path: ApiEndpoints.visitorPassword,
body: jsonEncode(body), body: jsonEncode(body),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
@@ -105,8 +121,9 @@ class AccessMangApi {
Future postOffLineOneTime( Future postOffLineOneTime(
{String? email, String? passwordName, List<String>? devicesUuid}) async { {String? email, String? passwordName, List<String>? devicesUuid}) async {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.sendOffLineOneTime, path: ApiEndpoints.visitorPassword,
body: jsonEncode({ body: jsonEncode({
"operationType": "OFFLINE_ONE_TIME",
"email": email, "email": email,
"passwordName": passwordName, "passwordName": passwordName,
"devicesUuid": devicesUuid "devicesUuid": devicesUuid
@@ -126,13 +143,14 @@ class AccessMangApi {
String? invalidTime, String? invalidTime,
List<String>? devicesUuid}) async { List<String>? devicesUuid}) async {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.sendOffLineMultipleTime, path: ApiEndpoints.visitorPassword,
body: jsonEncode({ body: jsonEncode({
"email": email, "email": email,
"devicesUuid": devicesUuid, "devicesUuid": devicesUuid,
"passwordName": passwordName, "passwordName": passwordName,
"effectiveTime": effectiveTime, "effectiveTime": effectiveTime,
"invalidTime": invalidTime, "invalidTime": invalidTime,
"operationType": "OFFLINE_MULTIPLE_TIME",
}), }),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
+11 -11
View File
@@ -23,9 +23,8 @@ class DevicesManagementApi {
: ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId), : ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<dynamic> jsonData = communityId.isNotEmpty && spaceId.isNotEmpty List<dynamic> jsonData =
? json['data'] communityId.isNotEmpty && spaceId.isNotEmpty ? json['data'] : json['data'];
: json;
List<AllDevicesModel> devicesList = jsonData.map((jsonItem) { List<AllDevicesModel> devicesList = jsonData.map((jsonItem) {
return AllDevicesModel.fromJson(jsonItem); return AllDevicesModel.fromJson(jsonItem);
}).toList(); }).toList();
@@ -34,7 +33,7 @@ class DevicesManagementApi {
); );
return response; return response;
} catch (e) { } catch (e) {
debugPrint('fetchDevices Error fetching $e'); debugPrint('Error fetching device $e');
return []; return [];
} }
} }
@@ -45,7 +44,7 @@ class DevicesManagementApi {
path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', uuid), path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', uuid),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return DeviceStatus.fromJson(json); return DeviceStatus.fromJson(json['data']);
}, },
); );
return response; return response;
@@ -62,7 +61,7 @@ class DevicesManagementApi {
Future getPowerClampInfo(String deviceId) async { Future getPowerClampInfo(String deviceId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId), path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', deviceId),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json; return json;
@@ -100,6 +99,7 @@ class DevicesManagementApi {
'devicesUuid': uuids, 'devicesUuid': uuids,
'code': code, 'code': code,
'value': value, 'value': value,
'operationType': 'COMMAND',
}; };
final response = await HTTPService().post( final response = await HTTPService().post(
@@ -107,7 +107,7 @@ class DevicesManagementApi {
body: body, body: body,
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return (json['successResults'] as List).isNotEmpty; return json['success'] ?? false;
}, },
); );
@@ -128,7 +128,7 @@ class DevicesManagementApi {
if (json == null || json.isEmpty || json == []) { if (json == null || json.isEmpty || json == []) {
return devices; return devices;
} }
for (var device in json['devices']) { for (var device in json['data']['devices']) {
devices.add(DeviceModel.fromJson(device)); devices.add(DeviceModel.fromJson(device));
} }
return devices; return devices;
@@ -158,7 +158,7 @@ class DevicesManagementApi {
.replaceAll('{code}', code), .replaceAll('{code}', code),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return DeviceReport.fromJson(json); return DeviceReport.fromJson(json['data']);
}, },
); );
return response; return response;
@@ -174,7 +174,7 @@ class DevicesManagementApi {
.replaceAll('{endTime}', to ?? ''), .replaceAll('{endTime}', to ?? ''),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return DeviceReport.fromJson(json); return DeviceReport.fromJson(json['data']);
}, },
); );
return response; return response;
@@ -190,7 +190,7 @@ class DevicesManagementApi {
queryParameters: queryParameters, queryParameters: queryParameters,
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return DeviceStatus.fromJson(json['status']); return DeviceStatus.fromJson(json['data']['status']);
}, },
); );
return response; return response;
+16 -28
View File
@@ -3,27 +3,24 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_m
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_model.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_response_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_response_model.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/create_space_template_body_model.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_body_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_body_model.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart';
import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/constants/api_const.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
class CommunitySpaceManagementApi { class CommunitySpaceManagementApi {
// Community Management APIs // Community Management APIs
Future<List<CommunityModel>> fetchCommunities(String projectId, Future<List<CommunityModel>> fetchCommunities(String projectId,
{int page = 1}) async { {int page = 1, bool includeSpaces = false}) async {
try { try {
List<CommunityModel> allCommunities = []; List<CommunityModel> allCommunities = [];
bool hasNext = true; bool hasNext = true;
while (hasNext) { while (hasNext) {
await HTTPService().get( await HTTPService().get(
path: ApiEndpoints.getCommunityList path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId),
.replaceAll('{projectId}', projectId), queryParameters: {'page': page, 'includeSpaces': includeSpaces},
queryParameters: {'page': page},
expectedResponseModel: (json) { expectedResponseModel: (json) {
try { try {
List<dynamic> jsonData = json['data'] ?? []; List<dynamic> jsonData = json['data'] ?? [];
@@ -52,8 +49,7 @@ class CommunitySpaceManagementApi {
Future<CommunityModel?> getCommunityById(String communityId) async { Future<CommunityModel?> getCommunityById(String communityId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getCommunityById path: ApiEndpoints.getCommunityById.replaceAll('{communityId}', communityId),
.replaceAll('{communityId}', communityId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return CommunityModel.fromJson(json['data']); return CommunityModel.fromJson(json['data']);
}, },
@@ -65,8 +61,7 @@ class CommunitySpaceManagementApi {
} }
} }
Future<CommunityModel?> createCommunity( Future<CommunityModel?> createCommunity(String name, String description, String projectId) async {
String name, String description, String projectId) async {
try { try {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.createCommunity.replaceAll('{projectId}', projectId), path: ApiEndpoints.createCommunity.replaceAll('{projectId}', projectId),
@@ -85,8 +80,7 @@ class CommunitySpaceManagementApi {
} }
} }
Future<bool> updateCommunity( Future<bool> updateCommunity(String communityId, String name, String projectId) async {
String communityId, String name, String projectId) async {
try { try {
final response = await HTTPService().put( final response = await HTTPService().put(
path: ApiEndpoints.updateCommunity path: ApiEndpoints.updateCommunity
@@ -123,8 +117,7 @@ class CommunitySpaceManagementApi {
} }
} }
Future<SpacesResponse> fetchSpaces( Future<SpacesResponse> fetchSpaces(String communityId, String projectId) async {
String communityId, String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.listSpaces path: ApiEndpoints.listSpaces
@@ -150,8 +143,7 @@ class CommunitySpaceManagementApi {
} }
} }
Future<SpaceModel?> getSpace( Future<SpaceModel?> getSpace(String communityId, String spaceId, String projectId) async {
String communityId, String spaceId, String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getSpace path: ApiEndpoints.getSpace
@@ -262,8 +254,7 @@ class CommunitySpaceManagementApi {
} }
} }
Future<bool> deleteSpace( Future<bool> deleteSpace(String communityId, String spaceId, String projectId) async {
String communityId, String spaceId, String projectId) async {
try { try {
final response = await HTTPService().delete( final response = await HTTPService().delete(
path: ApiEndpoints.deleteSpace path: ApiEndpoints.deleteSpace
@@ -281,17 +272,15 @@ class CommunitySpaceManagementApi {
} }
} }
Future<List<SpaceModel>> getSpaceHierarchy( Future<List<SpaceModel>> getSpaceHierarchy(String communityId, String projectId) async {
String communityId, String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getSpaceHierarchy path: ApiEndpoints.getSpaceHierarchy
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', projectId), .replaceAll('{projectId}', projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
final spaceModels = (json['data'] as List) final spaceModels =
.map((spaceJson) => SpaceModel.fromJson(spaceJson)) (json['data'] as List).map((spaceJson) => SpaceModel.fromJson(spaceJson)).toList();
.toList();
return spaceModels; return spaceModels;
}, },
@@ -302,17 +291,16 @@ class CommunitySpaceManagementApi {
return []; return [];
} }
} }
Future<List<SpaceModel>> getSpaceOnlyWithDevices(
{String? communityId, String? projectId}) async { Future<List<SpaceModel>> getSpaceOnlyWithDevices({String? communityId, String? projectId}) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.spaceOnlyWithDevices path: ApiEndpoints.spaceOnlyWithDevices
.replaceAll('{communityId}', communityId!) .replaceAll('{communityId}', communityId!)
.replaceAll('{projectId}', projectId!), .replaceAll('{projectId}', projectId!),
expectedResponseModel: (json) { expectedResponseModel: (json) {
final spaceModels = (json['data'] as List) final spaceModels =
.map((spaceJson) => SpaceModel.fromJson(spaceJson)) (json['data'] as List).map((spaceJson) => SpaceModel.fromJson(spaceJson)).toList();
.toList();
return spaceModels; return spaceModels;
}, },
); );
+13 -31
View File
@@ -9,21 +9,8 @@ abstract class ApiEndpoints {
static const String sendOtp = '/authentication/user/send-otp'; static const String sendOtp = '/authentication/user/send-otp';
static const String verifyOtp = '/authentication/user/verify-otp'; static const String verifyOtp = '/authentication/user/verify-otp';
static const String getRegion = '/region'; static const String getRegion = '/region';
static const String visitorPassword = static const String visitorPassword = '/visitor-passwords';
'/projects/{projectId}/visitor-password'; static const String getDevices = '/projects/{projectId}/devices';
static const String getDevices =
'/projects/{projectId}/visitor-password/devices';
static const String sendOnlineOneTime =
'/visitor-password/temporary-password/online/one-time';
static const String sendOnlineMultipleTime =
'/visitor-password/temporary-password/online/multiple-time';
//offline Password
static const String sendOffLineOneTime =
'/visitor-password/temporary-password/offline/one-time';
static const String sendOffLineMultipleTime =
'/visitor-password/temporary-password/offline/multiple-time';
static const String getUser = '/user/{userUuid}'; static const String getUser = '/user/{userUuid}';
@@ -32,15 +19,15 @@ abstract class ApiEndpoints {
static const String getAllDevices = '/projects/{projectId}/devices'; static const String getAllDevices = '/projects/{projectId}/devices';
static const String getSpaceDevices = static const String getSpaceDevices =
'/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/devices'; '/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
static const String getDeviceStatus = '/device/{uuid}/functions/status'; static const String getDeviceStatus = '/devices/{uuid}/functions/status';
static const String getBatchStatus = '/device/status/batch'; static const String getBatchStatus = '/devices/batch';
static const String deviceControl = '/device/{uuid}/control'; static const String deviceControl = '/devices/{uuid}/command';
static const String deviceBatchControl = '/device/control/batch'; static const String deviceBatchControl = '/devices/batch';
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices'; static const String gatewayApi = '/devices/gateway/{gatewayUuid}/devices';
static const String openDoorLock = '/door-lock/open/{doorLockUuid}'; static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}'; static const String getDeviceLogs = '/devices/{uuid}/report-logs?code={code}';
// Space Module // Space Module
static const String createSpace = static const String createSpace =
@@ -70,18 +57,13 @@ abstract class ApiEndpoints {
static const String createUserCommunity = static const String createUserCommunity =
'/projects/{projectId}/communities/user'; '/projects/{projectId}/communities/user';
static const String getDeviceLogsByDate = static const String getDeviceLogsByDate =
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}'; '/devices/{uuid}/report-logs?code={code}&startTime={startTime}&endTime={endTime}';
static const String scheduleByDeviceId = '/schedule/{deviceUuid}'; static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
static const String getScheduleByDeviceId = static const String getScheduleByDeviceId = '/schedule/{deviceUuid}?category={category}';
'/schedule/{deviceUuid}?category={category}'; static const String deleteScheduleByDeviceId = '/schedule/{deviceUuid}/{scheduleUuid}';
static const String deleteScheduleByDeviceId = static const String updateScheduleByDeviceId = '/schedule/enable/{deviceUuid}';
'/schedule/{deviceUuid}/{scheduleUuid}'; static const String factoryReset = '/devices/batch';
static const String updateScheduleByDeviceId =
'/schedule/enable/{deviceUuid}';
static const String factoryReset = '/device/factory/reset/{deviceUuid}';
static const String powerClamp =
'/device/{powerClampUuid}/power-clamp/status';
//product //product
static const String listProducts = '/products'; static const String listProducts = '/products';