Commit 3995f152 authored by Wei Han's avatar Wei Han

code update

parent 91919501
......@@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</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>
<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>
</array>
<key>CFBundlePackageType</key>
......
......@@ -16,7 +16,7 @@
#import "APIConfig.h"
#import "ImageCacheHelper.h"
@interface DashboardViewController ()
@interface DashboardViewController () <UIScrollViewDelegate>
@property (nonatomic, strong) NSArray *appointments;
@property (nonatomic, strong) NSArray *issues;
......@@ -44,11 +44,14 @@
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UIStackView *contentContainer;
@property (nonatomic, strong) UIView *inspectionBanner;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *contentView;
@property (nonatomic, strong) UIView *stickyBar;
@end
@implementation DashboardViewController {
UIScrollView *_scrollView;
NSMutableDictionary *_sectionViews;
CGFloat _currentY;
}
......@@ -57,7 +60,8 @@
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0];
_sectionViews = [NSMutableDictionary dictionary];
[self setupScrollView];
[self setupStickyBar];
[self setupHeader];
[self setupScrollContent];
[self setupFooter];
......@@ -66,7 +70,7 @@
NSLog(@"dashboard.drawerController = %@", self.drawerController);
// [[OfflineSyncManager shared] clearOfflineQueue];
//[[OfflineSyncManager shared] clearOfflineQueue];
}
- (void)viewWillAppear:(BOOL)animated {
......@@ -125,35 +129,95 @@
}
#pragma mark - Layout
- (void)viewDidLayoutSubviews {
NSLog(@"Header frame: %@", NSStringFromCGRect(_headerView.frame));
[super viewDidLayoutSubviews];
UIView *footerView = self.view.subviews.lastObject;
CGFloat footerHeight = 80.0;
CGFloat bottomInset = self.view.safeAreaInsets.bottom;
footerView.frame = CGRectMake(
0,
self.view.bounds.size.height - footerHeight - bottomInset,
self.view.bounds.size.width,
footerHeight + bottomInset
);
}
//- (void)viewDidLayoutSubviews {
// NSLog(@"Header frame: %@", NSStringFromCGRect(_headerView.frame));
// [super viewDidLayoutSubviews];
// UIView *footerView = self.view.subviews.lastObject;
// CGFloat footerHeight = 80.0;
// CGFloat bottomInset = self.view.safeAreaInsets.bottom;
// footerView.frame = CGRectMake(
// 0,
// self.view.bounds.size.height - footerHeight - bottomInset,
// self.view.bounds.size.width,
// footerHeight + bottomInset
// );
//}
#pragma mark - Header
- (void)setupStickyBar {
self.stickyBar = [[UIView alloc] init];
self.stickyBar.translatesAutoresizingMaskIntoConstraints = NO;
self.stickyBar.backgroundColor = [UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:0]; // start fully transparent
[self.view addSubview:self.stickyBar];
[NSLayoutConstraint activateConstraints:@[
[self.stickyBar.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.stickyBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.stickyBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.stickyBar.heightAnchor constraintEqualToConstant:44]
]];
// Back button
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"]
forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
[self.backButton addTarget:self action:@selector(onBack)
forControlEvents:UIControlEventTouchUpInside];
[self.stickyBar addSubview:self.backButton];
// Menu button
UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
menuButton.translatesAutoresizingMaskIntoConstraints = NO;
[menuButton setImage:[UIImage systemImageNamed:@"line.horizontal.3"]
forState:UIControlStateNormal];
menuButton.tintColor = UIColor.whiteColor;
[menuButton addTarget:self
action:@selector(handleMenuButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
[self.stickyBar addSubview:menuButton];
[NSLayoutConstraint activateConstraints:@[
[self.backButton.leadingAnchor constraintEqualToAnchor:self.stickyBar.leadingAnchor constant:8],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.stickyBar.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:24],
[self.backButton.heightAnchor constraintEqualToConstant:24],
[menuButton.trailingAnchor constraintEqualToAnchor:self.stickyBar.trailingAnchor constant:-16],
[menuButton.centerYAnchor constraintEqualToAnchor:self.stickyBar.centerYAnchor],
[menuButton.widthAnchor constraintEqualToConstant:26],
[menuButton.heightAnchor constraintEqualToConstant:26],
]];
UIView *statusBarBackground = [[UIView alloc] init];
statusBarBackground.translatesAutoresizingMaskIntoConstraints = NO;
statusBarBackground.backgroundColor =
[UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:1.0];
[self.view insertSubview:statusBarBackground aboveSubview:self.scrollView];
[NSLayoutConstraint activateConstraints:@[
[statusBarBackground.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[statusBarBackground.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[statusBarBackground.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[statusBarBackground.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
]];
}
- (void)setupHeader {
CGFloat headerHeight = 220.0;
CGFloat maxImageHeight = 220.0;
CGFloat headerHeight = 255.0;
CGFloat maxImageHeight = 255.0;
// ---------- Header Container ----------
self.headerView = [[UIView alloc] init];
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
self.headerView.backgroundColor = [UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:1.0];
[self.view addSubview:self.headerView];
[self.contentView addSubview:self.headerView];
[NSLayoutConstraint activateConstraints:@[
[self.headerView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
[self.headerView.heightAnchor constraintEqualToConstant:headerHeight]
]];
......@@ -188,7 +252,7 @@
self.overlayImageView.translatesAutoresizingMaskIntoConstraints = NO;
self.overlayImageView.contentMode = UIViewContentModeScaleToFill;
self.overlayImageView.userInteractionEnabled = NO;
self.overlayImageView.alpha = 0.5;
// self.overlayImageView.alpha = 0.5;
[imageContainer addSubview:self.overlayImageView];
......@@ -199,59 +263,17 @@
[self.overlayImageView.bottomAnchor constraintEqualToAnchor:imageContainer.bottomAnchor]
]];
// ---------- Header Bar (Top) ----------
UIView *headerBar = [[UIView alloc] init];
headerBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:headerBar];
[NSLayoutConstraint activateConstraints:@[
[headerBar.topAnchor constraintEqualToAnchor:self.headerView.safeAreaLayoutGuide.topAnchor],
[headerBar.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor],
[headerBar.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor],
[headerBar.heightAnchor constraintEqualToConstant:44]
]];
// ---------- Project Name ----------
self.projectNameLabel = [[UILabel alloc] init];
self.projectNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.projectNameLabel.font = [UIFont boldSystemFontOfSize:18];
self.projectNameLabel.textColor = UIColor.whiteColor;
self.projectNameLabel.textAlignment = NSTextAlignmentCenter;
[headerBar addSubview:self.projectNameLabel];
[imageContainer addSubview:self.projectNameLabel];
[NSLayoutConstraint activateConstraints:@[
[self.projectNameLabel.centerXAnchor constraintEqualToAnchor:headerBar.centerXAnchor],
[self.projectNameLabel.centerYAnchor constraintEqualToAnchor:headerBar.centerYAnchor]
]];
// ---------- Menu Button ----------
UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
menuButton.translatesAutoresizingMaskIntoConstraints = NO;
[menuButton setImage:[UIImage systemImageNamed:@"line.horizontal.3"] forState:UIControlStateNormal];
menuButton.tintColor = UIColor.whiteColor;
[menuButton addTarget:self action:@selector(handleMenuButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[headerBar addSubview:menuButton];
[NSLayoutConstraint activateConstraints:@[
[menuButton.trailingAnchor constraintEqualToAnchor:headerBar.trailingAnchor constant:-16],
[menuButton.centerYAnchor constraintEqualToAnchor:headerBar.centerYAnchor],
[menuButton.widthAnchor constraintEqualToConstant:26],
[menuButton.heightAnchor constraintEqualToConstant:26]
]];
// ---------- Back Button ----------
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"] forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
[self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
[headerBar addSubview:self.backButton];
[NSLayoutConstraint activateConstraints:@[
[self.backButton.leadingAnchor constraintEqualToAnchor:headerBar.leadingAnchor constant:8],
[self.backButton.centerYAnchor constraintEqualToAnchor:headerBar.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:24],
[self.backButton.heightAnchor constraintEqualToConstant:24]
[self.projectNameLabel.centerXAnchor constraintEqualToAnchor:self.stickyBar.centerXAnchor],
[self.projectNameLabel.centerYAnchor constraintEqualToAnchor:self.stickyBar.centerYAnchor]
]];
// ---------- Unit Name ----------
......@@ -281,6 +303,21 @@
[self.infoButton.heightAnchor constraintEqualToConstant:24]
]];
// ---------- Dark Overlay ----------
UIView *darkOverlay = [[UIView alloc] init];
darkOverlay.translatesAutoresizingMaskIntoConstraints = NO;
darkOverlay.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.35];
darkOverlay.userInteractionEnabled = NO;
[imageContainer addSubview:darkOverlay];
[NSLayoutConstraint activateConstraints:@[
[darkOverlay.topAnchor constraintEqualToAnchor:imageContainer.topAnchor],
[darkOverlay.leadingAnchor constraintEqualToAnchor:imageContainer.leadingAnchor],
[darkOverlay.trailingAnchor constraintEqualToAnchor:imageContainer.trailingAnchor],
[darkOverlay.bottomAnchor constraintEqualToAnchor:imageContainer.bottomAnchor]
]];
// ---------- Load Remote Image & Overlay ----------
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
UIImage *overlayImage =
......@@ -297,7 +334,10 @@
NSURL *url = [NSURL URLWithString:remoteHeaderURL];
[ImageCacheHelper loadImageWithURL:url completion:^(UIImage *image) {
self.backgroundImageView.image = image ?: [UIImage imageNamed:@"header_bg"];
[imageContainer bringSubviewToFront:self.backgroundImageView];
[imageContainer bringSubviewToFront:darkOverlay];
[imageContainer bringSubviewToFront:self.overlayImageView];
[imageContainer bringSubviewToFront:self.projectNameLabel];
}];
} else {
self.backgroundImageView.image = [UIImage imageNamed:@"header_bg"];
......@@ -307,7 +347,7 @@
#pragma mark - Footer
- (void)setupFooter {
CGFloat footerHeight = 80.0;
CGFloat footerHeight = 72.0;
CGFloat bottomInset = self.view.safeAreaInsets.bottom;
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(
0,
......@@ -320,9 +360,13 @@
footerView.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
footerView.layer.shadowOpacity = 0.8;
footerView.layer.shadowOffset = CGSizeMake(0, -1);
footerView.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
footerView.layer.cornerRadius = 16.0;
footerView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner; // top-left & top-right
footerView.clipsToBounds = YES;
[self.view addSubview:footerView];
NSArray *titles = @[ @"Make Appointment", @"Add Issue", @"View Access Item" ];
NSArray *titles = @[ @"Make Appt.", @"Add Issue", @"Access Item" ];
NSArray *icons = @[ @"calendar", @"plus.circle", @"list.bullet" ];
CGFloat buttonWidth = self.view.bounds.size.width / titles.count;
......@@ -330,9 +374,9 @@
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(i * buttonWidth, 0, buttonWidth, footerHeight);
[button setTitle:titles[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0] forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:13];
button.tintColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
button.tintColor = [UIColor whiteColor];
[button setImage:[UIImage systemImageNamed:icons[i]] forState:UIControlStateNormal];
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
......@@ -391,73 +435,64 @@
}
#pragma mark - Scroll Content
- (void)setupScrollContent {
// ScrollView
_scrollView = [[UIScrollView alloc] init];
_scrollView.translatesAutoresizingMaskIntoConstraints = NO;
_scrollView.alwaysBounceVertical = YES;
[self.view addSubview:_scrollView];
- (void)setupScrollView {
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
self.scrollView.alwaysBounceVertical = YES;
self.scrollView.delegate = self;
[self.view addSubview:self.scrollView];
CGFloat footerHeight = 80.0;
self.contentView = [[UIView alloc] init];
self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:self.contentView];
[NSLayoutConstraint activateConstraints:@[
[_scrollView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor],
[_scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[_scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[_scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:-footerHeight]
[self.scrollView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
[self.contentView.topAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.topAnchor],
[self.contentView.leadingAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.leadingAnchor],
[self.contentView.trailingAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.trailingAnchor],
[self.contentView.bottomAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.bottomAnchor],
[self.contentView.widthAnchor constraintEqualToAnchor:self.scrollView.frameLayoutGuide.widthAnchor],
]];
}
- (void)setupScrollContent {
UIView *banner = [self buildInspectionChecklistBanner];
UIView *stackContainer = [[UIView alloc] init];
stackContainer.translatesAutoresizingMaskIntoConstraints = NO;
[_scrollView addSubview:stackContainer];
CGFloat topOffset = 16;
if (banner) {
banner.translatesAutoresizingMaskIntoConstraints = NO;
[_scrollView addSubview:banner];
[self.contentView addSubview:banner];
[NSLayoutConstraint activateConstraints:@[
[banner.topAnchor constraintEqualToAnchor:_scrollView.contentLayoutGuide.topAnchor constant:topOffset],
[banner.leadingAnchor constraintEqualToAnchor:_scrollView.leadingAnchor constant:16],
[banner.trailingAnchor constraintEqualToAnchor:_scrollView.trailingAnchor constant:-16],
[banner.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:topOffset],
[banner.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[banner.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
[banner.heightAnchor constraintEqualToConstant:90]
]];
topOffset += 90 + 16; // stack starts after banner + spacing
topOffset += 90 + 16;
}
// Content container (STACK VIEW)
UIStackView *stack = [[UIStackView alloc] init];
stack.axis = UILayoutConstraintAxisVertical;
stack.spacing = 16;
stack.spacing = 22;
stack.translatesAutoresizingMaskIntoConstraints = NO;
stack.layoutMargins = UIEdgeInsetsMake(0, 16, 16, 16);
stack.layoutMarginsRelativeArrangement = YES;
[stackContainer addSubview:stack];
[self.contentView addSubview:stack];
self.contentContainer = stack;
[NSLayoutConstraint activateConstraints:@[
[stack.topAnchor constraintEqualToAnchor:stackContainer.topAnchor],
[stack.leadingAnchor constraintEqualToAnchor:stackContainer.leadingAnchor],
[stack.trailingAnchor constraintEqualToAnchor:stackContainer.trailingAnchor],
[stack.bottomAnchor constraintEqualToAnchor:stackContainer.bottomAnchor],
[stack.widthAnchor constraintEqualToAnchor:stackContainer.widthAnchor]
]];
[NSLayoutConstraint activateConstraints:@[
// Top/bottom for vertical scrolling
[stackContainer.topAnchor constraintEqualToAnchor:_scrollView.contentLayoutGuide.topAnchor constant:topOffset],
[stackContainer.bottomAnchor constraintEqualToAnchor:_scrollView.contentLayoutGuide.bottomAnchor],
// ⚡ Width locked to frame to prevent horizontal scroll
[stackContainer.widthAnchor constraintEqualToAnchor:_scrollView.frameLayoutGuide.widthAnchor],
// Leading/trailing optional, can just pin to zero if width is fixed
[stackContainer.leadingAnchor constraintEqualToAnchor:_scrollView.leadingAnchor],
[stackContainer.trailingAnchor constraintEqualToAnchor:_scrollView.trailingAnchor]
[stack.topAnchor constraintEqualToAnchor:(banner ? banner.bottomAnchor : self.headerView.bottomAnchor)
constant:16],
[stack.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[stack.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
[stack.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor]
]];
}
......@@ -556,7 +591,7 @@
if (pill) {
[constraints addObjectsFromArray:@[
[pill.topAnchor constraintEqualToAnchor:titleLabel.bottomAnchor constant:8],
[pill.topAnchor constraintEqualToAnchor:titleLabel.bottomAnchor constant:14],
[pill.leadingAnchor constraintEqualToAnchor:banner.leadingAnchor constant:16],
[pill.heightAnchor constraintEqualToConstant:28],
[pill.bottomAnchor constraintEqualToAnchor:banner.bottomAnchor constant:-16]
......@@ -793,7 +828,7 @@
[hScroll.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:12],
[hScroll.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[hScroll.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[hScroll.heightAnchor constraintEqualToConstant:90],
[hScroll.heightAnchor constraintEqualToConstant:80],
[hScroll.bottomAnchor constraintEqualToAnchor:section.bottomAnchor] // important
]];
......@@ -942,7 +977,7 @@
[section addSubview:list];
[NSLayoutConstraint activateConstraints:@[
[list.topAnchor constraintEqualToAnchor:title.bottomAnchor],
[list.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:12],
[list.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[list.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[list.bottomAnchor constraintEqualToAnchor:section.bottomAnchor]
......@@ -967,7 +1002,7 @@
card.layer.shadowOpacity = 0.3;
card.layer.shadowOffset = CGSizeMake(0, 1);
[card.heightAnchor constraintEqualToConstant:90].active = YES;
[card.heightAnchor constraintEqualToConstant:92].active = YES;
NSString *appointmentType = item[@"appointment_type"] ?: @"-";
NSString *status = item[@"status"] ?: @"-";
......@@ -1015,8 +1050,8 @@
[card addSubview:desc];
[NSLayoutConstraint activateConstraints:@[
[iconCircle.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[iconCircle.topAnchor constraintEqualToAnchor:card.topAnchor constant:14],
[iconCircle.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
[iconCircle.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[iconCircle.widthAnchor constraintEqualToConstant:24],
[iconCircle.heightAnchor constraintEqualToConstant:24],
......@@ -1026,15 +1061,15 @@
[bell.heightAnchor constraintEqualToConstant:16],
[statusLabel.leadingAnchor constraintEqualToAnchor:iconCircle.trailingAnchor constant:8],
[statusLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[statusLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:14],
[timeLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[timeLabel.centerYAnchor constraintEqualToAnchor:statusLabel.centerYAnchor],
[desc.topAnchor constraintEqualToAnchor:statusLabel.bottomAnchor constant:6],
[desc.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
[desc.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-16],
[desc.bottomAnchor constraintLessThanOrEqualToAnchor:card.bottomAnchor constant:-8]
[desc.topAnchor constraintEqualToAnchor:card.topAnchor constant:41],
[desc.leadingAnchor constraintEqualToAnchor:statusLabel.leadingAnchor],
[desc.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-20],
[desc.bottomAnchor constraintLessThanOrEqualToAnchor:card.bottomAnchor constant:-15]
]];
objc_setAssociatedObject(card, "appointmentData", item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
......@@ -1107,7 +1142,7 @@
[section addSubview:list];
[NSLayoutConstraint activateConstraints:@[
[list.topAnchor constraintEqualToAnchor:title.bottomAnchor],
[list.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:12],
[list.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[list.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[list.bottomAnchor constraintEqualToAnchor:section.bottomAnchor]
......@@ -1130,7 +1165,7 @@
card.layer.shadowOpacity = 0.3;
card.layer.shadowOffset = CGSizeMake(0, 1);
[card.heightAnchor constraintGreaterThanOrEqualToConstant:110].active = YES;
[card.heightAnchor constraintGreaterThanOrEqualToConstant:92].active = YES;
NSString *status = item[@"status_external"] ?: @"Unknown";
NSString *formattedDate = [self formatDate:item[@"created_at"]];
......@@ -1157,7 +1192,7 @@
dateLabel.textAlignment = NSTextAlignmentRight;
[card addSubview:dateLabel];
CGFloat imageSize = 44;
CGFloat imageSize = 30;
UIImageView *thumb = [[UIImageView alloc] init];
thumb.translatesAutoresizingMaskIntoConstraints = NO;
thumb.layer.cornerRadius = 6;
......@@ -1195,12 +1230,12 @@
[card addSubview:info];
[NSLayoutConstraint activateConstraints:@[
[dot.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[dot.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
[dot.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[dot.widthAnchor constraintEqualToConstant:16],
[dot.heightAnchor constraintEqualToConstant:16],
[statusLabel.leadingAnchor constraintEqualToAnchor:dot.trailingAnchor constant:6],
[statusLabel.leadingAnchor constraintEqualToAnchor:dot.trailingAnchor constant:14],
[statusLabel.centerYAnchor constraintEqualToAnchor:dot.centerYAnchor],
[dateLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
......@@ -1211,9 +1246,9 @@
[thumb.widthAnchor constraintEqualToConstant:imageSize],
[thumb.heightAnchor constraintEqualToConstant:imageSize],
[info.leadingAnchor constraintEqualToAnchor:thumb.trailingAnchor constant:10],
[info.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[info.centerYAnchor constraintEqualToAnchor:thumb.centerYAnchor],
[info.leadingAnchor constraintEqualToAnchor:thumb.trailingAnchor constant:14],
[info.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-14],
[info.topAnchor constraintEqualToAnchor:card.topAnchor constant:41],
[info.bottomAnchor constraintLessThanOrEqualToAnchor:card.bottomAnchor constant:-10]
]];
......@@ -1493,4 +1528,21 @@
[self.navigationController popViewControllerAnimated:YES];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat offsetY = scrollView.contentOffset.y;
// Parallax effect for the header image
if (offsetY < 0) {
self.backgroundImageView.transform = CGAffineTransformMakeTranslation(0, offsetY / 2);
} else {
self.backgroundImageView.transform = CGAffineTransformIdentity;
}
// Gradually fade in sticky bar
CGFloat fadeStart = 0;
CGFloat fadeEnd = 100; // how far scroll before fully opaque
CGFloat alpha = MIN(MAX((offsetY - fadeStart) / (fadeEnd - fadeStart), 0), 1);
self.stickyBar.backgroundColor = [UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:alpha];
}
@end
......@@ -23,6 +23,7 @@
@property (nonatomic) NSLayoutConstraint *infoBottom;
@property (nonatomic) NSLayoutConstraint *documentsBottom;
@property (nonatomic) NSLayoutConstraint *formsBottom;
@property (nonatomic, strong) UILabel *jointTitleLabel;
// Sections for tabs
@property (nonatomic, strong) UIView *infoContainer;
......@@ -238,12 +239,12 @@ typedef struct {
[self.infoContainer addSubview:self.ownerStack];
// --- Joint Owners Title ---
UILabel *jointTitle = [[UILabel alloc] init];
jointTitle.text = @"Joint Owner Details";
jointTitle.font = [UIFont boldSystemFontOfSize:16];
jointTitle.textColor = UIColor.darkGrayColor;
jointTitle.translatesAutoresizingMaskIntoConstraints = NO;
[self.infoContainer addSubview:jointTitle];
self.jointTitleLabel = [[UILabel alloc] init];
self.jointTitleLabel.text = @"Joint Owner Details";
self.jointTitleLabel.font = [UIFont boldSystemFontOfSize:16];
self.jointTitleLabel.textColor = UIColor.darkGrayColor;
self.jointTitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.infoContainer addSubview:self.jointTitleLabel];
// --- Joint Owners Stack ---
self.jointOwnersStack = [[UIStackView alloc] init];
......@@ -276,10 +277,10 @@ typedef struct {
[self.ownerStack.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.ownerStack.trailingAnchor constraintEqualToAnchor:self.infoContainer.trailingAnchor constant:-16],
[jointTitle.topAnchor constraintEqualToAnchor:self.ownerStack.bottomAnchor constant:20],
[jointTitle.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.jointTitleLabel.topAnchor constraintEqualToAnchor:self.ownerStack.bottomAnchor constant:20],
[self.jointTitleLabel.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.jointOwnersStack.topAnchor constraintEqualToAnchor:jointTitle.bottomAnchor constant:12],
[self.jointOwnersStack.topAnchor constraintEqualToAnchor:self.jointTitleLabel.bottomAnchor constant:12],
[self.jointOwnersStack.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.jointOwnersStack.trailingAnchor constraintEqualToAnchor:self.infoContainer.trailingAnchor constant:-16],
......@@ -643,7 +644,6 @@ typedef struct {
}
maxTitleWidth += 6;
UIStackView* (^OwnerCard)(NSDictionary *) = ^UIStackView* (NSDictionary *owner) {
UIStackView *card = [[UIStackView alloc] init];
......@@ -699,6 +699,11 @@ typedef struct {
[self.jointOwnersStack addArrangedSubview:OwnerCard(owner)];
}
BOOL hasJointOwners = self.jointOwnersStack.arrangedSubviews.count > 0;
self.jointOwnersStack.hidden = !hasJointOwners;
self.jointTitleLabel.hidden = !hasJointOwners;
// ------------------------
// 2️⃣ UNIT INFO SECTION
// ------------------------
......
......@@ -34,10 +34,10 @@
// label
self.nameLabel = [[UILabel alloc] init];
self.nameLabel.font = [UIFont boldSystemFontOfSize:20];
self.nameLabel.font = [UIFont boldSystemFontOfSize:18];
self.nameLabel.textColor = UIColor.whiteColor;
self.nameLabel.backgroundColor =
[[UIColor blackColor] colorWithAlphaComponent:0.35];
// self.nameLabel.backgroundColor =
// [[UIColor blackColor] colorWithAlphaComponent:0.35];
self.nameLabel.numberOfLines = 2;
self.nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.nameLabel];
......@@ -116,24 +116,24 @@
NSLog(@"ClientCode: %@", self.ClientCode);
NSLog(@"user_token: %@", self.user_token);
[self showLoadingOverlay:@"Loading..."];
if (![self isReadyToLoadDashboard]) {
NSLog(@"⏳ Waiting for all credentials to be ready...");
return;
}
if (_isLoadingDashboard) return;
self.isLoadingDashboard = YES;
NSLog(@"✅ All credentials ready. ClientID: %@, ClientCode: %@, user_token: %@",
self.ClientID, self.ClientCode, self.user_token);
[APIConfig setAuthTokem:self.user_token];
[APIConfig setClientId:self.ClientID];
[self requestProjectList];
// [self showLoadingOverlay:@"Loading..."];
//
// if (![self isReadyToLoadDashboard]) {
// NSLog(@"⏳ Waiting for all credentials to be ready...");
// return;
// }
//
// if (_isLoadingDashboard) return;
//
// self.isLoadingDashboard = YES;
//
// NSLog(@"✅ All credentials ready. ClientID: %@, ClientCode: %@, user_token: %@",
// self.ClientID, self.ClientCode, self.user_token);
//
//
// [APIConfig setAuthTokem:self.user_token];
// [APIConfig setClientId:self.ClientID];
self.ClientCode = @"spt";
[self requestCompanyCode];
}
......@@ -185,7 +185,7 @@
- (void)setupCollectionView {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.minimumLineSpacing = 16;
layout.minimumLineSpacing = 12;
layout.minimumInteritemSpacing = 16;
layout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
......@@ -202,7 +202,7 @@
// constraints
[NSLayoutConstraint activateConstraints:@[
[self.collectionView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:8],
[self.collectionView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:20],
[self.collectionView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.collectionView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
......@@ -273,7 +273,7 @@
CGFloat horizontalInset = 16 * 2; // section inset left + right
CGFloat width = collectionView.bounds.size.width - horizontalInset;
CGFloat height = 200; // OG-style banner height
CGFloat height = 140; // OG-style banner height
return CGSizeMake(width, height);
}
......@@ -400,16 +400,12 @@
return;
}
NSArray *project = data[@"Data"];
if (![project isKindOfClass:[NSArray class]]) {
NSLog(@"❌ Invalid project list format");
return;
}
if (!error) {
NSString *rawURL = data[@"Data"][@"url_path"];
NSString *baseURL = rawURL;
NSLog(@"base url: %@", baseURL);
// remove trailing slash if exists
if ([baseURL hasSuffix:@"/"]) {
baseURL = [baseURL substringToIndex:baseURL.length - 1];
......@@ -418,7 +414,8 @@
// append /api
baseURL = [baseURL stringByAppendingString:@"/api"];
NSLog(@"baseURL: %@", baseURL);
// [APIConfig setBaseURL:baseURL];
[APIConfig setBaseURL:baseURL];
[self requestProjectList];
}
}];
}
......
......@@ -110,10 +110,10 @@
[self.view addSubview:self.searchBar];
[NSLayoutConstraint activateConstraints:@[
[self.searchBar.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:8],
[self.searchBar.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:0],
[self.searchBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.searchBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.searchBar.heightAnchor constraintEqualToConstant:44]
[self.searchBar.heightAnchor constraintEqualToConstant:72]
]];
}
......@@ -151,11 +151,19 @@
[self.view addSubview:self.tableView];
UILabel *footerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 50)];
footerLabel.text = @"All items displayed";
footerLabel.textColor = UIColor.systemGrayColor;
footerLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
footerLabel.textAlignment = NSTextAlignmentCenter;
self.tableView.tableFooterView = footerLabel;
[NSLayoutConstraint activateConstraints:@[
[self.tableView.topAnchor constraintEqualToAnchor:self.searchBar.bottomAnchor constant:8],
[self.tableView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.tableView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.tableView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
[self.tableView.topAnchor constraintEqualToAnchor:self.searchBar.bottomAnchor constant:12],
[self.tableView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.tableView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.tableView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:self.view.safeAreaInsets.bottom]
]];
}
......@@ -169,6 +177,7 @@
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:@"UnitCell"
forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// ---- Reset reused cell ----
for (UIView *subview in cell.contentView.subviews) {
......@@ -186,25 +195,30 @@
// ---- Arrow ----
UIImageView *arrow = [[UIImageView alloc] initWithImage:
[UIImage systemImageNamed:@"chevron.right"]];
arrow.tintColor = UIColor.systemGrayColor;
arrow.tintColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
arrow.translatesAutoresizingMaskIntoConstraints = NO;
// ---- Card styling ----
cell.backgroundColor = UIColor.clearColor;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.contentView.backgroundColor = UIColor.whiteColor;
cell.contentView.layer.cornerRadius = 12;
cell.contentView.layer.borderWidth = 1;
cell.contentView.layer.borderColor = UIColor.systemGray4Color.CGColor;
cell.contentView.clipsToBounds = YES;
// ---- Add views ----
[cell.contentView addSubview:label];
[cell.contentView addSubview:arrow];
UIView *cardView = [[UIView alloc] init];
cardView.backgroundColor = UIColor.whiteColor;
cardView.layer.cornerRadius = 12;
cardView.layer.borderWidth = 1;
cardView.layer.borderColor = UIColor.systemGray4Color.CGColor;
cardView.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:cardView];
// Put label & arrow inside cardView
[cardView addSubview:label];
[cardView addSubview:arrow];
// ---- Constraints ----
[NSLayoutConstraint activateConstraints:@[
// Cardview
[cardView.topAnchor constraintEqualToAnchor:cell.contentView.topAnchor constant:8], // vertical spacing top
[cardView.bottomAnchor constraintEqualToAnchor:cell.contentView.bottomAnchor constant:-8], // vertical spacing bottom
[cardView.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:0], // horizontal spacing
[cardView.trailingAnchor constraintEqualToAnchor:cell.contentView.trailingAnchor constant:0],
// Label
[label.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:16],
[label.centerYAnchor constraintEqualToAnchor:cell.contentView.centerYAnchor],
......@@ -230,7 +244,7 @@ forRowAtIndexPath:(NSIndexPath *)indexPath {
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 64;
return 66;
}
- (void)tableView:(UITableView *)tableView
......
......@@ -60,8 +60,7 @@
#pragma mark - Header
- (void)setupHeader {
CGFloat statusBarHeight = UIApplication.sharedApplication.statusBarFrame.size.height;
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, statusBarHeight + 60)];
self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerView];
......
......@@ -82,30 +82,31 @@
[card.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:6],
[card.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:10],
[card.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-10],
[card.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-6],
[self.thumbView.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[self.thumbView.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[self.thumbView.widthAnchor constraintEqualToConstant:44],
[self.thumbView.heightAnchor constraintEqualToConstant:44],
[card.heightAnchor constraintEqualToConstant:141],
[self.statusLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[self.statusLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[self.statusLabel.widthAnchor constraintEqualToConstant:70],
[self.statusLabel.heightAnchor constraintEqualToConstant:24],
[self.referenceLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
[self.referenceLabel.trailingAnchor constraintEqualToAnchor:self.statusLabel.leadingAnchor constant:16],
[self.referenceLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:16],
[self.thumbView.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
[self.thumbView.topAnchor constraintEqualToAnchor:self.referenceLabel.bottomAnchor constant:12],
[self.thumbView.widthAnchor constraintEqualToConstant:44],
[self.thumbView.heightAnchor constraintEqualToConstant:44],
[self.locationLabel.leadingAnchor constraintEqualToAnchor:self.thumbView.trailingAnchor constant:12],
[self.locationLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[self.locationLabel.bottomAnchor constraintEqualToAnchor:self.thumbView.centerYAnchor constant:-1],
[self.createdLabel.leadingAnchor constraintEqualToAnchor:self.thumbView.trailingAnchor constant:12],
[self.createdLabel.topAnchor constraintEqualToAnchor:self.locationLabel.bottomAnchor constant:4],
[self.referenceLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[self.referenceLabel.topAnchor constraintEqualToAnchor:self.thumbView.bottomAnchor constant:8],
[self.createdLabel.topAnchor constraintEqualToAnchor:self.thumbView.centerYAnchor constant:1],
[self.detailsLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[self.detailsLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[self.detailsLabel.topAnchor constraintEqualToAnchor:self.referenceLabel.bottomAnchor constant:4],
[self.detailsLabel.topAnchor constraintEqualToAnchor:self.thumbView.bottomAnchor constant:12],
[self.detailsLabel.bottomAnchor constraintEqualToAnchor:card.bottomAnchor constant:-12],
]];
}
......
......@@ -715,8 +715,6 @@ didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
for (SyncUnit *unit in self.selectedUnits) {
[dictArray addObject:[self dictionaryFromUnit:unit]];
}
[LocalStorage saveArray:dictArray forKey:@"SELECTED_OFFLINE_UNITS"];
[self showOfflineUnit];
}
......
......@@ -670,7 +670,7 @@ static NSString * const kLastOfflineSyncDateKey = @"LAST_OFFLINE_SYNC_DATE";
}
- (NSInteger)loadOfflineUnitCount {
NSArray *units = [LocalStorage loadArrayForKey:@"SELECTED_OFFLINE_UNITS"];
NSArray *units = [LocalStorage loadArrayForKey:kSyncSelectedUnitsKey];
return units.count;
}
......@@ -714,5 +714,4 @@ static NSString * const kLastOfflineSyncDateKey = @"LAST_OFFLINE_SYNC_DATE";
self.yesBtn.alpha = enabled ? 1.0 : 0.5;
}
@end
......@@ -12,7 +12,7 @@
return;
}
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getAccessItem"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/plan/getAccessItem"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -84,7 +84,7 @@
}
// ✅ Construct URL (with token)
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getLocationByUnit"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/plan/getLocationByUnit"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -177,7 +177,7 @@
return;
}
NSURL *url = [APIConfig urlWithPath:@"/issue/getGeneralSettingByLocation"];
NSURL *url = [APIConfig urlWithPath:@"/framework/issue/getGeneralSettingByLocation"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -269,7 +269,7 @@
images:(NSArray<UIImage *> * _Nullable)images
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/addIssue"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/addIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -361,7 +361,7 @@
images:(NSArray<UIImage *> * _Nullable)images
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion{
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/updateIssue"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/updateIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -470,7 +470,7 @@
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/appointment/getSlot"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/appointment/getSlot"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -544,7 +544,7 @@
return;
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getUnitInfo"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/plan/getUnitInfo"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -614,7 +614,7 @@
+ (void)submitAppointment:(NSDictionary *)appointmentData
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/appointment/makeAppointment"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/appointment/makeAppointment"];
NSLog(@"🌍 SUBMIT (NO REP) URL: %@", url.absoluteString);
NSLog(@"📦 SUBMIT (NO REP) Body JSON: %@", appointmentData);
......@@ -673,7 +673,7 @@
+ (void)submitRepresentativeAppointment:(NSDictionary *)repData
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/appointment/makeAppointment"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/appointment/makeAppointment"];
NSLog(@"🌍 SUBMIT URL: %@", url.absoluteString);
// Create request
......@@ -743,7 +743,7 @@
return;
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/appointment/cancelAppointment"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/appointment/cancelAppointment"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -817,7 +817,7 @@
return;
}
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getIssueUpdateAppointmentInfo"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/plan/getIssueUpdateAppointmentInfo"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -883,7 +883,7 @@
return;
}
// ✅ Keep token in URL
NSURL *url = [APIConfig urlWithPath:@"/clientAnnouncement"];
NSURL *url = [APIConfig urlWithPath:@"/framework/clientAnnouncement"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -960,7 +960,7 @@
return;
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/getIssueHistory"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/getIssueHistory"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1033,7 +1033,7 @@
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/addInfo"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/addInfo"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1103,7 +1103,7 @@
mediaType:(NSString *)mediaType
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/addInfo"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/addInfo"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1218,7 +1218,7 @@
return;
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/getIssue"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/getIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1294,7 +1294,7 @@
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/voidIssue"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/voidIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1377,7 +1377,7 @@
return;
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/deleteIssue"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/deleteIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1451,7 +1451,7 @@
return;
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getCommonArea"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/plan/getCommonArea"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1525,7 +1525,7 @@
return;
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/getGeneralSetting"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/issue/getGeneralSetting"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1599,7 +1599,7 @@
// return;
// }
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/issue/getGeneralSettingByUnit"];
NSURL *url = [APIConfig urlWithPath:@"/framework/issue/getGeneralSettingByUnit"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1669,7 +1669,7 @@
return;
}
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/project/listProject"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/project/listProject"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......@@ -1739,7 +1739,7 @@
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/offline/syncImageArray"];
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/offline/syncImageArray"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
......
......@@ -3,10 +3,10 @@
#import "LocalStorage.h"
#import "NetworkManager.h"
static NSString *kBaseURL = @"https://kitadev.commudesk.com/api";
static NSString *kBaseURL = @"https://sptest.commudesk.com/api";
static NSString *kDrawingPlanId = @"";
static NSString *kProjectId = @"";
static NSString *kAuthToken = @"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6ImF0aGlyYWh6YWlkaUBjb252ZXAuY29tIiwicGFzc3dvcmQiOiIkMnkkMTAkNU9xYklqMnZ6UHJwckJrcVd5c3I2LmJCc1hVYS9Hd014eUhnL3RhUUhPUkNQcGdmTG8yakciLCJzdWIiOjIxNzAsImlzcyI6Imh0dHBzOi8va2l0YWRldi5jb21tdWRlc2suY29tL2FwaS9vd25lci9hdXRoL3Bhc3N3b3JkbGVzc19sb2dpbiIsImlhdCI6MTc2MDMxNTM1MiwiZXhwIjoyMDc1ODg0ODcyLCJuYmYiOjE3NjAzMTUzNTIsImp0aSI6IktoQmNyQnJEdDVNdDZlWmMifQ.JnxGbZ7hTeoOr6oibIzZMphgyKtTo2Aq9Efx6mrGfFA";
static NSString *kAuthToken = @"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzY29wZSI6InNlcnZlci10by1zZXJ2ZXIiLCJmcmFtZXdvcmstYXBpIjp0cnVlLCJjb21wYW55X2NvZGUiOiJTUFQiLCJzdWIiOjE1NTcsImlzcyI6Imh0dHBzOi8vc3B0ZXN0LmNvbW11ZGVzay5jb20vYXBpL2ZyYW1ld29yay9vd25lci9hdXRoL2NsaWVudF9hdXRoZW50aWNhdGlvbiIsImlhdCI6MTc2Nzc1MjU5OSwiZXhwIjoyMDgzMzIyMTE5LCJuYmYiOjE3Njc3NTI1OTksImp0aSI6IktEcmhmSXgzeWU0WmxaUEYifQ.Bv4ZSjGRm9YYOjGItLSV_3wS7grKuPTabL60BFnp88o";
static NSString *kClientId = @"3";
@implementation APIConfig
......
......@@ -6,10 +6,12 @@
@interface QmsDashboardView : UIView
@property (nonatomic, strong) UIViewController *dashboardVC;
@property (nonatomic, assign) BOOL didSetupVC;
// New props
@property (nonatomic, copy) NSString *ClientID;
@property (nonatomic, copy) NSString *ClientCode;
@property (nonatomic, copy) NSString *user_token;
@property (nonatomic, copy) RCTDirectEventBlock onClose;
@end
@implementation QmsDashboardView
......@@ -19,6 +21,12 @@
_dashboardVC = [QmsPluginUI makeViewController];
_didSetupVC = NO;
_dashboardVC.view.backgroundColor = [UIColor whiteColor];
// Listen for native dashboard close notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleDashboardClose:)
name:@"QmsDashboardDidCloseNotification"
object:nil];
}
return self;
}
......@@ -28,6 +36,10 @@
if (self.window && !_didSetupVC) {
UIViewController *parentVC = [UIApplication sharedApplication].keyWindow.rootViewController;
if (parentVC) {
// 1️⃣ create VC with props
_dashboardVC = [QmsPluginUI makeViewController];
[parentVC addChildViewController:_dashboardVC];
_dashboardVC.view.frame = parentVC.view.bounds;
_dashboardVC.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
......@@ -35,14 +47,34 @@
[_dashboardVC didMoveToParentViewController:parentVC];
_didSetupVC = YES;
// Forward props once the VC is added
// 2️⃣ forward props again if needed
[self forwardPropsToVC];
}
}
}
#pragma mark - Prop Setters
- (void)handleDashboardClose:(NSNotification *)note {
// 1️⃣ Notify JS
if (self.onClose) {
self.onClose(@{});
}
// 2️⃣ Clean up the native view controller
[self cleanupDashboard];
}
- (void)cleanupDashboard {
if (!_dashboardVC) return;
[_dashboardVC willMoveToParentViewController:nil];
[_dashboardVC.view removeFromSuperview];
[_dashboardVC removeFromParentViewController];
_dashboardVC = nil;
_didSetupVC = NO;
}
#pragma mark - Prop Setters
- (void)setClientID:(NSString *)ClientID {
_ClientID = [ClientID copy];
[self forwardProp:@"ClientID" value:_ClientID];
......@@ -59,7 +91,6 @@
}
#pragma mark - Forward Props via KVC
- (void)forwardProp:(NSString *)key value:(NSString *)value {
if (_dashboardVC && [_dashboardVC respondsToSelector:NSSelectorFromString(key)]) {
@try {
......@@ -76,6 +107,11 @@
[self forwardProp:@"user_token" value:_user_token];
}
- (void)removeFromSuperview {
[self cleanupDashboard];
[super removeFromSuperview];
}
@end
@interface QmsDashboardViewManager : RCTViewManager
......
......@@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</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>
<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>
</array>
<key>CFBundlePackageType</key>
......
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