mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-09 22:57:21 +00:00
visitor password api
This commit is contained in:
@ -14,6 +14,8 @@
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
E44A9405B1EB1B638DD05A58 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ABF0EC746A2D686A0ED574F /* Pods_RunnerTests.framework */; };
|
||||
FF49F60EC38658783D8D66DA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AFAE479A87ECDEBD5D6EB30 /* Pods_Runner.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -42,12 +44,19 @@
|
||||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
22428D486F110EE0B969469D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
253C5EA6840355311DB030EA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2AFAE479A87ECDEBD5D6EB30 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2C0D722D2ED971BF672D18D5 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
544621C7727C798253BAB2C8 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
7ABF0EC746A2D686A0ED574F /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
877FDC97D8B87080E35B3EB7 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -55,19 +64,52 @@
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D3AD250AADBF93406007C9EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
759A57780A409ED209817654 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E44A9405B1EB1B638DD05A58 /* Pods_RunnerTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FF49F60EC38658783D8D66DA /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
1454C118FFCECEEDF59152D2 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
253C5EA6840355311DB030EA /* Pods-Runner.debug.xcconfig */,
|
||||
22428D486F110EE0B969469D /* Pods-Runner.release.xcconfig */,
|
||||
D3AD250AADBF93406007C9EB /* Pods-Runner.profile.xcconfig */,
|
||||
2C0D722D2ED971BF672D18D5 /* Pods-RunnerTests.debug.xcconfig */,
|
||||
877FDC97D8B87080E35B3EB7 /* Pods-RunnerTests.release.xcconfig */,
|
||||
544621C7727C798253BAB2C8 /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
20A3C64D2B1CFED5A81C3251 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2AFAE479A87ECDEBD5D6EB30 /* Pods_Runner.framework */,
|
||||
7ABF0EC746A2D686A0ED574F /* Pods_RunnerTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
331C8082294A63A400263BE5 /* RunnerTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -94,6 +136,8 @@
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||
1454C118FFCECEEDF59152D2 /* Pods */,
|
||||
20A3C64D2B1CFED5A81C3251 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@ -128,8 +172,10 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||
buildPhases = (
|
||||
B9A66CAAF434B6A1BD8C4E09 /* [CP] Check Pods Manifest.lock */,
|
||||
331C807D294A63A400263BE5 /* Sources */,
|
||||
331C807F294A63A400263BE5 /* Resources */,
|
||||
759A57780A409ED209817654 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -145,12 +191,14 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
C1C48B0232C0B26BFF405512 /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
33590C9CD073D3D5EBA02CDE /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -222,6 +270,23 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
33590C9CD073D3D5EBA02CDE /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
@ -253,6 +318,50 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
B9A66CAAF434B6A1BD8C4E09 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C1C48B0232C0B26BFF405512 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@ -378,6 +487,7 @@
|
||||
};
|
||||
331C8088294A63A400263BE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 2C0D722D2ED971BF672D18D5 /* Pods-RunnerTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@ -395,6 +505,7 @@
|
||||
};
|
||||
331C8089294A63A400263BE5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 877FDC97D8B87080E35B3EB7 /* Pods-RunnerTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@ -410,6 +521,7 @@
|
||||
};
|
||||
331C808A294A63A400263BE5 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 544621C7727C798253BAB2C8 /* Pods-RunnerTests.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
@ -4,4 +4,7 @@
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -59,8 +59,8 @@ class MyApp extends StatelessWidget {
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
||||
useMaterial3: true, // Enable Material 3
|
||||
),
|
||||
// home: AddDeviceDialog()
|
||||
home:isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||
home: VisitorPasswordDialog()
|
||||
// home:isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
|
||||
}
|
||||
return matchesCriteria;
|
||||
}).toList();
|
||||
print('Filtered data: $filteredData'); // Print to debug filtered data
|
||||
print('Filtered data: $filteredData');
|
||||
emit(TableLoaded(filteredData));
|
||||
} catch (e) {
|
||||
print('Error occurred during filtering: $e');
|
||||
|
@ -235,8 +235,9 @@ class AccessManagementPage extends StatelessWidget {
|
||||
Expanded(
|
||||
child: state is TableLoaded
|
||||
? DynamicTable(
|
||||
withCheckBox: false,
|
||||
size: size,
|
||||
cellDecoration: containerDecoration,
|
||||
// cellDecoration: containerDecoration,
|
||||
headers: const [
|
||||
'Name',
|
||||
'Access Type',
|
||||
|
@ -1,55 +1,107 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class DynamicTable extends StatelessWidget {
|
||||
class DynamicTable extends StatefulWidget {
|
||||
final List<String> headers;
|
||||
final List<List<dynamic>> data;
|
||||
final BoxDecoration? headerDecoration;
|
||||
final BoxDecoration? cellDecoration;
|
||||
final Size size;
|
||||
final bool withCheckBox;
|
||||
final void Function(bool?)? onChanged;
|
||||
final void Function(bool?)? selectAll;
|
||||
final void Function(int, bool?)? onRowCheckboxChanged;
|
||||
|
||||
const DynamicTable({
|
||||
Key? key,
|
||||
required this.headers,
|
||||
required this.data,
|
||||
required this.size,
|
||||
required this.withCheckBox,
|
||||
this.headerDecoration,
|
||||
this.cellDecoration,
|
||||
this.onChanged,
|
||||
this.selectAll,
|
||||
this.onRowCheckboxChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_DynamicTableState createState() => _DynamicTableState();
|
||||
}
|
||||
|
||||
class _DynamicTableState extends State<DynamicTable> {
|
||||
late List<bool> _selected;
|
||||
bool _selectAll = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selected = List<bool>.filled(widget.data.length, false);
|
||||
}
|
||||
|
||||
void _toggleSelectAll(bool? value) {
|
||||
setState(() {
|
||||
_selectAll = value ?? false;
|
||||
_selected = List<bool>.filled(widget.data.length, _selectAll);
|
||||
if (widget.selectAll != null) {
|
||||
widget.selectAll!(_selectAll);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _toggleRowSelection(int index, bool? value) {
|
||||
setState(() {
|
||||
_selected[index] = value ?? false;
|
||||
_selectAll = _selected.every((element) => element == true);
|
||||
if (widget.onRowCheckboxChanged != null) {
|
||||
widget.onRowCheckboxChanged!(index, _selected[index]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
|
||||
decoration: cellDecoration,
|
||||
decoration: widget.cellDecoration,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
Container(
|
||||
width:size.width,
|
||||
SizedBox(
|
||||
width: widget.size.width,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: headerDecoration ??
|
||||
decoration: widget.headerDecoration ??
|
||||
BoxDecoration(color: Colors.grey[200]),
|
||||
child: Row(
|
||||
children: headers.map((header) =>
|
||||
_buildTableHeaderCell(header)).toList(),
|
||||
children: [
|
||||
if (widget.withCheckBox)
|
||||
_buildSelectAllCheckbox(),
|
||||
...widget.headers
|
||||
.map((header) => _buildTableHeaderCell(header))
|
||||
.toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
child: ListView(
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
children: data.map((row) {
|
||||
itemCount: widget.data.length,
|
||||
itemBuilder: (context, index) {
|
||||
final row = widget.data[index];
|
||||
return Row(
|
||||
children: row.map((cell) =>
|
||||
children: [
|
||||
if (widget.withCheckBox)
|
||||
_buildRowCheckbox(index),
|
||||
...row.map((cell) =>
|
||||
_buildTableCell(cell.toString())).toList(),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -61,7 +113,29 @@ class DynamicTable extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSelectAllCheckbox() {
|
||||
return SizedBox(
|
||||
width: 50,
|
||||
child: Checkbox(
|
||||
value: _selectAll,
|
||||
onChanged: _toggleSelectAll,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildRowCheckbox(int index) {
|
||||
return SizedBox(
|
||||
width: 50,
|
||||
child: Checkbox(
|
||||
value: _selected[index],
|
||||
onChanged: (bool? value) {
|
||||
_toggleRowSelection(index, value);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTableHeaderCell(String title) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
@ -71,7 +145,7 @@ Widget _buildTableHeaderCell(String title) {
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(title, style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
child: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -84,20 +158,17 @@ Widget _buildTableCell(String content) {
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide( // <--- right side
|
||||
bottom: BorderSide(
|
||||
color: ColorsManager.boxDivider,
|
||||
width: 1.0,
|
||||
),
|
||||
)
|
||||
),
|
||||
)),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
content,
|
||||
style: TextStyle(color: Colors.black, fontSize: 12),
|
||||
style: const TextStyle(color: Colors.black, fontSize: 12),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -9,12 +9,14 @@ class CustomWebTextField extends StatelessWidget {
|
||||
required this.textFieldName,
|
||||
required this.controller,
|
||||
this.description,
|
||||
this.validator,
|
||||
});
|
||||
|
||||
final bool isRequired;
|
||||
final String textFieldName;
|
||||
final String? description;
|
||||
final TextEditingController? controller;
|
||||
final String? Function(String?)? validator;
|
||||
|
||||
|
||||
@override
|
||||
@ -53,7 +55,6 @@ class CustomWebTextField extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 7,),
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height*0.05,
|
||||
decoration: containerDecoration.copyWith(
|
||||
color: const Color(0xFFF5F6F7),
|
||||
boxShadow: [
|
||||
@ -62,15 +63,19 @@ class CustomWebTextField extends StatelessWidget {
|
||||
spreadRadius:2,
|
||||
blurRadius: 3,
|
||||
offset: Offset(1, 1), // changes position of shadow
|
||||
), ]
|
||||
),
|
||||
]
|
||||
),
|
||||
child: Container(
|
||||
child: TextFormField(
|
||||
validator: validator,
|
||||
controller: controller,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: textBoxDecoration()!
|
||||
.copyWith(hintText: 'Please enter'),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/model/schedule_model.dart';
|
||||
import 'package:syncrow_web/services/access_mang_api.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/snack_bar.dart';
|
||||
|
||||
// Define the BLoC
|
||||
class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
||||
class VisitorPasswordBloc
|
||||
extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
||||
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
|
||||
on<SelectUsageFrequency>(selectUsageFrequency);
|
||||
on<FetchDevice>(_onFetchDevice);
|
||||
@ -17,25 +22,25 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
on<SelectTimeVisitorPassword>(selectTimeVisitorPassword);
|
||||
on<ToggleRepeatEvent>(toggleRepeat);
|
||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||
on<SelectDeviceEvent>(selectDevice);
|
||||
on<OnlineOneTimePasswordEvent>(postOnlineOneTimePassword);
|
||||
on<OnlineMultipleTimePasswordEvent>(postOnlineMultipleTimePassword);
|
||||
}
|
||||
final TextEditingController userNameController = TextEditingController();
|
||||
final TextEditingController emailController = TextEditingController();
|
||||
|
||||
|
||||
|
||||
final TextEditingController deviceNameController = TextEditingController();
|
||||
final TextEditingController deviceIdController = TextEditingController();
|
||||
final TextEditingController unitNameController = TextEditingController();
|
||||
final TextEditingController virtualAddressController = TextEditingController();
|
||||
|
||||
List<DeviceModel> data = [];
|
||||
List<String> selectedDeviceIds = ['909e052c-6934-48f3-b22d-67ee04ad7265'];
|
||||
final forgetFormKey = GlobalKey<FormState>();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
String accessTypeSelected='Offline Password';
|
||||
String accessTypeSelected = 'Online Password';
|
||||
String usageFrequencySelected = 'One-Time';
|
||||
String passwordController = '';
|
||||
|
||||
bool repeat = false;
|
||||
|
||||
@ -45,18 +50,24 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
String startTime = 'Start Time';
|
||||
String endTime = 'End Time';
|
||||
|
||||
selectAccessType(SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
|
||||
DateTime? repeatStartTime=DateTime.now();
|
||||
DateTime? repeatEndTime;
|
||||
|
||||
selectAccessType(
|
||||
SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
|
||||
accessTypeSelected = event.type;
|
||||
emit(PasswordTypeSelected(event.type));
|
||||
}
|
||||
|
||||
selectUsageFrequency(SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
|
||||
selectUsageFrequency(
|
||||
SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
|
||||
usageFrequencySelected = event.usageType;
|
||||
emit(UsageFrequencySelected(event.usageType));
|
||||
}
|
||||
|
||||
|
||||
Future<void> selectTimeVisitorPassword(SelectTimeVisitorPassword event, Emitter<VisitorPasswordState> emit) async {
|
||||
Future<void> selectTimeVisitorPassword(
|
||||
SelectTimeVisitorPassword event,
|
||||
Emitter<VisitorPasswordState> emit) async {
|
||||
final DateTime? picked = await showDatePicker(
|
||||
context: event.context,
|
||||
initialDate: DateTime.now(),
|
||||
@ -67,7 +78,6 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
final TimeOfDay? timePicked = await showTimePicker(
|
||||
context: event.context,
|
||||
initialTime: TimeOfDay.now(),
|
||||
|
||||
builder: (context, child) {
|
||||
return Theme(
|
||||
data: ThemeData.light().copyWith(
|
||||
@ -99,38 +109,52 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
selectedDateTime.day,
|
||||
selectedDateTime.hour,
|
||||
selectedDateTime.minute,
|
||||
).millisecondsSinceEpoch ~/ 1000; // Divide by 1000 to remove milliseconds
|
||||
).millisecondsSinceEpoch ~/
|
||||
1000; // Divide by 1000 to remove milliseconds
|
||||
if (event.isStart) {
|
||||
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
|
||||
if (expirationTimeTimeStamp != null &&
|
||||
selectedTimestamp > expirationTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
'Effective Time cannot be later than Expiration Time.');
|
||||
} else {
|
||||
startTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||
startTime = selectedDateTime
|
||||
.toString()
|
||||
.split('.')
|
||||
.first; // Remove seconds and milliseconds
|
||||
effectiveTimeTimeStamp = selectedTimestamp;
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
|
||||
} else {
|
||||
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
|
||||
if (effectiveTimeTimeStamp != null &&
|
||||
selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
'Expiration Time cannot be earlier than Effective Time.');
|
||||
} else {
|
||||
endTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||
endTime = selectedDateTime
|
||||
.toString()
|
||||
.split('.')
|
||||
.first; // Remove seconds and milliseconds
|
||||
expirationTimeTimeStamp = selectedTimestamp;
|
||||
}
|
||||
emit(VisitorPasswordInitial());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit(AccessInitial());
|
||||
// emit(TableLoaded(data));
|
||||
}
|
||||
|
||||
|
||||
bool toggleRepeat(ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
|
||||
bool toggleRepeat(
|
||||
ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
|
||||
emit(LoadingInitialState());
|
||||
repeat = !repeat;
|
||||
emit(IsRepeatState(repeat: repeat));
|
||||
return repeat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<Map<String, String>> days = [
|
||||
{"day": "Sun", "key": "Sun"},
|
||||
{"day": "Mon", "key": "Mon"},
|
||||
@ -143,7 +167,10 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
|
||||
List<String> selectedDays = [];
|
||||
|
||||
Future<void> toggleDaySelection(ToggleDaySelectionEvent event, Emitter<VisitorPasswordState> emit,)async {
|
||||
Future<void> toggleDaySelection(
|
||||
ToggleDaySelectionEvent event,
|
||||
Emitter<VisitorPasswordState> emit,
|
||||
) async {
|
||||
emit(LoadingInitialState());
|
||||
if (selectedDays.contains(event.key)) {
|
||||
selectedDays.remove(event.key);
|
||||
@ -152,7 +179,6 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
}
|
||||
//Add Accessible Device
|
||||
|
||||
Future<void> _onFetchDevice(
|
||||
FetchDevice event, Emitter<VisitorPasswordState> emit) async {
|
||||
@ -165,4 +191,78 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> postOnlineOneTimePassword(
|
||||
OnlineOneTimePasswordEvent event,
|
||||
Emitter<VisitorPasswordState> emit) async {
|
||||
try {
|
||||
// emit(DeviceLoaded());
|
||||
await AccessMangApi().postOnlineOneTime(
|
||||
email: event.email,
|
||||
devicesUuid: selectedDeviceIds,
|
||||
passwordName: event.passwordName);
|
||||
// emit(TableLoaded(data));
|
||||
} catch (e) {
|
||||
emit(FailedState(e.toString()));
|
||||
}
|
||||
}
|
||||
Future<void> postOnlineMultipleTimePassword(
|
||||
OnlineMultipleTimePasswordEvent event,
|
||||
Emitter<VisitorPasswordState> emit) async {
|
||||
try {
|
||||
generate7DigitNumber();
|
||||
// emit(DeviceLoaded());
|
||||
await AccessMangApi().postOnlineMultipleTime(
|
||||
scheduleList:[
|
||||
if (repeat)
|
||||
Schedule(
|
||||
effectiveTime: getTimeOnly(repeatStartTime),
|
||||
invalidTime: getTimeOnly(repeatEndTime).toString(),
|
||||
workingDay: selectedDays,
|
||||
),
|
||||
] ,
|
||||
password: passwordController,
|
||||
invalidTime:event.invalidTime ,
|
||||
effectiveTime:event.effectiveTime ,
|
||||
email: event.email,
|
||||
devicesUuid: selectedDeviceIds,
|
||||
passwordName: event.passwordName
|
||||
);
|
||||
// emit(TableLoaded(data));
|
||||
} catch (e) {
|
||||
emit(FailedState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void selectDevice(
|
||||
SelectDeviceEvent event, Emitter<VisitorPasswordState> emit) {
|
||||
if (selectedDeviceIds.contains(event.deviceId)) {
|
||||
selectedDeviceIds.remove(event.deviceId);
|
||||
} else {
|
||||
selectedDeviceIds.add(event.deviceId);
|
||||
}
|
||||
print(selectedDeviceIds);
|
||||
}
|
||||
|
||||
String? validate(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Field is required';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Future generate7DigitNumber() async {
|
||||
emit(LoadingInitialState());
|
||||
passwordController='';
|
||||
Random random = Random();
|
||||
int min = 1000000;
|
||||
int max = 9999999;
|
||||
passwordController = (min + random.nextInt(max - min + 1)).toString();
|
||||
emit(GeneratePasswordState());
|
||||
return passwordController;
|
||||
}
|
||||
String getTimeOnly(DateTime? dateTime) {
|
||||
if (dateTime == null) return '';
|
||||
return DateFormat('HH:mm').format(dateTime);
|
||||
}
|
||||
}
|
||||
|
@ -47,4 +47,32 @@ class ToggleDaySelectionEvent extends VisitorPasswordEvent {
|
||||
|
||||
|
||||
class ToggleRepeatEvent extends VisitorPasswordEvent {}
|
||||
class GeneratePasswordEvent extends VisitorPasswordEvent {}
|
||||
|
||||
class FetchDevice extends VisitorPasswordEvent {}
|
||||
|
||||
class OnlineOneTimePasswordEvent extends VisitorPasswordEvent {
|
||||
final String? email;
|
||||
final String? passwordName;
|
||||
|
||||
const OnlineOneTimePasswordEvent({this.email,this.passwordName});
|
||||
|
||||
@override
|
||||
List<Object> get props => [email!,passwordName!,];
|
||||
}
|
||||
class OnlineMultipleTimePasswordEvent extends VisitorPasswordEvent {
|
||||
final String? email;
|
||||
final String? passwordName;
|
||||
final String? invalidTime;
|
||||
final String? effectiveTime;
|
||||
|
||||
const OnlineMultipleTimePasswordEvent({this.email,this.passwordName,this.invalidTime,this.effectiveTime});
|
||||
|
||||
@override
|
||||
List<Object> get props => [email!,passwordName!,invalidTime!,effectiveTime!];
|
||||
}
|
||||
|
||||
class SelectDeviceEvent extends VisitorPasswordEvent {
|
||||
final String deviceId;
|
||||
const SelectDeviceEvent(this.deviceId);
|
||||
}
|
@ -44,6 +44,7 @@ class IsRepeatState extends VisitorPasswordState {
|
||||
class LoadingInitialState extends VisitorPasswordState {}
|
||||
class ChangeTimeState extends VisitorPasswordState {}
|
||||
class DeviceLoaded extends VisitorPasswordState {}
|
||||
class GeneratePasswordState extends VisitorPasswordState {}
|
||||
class FailedState extends VisitorPasswordState {
|
||||
final String message;
|
||||
|
||||
@ -60,3 +61,8 @@ class TableLoaded extends VisitorPasswordState {
|
||||
@override
|
||||
List<Object> get props => [data];
|
||||
}
|
||||
|
||||
class DeviceSelectionUpdated extends VisitorPasswordState {
|
||||
final List<String> selectedDeviceIds;
|
||||
const DeviceSelectionUpdated(this.selectedDeviceIds);
|
||||
}
|
27
lib/pages/visitor_password/model/schedule_model.dart
Normal file
27
lib/pages/visitor_password/model/schedule_model.dart
Normal file
@ -0,0 +1,27 @@
|
||||
class Schedule {
|
||||
final String effectiveTime;
|
||||
final String invalidTime;
|
||||
final List<String> workingDay;
|
||||
|
||||
Schedule({
|
||||
required this.effectiveTime,
|
||||
required this.invalidTime,
|
||||
required this.workingDay,
|
||||
});
|
||||
|
||||
factory Schedule.fromJson(Map<String, dynamic> json) {
|
||||
return Schedule(
|
||||
effectiveTime: json['effectiveTime'],
|
||||
invalidTime: json['invalidTime'],
|
||||
workingDay: List<String>.from(json['workingDay']),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'effectiveTime': effectiveTime,
|
||||
'invalidTime': invalidTime,
|
||||
'workingDay': workingDay,
|
||||
};
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ import '../../common/custom_table.dart';
|
||||
|
||||
class AddDeviceDialog extends StatelessWidget {
|
||||
const AddDeviceDialog({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
@ -138,21 +137,30 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Container(
|
||||
child: Expanded(
|
||||
const SizedBox(height: 20),
|
||||
Expanded(
|
||||
child: state is TableLoaded
|
||||
? Container(
|
||||
decoration: containerDecoration,
|
||||
child: DynamicTable(
|
||||
selectAll: (p0) {
|
||||
visitorBloc.selectedDeviceIds.clear();
|
||||
for (var item in state.data) {
|
||||
visitorBloc.add(SelectDeviceEvent(item.uuid));
|
||||
}
|
||||
},
|
||||
onRowCheckboxChanged: (index, isSelected) {
|
||||
final deviceId = state.data[index].uuid; // Adjust as per your actual data structure
|
||||
visitorBloc.add(SelectDeviceEvent(deviceId));
|
||||
},
|
||||
withCheckBox: true,
|
||||
size: size*0.5,
|
||||
headers: ['Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status'],
|
||||
headers: const [ 'Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status'],
|
||||
data: state.data.map((item) {
|
||||
return [
|
||||
item.name.toString(),
|
||||
@ -160,19 +168,11 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
item.productType.toString(),
|
||||
'',
|
||||
item.online.toString(),
|
||||
// item.categoryName.toString(),
|
||||
// accessBloc.timestampToDateTime(item.effectiveTime).toString(),
|
||||
// accessBloc.timestampToDateTime(item.invalidTime).toString(),
|
||||
// item.deviceUuid.toString(),
|
||||
// item.passwordCreated != null ? accessBloc.timestampToDateTime(item.passwordCreated).toString() : 'no data',
|
||||
// item.passwordStatus.toString(),
|
||||
];
|
||||
}).toList(),
|
||||
),
|
||||
)
|
||||
// TableWidget(size: size, headers: ['Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status', 'Virtual Address',], data: [], bloc: bloc)
|
||||
: const Center(child: CircularProgressIndicator())),
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator()))
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -195,9 +195,14 @@ class AddDeviceDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.2,
|
||||
child: const DefaultButton(
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(); // Close the dialog
|
||||
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('Ok'),
|
||||
),
|
||||
|
@ -27,6 +27,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
backgroundColor: Colors.white,
|
||||
title: const Text('Create visitor password'),
|
||||
content: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: visitorBloc.forgetFormKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: ListBody(
|
||||
@ -37,6 +39,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CustomWebTextField(
|
||||
validator: visitorBloc.validate,
|
||||
controller: visitorBloc.userNameController,
|
||||
isRequired: true,
|
||||
textFieldName: 'Name',
|
||||
@ -47,6 +50,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CustomWebTextField(
|
||||
validator: visitorBloc.validate,
|
||||
controller: visitorBloc.emailController,
|
||||
isRequired: true,
|
||||
textFieldName: 'Email Address',
|
||||
@ -75,21 +79,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Offline Password'),
|
||||
value: 'Offline Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
@ -105,6 +95,23 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Offline Password'),
|
||||
value: 'Offline Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
@ -218,7 +225,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
const Text('Within the validity period, each device can be unlocked only once.'),
|
||||
const SizedBox(height: 20,),
|
||||
visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Offline Password'?
|
||||
if(visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Online Password')
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: ListTile(
|
||||
@ -235,7 +242,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
):const SizedBox(),
|
||||
),
|
||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
@ -262,6 +269,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actionsAlignment: MainAxisAlignment.center,
|
||||
actions: <Widget>[
|
||||
Container(
|
||||
@ -282,7 +290,36 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.2,
|
||||
child: const DefaultButton(
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
if(visitorBloc.forgetFormKey.currentState!.validate()){
|
||||
if(visitorBloc.usageFrequencySelected=='One-Time'&&visitorBloc.accessTypeSelected=='Online Password'){
|
||||
visitorBloc.add(OnlineOneTimePasswordEvent(
|
||||
passwordName:visitorBloc.userNameController.text ,
|
||||
email: visitorBloc.emailController.text
|
||||
)
|
||||
);
|
||||
}else if(visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Online Password') {
|
||||
visitorBloc.add(OnlineMultipleTimePasswordEvent(
|
||||
passwordName:visitorBloc.userNameController.text ,
|
||||
email: visitorBloc.emailController.text,
|
||||
effectiveTime:visitorBloc.effectiveTimeTimeStamp.toString() ,
|
||||
invalidTime:visitorBloc.expirationTimeTimeStamp.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
else if(visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Online Password') {
|
||||
visitorBloc.add(OnlineMultipleTimePasswordEvent(
|
||||
passwordName:visitorBloc.userNameController.text ,
|
||||
email: visitorBloc.emailController.text,
|
||||
effectiveTime:visitorBloc.effectiveTimeTimeStamp.toString() ,
|
||||
invalidTime:visitorBloc.expirationTimeTimeStamp.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('Ok'),
|
||||
),
|
||||
|
@ -1,8 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:syncrow_web/pages/access_management/model/password_model.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/model/schedule_model.dart';
|
||||
import 'package:syncrow_web/services/api/http_service.dart';
|
||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||
|
||||
@ -10,8 +9,6 @@ import '../pages/visitor_password/model/device_model.dart';
|
||||
|
||||
class AccessMangApi{
|
||||
|
||||
|
||||
|
||||
Future<List<PasswordModel>> fetchVisitorPassword() async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
@ -54,6 +51,76 @@ class AccessMangApi{
|
||||
}
|
||||
}
|
||||
|
||||
Future postOnlineOneTime({String? email,String? passwordName,List<String>? devicesUuid}) async {
|
||||
try {
|
||||
|
||||
print('postOfflineOneTime List: ${
|
||||
{
|
||||
"email": email,
|
||||
"passwordName": passwordName,
|
||||
"devicesUuid": devicesUuid
|
||||
}
|
||||
}');
|
||||
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.sendOfflineOneTime,
|
||||
body: jsonEncode({
|
||||
"email": email,
|
||||
"passwordName": passwordName,
|
||||
"devicesUuid": devicesUuid
|
||||
}),
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
List<dynamic> jsonData = json;
|
||||
print('postOfflineOneTime List: $json');
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future postOnlineMultipleTime({
|
||||
String? effectiveTime,
|
||||
String? invalidTime,
|
||||
String? email,
|
||||
String? password,
|
||||
String? passwordName,
|
||||
List<Schedule>? scheduleList,
|
||||
List<String>? devicesUuid}) async {
|
||||
try {
|
||||
Map<String, dynamic> body = {
|
||||
"email": email,
|
||||
"devicesUuid": devicesUuid,
|
||||
"passwordName": passwordName,
|
||||
"password": password,
|
||||
"effectiveTime": effectiveTime,
|
||||
"invalidTime": invalidTime,
|
||||
};
|
||||
print('createPassword =${scheduleList![0].workingDay}');
|
||||
if (scheduleList != null) {
|
||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||
}
|
||||
print('createPassword =$body');
|
||||
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.sendOfflineMultipleTime,
|
||||
body: jsonEncode(body),
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
List<dynamic> jsonData = json;
|
||||
print('postOfflineOneTime List: $json');
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -11,5 +11,11 @@ abstract class ApiEndpoints {
|
||||
static const String getRegion = '$baseUrl/region';
|
||||
static const String visitorPassword = '$baseUrl/visitor-password';
|
||||
static const String getDevices = '$baseUrl/visitor-password/devices';
|
||||
|
||||
|
||||
static const String sendOfflineOneTime = '$baseUrl/visitor-password/temporary-password/online/one-time';
|
||||
static const String sendOfflineMultipleTime = '$baseUrl/visitor-password/temporary-password/online/multiple-time';
|
||||
|
||||
|
||||
static const String getUser = '$baseUrl/user/{userUuid}';
|
||||
}
|
||||
|
@ -240,6 +240,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.19.0"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -44,7 +44,7 @@ dependencies:
|
||||
flutter_secure_storage: ^9.2.2
|
||||
shared_preferences: ^2.3.0
|
||||
data_table_2: ^2.5.15
|
||||
|
||||
intl: ^0.19.0
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
Reference in New Issue
Block a user