Commit e25e0600 authored by Wei Han's avatar Wei Han

xcframework accepts strings from js

parent 1ce35c7d
...@@ -6,20 +6,16 @@ import { QmsDashboardView } from 'QmsPlugin'; ...@@ -6,20 +6,16 @@ import { QmsDashboardView } from 'QmsPlugin';
function App() { function App() {
const isDarkMode = useColorScheme() === 'dark'; const isDarkMode = useColorScheme() === 'dark';
// useEffect(() => {
// console.log('🚀 Launching plugin UI immediately...');
// try {
// showPluginUI();
// } catch (e) {
// console.error('❌ Error launching plugin UI:', e);
// }
// }, []);
return ( return (
<SafeAreaView> <SafeAreaView>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
<QmsDashboardView style={{ flex: 1 }} /> <QmsDashboardView
style={{ flex: 1 }}
ClientID={'client id test'}
ClientCode={'client code test'}
user_token={'user token test'}
/>
</View> </View>
</SafeAreaView> </SafeAreaView>
); );
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
04AD2AFD03B4D56C1CE62F6A /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C73ABF42EDEF67482B70912 /* libPods-example.a */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
44006126336D83DB220E7214 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; }; 44006126336D83DB220E7214 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; };
761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; }; 761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
D458042D2F0D3FDEC170C143 /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B322AC5237F8AE5669A0FABE /* libPods-example.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = "<group>"; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = "<group>"; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = "<group>"; };
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = example/PrivacyInfo.xcprivacy; sourceTree = "<group>"; }; 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = example/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
38EC829E51DAE9347EEBB719 /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = "<group>"; }; 1C73ABF42EDEF67482B70912 /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = example/AppDelegate.swift; sourceTree = "<group>"; }; 761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = example/AppDelegate.swift; sourceTree = "<group>"; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = example/LaunchScreen.storyboard; sourceTree = "<group>"; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = example/LaunchScreen.storyboard; sourceTree = "<group>"; };
B322AC5237F8AE5669A0FABE /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
DE57DCC5FB89A01CC4F15D08 /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
F97D380E3689279E81FCCF0D /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = "<group>"; };
FD2BE23365AFCE8816A3B912 /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
D458042D2F0D3FDEC170C143 /* libPods-example.a in Frameworks */, 04AD2AFD03B4D56C1CE62F6A /* libPods-example.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
B322AC5237F8AE5669A0FABE /* libPods-example.a */, 1C73ABF42EDEF67482B70912 /* libPods-example.a */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -92,8 +92,8 @@ ...@@ -92,8 +92,8 @@
BBD78D7AC51CEA395F1C20DB /* Pods */ = { BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DE57DCC5FB89A01CC4F15D08 /* Pods-example.debug.xcconfig */, F97D380E3689279E81FCCF0D /* Pods-example.debug.xcconfig */,
38EC829E51DAE9347EEBB719 /* Pods-example.release.xcconfig */, FD2BE23365AFCE8816A3B912 /* Pods-example.release.xcconfig */,
); );
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -105,13 +105,13 @@ ...@@ -105,13 +105,13 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */;
buildPhases = ( buildPhases = (
E64512420461EC9A112A889B /* [CP] Check Pods Manifest.lock */, 09928E3D5127D716871C58DB /* [CP] Check Pods Manifest.lock */,
13B07F871A680F5B00A75B9A /* Sources */, 13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */, 13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
ABAB5ABD407312F464F54478 /* [CP] Embed Pods Frameworks */, 49A09A0160A62946A28722B3 /* [CP] Embed Pods Frameworks */,
73271984CC447AE7F2C70BD0 /* [CP] Copy Pods Resources */, 66729857758E088B57840AEF /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
...@@ -183,24 +183,29 @@ ...@@ -183,24 +183,29 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
}; };
73271984CC447AE7F2C70BD0 /* [CP] Copy Pods Resources */ = { 09928E3D5127D716871C58DB /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-input-files.xcfilelist",
); );
name = "[CP] Copy Pods Resources"; inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-output-files.xcfilelist", );
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh\"\n"; 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; showEnvVarsInLog = 0;
}; };
ABAB5ABD407312F464F54478 /* [CP] Embed Pods Frameworks */ = { 49A09A0160A62946A28722B3 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
...@@ -217,26 +222,21 @@ ...@@ -217,26 +222,21 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
E64512420461EC9A112A889B /* [CP] Check Pods Manifest.lock */ = { 66729857758E088B57840AEF /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-input-files.xcfilelist",
); );
inputPaths = ( name = "[CP] Copy Pods Resources";
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = ( outputFileListPaths = (
); "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-output-files.xcfilelist",
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; 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"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
...@@ -255,7 +255,7 @@ ...@@ -255,7 +255,7 @@
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = { 13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = DE57DCC5FB89A01CC4F15D08 /* Pods-example.debug.xcconfig */; baseConfigurationReference = F97D380E3689279E81FCCF0D /* Pods-example.debug.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
...@@ -283,7 +283,7 @@ ...@@ -283,7 +283,7 @@
}; };
13B07F951A680F5B00A75B9A /* Release */ = { 13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 38EC829E51DAE9347EEBB719 /* Pods-example.release.xcconfig */; baseConfigurationReference = FD2BE23365AFCE8816A3B912 /* Pods-example.release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>
//QmsPlugin.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface QmsPluginUI : NSObject
+ (UIViewController *)makeViewController;
@end
NS_ASSUME_NONNULL_END
//
// QmsPluginFramework.h
// QmsPluginFramework
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
//! Project version number for QmsPluginFramework.
FOUNDATION_EXPORT double QmsPluginFrameworkVersionNumber;
//! Project version string for QmsPluginFramework.
FOUNDATION_EXPORT const unsigned char QmsPluginFrameworkVersionString[];
// Public headers
#import <QmsPluginFramework/QmsPlugin.h>
framework module QmsPluginFramework {
umbrella header "QmsPluginFramework.h"
export *
module * { export * }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Assets.car</key>
<data>
mDeq0E4lblXfFuIgkojjE5zY6hk=
</data>
<key>Headers/QmsPlugin.h</key>
<data>
46196FWEMwEuy8Dd/6jLyvdFEok=
</data>
<key>Headers/QmsPluginFramework.h</key>
<data>
jlHmWnGf08fskfPJb//4vaShDlo=
</data>
<key>Info.plist</key>
<data>
/JZsUWwwr7A+ZF0o001HQXRnzpI=
</data>
<key>Modules/module.modulemap</key>
<data>
BD9YnWBkeFmDcuOl4cAjALd/7yw=
</data>
</dict>
<key>files2</key>
<dict>
<key>Assets.car</key>
<dict>
<key>hash2</key>
<data>
0+eonZqFOeyimWUH94CuUhfXNEulhfi9YeuUE/wnX0s=
</data>
</dict>
<key>Headers/QmsPlugin.h</key>
<dict>
<key>hash2</key>
<data>
uuQ2Omt7lnrShVFriPpMiXZhx8kx6Km97GxC3m1ro+A=
</data>
</dict>
<key>Headers/QmsPluginFramework.h</key>
<dict>
<key>hash2</key>
<data>
/9Qe6QJ19ZC61+OfPl2+OZK1DI2Wa1lS++m7D41g3zI=
</data>
</dict>
<key>Modules/module.modulemap</key>
<dict>
<key>hash2</key>
<data>
e+P6RtiuicqWfZ3H2B43r960DPkFwUWqXKWU+w7OVD0=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>
//QmsPlugin.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface QmsPluginUI : NSObject
+ (UIViewController *)makeViewController;
@end
NS_ASSUME_NONNULL_END
//
// QmsPluginFramework.h
// QmsPluginFramework
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
//! Project version number for QmsPluginFramework.
FOUNDATION_EXPORT double QmsPluginFrameworkVersionNumber;
//! Project version string for QmsPluginFramework.
FOUNDATION_EXPORT const unsigned char QmsPluginFrameworkVersionString[];
// Public headers
#import <QmsPluginFramework/QmsPlugin.h>
framework module QmsPluginFramework {
umbrella header "QmsPluginFramework.h"
export *
module * { export * }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Assets.car</key>
<data>
mDeq0E4lblXfFuIgkojjE5zY6hk=
</data>
<key>Headers/QmsPlugin.h</key>
<data>
46196FWEMwEuy8Dd/6jLyvdFEok=
</data>
<key>Headers/QmsPluginFramework.h</key>
<data>
jlHmWnGf08fskfPJb//4vaShDlo=
</data>
<key>Info.plist</key>
<data>
4pQwOIuYwsUH4Iiw1M402s3Ii8Y=
</data>
<key>Modules/module.modulemap</key>
<data>
BD9YnWBkeFmDcuOl4cAjALd/7yw=
</data>
</dict>
<key>files2</key>
<dict>
<key>Assets.car</key>
<dict>
<key>hash2</key>
<data>
0+eonZqFOeyimWUH94CuUhfXNEulhfi9YeuUE/wnX0s=
</data>
</dict>
<key>Headers/QmsPlugin.h</key>
<dict>
<key>hash2</key>
<data>
uuQ2Omt7lnrShVFriPpMiXZhx8kx6Km97GxC3m1ro+A=
</data>
</dict>
<key>Headers/QmsPluginFramework.h</key>
<dict>
<key>hash2</key>
<data>
/9Qe6QJ19ZC61+OfPl2+OZK1DI2Wa1lS++m7D41g3zI=
</data>
</dict>
<key>Modules/module.modulemap</key>
<dict>
<key>hash2</key>
<data>
e+P6RtiuicqWfZ3H2B43r960DPkFwUWqXKWU+w7OVD0=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>
...@@ -23,9 +23,20 @@ ...@@ -23,9 +23,20 @@
@property (nonatomic, strong) UIView *repCard; @property (nonatomic, strong) UIView *repCard;
@property (nonatomic, strong) UIView *buttonSection; @property (nonatomic, strong) UIView *buttonSection;
@property (nonatomic, strong) UIView *tabsBar; @property (nonatomic, strong) UIView *tabsBar;
@property (nonatomic, strong) UIView *summaryContainer;
@property (nonatomic, strong) UIView *ownerInfoContainer;
@property (nonatomic, strong) UIView *loadingOverlay; @property (nonatomic, strong) UIView *loadingOverlay;
@property (nonatomic, strong) UILabel *typeField;
@property (nonatomic, strong) UILabel *dateField;
@property (nonatomic, strong) UILabel *slotField;
@property (nonatomic, strong) UILabel *locField;
@property (nonatomic, strong) UILabel *termsField;
@property (nonatomic, strong) UIButton *summaryBtn;
@property (nonatomic, strong) UIButton *ownerBtn;
@end @end
...@@ -38,9 +49,10 @@ ...@@ -38,9 +49,10 @@
[self setupNavBar]; [self setupNavBar];
[self setupScrollView]; [self setupScrollView];
[self setupStatusBanner]; [self setupStatusBanner];
[self setupUnitInfoHeader]; [self setupUnitInfoHeader];
[self setupTabs];
[self setupContainers];
[self setupSummaryCard]; [self setupSummaryCard];
[self setupRepresentativeCard];
[self setupButtonSection]; [self setupButtonSection];
[self setupLoadingOverlay]; [self setupLoadingOverlay];
...@@ -120,7 +132,7 @@ ...@@ -120,7 +132,7 @@
[header addSubview:floorPlan]; [header addSubview:floorPlan];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[header.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:20], [header.topAnchor constraintEqualToAnchor:self.statusBanner.topAnchor constant:20],
[header.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16], [header.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[header.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16], [header.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
...@@ -214,16 +226,16 @@ ...@@ -214,16 +226,16 @@
self.summaryCard.layer.borderWidth = 1; self.summaryCard.layer.borderWidth = 1;
self.summaryCard.layer.borderColor = [UIColor colorWithWhite:0.9 alpha:1].CGColor; self.summaryCard.layer.borderColor = [UIColor colorWithWhite:0.9 alpha:1].CGColor;
self.summaryCard.translatesAutoresizingMaskIntoConstraints = NO; self.summaryCard.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.summaryCard]; [self.summaryContainer addSubview:self.summaryCard];
UILabel *title = [[UILabel alloc] init]; UILabel *title = [[UILabel alloc] init];
title.text = @"Appointment Summary"; title.text = @"Appointment Summary";
title.font = [UIFont boldSystemFontOfSize:16]; title.font = [UIFont boldSystemFontOfSize:16];
title.translatesAutoresizingMaskIntoConstraints = NO; title.translatesAutoresizingMaskIntoConstraints = NO;
[self.summaryCard addSubview:title]; [self.summaryContainer addSubview:title];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[self.summaryCard.topAnchor constraintEqualToAnchor:self.statusBanner.bottomAnchor constant:20], [self.summaryCard.topAnchor constraintEqualToAnchor:self.tabsBar.bottomAnchor constant:20],
[self.summaryCard.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16], [self.summaryCard.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[self.summaryCard.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16], [self.summaryCard.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
...@@ -241,10 +253,11 @@ ...@@ -241,10 +253,11 @@
return field; return field;
}; };
UILabel *typeField = makeField(@"Type :", self.appointmentData[@"type"]); self.typeField = makeField(@"Type :", self.appointmentData[@"type"]);
UILabel *dateField = makeField(@"Date :", self.appointmentData[@"date"]); self.dateField = makeField(@"Date :", self.appointmentData[@"date"]);
UILabel *slotField = makeField(@"Time Slot :", self.appointmentData[@"time"]); self.slotField = makeField(@"Time Slot :", self.appointmentData[@"time"]);
UILabel *locField = makeField(@"Location :", self.appointmentData[@"location"]); self.locField = makeField(@"Location :", self.appointmentData[@"location"]);
self.termsField = makeField(@"Terms &\n Conditions :", @"View Here");
UIButton *calendarBtn = [UIButton buttonWithType:UIButtonTypeCustom]; UIButton *calendarBtn = [UIButton buttonWithType:UIButtonTypeCustom];
calendarBtn.layer.cornerRadius = 12; calendarBtn.layer.cornerRadius = 12;
...@@ -255,55 +268,121 @@ ...@@ -255,55 +268,121 @@
[calendarBtn setTitle:@" Add To Calendar" forState:UIControlStateNormal]; [calendarBtn setTitle:@" Add To Calendar" forState:UIControlStateNormal];
[calendarBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal]; [calendarBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
calendarBtn.translatesAutoresizingMaskIntoConstraints = NO; calendarBtn.translatesAutoresizingMaskIntoConstraints = NO;
[self.summaryCard addSubview:calendarBtn]; [self.summaryContainer addSubview:calendarBtn];
[NSLayoutConstraint activateConstraints:@[
[self.typeField.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:10],
[self.typeField.leadingAnchor constraintEqualToAnchor:self.summaryCard.leadingAnchor constant:16],
[self.typeField.trailingAnchor constraintEqualToAnchor:self.summaryCard.trailingAnchor constant:-16],
[self.dateField.topAnchor constraintEqualToAnchor:self.typeField.bottomAnchor constant:10],
[self.dateField.leadingAnchor constraintEqualToAnchor:self.typeField.leadingAnchor],
[self.dateField.trailingAnchor constraintEqualToAnchor:self.typeField.trailingAnchor],
[self.slotField.topAnchor constraintEqualToAnchor:self.dateField.bottomAnchor constant:10],
[self.slotField.leadingAnchor constraintEqualToAnchor:self.typeField.leadingAnchor],
[self.slotField.trailingAnchor constraintEqualToAnchor:self.typeField.trailingAnchor],
[self.locField.topAnchor constraintEqualToAnchor:self.slotField.bottomAnchor constant:10],
[self.locField.leadingAnchor constraintEqualToAnchor:self.typeField.leadingAnchor],
[self.locField.trailingAnchor constraintEqualToAnchor:self.typeField.trailingAnchor],
[self.termsField.topAnchor constraintEqualToAnchor:self.locField.bottomAnchor constant:10],
[self.termsField.leadingAnchor constraintEqualToAnchor:self.typeField.leadingAnchor],
[self.termsField.trailingAnchor constraintEqualToAnchor:self.typeField.trailingAnchor],
[calendarBtn.topAnchor constraintEqualToAnchor:self.termsField.bottomAnchor constant:10],
[calendarBtn.leadingAnchor constraintEqualToAnchor:self.typeField.leadingAnchor],
[calendarBtn.trailingAnchor constraintEqualToAnchor:self.typeField.trailingAnchor],
[calendarBtn.heightAnchor constraintEqualToConstant:44],
[self.summaryCard.bottomAnchor constraintEqualToAnchor:calendarBtn.bottomAnchor constant:16]
]];
} }
#pragma mark - Summary Tabs #pragma mark - Summary Tabs
- (void)setupTabs { - (void)setupTabs {
UIView *tabs = [[UIView alloc] init]; UIView *tabs = [[UIView alloc] init];
tabs.translatesAutoresizingMaskIntoConstraints = NO; tabs.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:tabs]; [self.contentView addSubview:tabs];
UIButton *summaryBtn = [UIButton buttonWithType:UIButtonTypeCustom]; self.summaryBtn = [UIButton buttonWithType:UIButtonTypeCustom];
summaryBtn.backgroundColor = [UIColor colorWithRed:0 green:0.45 blue:0.55 alpha:1]; self.summaryBtn.backgroundColor = [UIColor colorWithRed:0 green:0.45 blue:0.55 alpha:1];
[summaryBtn setTitle:@"Summary" forState:UIControlStateNormal]; [self.summaryBtn setTitle:@"Summary" forState:UIControlStateNormal];
summaryBtn.titleLabel.font = [UIFont boldSystemFontOfSize:15]; self.summaryBtn.layer.cornerRadius = 20;
summaryBtn.layer.cornerRadius = 20; self.summaryBtn.translatesAutoresizingMaskIntoConstraints = NO;
summaryBtn.translatesAutoresizingMaskIntoConstraints = NO;
UIButton *ownerBtn = [UIButton buttonWithType:UIButtonTypeCustom]; self.ownerBtn = [UIButton buttonWithType:UIButtonTypeCustom];
ownerBtn.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1]; self.ownerBtn.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];
ownerBtn.layer.cornerRadius = 20; self.ownerBtn.layer.cornerRadius = 20;
[ownerBtn setTitle:@"Owner Info" forState:UIControlStateNormal]; [self.ownerBtn setTitle:@"Owner Info" forState:UIControlStateNormal];
ownerBtn.titleLabel.font = [UIFont systemFontOfSize:15]; self.ownerBtn.translatesAutoresizingMaskIntoConstraints = NO;
ownerBtn.translatesAutoresizingMaskIntoConstraints = NO;
[tabs addSubview:summaryBtn]; [tabs addSubview:self.summaryBtn];
[tabs addSubview:ownerBtn]; [tabs addSubview:self.ownerBtn];
[self.summaryBtn addTarget:self action:@selector(showSummary) forControlEvents:UIControlEventTouchUpInside];
[self.ownerBtn addTarget:self action:@selector(showOwnerInfo) forControlEvents:UIControlEventTouchUpInside];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[tabs.topAnchor constraintEqualToAnchor:self.unitInfoHeader.bottomAnchor constant:20], [tabs.topAnchor constraintEqualToAnchor:self.unitInfoHeader.bottomAnchor constant:20],
[tabs.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16], [tabs.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[tabs.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16], [tabs.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
[summaryBtn.topAnchor constraintEqualToAnchor:tabs.topAnchor], [self.summaryBtn.topAnchor constraintEqualToAnchor:tabs.topAnchor],
[summaryBtn.leadingAnchor constraintEqualToAnchor:tabs.leadingAnchor], [self.summaryBtn.leadingAnchor constraintEqualToAnchor:tabs.leadingAnchor],
[summaryBtn.widthAnchor constraintEqualToAnchor:tabs.widthAnchor multiplier:0.5], [self.summaryBtn.widthAnchor constraintEqualToAnchor:tabs.widthAnchor multiplier:0.5],
[summaryBtn.heightAnchor constraintEqualToConstant:40], [self.summaryBtn.heightAnchor constraintEqualToConstant:40],
[ownerBtn.topAnchor constraintEqualToAnchor:tabs.topAnchor], [self.ownerBtn.topAnchor constraintEqualToAnchor:tabs.topAnchor],
[ownerBtn.trailingAnchor constraintEqualToAnchor:tabs.trailingAnchor], [self.ownerBtn.trailingAnchor constraintEqualToAnchor:tabs.trailingAnchor],
[ownerBtn.widthAnchor constraintEqualToAnchor:tabs.widthAnchor multiplier:0.5], [self.ownerBtn.widthAnchor constraintEqualToAnchor:tabs.widthAnchor multiplier:0.5],
[ownerBtn.heightAnchor constraintEqualToConstant:40], [self.ownerBtn.heightAnchor constraintEqualToConstant:40],
[tabs.bottomAnchor constraintEqualToAnchor:summaryBtn.bottomAnchor] [tabs.bottomAnchor constraintEqualToAnchor:self.summaryBtn.bottomAnchor]
]]; ]];
self.tabsBar = tabs; self.tabsBar = tabs;
} }
- (void)showSummary {
self.summaryContainer.hidden = NO;
self.ownerInfoContainer.hidden = YES;
// Update tab colors
self.summaryBtn.backgroundColor = [UIColor colorWithRed:0 green:0.45 blue:0.55 alpha:1];
self.ownerBtn.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];
}
- (void)showOwnerInfo {
self.summaryContainer.hidden = YES;
self.ownerInfoContainer.hidden = NO;
// Update tab colors
self.summaryBtn.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];
self.ownerBtn.backgroundColor = [UIColor colorWithRed:0 green:0.45 blue:0.55 alpha:1];
}
#pragma mark - Containers
- (void)setupContainers {
self.summaryContainer = [[UIView alloc] init];
self.summaryContainer.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.summaryContainer];
self.ownerInfoContainer = [[UIView alloc] init];
self.ownerInfoContainer.translatesAutoresizingMaskIntoConstraints = NO;
self.ownerInfoContainer.hidden = YES; // Start hidden
[self.contentView addSubview:self.ownerInfoContainer];
[NSLayoutConstraint activateConstraints:@[
[self.summaryContainer.topAnchor constraintEqualToAnchor:self.tabsBar.bottomAnchor constant:20],
[self.summaryContainer.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.summaryContainer.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
[self.ownerInfoContainer.topAnchor constraintEqualToAnchor:self.tabsBar.bottomAnchor constant:20],
[self.ownerInfoContainer.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.ownerInfoContainer.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
]];
}
#pragma mark - Representative Card #pragma mark - Representative Card
...@@ -314,18 +393,19 @@ ...@@ -314,18 +393,19 @@
self.repCard.layer.borderColor = [UIColor colorWithWhite:0.9 alpha:1].CGColor; self.repCard.layer.borderColor = [UIColor colorWithWhite:0.9 alpha:1].CGColor;
self.repCard.layer.borderWidth = 1; self.repCard.layer.borderWidth = 1;
self.repCard.translatesAutoresizingMaskIntoConstraints = NO; self.repCard.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.repCard]; [self.ownerInfoContainer addSubview:self.repCard];
UILabel *title = [[UILabel alloc] init]; UILabel *title = [[UILabel alloc] init];
title.text = @"Representative"; title.text = @"Representative";
title.font = [UIFont boldSystemFontOfSize:16]; title.font = [UIFont boldSystemFontOfSize:16];
title.translatesAutoresizingMaskIntoConstraints = NO; title.translatesAutoresizingMaskIntoConstraints = NO;
[self.repCard addSubview:title]; [self.ownerInfoContainer addSubview:title];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[self.repCard.topAnchor constraintEqualToAnchor:self.summaryCard.bottomAnchor constant:20], [self.repCard.topAnchor constraintEqualToAnchor:self.ownerInfoContainer.topAnchor constant:0],
[self.repCard.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16], [self.repCard.leadingAnchor constraintEqualToAnchor:self.ownerInfoContainer.leadingAnchor constant:16],
[self.repCard.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16], [self.repCard.trailingAnchor constraintEqualToAnchor:self.ownerInfoContainer.trailingAnchor constant:-16],
[self.repCard.bottomAnchor constraintEqualToAnchor:self.ownerInfoContainer.bottomAnchor constant:-20],
[title.topAnchor constraintEqualToAnchor:self.repCard.topAnchor constant:16], [title.topAnchor constraintEqualToAnchor:self.repCard.topAnchor constant:16],
[title.leadingAnchor constraintEqualToAnchor:self.repCard.leadingAnchor constant:16], [title.leadingAnchor constraintEqualToAnchor:self.repCard.leadingAnchor constant:16],
...@@ -333,20 +413,7 @@ ...@@ -333,20 +413,7 @@
} }
#pragma mark - Buttons Section #pragma mark - Buttons Section
- (UIButton *)buildCancelButton {
- (void)setupButtonSection {
self.buttonSection = [[UIView alloc] init];
self.buttonSection.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.buttonSection];
[NSLayoutConstraint activateConstraints:@[
[self.buttonSection.topAnchor constraintEqualToAnchor:self.summaryCard.bottomAnchor constant:30],
[self.buttonSection.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.buttonSection.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
[self.buttonSection.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-40],
[self.buttonSection.heightAnchor constraintEqualToConstant:200], // dynamic later
]];
UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom]; UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
cancelBtn.backgroundColor = [UIColor colorWithRed:1.0 green:0.45 blue:0.45 alpha:1]; cancelBtn.backgroundColor = [UIColor colorWithRed:1.0 green:0.45 blue:0.45 alpha:1];
cancelBtn.layer.cornerRadius = 12; cancelBtn.layer.cornerRadius = 12;
...@@ -355,19 +422,53 @@ ...@@ -355,19 +422,53 @@
[cancelBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [cancelBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
cancelBtn.translatesAutoresizingMaskIntoConstraints = NO; cancelBtn.translatesAutoresizingMaskIntoConstraints = NO;
[cancelBtn addTarget:self [cancelBtn addTarget:self
action:@selector(cancelPressed) action:@selector(cancelPressed)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
return cancelBtn;
}
- (void)setupButtonSection {
self.buttonSection = [[UIView alloc] init];
self.buttonSection.translatesAutoresizingMaskIntoConstraints = NO;
[self.summaryContainer addSubview:self.buttonSection];
UIButton *cancelBtn = [self buildCancelButton];
[self.buttonSection addSubview:cancelBtn]; [self.buttonSection addSubview:cancelBtn];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[self.buttonSection.topAnchor constraintEqualToAnchor:self.summaryCard.bottomAnchor constant:30],
[self.buttonSection.leadingAnchor constraintEqualToAnchor:self.summaryContainer.leadingAnchor],
[self.buttonSection.trailingAnchor constraintEqualToAnchor:self.summaryContainer.trailingAnchor],
[self.buttonSection.bottomAnchor constraintEqualToAnchor:self.summaryContainer.bottomAnchor constant:-50],
[cancelBtn.topAnchor constraintEqualToAnchor:self.buttonSection.topAnchor], [cancelBtn.topAnchor constraintEqualToAnchor:self.buttonSection.topAnchor],
[cancelBtn.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16], [cancelBtn.leadingAnchor constraintEqualToAnchor:self.summaryContainer.leadingAnchor constant:16],
[cancelBtn.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16], [cancelBtn.trailingAnchor constraintEqualToAnchor:self.summaryContainer.trailingAnchor constant:-16],
[cancelBtn.heightAnchor constraintEqualToConstant:55], [cancelBtn.heightAnchor constraintEqualToConstant:55],
]]; ]];
} }
- (void)setupOwnerInfoButtons {
UIView *ownerButtonSection = [[UIView alloc] init];
ownerButtonSection.translatesAutoresizingMaskIntoConstraints = NO;
[self.ownerInfoContainer addSubview:ownerButtonSection];
UIButton *cancelBtn2 = [self buildCancelButton];
[ownerButtonSection addSubview:cancelBtn2];
[NSLayoutConstraint activateConstraints:@[
[ownerButtonSection.topAnchor constraintEqualToAnchor:self.repCard.bottomAnchor constant:30],
[ownerButtonSection.leadingAnchor constraintEqualToAnchor:self.ownerInfoContainer.leadingAnchor],
[ownerButtonSection.trailingAnchor constraintEqualToAnchor:self.ownerInfoContainer.trailingAnchor],
[ownerButtonSection.bottomAnchor constraintEqualToAnchor:self.ownerInfoContainer.bottomAnchor constant:-50],
[cancelBtn2.topAnchor constraintEqualToAnchor:ownerButtonSection.topAnchor],
[cancelBtn2.leadingAnchor constraintEqualToAnchor:self.ownerInfoContainer.leadingAnchor constant:16],
[cancelBtn2.trailingAnchor constraintEqualToAnchor:self.ownerInfoContainer.trailingAnchor constant:-16],
[cancelBtn2.heightAnchor constraintEqualToConstant:55]
]];
}
#pragma mark - Loading Overlay #pragma mark - Loading Overlay
- (void)setupLoadingOverlay { - (void)setupLoadingOverlay {
...@@ -404,10 +505,11 @@ ...@@ -404,10 +505,11 @@
self.statusLabel.text = status; self.statusLabel.text = status;
self.reasonLabel.text = self.appointmentData[@"rejected_reason"]; self.reasonLabel.text = self.appointmentData[@"rejected_reason"];
// TODO: fill summary card fields self.typeField.text = [NSString stringWithFormat:@"Type : %@", self.appointmentData[@"appointment_type"]];
// TODO: fill representative card fields self.dateField.text = [NSString stringWithFormat:@"Date : %@", self.appointmentData[@"appointment_date"]];
// TODO: build action buttons based on status self.slotField.text = [NSString stringWithFormat:@"Time Slot : %@", self.appointmentData[@"appointment_time"]];
self.locField.text = [NSString stringWithFormat:@"Location : %@", self.appointmentData[@"location"]];
} }
#pragma mark - Actions #pragma mark - Actions
...@@ -416,14 +518,85 @@ ...@@ -416,14 +518,85 @@
[self.navigationController popViewControllerAnimated:YES]; [self.navigationController popViewControllerAnimated:YES];
} }
- (void) cancelPressed { #pragma mark - cancel button
// [AppointmentAPIClient fetch:self.appointmentID reason:something completion:^(NSDictionary *data, NSError *error) { - (void)cancelPressed {
// if (error) {
// NSLog(@"Error %@", error.localizedDescription); // STEP 1 — Confirmation alert
// return; UIAlertController *confirmAlert =
// } [UIAlertController alertControllerWithTitle:@"Cancel Appointment"
// }]; message:@"Are you sure you want to cancel this appointment?"
preferredStyle:UIAlertControllerStyleAlert];
// NO button — dismiss only
[confirmAlert addAction:[UIAlertAction actionWithTitle:@"No"
style:UIAlertActionStyleCancel
handler:nil]];
// YES button — go to step 2
[confirmAlert addAction:[UIAlertAction actionWithTitle:@"Yes"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action)
{
[self showReasonPopupForCancellation];
}]];
[self presentViewController:confirmAlert animated:YES completion:nil];
} }
- (void)showReasonPopupForCancellation {
UIAlertController *reasonAlert =
[UIAlertController alertControllerWithTitle:@"Reason for Cancellation"
message:@"Please tell us why you want to cancel this appointment."
preferredStyle:UIAlertControllerStyleAlert];
// Add text field
[reasonAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = @"Enter reason...";
}];
// CANCEL button — closes this popup only
[reasonAlert addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:nil]];
// OK button — execute API
[reasonAlert addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action)
{
NSString *remarks = reasonAlert.textFields.firstObject.text ?: @"";
[self sendCancellationRequestWithReason:remarks];
}]];
[self presentViewController:reasonAlert animated:YES completion:nil];
}
- (void)sendCancellationRequestWithReason:(NSString *)remarks {
if (remarks.length == 0) {
remarks = @"No reason provided";
}
[AppointmentAPIClient fetchCancelAppointment:self.appointmentID
reason:remarks
completion:^(NSDictionary *data, NSError *error)
{
if (error) {
NSLog(@"❌ Cancel Error: %@", error.localizedDescription);
return;
}
NSLog(@"✅ Appointment cancelled successfully.");
// Optional: close screen after cancel success
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
});
}];
}
@end @end
// DashboardViewController // DashboardViewController.h
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface DashboardViewController : UIViewController @interface DashboardViewController : UIViewController
@property (nonatomic, copy) NSString *ClientID;
@property (nonatomic, copy) NSString *ClientCode;
@property (nonatomic, copy) NSString *user_token;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
self.projectName = @"Ara E`Residence Dev"; self.projectName = @"Ara E`Residence Dev";
[self refreshDashboardContent]; [self refreshDashboardContent];
NSLog(@"in viewDidLoad ClientID: %@, ClientCode: %@, user_token: %@", self.ClientID, self.ClientCode, self.user_token);
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
...@@ -62,6 +63,7 @@ ...@@ -62,6 +63,7 @@
NSLog(@"Dashboard loaded, refreshing data"); NSLog(@"Dashboard loaded, refreshing data");
[self refreshDashboardContent]; [self refreshDashboardContent];
NSLog(@"in viewWillAppear ClientID: %@, ClientCode: %@, user_token: %@", self.ClientID, self.ClientCode, self.user_token);
} }
#pragma mark - Refresh Logic #pragma mark - Refresh Logic
...@@ -464,14 +466,6 @@ ...@@ -464,14 +466,6 @@
[[NSUserDefaults standardUserDefaults] synchronize]; [[NSUserDefaults standardUserDefaults] synchronize];
NSLog(@"✅ Stored %lu announcements", (unsigned long)sorted.count); NSLog(@"✅ Stored %lu announcements", (unsigned long)sorted.count);
// === Check for popup announcements ===
// for (NSDictionary *ann in sorted) {
// if ([ann[@"popup"] integerValue] == 1) {
// [self showPopupForAnnouncement:ann];
// break;
// }
// }
} }
- (void)refreshDashboardSectionsWithData:(NSDictionary *)mainData { - (void)refreshDashboardSectionsWithData:(NSDictionary *)mainData {
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
@interface QmsDashboardView : UIView @interface QmsDashboardView : UIView
@property (nonatomic, strong) UIViewController *dashboardVC; @property (nonatomic, strong) UIViewController *dashboardVC;
@property (nonatomic, assign) BOOL didSetupVC; @property (nonatomic, assign) BOOL didSetupVC;
// New props
@property (nonatomic, copy) NSString *ClientID;
@property (nonatomic, copy) NSString *ClientCode;
@property (nonatomic, copy) NSString *user_token;
@end @end
@implementation QmsDashboardView @implementation QmsDashboardView
...@@ -24,17 +28,54 @@ ...@@ -24,17 +28,54 @@
UIViewController *parentVC = [UIApplication sharedApplication].keyWindow.rootViewController; UIViewController *parentVC = [UIApplication sharedApplication].keyWindow.rootViewController;
if (parentVC) { if (parentVC) {
[parentVC addChildViewController:_dashboardVC]; [parentVC addChildViewController:_dashboardVC];
_dashboardVC.view.frame = parentVC.view.bounds; // Force full screen _dashboardVC.view.frame = parentVC.view.bounds;
_dashboardVC.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; _dashboardVC.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[parentVC.view addSubview:_dashboardVC.view]; // Add directly to root VC [parentVC.view addSubview:_dashboardVC.view];
[_dashboardVC didMoveToParentViewController:parentVC]; [_dashboardVC didMoveToParentViewController:parentVC];
_didSetupVC = YES; _didSetupVC = YES;
// Forward props once the VC is added
[self forwardPropsToVC];
} }
} }
} }
@end #pragma mark - Prop Setters
- (void)setClientID:(NSString *)ClientID {
_ClientID = [ClientID copy];
[self forwardProp:@"ClientID" value:_ClientID];
}
- (void)setClientCode:(NSString *)ClientCode {
_ClientCode = [ClientCode copy];
[self forwardProp:@"ClientCode" value:_ClientCode];
}
- (void)setUser_token:(NSString *)user_token {
_user_token = [user_token copy];
[self forwardProp:@"user_token" value:_user_token];
}
#pragma mark - Forward Props via KVC
- (void)forwardProp:(NSString *)key value:(NSString *)value {
if (_dashboardVC && [_dashboardVC respondsToSelector:NSSelectorFromString(key)]) {
@try {
[_dashboardVC setValue:value forKey:key];
} @catch (NSException *exception) {
NSLog(@"⚠️ Failed to set %@ on dashboardVC: %@", key, exception);
}
}
}
- (void)forwardPropsToVC {
[self forwardProp:@"ClientID" value:_ClientID];
[self forwardProp:@"ClientCode" value:_ClientCode];
[self forwardProp:@"user_token" value:_user_token];
}
@end
@interface QmsDashboardViewManager : RCTViewManager @interface QmsDashboardViewManager : RCTViewManager
@end @end
...@@ -47,4 +88,9 @@ RCT_EXPORT_MODULE(QmsDashboardView) ...@@ -47,4 +88,9 @@ RCT_EXPORT_MODULE(QmsDashboardView)
return [[QmsDashboardView alloc] init]; return [[QmsDashboardView alloc] init];
} }
// ✅ Export the props so JS can pass values
RCT_EXPORT_VIEW_PROPERTY(ClientID, NSString)
RCT_EXPORT_VIEW_PROPERTY(ClientCode, NSString)
RCT_EXPORT_VIEW_PROPERTY(user_token, NSString)
@end @end
...@@ -8,32 +8,32 @@ ...@@ -8,32 +8,32 @@
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64</string> <string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
<dict> <dict>
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string> <string>ios-arm64</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
</array> </array>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
......
...@@ -5,6 +5,9 @@ import type { ViewStyle } from 'react-native'; ...@@ -5,6 +5,9 @@ import type { ViewStyle } from 'react-native';
type Props = { type Props = {
style?: ViewStyle; style?: ViewStyle;
ClientID?: string;
ClientCode?: string;
user_token?: string;
}; };
const NativeQmsDashboardView = requireNativeComponent<Props>('QmsDashboardView'); const NativeQmsDashboardView = requireNativeComponent<Props>('QmsDashboardView');
......
...@@ -4,8 +4,3 @@ export { QmsDashboardView } from './QmsDashboardView'; ...@@ -4,8 +4,3 @@ export { QmsDashboardView } from './QmsDashboardView';
export function showPluginUI(): void { export function showPluginUI(): void {
QmsPlugin.showPluginUI(); QmsPlugin.showPluginUI();
} }
// export default {
// showPluginUI,
// QmsDashboardView,
// };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment