Commit 01266f51 authored by Wei Han's avatar Wei Han

code update

parent 7b821f42
nodeLinker: node-modules
nmHoistingLimits: workspaces nmHoistingLimits: workspaces
nodeLinker: node-modules
plugins: plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools" spec: "@yarnpkg/plugin-interactive-tools"
......
...@@ -1779,93 +1779,6 @@ PODS: ...@@ -1779,93 +1779,6 @@ PODS:
- React-RCTFBReactNativeSpec - React-RCTFBReactNativeSpec
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- react-native-safe-area-context (5.6.2):
- boost
- DoubleConversion
- fast_float
- fmt
- glog
- hermes-engine
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- react-native-safe-area-context/common (= 5.6.2)
- react-native-safe-area-context/fabric (= 5.6.2)
- React-NativeModulesApple
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- react-native-safe-area-context/common (5.6.2):
- boost
- DoubleConversion
- fast_float
- fmt
- glog
- hermes-engine
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- react-native-safe-area-context/fabric (5.6.2):
- boost
- DoubleConversion
- fast_float
- fmt
- glog
- hermes-engine
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- react-native-safe-area-context/common
- React-NativeModulesApple
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- React-NativeModulesApple (0.81.4): - React-NativeModulesApple (0.81.4):
- boost - boost
- DoubleConversion - DoubleConversion
...@@ -2417,7 +2330,6 @@ DEPENDENCIES: ...@@ -2417,7 +2330,6 @@ DEPENDENCIES:
- React-logger (from `../node_modules/react-native/ReactCommon/logger`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`) - React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`) - React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
- React-oscompat (from `../node_modules/react-native/ReactCommon/oscompat`) - React-oscompat (from `../node_modules/react-native/ReactCommon/oscompat`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
...@@ -2540,8 +2452,6 @@ EXTERNAL SOURCES: ...@@ -2540,8 +2452,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon" :path: "../node_modules/react-native/ReactCommon"
React-microtasksnativemodule: React-microtasksnativemodule:
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks" :path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
React-NativeModulesApple: React-NativeModulesApple:
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios"
React-oscompat: React-oscompat:
...@@ -2648,7 +2558,6 @@ SPEC CHECKSUMS: ...@@ -2648,7 +2558,6 @@ SPEC CHECKSUMS:
React-logger: 1767babce2d28c3251039ce05556714a2c8c6ded React-logger: 1767babce2d28c3251039ce05556714a2c8c6ded
React-Mapbuffer: 33f678ee25b6c0ee2b01b1ecec08e3e02424cefe React-Mapbuffer: 33f678ee25b6c0ee2b01b1ecec08e3e02424cefe
React-microtasksnativemodule: 44b44a4d3cd6ffb85d928abf741acdc26722de2e React-microtasksnativemodule: 44b44a4d3cd6ffb85d928abf741acdc26722de2e
react-native-safe-area-context: 54d812805f3c4e08a4580ad086cbde1d8780c2e4
React-NativeModulesApple: b5d18bc109c45c9a1c6b71664991b5cc3adc4e48 React-NativeModulesApple: b5d18bc109c45c9a1c6b71664991b5cc3adc4e48
React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d
React-perflogger: a03d913e3205b00aee4128082abe42fd45ce0c98 React-perflogger: a03d913e3205b00aee4128082abe42fd45ce0c98
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
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 */; };
AFC1B725D41173F56B62FA3B /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F2A6CDBD96A29E1979EF0BD3 /* libPods-example.a */; }; A9347BA1DEB0869A7449D25A /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 62D3056EB1529798F78D8AAE /* 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>"; };
5C8BADDA6881DBD3E3FFBD0E /* 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>"; };
62D3056EB1529798F78D8AAE /* 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>"; };
9585DFA7130596921EB0F5A6 /* 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>"; }; 9C044A90156FCEF85786783C /* 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>"; };
C92BFB68E35543E7EF3282FC /* 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; };
F2A6CDBD96A29E1979EF0BD3 /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* 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 = (
AFC1B725D41173F56B62FA3B /* libPods-example.a in Frameworks */, A9347BA1DEB0869A7449D25A /* 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 */,
F2A6CDBD96A29E1979EF0BD3 /* libPods-example.a */, 62D3056EB1529798F78D8AAE /* 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 = (
C92BFB68E35543E7EF3282FC /* Pods-example.debug.xcconfig */, 9C044A90156FCEF85786783C /* Pods-example.debug.xcconfig */,
9585DFA7130596921EB0F5A6 /* Pods-example.release.xcconfig */, 5C8BADDA6881DBD3E3FFBD0E /* 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 = (
94C2598371F476B4E1E60F33 /* [CP] Check Pods Manifest.lock */, 309150C9AAFDB30830CFACCC /* [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 */,
97557091BD8C2C7B4B6F7AD4 /* [CP] Embed Pods Frameworks */, 82D720B7A901D1E9C13BE9D2 /* [CP] Embed Pods Frameworks */,
052C3E3D9666B087C0F21867 /* [CP] Copy Pods Resources */, 9C3136C3E0FC26587EC44C8F /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
...@@ -183,24 +183,7 @@ ...@@ -183,24 +183,7 @@
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";
}; };
052C3E3D9666B087C0F21867 /* [CP] Copy Pods Resources */ = { 309150C9AAFDB30830CFACCC /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
94C2598371F476B4E1E60F33 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
...@@ -222,7 +205,7 @@ ...@@ -222,7 +205,7 @@
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 = "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;
}; };
97557091BD8C2C7B4B6F7AD4 /* [CP] Embed Pods Frameworks */ = { 82D720B7A901D1E9C13BE9D2 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
...@@ -239,6 +222,23 @@ ...@@ -239,6 +222,23 @@
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;
}; };
9C3136C3E0FC26587EC44C8F /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
...@@ -255,7 +255,7 @@ ...@@ -255,7 +255,7 @@
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = { 13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = C92BFB68E35543E7EF3282FC /* Pods-example.debug.xcconfig */; baseConfigurationReference = 9C044A90156FCEF85786783C /* 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 = 9585DFA7130596921EB0F5A6 /* Pods-example.release.xcconfig */; baseConfigurationReference = 5C8BADDA6881DBD3E3FFBD0E /* Pods-example.release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
@interface AccessAppointmentViewController : UIViewController @interface AccessAppointmentViewController : UIViewController
@property (nonatomic, strong) NSDictionary *appointmentData; @property (nonatomic, strong) NSDictionary *appointmentData;
@property (nonatomic, strong) NSString *unitID;
@property (nonatomic, strong) NSString *unitName;
@end @end
// AccessAppointmentViewController.mm // AccessAppointmentViewController.mm
#import "AccessAppointmentViewController.h" #import "AccessAppointmentViewController.h"
#import <EventKit/EventKit.h>
#import "AppointmentAPIClient.h"
@interface AccessAppointmentViewController () @interface AccessAppointmentViewController ()
...@@ -17,6 +19,7 @@ ...@@ -17,6 +19,7 @@
@property (nonatomic, strong) UILabel *dateValueLabel; @property (nonatomic, strong) UILabel *dateValueLabel;
@property (nonatomic, strong) UILabel *timeValueLabel; @property (nonatomic, strong) UILabel *timeValueLabel;
@property (nonatomic, strong) UILabel *issuesLabel; @property (nonatomic, strong) UILabel *issuesLabel;
@property (nonatomic, strong) UILabel *issuesTitle;
// Buttons // Buttons
@property (nonatomic, strong) UIButton *cancelButton; @property (nonatomic, strong) UIButton *cancelButton;
...@@ -37,7 +40,6 @@ ...@@ -37,7 +40,6 @@
[self setupScrollView]; [self setupScrollView];
[self setupUnitSection]; [self setupUnitSection];
[self setupAppointmentCard]; [self setupAppointmentCard];
[self setupIssuesSection];
[self setupActionButtonsIfNeeded]; [self setupActionButtonsIfNeeded];
// Fill data // Fill data
...@@ -151,47 +153,68 @@ ...@@ -151,47 +153,68 @@
self.cardView.layer.shadowOffset = CGSizeMake(0, 3); self.cardView.layer.shadowOffset = CGSizeMake(0, 3);
[self.contentView addSubview:self.cardView]; [self.contentView addSubview:self.cardView];
// Title // --- Title ---
UILabel *title = [[UILabel alloc] init]; UILabel *title = [[UILabel alloc] init];
title.translatesAutoresizingMaskIntoConstraints = NO; title.translatesAutoresizingMaskIntoConstraints = NO;
title.text = @"Appointment Info"; title.text = @"Appointment Info";
title.font = [UIFont boldSystemFontOfSize:18]; title.font = [UIFont boldSystemFontOfSize:18];
[self.cardView addSubview:title]; [self.cardView addSubview:title];
// Type label + pill // --- Type ---
UILabel *typeLabel = [self lightLabelWithText:@"Type :"]; UILabel *typeLabel = [self lightLabelWithText:@"Type :"];
[self.cardView addSubview:typeLabel]; [self.cardView addSubview:typeLabel];
self.typeValueLabel = [self pillLabel:@"Rectification"]; self.typeValueLabel = [self pillLabel:@"Rectification"];
[self.cardView addSubview:self.typeValueLabel]; [self.cardView addSubview:self.typeValueLabel];
// Calendar button (right) // --- Calendar button ---
self.calendarButton = [self calendarBoxButton]; self.calendarButton = [self calendarBoxButton];
[self.cardView addSubview:self.calendarButton]; [self.cardView addSubview:self.calendarButton];
// Date // --- Date ---
UILabel *dateLabel = [self lightLabelWithText:@"Date :"]; UILabel *dateLabel = [self lightLabelWithText:@"Date :"];
[self.cardView addSubview:dateLabel]; [self.cardView addSubview:dateLabel];
self.dateValueLabel = [self regularLabelWithText:@"--"]; self.dateValueLabel = [self regularLabelWithText:@"--"];
[self.cardView addSubview:self.dateValueLabel]; [self.cardView addSubview:self.dateValueLabel];
// Time // --- Time ---
UILabel *timeLabel = [self lightLabelWithText:@"Time Slot :"]; UILabel *timeLabel = [self lightLabelWithText:@"Time Slot :"];
[self.cardView addSubview:timeLabel]; [self.cardView addSubview:timeLabel];
self.timeValueLabel = [self regularLabelWithText:@"--"]; self.timeValueLabel = [self regularLabelWithText:@"--"];
[self.cardView addSubview:self.timeValueLabel]; [self.cardView addSubview:self.timeValueLabel];
// Layout constraints // --- Issues section (stack view) ---
self.issuesTitle = [[UILabel alloc] init];
self.issuesTitle.translatesAutoresizingMaskIntoConstraints = NO;
self.issuesTitle.text = @"Issue(s) Info";
self.issuesTitle.font = [UIFont boldSystemFontOfSize:18];
self.issuesLabel = [self regularLabelWithText:@"--"];
self.issuesLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.issuesLabel.numberOfLines = 0;
UIStackView *issuesStack = [[UIStackView alloc] init];
issuesStack.translatesAutoresizingMaskIntoConstraints = NO;
issuesStack.axis = UILayoutConstraintAxisVertical;
issuesStack.spacing = 6;
[issuesStack addArrangedSubview:self.issuesTitle];
[issuesStack addArrangedSubview:self.issuesLabel];
[self.cardView addSubview:issuesStack];
// --- Layout constraints ---
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
// Card position
[self.cardView.topAnchor constraintEqualToAnchor:self.unitLine.bottomAnchor constant:18], [self.cardView.topAnchor constraintEqualToAnchor:self.unitLine.bottomAnchor constant:18],
[self.cardView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16], [self.cardView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[self.cardView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16], [self.cardView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
// Title
[title.topAnchor constraintEqualToAnchor:self.cardView.topAnchor constant:16], [title.topAnchor constraintEqualToAnchor:self.cardView.topAnchor constant:16],
[title.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16], [title.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16],
// Type
[typeLabel.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:18], [typeLabel.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:18],
[typeLabel.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16], [typeLabel.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16],
...@@ -203,55 +226,34 @@ ...@@ -203,55 +226,34 @@
[self.calendarButton.widthAnchor constraintEqualToConstant:92], [self.calendarButton.widthAnchor constraintEqualToConstant:92],
[self.calendarButton.heightAnchor constraintEqualToConstant:46], [self.calendarButton.heightAnchor constraintEqualToConstant:46],
// Date
[dateLabel.topAnchor constraintEqualToAnchor:typeLabel.bottomAnchor constant:18], [dateLabel.topAnchor constraintEqualToAnchor:typeLabel.bottomAnchor constant:18],
[dateLabel.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16], [dateLabel.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16],
[self.dateValueLabel.centerYAnchor constraintEqualToAnchor:dateLabel.centerYAnchor], [self.dateValueLabel.centerYAnchor constraintEqualToAnchor:dateLabel.centerYAnchor],
[self.dateValueLabel.leadingAnchor constraintEqualToAnchor:dateLabel.trailingAnchor constant:8], [self.dateValueLabel.leadingAnchor constraintEqualToAnchor:dateLabel.trailingAnchor constant:8],
// Time
[timeLabel.topAnchor constraintEqualToAnchor:dateLabel.bottomAnchor constant:14], [timeLabel.topAnchor constraintEqualToAnchor:dateLabel.bottomAnchor constant:14],
[timeLabel.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16], [timeLabel.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16],
[self.timeValueLabel.centerYAnchor constraintEqualToAnchor:timeLabel.centerYAnchor], [self.timeValueLabel.centerYAnchor constraintEqualToAnchor:timeLabel.centerYAnchor],
[self.timeValueLabel.leadingAnchor constraintEqualToAnchor:timeLabel.trailingAnchor constant:8], [self.timeValueLabel.leadingAnchor constraintEqualToAnchor:timeLabel.trailingAnchor constant:8],
// bottom anchor of card (provides contentView sizing) // Issues stack
[self.timeValueLabel.bottomAnchor constraintEqualToAnchor:self.cardView.bottomAnchor constant:-18] [issuesStack.topAnchor constraintEqualToAnchor:self.timeValueLabel.bottomAnchor constant:16],
]]; [issuesStack.leadingAnchor constraintEqualToAnchor:self.cardView.leadingAnchor constant:16],
} [issuesStack.trailingAnchor constraintEqualToAnchor:self.cardView.trailingAnchor constant:-16],
[issuesStack.bottomAnchor constraintEqualToAnchor:self.cardView.bottomAnchor constant:-16]
#pragma mark - Issues section
- (void)setupIssuesSection {
UILabel *title = [[UILabel alloc] init];
title.translatesAutoresizingMaskIntoConstraints = NO;
title.text = @"Issue(s) Info";
title.font = [UIFont boldSystemFontOfSize:18];
[self.contentView addSubview:title];
self.issuesLabel = [self regularLabelWithText:@"--"];
self.issuesLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.issuesLabel.numberOfLines = 0;
[self.contentView addSubview:self.issuesLabel];
[NSLayoutConstraint activateConstraints:@[
[title.topAnchor constraintEqualToAnchor:self.cardView.bottomAnchor constant:20],
[title.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[self.issuesLabel.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:10],
[self.issuesLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[self.issuesLabel.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
[self.issuesLabel.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-30]
]]; ]];
} }
#pragma mark - Action Buttons (Cancel + optional) #pragma mark - Action Buttons (Cancel + optional)
- (void)setupActionButtonsIfNeeded { - (void)setupActionButtonsIfNeeded {
// If you always want to show cancel, set this to YES. Otherwise compute based on date/status. NSString *status = self.appointmentData[@"appointment_status"];
BOOL shouldShowCancel = NO; // default: no
// If appointmentData includes a "can_cancel" key, respect it: // Only show cancel button if status is "Confirmed"
if (self.appointmentData[@"can_cancel"]) { BOOL shouldShowCancel = [status isEqualToString:@"Confirmed"];
shouldShowCancel = [self.appointmentData[@"can_cancel"] boolValue];
}
if (!shouldShowCancel) return; if (!shouldShowCancel) return;
...@@ -281,28 +283,44 @@ ...@@ -281,28 +283,44 @@
// appointmentData expected keys: unit_no, type, date, time_slot, issues // appointmentData expected keys: unit_no, type, date, time_slot, issues
if (self.appointmentData == nil) return; if (self.appointmentData == nil) return;
NSString *unitNo = self.appointmentData[@"unit_no"] ?: @"--"; NSString *unitNo = self.unitID ?: @"--";
self.unitLabel.text = unitNo; self.unitLabel.text = unitNo;
NSString *type = self.appointmentData[@"type"] ?: @"Rectification"; NSString *type = self.appointmentData[@"type"] ?: @"Rectification";
self.typeValueLabel.text = type; self.typeValueLabel.text = type;
// date parsing: accepts yyyy-MM-dd or server format; fallback to raw string // date parsing: accepts yyyy-MM-dd or server format; fallback to raw string
NSString *rawDate = self.appointmentData[@"date"]; NSString *rawDate = self.appointmentData[@"appointment_date"];
if (rawDate) { if (rawDate) {
NSString *formatted = [self formattedDateStringFromRaw:rawDate]; NSString *formatted = [self formattedDateStringFromRaw:rawDate];
self.dateValueLabel.text = formatted; self.dateValueLabel.text = formatted;
} }
NSString *timeSlot = self.appointmentData[@"time_slot"] ?: self.appointmentData[@"time"] ?: @"--"; NSString *timeSlot = self.appointmentData[@"appointment_time"] ?: @"--";
self.timeValueLabel.text = timeSlot; self.timeValueLabel.text = timeSlot;
NSString *issues = self.appointmentData[@"issues"]; NSArray *issuesArray = self.appointmentData[@"Issues"];
if (!issues && self.appointmentData[@"issue_list"]) { if (!issuesArray || issuesArray.count == 0) {
NSArray *arr = self.appointmentData[@"issue_list"]; self.issuesTitle.hidden = YES;
issues = [arr componentsJoinedByString:@"\n"]; self.issuesLabel.hidden = YES;
NSLog(@"Hiding Issues");
} else {
self.issuesTitle.hidden = NO;
self.issuesLabel.hidden = NO;
NSLog(@"Showing issues");
NSMutableArray *refs = [NSMutableArray array];
NSMutableArray *numLines = [NSMutableArray array];
NSInteger idx = 1;
for (NSDictionary *issueDict in issuesArray) {
NSString *ref = issueDict[@"reference"];
if (ref) {
[numLines addObject:[NSString stringWithFormat:@"%ld. %@", (long)idx, ref]];
idx++;
}
}
self.issuesLabel.text = [numLines componentsJoinedByString:@"\n"];
} }
self.issuesLabel.text = issues ?: @"No issues specified";
} }
#pragma mark - Helpers / UI helpers #pragma mark - Helpers / UI helpers
...@@ -398,12 +416,59 @@ ...@@ -398,12 +416,59 @@
} }
- (void)addToCalendarTapped { - (void)addToCalendarTapped {
// Hook: create event using EventKit if you want EKEventStore *eventStore = [[EKEventStore alloc] init];
UIAlertController *a = [UIAlertController alertControllerWithTitle:@"Add to Calendar"
message:@"Calendar integration not implemented yet." // Request access to Calendar
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
// Set title
NSString *title = [NSString stringWithFormat:@"[%@] %@: %@.",
self.appointmentData[@"project_name"],
self.appointmentData[@"unit_no"],
self.appointmentData[@"appointment_type"]];
event.title = title;
// Set start & end dates
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"dd MMM yyyy hh:mm a";
NSString *startString = [NSString stringWithFormat:@"%@ %@",
self.appointmentData[@"appointment_date"],
self.appointmentData[@"appointment_time"]];
event.startDate = [formatter dateFromString:startString];
// Add to default calendar
event.calendar = [eventStore defaultCalendarForNewEvents];
NSError *err = nil;
[eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
if (err) {
NSLog(@"❌ Error saving event: %@", err);
} else {
NSLog(@"✅ Event saved successfully");
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Success"
message:@"Event added to Calendar"
preferredStyle:UIAlertControllerStyleAlert]; preferredStyle:UIAlertControllerStyleAlert];
[a addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:a animated:YES completion:nil]; [self presentViewController:alert animated:YES completion:nil];
}
});
} else {
NSLog(@"❌ Calendar permission not granted: %@", error);
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Permission Denied"
message:@"Enable Calendar access in Settings"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
});
}
}];
} }
- (void)cancelPressed { - (void)cancelPressed {
...@@ -437,24 +502,48 @@ ...@@ -437,24 +502,48 @@
} }
- (void)sendCancellationRequestWithReason:(NSString *)remarks { - (void)sendCancellationRequestWithReason:(NSString *)remarks {
if (remarks.length == 0) remarks = @"No reason provided";
if (remarks.length == 0) {
remarks = @"No reason provided";
}
if (!self.appointmentData[@"id"]) { if (!self.appointmentData[@"id"]) {
NSLog(@"No appointment id, aborting cancellation"); NSLog(@"❌ Cannot cancel appointment: appointmentID is nil");
return; return;
} }
// call API - placeholder [AppointmentAPIClient fetchCancelAppointment:self.appointmentData[@"appointment_id"]
// [AppointmentAPIClient fetchCancelAppointment:self.appointmentData[@"id"] reason:remarks completion:...] reason:remarks
// For now simulate success: completion:^(NSDictionary *data, NSError *error)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ {
UIAlertController *status = [UIAlertController alertControllerWithTitle:@"Appointment Cancelled" dispatch_async(dispatch_get_main_queue(), ^{
message:@"Your appointment has been cancelled."
NSString *title;
NSString *message;
if (error) {
title = @"Cancellation Failed";
message = error.localizedDescription ?: @"An unknown error occurred.";
} else {
title = @"Appointment Cancelled";
message = @"Your appointment has been successfully cancelled.";
}
UIAlertController *statusAlert =
[UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert]; preferredStyle:UIAlertControllerStyleAlert];
[status addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[statusAlert addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
// Optional: dismiss this screen if you want after user taps OK
[self dismissViewControllerAnimated:YES completion:nil]; [self dismissViewControllerAnimated:YES completion:nil];
}]]; }]];
[self presentViewController:status animated:YES completion:nil];
[self presentViewController:statusAlert animated:YES completion:nil];
}); });
}];
} }
@end @end
...@@ -434,6 +434,8 @@ ...@@ -434,6 +434,8 @@
if ([item[@"status"] isEqualToString:@"Rectification Appointment"]) { if ([item[@"status"] isEqualToString:@"Rectification Appointment"]) {
AccessAppointmentViewController *vc = [[AccessAppointmentViewController alloc] init]; AccessAppointmentViewController *vc = [[AccessAppointmentViewController alloc] init];
vc.appointmentData = item; vc.appointmentData = item;
vc.unitID = self.unitID;
vc.unitName = self.unitName;
vc.modalPresentationStyle = UIModalPresentationFullScreen; vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:vc animated:YES completion:nil]; [self presentViewController:vc animated:YES completion:nil];
} else { } else {
......
...@@ -193,32 +193,42 @@ ...@@ -193,32 +193,42 @@
} }
- (UIView *)createTableHeader { - (UIView *)createTableHeader {
CGFloat headerHeight = 40;
NSArray *titles = @[@"No.", @"Item", @"Possession", @"Qty."]; NSArray *titles = @[@"No.", @"Item", @"Possession", @"Qty."];
CGFloat flexes[] = {0.7, 1.3, 1.3, 0.7}; // React Native style CGFloat flexes[] = {0.7, 1.3, 1.3, 0.7};
CGFloat totalFlex = 0.7 + 1.3 + 1.3 + 0.7;
CGFloat spacing = 12;
UIView *header = [[UIView alloc] init]; UIView *header = [[UIView alloc] init];
header.backgroundColor = UIColor.blackColor; header.backgroundColor = UIColor.blackColor;
header.translatesAutoresizingMaskIntoConstraints = NO;
UILabel *prev = nil; UIView *container = [[UIView alloc] init];
CGFloat totalFlex = 0.7 + 1.3 + 1.3 + 0.7; container.translatesAutoresizingMaskIntoConstraints = NO;
[header addSubview:container];
// Pin container edges to header
[NSLayoutConstraint activateConstraints:@[
[container.topAnchor constraintEqualToAnchor:header.topAnchor],
[container.leadingAnchor constraintEqualToAnchor:header.leadingAnchor],
[container.trailingAnchor constraintEqualToAnchor:header.trailingAnchor],
[container.bottomAnchor constraintEqualToAnchor:header.bottomAnchor]
]];
UILabel *prev = nil;
for (int i = 0; i < titles.count; i++) { for (int i = 0; i < titles.count; i++) {
UILabel *lbl = [self createHeaderLabel:titles[i]]; UILabel *lbl = [self createHeaderLabel:titles[i]];
[header addSubview:lbl];
lbl.translatesAutoresizingMaskIntoConstraints = NO; lbl.translatesAutoresizingMaskIntoConstraints = NO;
[container addSubview:lbl];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[lbl.topAnchor constraintEqualToAnchor:header.topAnchor constant:12], [lbl.topAnchor constraintEqualToAnchor:container.topAnchor constant:spacing],
[lbl.bottomAnchor constraintEqualToAnchor:header.bottomAnchor constant:-12], [lbl.bottomAnchor constraintEqualToAnchor:container.bottomAnchor constant:-spacing],
[lbl.widthAnchor constraintEqualToAnchor:header.widthAnchor multiplier:flexes[i]/totalFlex] [lbl.widthAnchor constraintEqualToAnchor:container.widthAnchor multiplier:flexes[i]/totalFlex]
]]; ]];
if (prev) { if (prev) {
[lbl.leadingAnchor constraintEqualToAnchor:prev.trailingAnchor].active = YES; [lbl.leadingAnchor constraintEqualToAnchor:prev.trailingAnchor].active = YES;
} else { } else {
[lbl.leadingAnchor constraintEqualToAnchor:header.leadingAnchor].active = YES; [lbl.leadingAnchor constraintEqualToAnchor:container.leadingAnchor].active = YES;
} }
prev = lbl; prev = lbl;
...@@ -227,18 +237,22 @@ ...@@ -227,18 +237,22 @@
UIView *sep = [[UIView alloc] init]; UIView *sep = [[UIView alloc] init];
sep.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0]; sep.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
sep.translatesAutoresizingMaskIntoConstraints = NO; sep.translatesAutoresizingMaskIntoConstraints = NO;
[header addSubview:sep]; [container addSubview:sep];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[sep.widthAnchor constraintEqualToConstant:0.5], [sep.widthAnchor constraintEqualToConstant:0.5],
[sep.topAnchor constraintEqualToAnchor:header.topAnchor constant:12], [sep.topAnchor constraintEqualToAnchor:container.topAnchor constant:spacing],
[sep.bottomAnchor constraintEqualToAnchor:header.bottomAnchor constant:-12], [sep.bottomAnchor constraintEqualToAnchor:container.bottomAnchor constant:-spacing],
[sep.leadingAnchor constraintEqualToAnchor:lbl.trailingAnchor] [sep.leadingAnchor constraintEqualToAnchor:lbl.trailingAnchor]
]]; ]];
} }
} }
// Force intrinsic height // Force header height dynamically
[header.heightAnchor constraintEqualToConstant:headerHeight].active = YES; [header layoutIfNeeded];
CGFloat height = [header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
header.frame = CGRectMake(0, 0, self.itemsTable.frame.size.width, height);
return header; return header;
} }
...@@ -342,6 +356,13 @@ ...@@ -342,6 +356,13 @@
submittedSignature.translatesAutoresizingMaskIntoConstraints = NO; submittedSignature.translatesAutoresizingMaskIntoConstraints = NO;
submittedSignature.contentMode = UIViewContentModeScaleAspectFit; submittedSignature.contentMode = UIViewContentModeScaleAspectFit;
submittedSignature.clipsToBounds = YES; submittedSignature.clipsToBounds = YES;
submittedSignature.layer.borderColor = UIColor.blackColor.CGColor;
submittedSignature.layer.borderWidth = 1.0;
submittedSignature.layer.cornerRadius = 4.0; // optional rounded corners
submittedSignature.clipsToBounds = YES;
submittedSignature.userInteractionEnabled = YES;
UITapGestureRecognizer *tapSubmitted = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapSignature:)];
[submittedSignature addGestureRecognizer:tapSubmitted];
NSURL *submittedURL = [NSURL URLWithString:self.transactionData[@"signature_submit"]]; NSURL *submittedURL = [NSURL URLWithString:self.transactionData[@"signature_submit"]];
if (submittedURL) { if (submittedURL) {
// Simple async load // Simple async load
...@@ -371,6 +392,13 @@ ...@@ -371,6 +392,13 @@
receivedSignature.translatesAutoresizingMaskIntoConstraints = NO; receivedSignature.translatesAutoresizingMaskIntoConstraints = NO;
receivedSignature.contentMode = UIViewContentModeScaleAspectFit; receivedSignature.contentMode = UIViewContentModeScaleAspectFit;
receivedSignature.clipsToBounds = YES; receivedSignature.clipsToBounds = YES;
receivedSignature.layer.borderColor = UIColor.blackColor.CGColor;
receivedSignature.layer.borderWidth = 1.0;
receivedSignature.layer.cornerRadius = 4.0;
receivedSignature.clipsToBounds = YES;
receivedSignature.userInteractionEnabled = YES;
UITapGestureRecognizer *tapReceived = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapSignature:)];
[receivedSignature addGestureRecognizer:tapReceived];
NSURL *receivedURL = [NSURL URLWithString:self.transactionData[@"signature_receive"]]; NSURL *receivedURL = [NSURL URLWithString:self.transactionData[@"signature_receive"]];
if (receivedURL) { if (receivedURL) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
...@@ -435,6 +463,44 @@ ...@@ -435,6 +463,44 @@
]]; ]];
} }
- (void)onTapSignature:(UITapGestureRecognizer *)sender {
UIImageView *imgView = (UIImageView *)sender.view;
if (!imgView.image) return;
// Create full-screen viewer
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = UIColor.blackColor;
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:vc.view.bounds];
scroll.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
scroll.minimumZoomScale = 1.0;
scroll.maximumZoomScale = 3.0;
scroll.delegate = (id<UIScrollViewDelegate>)self;
[vc.view addSubview:scroll];
UIImageView *zoomImage = [[UIImageView alloc] initWithImage:imgView.image];
zoomImage.frame = scroll.bounds;
zoomImage.contentMode = UIViewContentModeScaleAspectFit;
zoomImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[scroll addSubview:zoomImage];
// Tag to identify for zoom delegate
zoomImage.tag = 100;
UITapGestureRecognizer *dismissTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissViewer)];
[vc.view addGestureRecognizer:dismissTap];
// Present full-screen
[self presentViewController:vc animated:YES completion:nil];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return [scrollView viewWithTag:100];
}
- (void)dismissViewer {
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Table #pragma mark - Table
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
......
...@@ -566,7 +566,7 @@ ...@@ -566,7 +566,7 @@
NSString *title = [NSString stringWithFormat:@"[%@] %@: %@.", NSString *title = [NSString stringWithFormat:@"[%@] %@: %@.",
self.appointmentData[@"project_name"], self.appointmentData[@"project_name"],
self.appointmentData[@"unit_no"], self.appointmentData[@"unit_no"],
self.appointmentData[@"appointment_type"]]; self.appointmentData[@"status"]];
event.title = title; event.title = title;
// Set start & end dates // Set start & end dates
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -4038,11 +4038,11 @@ __metadata: ...@@ -4038,11 +4038,11 @@ __metadata:
"QmsPlugin@file:../::locator=qms-plugin-example%40workspace%3Aexample": "QmsPlugin@file:../::locator=qms-plugin-example%40workspace%3Aexample":
version: 0.1.0 version: 0.1.0
resolution: "QmsPlugin@file:../#../::hash=af21c5&locator=qms-plugin-example%40workspace%3Aexample" resolution: "QmsPlugin@file:../#../::hash=0b253a&locator=qms-plugin-example%40workspace%3Aexample"
peerDependencies: peerDependencies:
react: "*" react: "*"
react-native: "*" react-native: "*"
checksum: 62359d48e334f58417817ce08cbadbc903d955edfcec23fcd1f25e51a95155b0465958c08490b7333e72f4e1272fd5bd0678dd812a5805f8c5daeb7d6c891213 checksum: fe5001e87d7c2eb94dc2b5f47a53c81c9c7490a0a9f313c06aa692f505b29f6195b231247c92bfd7baa6b530ec534e88f12c379bcdbf69742ef3bf00a35ea729
languageName: node languageName: node
linkType: hard linkType: hard
......
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