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 */; };
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -42,12 +44,19 @@
|
|||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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 */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
759A57780A409ED209817654 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
E44A9405B1EB1B638DD05A58 /* Pods_RunnerTests.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
FF49F60EC38658783D8D66DA /* Pods_Runner.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup 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 */ = {
|
331C8082294A63A400263BE5 /* RunnerTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -94,6 +136,8 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
97C146EF1CF9000F007C117D /* Products */,
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||||
|
1454C118FFCECEEDF59152D2 /* Pods */,
|
||||||
|
20A3C64D2B1CFED5A81C3251 /* Frameworks */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@ -128,8 +172,10 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
B9A66CAAF434B6A1BD8C4E09 /* [CP] Check Pods Manifest.lock */,
|
||||||
331C807D294A63A400263BE5 /* Sources */,
|
331C807D294A63A400263BE5 /* Sources */,
|
||||||
331C807F294A63A400263BE5 /* Resources */,
|
331C807F294A63A400263BE5 /* Resources */,
|
||||||
|
759A57780A409ED209817654 /* Frameworks */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -145,12 +191,14 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
C1C48B0232C0B26BFF405512 /* [CP] Check Pods Manifest.lock */,
|
||||||
9740EEB61CF901F6004384FC /* Run Script */,
|
9740EEB61CF901F6004384FC /* Run Script */,
|
||||||
97C146EA1CF9000F007C117D /* Sources */,
|
97C146EA1CF9000F007C117D /* Sources */,
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||||
97C146EC1CF9000F007C117D /* Resources */,
|
97C146EC1CF9000F007C117D /* Resources */,
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
|
33590C9CD073D3D5EBA02CDE /* [CP] Embed Pods Frameworks */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -222,6 +270,23 @@
|
|||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase 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 */ = {
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
@ -253,6 +318,50 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
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 */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
@ -378,6 +487,7 @@
|
|||||||
};
|
};
|
||||||
331C8088294A63A400263BE5 /* Debug */ = {
|
331C8088294A63A400263BE5 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 2C0D722D2ED971BF672D18D5 /* Pods-RunnerTests.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
@ -395,6 +505,7 @@
|
|||||||
};
|
};
|
||||||
331C8089294A63A400263BE5 /* Release */ = {
|
331C8089294A63A400263BE5 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 877FDC97D8B87080E35B3EB7 /* Pods-RunnerTests.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
@ -410,6 +521,7 @@
|
|||||||
};
|
};
|
||||||
331C808A294A63A400263BE5 /* Profile */ = {
|
331C808A294A63A400263BE5 /* Profile */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 544621C7727C798253BAB2C8 /* Pods-RunnerTests.profile.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
@ -4,4 +4,7 @@
|
|||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "group:Runner.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
@ -59,8 +59,8 @@ class MyApp extends StatelessWidget {
|
|||||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
||||||
useMaterial3: true, // Enable Material 3
|
useMaterial3: true, // Enable Material 3
|
||||||
),
|
),
|
||||||
// home: AddDeviceDialog()
|
home: VisitorPasswordDialog()
|
||||||
home:isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
// home:isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
|
|||||||
}
|
}
|
||||||
return matchesCriteria;
|
return matchesCriteria;
|
||||||
}).toList();
|
}).toList();
|
||||||
print('Filtered data: $filteredData'); // Print to debug filtered data
|
print('Filtered data: $filteredData');
|
||||||
emit(TableLoaded(filteredData));
|
emit(TableLoaded(filteredData));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error occurred during filtering: $e');
|
print('Error occurred during filtering: $e');
|
||||||
|
@ -235,8 +235,9 @@ class AccessManagementPage extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: state is TableLoaded
|
child: state is TableLoaded
|
||||||
? DynamicTable(
|
? DynamicTable(
|
||||||
|
withCheckBox: false,
|
||||||
size: size,
|
size: size,
|
||||||
cellDecoration: containerDecoration,
|
// cellDecoration: containerDecoration,
|
||||||
headers: const [
|
headers: const [
|
||||||
'Name',
|
'Name',
|
||||||
'Access Type',
|
'Access Type',
|
||||||
|
@ -1,55 +1,107 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class DynamicTable extends StatelessWidget {
|
class DynamicTable extends StatefulWidget {
|
||||||
final List<String> headers;
|
final List<String> headers;
|
||||||
final List<List<dynamic>> data;
|
final List<List<dynamic>> data;
|
||||||
final BoxDecoration? headerDecoration;
|
final BoxDecoration? headerDecoration;
|
||||||
final BoxDecoration? cellDecoration;
|
final BoxDecoration? cellDecoration;
|
||||||
final Size size;
|
final Size size;
|
||||||
|
final bool withCheckBox;
|
||||||
|
final void Function(bool?)? onChanged;
|
||||||
|
final void Function(bool?)? selectAll;
|
||||||
|
final void Function(int, bool?)? onRowCheckboxChanged;
|
||||||
|
|
||||||
const DynamicTable({
|
const DynamicTable({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.headers,
|
required this.headers,
|
||||||
required this.data,
|
required this.data,
|
||||||
required this.size,
|
required this.size,
|
||||||
|
required this.withCheckBox,
|
||||||
this.headerDecoration,
|
this.headerDecoration,
|
||||||
this.cellDecoration,
|
this.cellDecoration,
|
||||||
|
this.onChanged,
|
||||||
|
this.selectAll,
|
||||||
|
this.onRowCheckboxChanged,
|
||||||
}) : super(key: key);
|
}) : 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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
|
decoration: widget.cellDecoration,
|
||||||
decoration: cellDecoration,
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(10.0),
|
padding: const EdgeInsets.all(10.0),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
SizedBox(
|
||||||
width:size.width,
|
width: widget.size.width,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
decoration: headerDecoration ??
|
decoration: widget.headerDecoration ??
|
||||||
BoxDecoration(color: Colors.grey[200]),
|
BoxDecoration(color: Colors.grey[200]),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: headers.map((header) =>
|
children: [
|
||||||
_buildTableHeaderCell(header)).toList(),
|
if (widget.withCheckBox)
|
||||||
|
_buildSelectAllCheckbox(),
|
||||||
|
...widget.headers
|
||||||
|
.map((header) => _buildTableHeaderCell(header))
|
||||||
|
.toList(),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: ListView(
|
child: ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: data.map((row) {
|
itemCount: widget.data.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final row = widget.data[index];
|
||||||
return Row(
|
return Row(
|
||||||
children: row.map((cell) =>
|
children: [
|
||||||
_buildTableCell(cell.toString())).toList(),
|
if (widget.withCheckBox)
|
||||||
|
_buildRowCheckbox(index),
|
||||||
|
...row.map((cell) =>
|
||||||
|
_buildTableCell(cell.toString())).toList(),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}).toList(),
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -61,43 +113,62 @@ class DynamicTable extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Widget _buildTableHeaderCell(String title) {
|
Widget _buildSelectAllCheckbox() {
|
||||||
return Expanded(
|
return SizedBox(
|
||||||
child: Container(
|
width: 50,
|
||||||
decoration: const BoxDecoration(
|
child: Checkbox(
|
||||||
border: Border.symmetric(
|
value: _selectAll,
|
||||||
vertical: BorderSide(color: ColorsManager.boxDivider))),
|
onChanged: _toggleSelectAll,
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Text(title, style: TextStyle(fontWeight: FontWeight.bold)),
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildTableCell(String content) {
|
Widget _buildRowCheckbox(int index) {
|
||||||
return Expanded(
|
return SizedBox(
|
||||||
child: Container(
|
width: 50,
|
||||||
height: 80,
|
child: Checkbox(
|
||||||
padding: const EdgeInsets.all(20.0),
|
value: _selected[index],
|
||||||
decoration: const BoxDecoration(
|
onChanged: (bool? value) {
|
||||||
border: Border(
|
_toggleRowSelection(index, value);
|
||||||
bottom: BorderSide( // <--- right side
|
},
|
||||||
color: ColorsManager.boxDivider,
|
|
||||||
width: 1.0,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
alignment: Alignment.centerLeft,
|
);
|
||||||
child: Text(
|
}
|
||||||
content,
|
|
||||||
style: TextStyle(color: Colors.black, fontSize: 12),
|
Widget _buildTableHeaderCell(String title) {
|
||||||
|
return Expanded(
|
||||||
|
child: Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border.symmetric(
|
||||||
|
vertical: BorderSide(color: ColorsManager.boxDivider))),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}
|
||||||
|
|
||||||
|
Widget _buildTableCell(String content) {
|
||||||
|
return Expanded(
|
||||||
|
child: Container(
|
||||||
|
height: 80,
|
||||||
|
padding: const EdgeInsets.all(20.0),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: ColorsManager.boxDivider,
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(
|
||||||
|
content,
|
||||||
|
style: const TextStyle(color: Colors.black, fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,12 +9,14 @@ class CustomWebTextField extends StatelessWidget {
|
|||||||
required this.textFieldName,
|
required this.textFieldName,
|
||||||
required this.controller,
|
required this.controller,
|
||||||
this.description,
|
this.description,
|
||||||
|
this.validator,
|
||||||
});
|
});
|
||||||
|
|
||||||
final bool isRequired;
|
final bool isRequired;
|
||||||
final String textFieldName;
|
final String textFieldName;
|
||||||
final String? description;
|
final String? description;
|
||||||
final TextEditingController? controller;
|
final TextEditingController? controller;
|
||||||
|
final String? Function(String?)? validator;
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -53,7 +55,6 @@ class CustomWebTextField extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 7,),
|
const SizedBox(height: 7,),
|
||||||
Container(
|
Container(
|
||||||
height: MediaQuery.of(context).size.height*0.05,
|
|
||||||
decoration: containerDecoration.copyWith(
|
decoration: containerDecoration.copyWith(
|
||||||
color: const Color(0xFFF5F6F7),
|
color: const Color(0xFFF5F6F7),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
@ -62,13 +63,17 @@ class CustomWebTextField extends StatelessWidget {
|
|||||||
spreadRadius:2,
|
spreadRadius:2,
|
||||||
blurRadius: 3,
|
blurRadius: 3,
|
||||||
offset: Offset(1, 1), // changes position of shadow
|
offset: Offset(1, 1), // changes position of shadow
|
||||||
), ]
|
),
|
||||||
|
]
|
||||||
),
|
),
|
||||||
child: TextFormField(
|
child: Container(
|
||||||
controller: controller,
|
child: TextFormField(
|
||||||
style: const TextStyle(color: Colors.black),
|
validator: validator,
|
||||||
decoration: textBoxDecoration()!
|
controller: controller,
|
||||||
.copyWith(hintText: 'Please enter'),
|
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/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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_event.dart';
|
||||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.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/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/services/access_mang_api.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/snack_bar.dart';
|
import 'package:syncrow_web/utils/snack_bar.dart';
|
||||||
|
|
||||||
// Define the BLoC
|
// Define the BLoC
|
||||||
class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
class VisitorPasswordBloc
|
||||||
|
extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
||||||
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
|
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
|
||||||
on<SelectUsageFrequency>(selectUsageFrequency);
|
on<SelectUsageFrequency>(selectUsageFrequency);
|
||||||
on<FetchDevice>(_onFetchDevice);
|
on<FetchDevice>(_onFetchDevice);
|
||||||
@ -17,25 +22,25 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
|||||||
on<SelectTimeVisitorPassword>(selectTimeVisitorPassword);
|
on<SelectTimeVisitorPassword>(selectTimeVisitorPassword);
|
||||||
on<ToggleRepeatEvent>(toggleRepeat);
|
on<ToggleRepeatEvent>(toggleRepeat);
|
||||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||||
|
on<SelectDeviceEvent>(selectDevice);
|
||||||
|
on<OnlineOneTimePasswordEvent>(postOnlineOneTimePassword);
|
||||||
|
on<OnlineMultipleTimePasswordEvent>(postOnlineMultipleTimePassword);
|
||||||
}
|
}
|
||||||
final TextEditingController userNameController = TextEditingController();
|
final TextEditingController userNameController = TextEditingController();
|
||||||
final TextEditingController emailController = TextEditingController();
|
final TextEditingController emailController = TextEditingController();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final TextEditingController deviceNameController = TextEditingController();
|
final TextEditingController deviceNameController = TextEditingController();
|
||||||
final TextEditingController deviceIdController = TextEditingController();
|
final TextEditingController deviceIdController = TextEditingController();
|
||||||
final TextEditingController unitNameController = TextEditingController();
|
final TextEditingController unitNameController = TextEditingController();
|
||||||
final TextEditingController virtualAddressController = TextEditingController();
|
final TextEditingController virtualAddressController = TextEditingController();
|
||||||
|
|
||||||
List<DeviceModel> data=[];
|
List<DeviceModel> data = [];
|
||||||
|
List<String> selectedDeviceIds = ['909e052c-6934-48f3-b22d-67ee04ad7265'];
|
||||||
|
final forgetFormKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
String accessTypeSelected = 'Online Password';
|
||||||
|
String usageFrequencySelected = 'One-Time';
|
||||||
|
String passwordController = '';
|
||||||
|
|
||||||
String accessTypeSelected='Offline Password';
|
|
||||||
String usageFrequencySelected='One-Time';
|
|
||||||
|
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
|
|
||||||
@ -45,18 +50,24 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
|||||||
String startTime = 'Start Time';
|
String startTime = 'Start Time';
|
||||||
String endTime = 'End Time';
|
String endTime = 'End Time';
|
||||||
|
|
||||||
selectAccessType(SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
|
DateTime? repeatStartTime=DateTime.now();
|
||||||
accessTypeSelected=event.type;
|
DateTime? repeatEndTime;
|
||||||
emit(PasswordTypeSelected(event.type));
|
|
||||||
|
selectAccessType(
|
||||||
|
SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
|
||||||
|
accessTypeSelected = event.type;
|
||||||
|
emit(PasswordTypeSelected(event.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
selectUsageFrequency(SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
|
selectUsageFrequency(
|
||||||
usageFrequencySelected=event.usageType;
|
SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
|
||||||
emit(UsageFrequencySelected(event.usageType));
|
usageFrequencySelected = event.usageType;
|
||||||
|
emit(UsageFrequencySelected(event.usageType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> selectTimeVisitorPassword(
|
||||||
Future<void> selectTimeVisitorPassword(SelectTimeVisitorPassword event, Emitter<VisitorPasswordState> emit) async {
|
SelectTimeVisitorPassword event,
|
||||||
|
Emitter<VisitorPasswordState> emit) async {
|
||||||
final DateTime? picked = await showDatePicker(
|
final DateTime? picked = await showDatePicker(
|
||||||
context: event.context,
|
context: event.context,
|
||||||
initialDate: DateTime.now(),
|
initialDate: DateTime.now(),
|
||||||
@ -67,7 +78,6 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
|||||||
final TimeOfDay? timePicked = await showTimePicker(
|
final TimeOfDay? timePicked = await showTimePicker(
|
||||||
context: event.context,
|
context: event.context,
|
||||||
initialTime: TimeOfDay.now(),
|
initialTime: TimeOfDay.now(),
|
||||||
|
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: ThemeData.light().copyWith(
|
data: ThemeData.light().copyWith(
|
||||||
@ -94,43 +104,57 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
|||||||
timePicked.minute,
|
timePicked.minute,
|
||||||
);
|
);
|
||||||
final selectedTimestamp = DateTime(
|
final selectedTimestamp = DateTime(
|
||||||
selectedDateTime.year,
|
selectedDateTime.year,
|
||||||
selectedDateTime.month,
|
selectedDateTime.month,
|
||||||
selectedDateTime.day,
|
selectedDateTime.day,
|
||||||
selectedDateTime.hour,
|
selectedDateTime.hour,
|
||||||
selectedDateTime.minute,
|
selectedDateTime.minute,
|
||||||
).millisecondsSinceEpoch ~/ 1000; // Divide by 1000 to remove milliseconds
|
).millisecondsSinceEpoch ~/
|
||||||
|
1000; // Divide by 1000 to remove milliseconds
|
||||||
if (event.isStart) {
|
if (event.isStart) {
|
||||||
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
|
if (expirationTimeTimeStamp != null &&
|
||||||
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
|
selectedTimestamp > expirationTimeTimeStamp!) {
|
||||||
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'Effective Time cannot be later than Expiration Time.');
|
||||||
} else {
|
} else {
|
||||||
startTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
startTime = selectedDateTime
|
||||||
|
.toString()
|
||||||
|
.split('.')
|
||||||
|
.first; // Remove seconds and milliseconds
|
||||||
effectiveTimeTimeStamp = selectedTimestamp;
|
effectiveTimeTimeStamp = selectedTimestamp;
|
||||||
}
|
}
|
||||||
|
emit(ChangeTimeState());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
if (effectiveTimeTimeStamp != null &&
|
||||||
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
|
selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||||
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'Expiration Time cannot be earlier than Effective Time.');
|
||||||
} else {
|
} else {
|
||||||
endTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
endTime = selectedDateTime
|
||||||
|
.toString()
|
||||||
|
.split('.')
|
||||||
|
.first; // Remove seconds and milliseconds
|
||||||
expirationTimeTimeStamp = selectedTimestamp;
|
expirationTimeTimeStamp = selectedTimestamp;
|
||||||
}
|
}
|
||||||
|
emit(VisitorPasswordInitial());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit(AccessInitial());
|
// emit(AccessInitial());
|
||||||
// emit(TableLoaded(data));
|
// emit(TableLoaded(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool toggleRepeat(
|
||||||
bool toggleRepeat(ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
|
ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
repeat = !repeat;
|
repeat = !repeat;
|
||||||
emit(IsRepeatState(repeat: repeat));
|
emit(IsRepeatState(repeat: repeat));
|
||||||
return repeat;
|
return repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Map<String, String>> days = [
|
List<Map<String, String>> days = [
|
||||||
{"day": "Sun", "key": "Sun"},
|
{"day": "Sun", "key": "Sun"},
|
||||||
{"day": "Mon", "key": "Mon"},
|
{"day": "Mon", "key": "Mon"},
|
||||||
@ -143,7 +167,10 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
|||||||
|
|
||||||
List<String> selectedDays = [];
|
List<String> selectedDays = [];
|
||||||
|
|
||||||
Future<void> toggleDaySelection(ToggleDaySelectionEvent event, Emitter<VisitorPasswordState> emit,)async {
|
Future<void> toggleDaySelection(
|
||||||
|
ToggleDaySelectionEvent event,
|
||||||
|
Emitter<VisitorPasswordState> emit,
|
||||||
|
) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
if (selectedDays.contains(event.key)) {
|
if (selectedDays.contains(event.key)) {
|
||||||
selectedDays.remove(event.key);
|
selectedDays.remove(event.key);
|
||||||
@ -152,17 +179,90 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
|||||||
}
|
}
|
||||||
emit(ChangeTimeState());
|
emit(ChangeTimeState());
|
||||||
}
|
}
|
||||||
//Add Accessible Device
|
|
||||||
|
|
||||||
Future<void> _onFetchDevice(
|
Future<void> _onFetchDevice(
|
||||||
FetchDevice event, Emitter<VisitorPasswordState> emit) async {
|
FetchDevice event, Emitter<VisitorPasswordState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(DeviceLoaded());
|
emit(DeviceLoaded());
|
||||||
data = await AccessMangApi().fetchDevices();
|
data = await AccessMangApi().fetchDevices();
|
||||||
emit(TableLoaded(data));
|
emit(TableLoaded(data));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(e.toString()));
|
emit(FailedState(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 ToggleRepeatEvent extends VisitorPasswordEvent {}
|
||||||
|
class GeneratePasswordEvent extends VisitorPasswordEvent {}
|
||||||
|
|
||||||
class FetchDevice 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 LoadingInitialState extends VisitorPasswordState {}
|
||||||
class ChangeTimeState extends VisitorPasswordState {}
|
class ChangeTimeState extends VisitorPasswordState {}
|
||||||
class DeviceLoaded extends VisitorPasswordState {}
|
class DeviceLoaded extends VisitorPasswordState {}
|
||||||
|
class GeneratePasswordState extends VisitorPasswordState {}
|
||||||
class FailedState extends VisitorPasswordState {
|
class FailedState extends VisitorPasswordState {
|
||||||
final String message;
|
final String message;
|
||||||
|
|
||||||
@ -59,4 +60,9 @@ class TableLoaded extends VisitorPasswordState {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [data];
|
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 {
|
class AddDeviceDialog extends StatelessWidget {
|
||||||
const AddDeviceDialog({super.key});
|
const AddDeviceDialog({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
@ -138,41 +137,42 @@ class AddDeviceDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Container(
|
Expanded(
|
||||||
child: Expanded(
|
child: state is TableLoaded
|
||||||
child: state is TableLoaded
|
? Container(
|
||||||
? Container(
|
decoration: containerDecoration,
|
||||||
decoration: containerDecoration,
|
child: DynamicTable(
|
||||||
child: DynamicTable(
|
selectAll: (p0) {
|
||||||
size: size*0.5,
|
visitorBloc.selectedDeviceIds.clear();
|
||||||
headers: ['Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status'],
|
for (var item in state.data) {
|
||||||
data: state.data.map((item) {
|
visitorBloc.add(SelectDeviceEvent(item.uuid));
|
||||||
return [
|
}
|
||||||
item.name.toString(),
|
},
|
||||||
item.uuid.toString(),
|
onRowCheckboxChanged: (index, isSelected) {
|
||||||
item.productType.toString(),
|
final deviceId = state.data[index].uuid; // Adjust as per your actual data structure
|
||||||
'',
|
visitorBloc.add(SelectDeviceEvent(deviceId));
|
||||||
item.online.toString(),
|
},
|
||||||
// item.categoryName.toString(),
|
withCheckBox: true,
|
||||||
// accessBloc.timestampToDateTime(item.effectiveTime).toString(),
|
size: size*0.5,
|
||||||
// accessBloc.timestampToDateTime(item.invalidTime).toString(),
|
headers: const [ 'Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status'],
|
||||||
// item.deviceUuid.toString(),
|
data: state.data.map((item) {
|
||||||
// item.passwordCreated != null ? accessBloc.timestampToDateTime(item.passwordCreated).toString() : 'no data',
|
return [
|
||||||
// item.passwordStatus.toString(),
|
item.name.toString(),
|
||||||
];
|
item.uuid.toString(),
|
||||||
}).toList(),
|
item.productType.toString(),
|
||||||
),
|
'',
|
||||||
)
|
item.online.toString(),
|
||||||
// TableWidget(size: size, headers: ['Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status', 'Virtual Address',], data: [], bloc: bloc)
|
];
|
||||||
: const Center(child: CircularProgressIndicator())),
|
}).toList(),
|
||||||
)
|
),
|
||||||
|
)
|
||||||
|
: const Center(child: CircularProgressIndicator()))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -195,9 +195,14 @@ class AddDeviceDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
|
|
||||||
decoration: containerDecoration,
|
decoration: containerDecoration,
|
||||||
width: size.width * 0.2,
|
width: size.width * 0.2,
|
||||||
child: const DefaultButton(
|
child: DefaultButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(); // Close the dialog
|
||||||
|
|
||||||
|
},
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
child: Text('Ok'),
|
child: Text('Ok'),
|
||||||
),
|
),
|
||||||
|
@ -27,238 +27,246 @@ class VisitorPasswordDialog extends StatelessWidget {
|
|||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
title: const Text('Create visitor password'),
|
title: const Text('Create visitor password'),
|
||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
child: Padding(
|
child: Form(
|
||||||
padding: const EdgeInsets.all(10.0),
|
key: visitorBloc.forgetFormKey,
|
||||||
child: ListBody(
|
child: Padding(
|
||||||
children: <Widget>[
|
padding: const EdgeInsets.all(10.0),
|
||||||
Container(
|
child: ListBody(
|
||||||
child: Row(
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: CustomWebTextField(
|
||||||
|
validator: visitorBloc.validate,
|
||||||
|
controller: visitorBloc.userNameController,
|
||||||
|
isRequired: true,
|
||||||
|
textFieldName: 'Name',
|
||||||
|
description: '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: CustomWebTextField(
|
||||||
|
validator: visitorBloc.validate,
|
||||||
|
controller: visitorBloc.emailController,
|
||||||
|
isRequired: true,
|
||||||
|
textFieldName: 'Email Address',
|
||||||
|
description: 'The password will be sent to the visitor’s email address.',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20,),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Row(
|
||||||
flex: 2,
|
children: [
|
||||||
child: CustomWebTextField(
|
Text(
|
||||||
controller: visitorBloc.userNameController,
|
'* ',
|
||||||
isRequired: true,
|
style: Theme.of(context)
|
||||||
textFieldName: 'Name',
|
.textTheme
|
||||||
description: '',
|
.bodyMedium!
|
||||||
),
|
.copyWith(color: Colors.red),
|
||||||
|
),
|
||||||
|
const Text('Access Type'),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const Spacer(),
|
Row(
|
||||||
Expanded(
|
children: <Widget>[
|
||||||
flex: 2,
|
|
||||||
child: CustomWebTextField(
|
SizedBox(
|
||||||
controller: visitorBloc.emailController,
|
width: size.width * 0.15,
|
||||||
isRequired: true,
|
child: RadioListTile<String>(
|
||||||
textFieldName: 'Email Address',
|
title: const Text('Online Password'),
|
||||||
description: 'The password will be sent to the visitor’s email address.',
|
value: 'Online 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>(
|
||||||
|
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>(
|
||||||
|
title: const Text('Dynamic Password'),
|
||||||
|
value: 'Dynamic Password',
|
||||||
|
groupValue: (state is PasswordTypeSelected)
|
||||||
|
? state.selectedType
|
||||||
|
: visitorBloc.accessTypeSelected,
|
||||||
|
onChanged: (String? value) {
|
||||||
|
if (value != null) {
|
||||||
|
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Text('Only currently online devices can be selected. It is recommended to use when the device network is stable, and the system randomly generates a digital password'),
|
||||||
|
SizedBox(height: 20,)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||||
SizedBox(height: 20,),
|
SizedBox():
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'* ',
|
'* ',
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(color: Colors.red),
|
.copyWith(color: Colors.red),
|
||||||
),
|
|
||||||
const Text('Access Type'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
const Text('Usage Frequency'),
|
||||||
SizedBox(
|
],
|
||||||
width: size.width * 0.15,
|
),
|
||||||
child: RadioListTile<String>(
|
Row(
|
||||||
title: const Text('Online Password'),
|
children: <Widget>[
|
||||||
value: 'Online Password',
|
SizedBox(
|
||||||
groupValue: (state is PasswordTypeSelected)
|
width: 200,
|
||||||
? state.selectedType
|
child: RadioListTile<String>(
|
||||||
: visitorBloc.accessTypeSelected,
|
title: const Text('One-Time'),
|
||||||
onChanged: (String? value) {
|
value: 'One-Time',
|
||||||
if (value != null) {
|
groupValue: (state is UsageFrequencySelected)
|
||||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
? state.selectedFrequency
|
||||||
}
|
: visitorBloc.usageFrequencySelected,
|
||||||
},
|
onChanged: (String? value) {
|
||||||
|
if (value != null) {
|
||||||
|
context.read<VisitorPasswordBloc>().add(SelectUsageFrequency(value));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
SizedBox(
|
width: 200,
|
||||||
width: size.width * 0.15,
|
child: RadioListTile<String>(
|
||||||
child: RadioListTile<String>(
|
title: const Text('Periodic'),
|
||||||
title: const Text('Dynamic Password'),
|
value: 'Periodic',
|
||||||
value: 'Dynamic Password',
|
groupValue: (state is UsageFrequencySelected)
|
||||||
groupValue: (state is PasswordTypeSelected)
|
? state.selectedFrequency
|
||||||
? state.selectedType
|
: visitorBloc.usageFrequencySelected,
|
||||||
: visitorBloc.accessTypeSelected,
|
onChanged: (String? value) {
|
||||||
onChanged: (String? value) {
|
if (value != null) {
|
||||||
if (value != null) {
|
context.read<VisitorPasswordBloc>().add(SelectUsageFrequency(value));
|
||||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
}
|
||||||
}
|
},
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
|
||||||
const Text('Only currently online devices can be selected. It is recommended to use when the device network is stable, and the system randomly generates a digital password'),
|
|
||||||
SizedBox(height: 20,)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
|
||||||
SizedBox():
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'* ',
|
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodyMedium!
|
|
||||||
.copyWith(color: Colors.red),
|
|
||||||
),
|
|
||||||
const Text('Usage Frequency'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: <Widget>[
|
|
||||||
SizedBox(
|
|
||||||
width: 200,
|
|
||||||
child: RadioListTile<String>(
|
|
||||||
title: const Text('One-Time'),
|
|
||||||
value: 'One-Time',
|
|
||||||
groupValue: (state is UsageFrequencySelected)
|
|
||||||
? state.selectedFrequency
|
|
||||||
: visitorBloc.usageFrequencySelected,
|
|
||||||
onChanged: (String? value) {
|
|
||||||
if (value != null) {
|
|
||||||
context.read<VisitorPasswordBloc>().add(SelectUsageFrequency(value));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 200,
|
|
||||||
child: RadioListTile<String>(
|
|
||||||
title: const Text('Periodic'),
|
|
||||||
value: 'Periodic',
|
|
||||||
groupValue: (state is UsageFrequencySelected)
|
|
||||||
? state.selectedFrequency
|
|
||||||
: visitorBloc.usageFrequencySelected,
|
|
||||||
onChanged: (String? value) {
|
|
||||||
if (value != null) {
|
|
||||||
context.read<VisitorPasswordBloc>().add(SelectUsageFrequency(value));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
Text('Within the validity period, each device can be unlocked only once.')
|
Text('Within the validity period, each device can be unlocked only once.')
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 20,),
|
const SizedBox(height: 20,),
|
||||||
|
|
||||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||||
SizedBox():
|
SizedBox():
|
||||||
DateTimeWebWidget(
|
DateTimeWebWidget(
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
title: 'Access Period',
|
title: 'Access Period',
|
||||||
size: size,
|
size: size,
|
||||||
endTime: () {
|
endTime: () {
|
||||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false));
|
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false));
|
||||||
},
|
},
|
||||||
startTime: () {
|
startTime: () {
|
||||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
||||||
},
|
},
|
||||||
firstString: visitorBloc.startTime,
|
firstString: visitorBloc.startTime,
|
||||||
secondString: visitorBloc.endTime,
|
secondString: visitorBloc.endTime,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20,),
|
const SizedBox(height: 20,),
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'* ',
|
'* ',
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(color: Colors.red),
|
.copyWith(color: Colors.red),
|
||||||
),
|
),
|
||||||
const Text('Access Devices'),
|
const Text('Access Devices'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const Text('Within the validity period, each device can be unlocked only once.'),
|
const Text('Within the validity period, each device can be unlocked only once.'),
|
||||||
const SizedBox(height: 20,),
|
const SizedBox(height: 20,),
|
||||||
visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Offline Password'?
|
if(visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Online Password')
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 100,
|
width: 100,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
leading: const Text('Repeat'),
|
leading: const Text('Repeat'),
|
||||||
trailing: Transform.scale(
|
trailing: Transform.scale(
|
||||||
scale: .8,
|
scale: .8,
|
||||||
child: CupertinoSwitch(
|
child: CupertinoSwitch(
|
||||||
value: visitorBloc.repeat,
|
value: visitorBloc.repeat,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
visitorBloc.add(ToggleRepeatEvent());
|
visitorBloc.add(ToggleRepeatEvent());
|
||||||
},
|
},
|
||||||
applyTheme: true,
|
applyTheme: true,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
):const SizedBox(),
|
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
Container(
|
||||||
Container(
|
decoration: containerDecoration,
|
||||||
decoration: containerDecoration,
|
width: size.width * 0.1,
|
||||||
width: size.width * 0.1,
|
child: DefaultButton(
|
||||||
child: DefaultButton(
|
onPressed: () {
|
||||||
onPressed: () {
|
showDialog(
|
||||||
showDialog(
|
context: context,
|
||||||
context: context,
|
barrierDismissible: false,
|
||||||
barrierDismissible: false,
|
builder: (BuildContext context) {
|
||||||
builder: (BuildContext context) {
|
return const AddDeviceDialog();
|
||||||
return const AddDeviceDialog();
|
|
||||||
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
child: Text('+ Add Device'),
|
child: Text('+ Add Device'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
|
||||||
|
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -282,7 +290,36 @@ class VisitorPasswordDialog extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
decoration: containerDecoration,
|
decoration: containerDecoration,
|
||||||
width: size.width * 0.2,
|
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,
|
borderRadius: 8,
|
||||||
child: Text('Ok'),
|
child: Text('Ok'),
|
||||||
),
|
),
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/model/password_model.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/services/api/http_service.dart';
|
||||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||||
|
|
||||||
@ -10,8 +9,6 @@ import '../pages/visitor_password/model/device_model.dart';
|
|||||||
|
|
||||||
class AccessMangApi{
|
class AccessMangApi{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Future<List<PasswordModel>> fetchVisitorPassword() async {
|
Future<List<PasswordModel>> fetchVisitorPassword() async {
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
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 getRegion = '$baseUrl/region';
|
||||||
static const String visitorPassword = '$baseUrl/visitor-password';
|
static const String visitorPassword = '$baseUrl/visitor-password';
|
||||||
static const String getDevices = '$baseUrl/visitor-password/devices';
|
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}';
|
static const String getUser = '$baseUrl/user/{userUuid}';
|
||||||
}
|
}
|
||||||
|
@ -240,6 +240,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.0.2"
|
||||||
|
intl:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.19.0"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -44,7 +44,7 @@ dependencies:
|
|||||||
flutter_secure_storage: ^9.2.2
|
flutter_secure_storage: ^9.2.2
|
||||||
shared_preferences: ^2.3.0
|
shared_preferences: ^2.3.0
|
||||||
data_table_2: ^2.5.15
|
data_table_2: ^2.5.15
|
||||||
|
intl: ^0.19.0
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
Reference in New Issue
Block a user