Commit db23c5fb authored by Wei Han's avatar Wei Han

native UI update

parent 579f896f
...@@ -8,32 +8,32 @@ ...@@ -8,32 +8,32 @@
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64</string> <string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
<dict> <dict>
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string> <string>ios-arm64</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
</array> </array>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
......
// DetailsViewController.mm
#import "DetailsViewController.h" #import "DetailsViewController.h"
@interface AddIssueDetailsViewController () @interface AddIssueDetailsViewController ()
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UIScrollView *scrollView; @property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UITextField *locationField; @property (nonatomic, strong) UITextField *locationField;
@property (nonatomic, strong) UITextView *commentField; @property (nonatomic, strong) UITextView *commentField;
@property (nonatomic, strong) UIButton *submitButton; @property (nonatomic, strong) UIButton *submitButton;
@property (nonatomic, strong) UIButton *resetButton;
@end @end
@implementation AddIssueDetailsViewController @implementation AddIssueDetailsViewController
...@@ -13,34 +14,125 @@ ...@@ -13,34 +14,125 @@
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor; self.view.backgroundColor = UIColor.whiteColor;
[self setupHeader];
[self setupForm]; // Create all views (don’t position them yet)
[self createHeader];
[self createForm];
} }
- (void)setupHeader { - (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGFloat topInset = self.view.safeAreaInsets.top; CGFloat topInset = self.view.safeAreaInsets.top;
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, topInset, self.view.bounds.size.width, 48)]; CGFloat headerHeight = 48.0;
header.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1];
header.autoresizingMask = UIViewAutoresizingFlexibleWidth; // Header layout
[self.view addSubview:header]; self.headerView.frame = CGRectMake(0, topInset, self.view.bounds.size.width, headerHeight);
// Title Label
UILabel *title = [self.headerView viewWithTag:101];
if (title) {
title.frame = CGRectMake(0, 8, self.headerView.bounds.size.width, 32);
}
// Scroll view layout (below header)
CGFloat scrollY = topInset + headerHeight;
self.scrollView.frame = CGRectMake(0, scrollY,
self.view.bounds.size.width,
self.view.bounds.size.height - scrollY);
// Adjust internal subviews (since width may have changed)
self.locationField.frame = CGRectMake(20, 50, self.view.bounds.size.width - 40, 40);
self.commentField.frame = CGRectMake(20, 140, self.view.bounds.size.width - 40, 100);
self.submitButton.frame = CGRectMake(20, 260, self.view.bounds.size.width - 40, 48);
}
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 8, header.bounds.size.width, 32)]; #pragma mark - Setup
- (void)createHeader {
// Header container
self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1];
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerView];
// Back button (SF Symbol)
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeSystem];
backButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *backImage = [UIImage systemImageNamed:@"chevron.left"];
backImage = [backImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[backButton setImage:backImage forState:UIControlStateNormal];
backButton.tintColor = [UIColor whiteColor];
backButton.backgroundColor = [UIColor clearColor];
[backButton addTarget:self action:@selector(dismissSelf)
forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:backButton];
// Title label
UILabel *title = [[UILabel alloc] init];
title.translatesAutoresizingMaskIntoConstraints = NO;
title.text = @"Add Issue Details"; title.text = @"Add Issue Details";
title.textColor = UIColor.whiteColor; title.textColor = UIColor.whiteColor;
title.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium]; title.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
title.textAlignment = NSTextAlignmentCenter; title.textAlignment = NSTextAlignmentCenter;
[header addSubview:title]; [self.headerView addSubview:title];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; // ✅ Reset button (refresh icon)
backButton.frame = CGRectMake(12, 8, 32, 32); self.resetButton = [UIButton buttonWithType:UIButtonTypeSystem];
[backButton setImage:[UIImage imageNamed:@"back24"] forState:UIControlStateNormal]; self.resetButton.translatesAutoresizingMaskIntoConstraints = NO;
[backButton addTarget:self action:@selector(dismissSelf) forControlEvents:UIControlEventTouchUpInside];
[header addSubview:backButton]; UIImage *refreshImage = [UIImage systemImageNamed:@"arrow.clockwise"];
refreshImage = [refreshImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.resetButton setImage:refreshImage forState:UIControlStateNormal];
self.resetButton.tintColor = [UIColor whiteColor];
self.resetButton.backgroundColor = [UIColor clearColor];
[self.resetButton addTarget:self
action:@selector(handleReset)
forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:self.resetButton];
// Status bar background (same color as header)
UIView *statusBarBackground = [[UIView alloc] init];
statusBarBackground.backgroundColor = self.headerView.backgroundColor;
statusBarBackground.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:statusBarBackground];
// Auto Layout
UILayoutGuide *safe = self.view.safeAreaLayoutGuide;
[NSLayoutConstraint activateConstraints:@[
// Header
[self.headerView.topAnchor constraintEqualToAnchor:safe.topAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerView.heightAnchor constraintEqualToConstant:48],
// Back button
[backButton.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor constant:8],
[backButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[backButton.widthAnchor constraintEqualToConstant:44],
[backButton.heightAnchor constraintEqualToConstant:44],
// Title centered
[title.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[title.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
// ✅ Reset button (right)
[self.resetButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-8],
[self.resetButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.resetButton.widthAnchor constraintEqualToConstant:44],
[self.resetButton.heightAnchor constraintEqualToConstant:44],
// Status bar color fill
[statusBarBackground.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[statusBarBackground.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[statusBarBackground.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[statusBarBackground.bottomAnchor constraintEqualToAnchor:safe.topAnchor],
]];
} }
- (void)setupForm { - (void)createForm {
CGFloat topInset = self.view.safeAreaInsets.top + 48; self.scrollView = [[UIScrollView alloc] init];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, topInset, self.view.bounds.size.width, self.view.bounds.size.height - topInset)];
[self.view addSubview:self.scrollView]; [self.view addSubview:self.scrollView];
UILabel *locationLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 200, 20)]; UILabel *locationLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 200, 20)];
...@@ -48,7 +140,7 @@ ...@@ -48,7 +140,7 @@
locationLabel.font = [UIFont boldSystemFontOfSize:16]; locationLabel.font = [UIFont boldSystemFontOfSize:16];
[self.scrollView addSubview:locationLabel]; [self.scrollView addSubview:locationLabel];
self.locationField = [[UITextField alloc] initWithFrame:CGRectMake(20, 50, self.view.bounds.size.width - 40, 40)]; self.locationField = [[UITextField alloc] initWithFrame:CGRectZero];
self.locationField.borderStyle = UITextBorderStyleRoundedRect; self.locationField.borderStyle = UITextBorderStyleRoundedRect;
[self.scrollView addSubview:self.locationField]; [self.scrollView addSubview:self.locationField];
...@@ -57,14 +149,14 @@ ...@@ -57,14 +149,14 @@
commentLabel.font = [UIFont boldSystemFontOfSize:16]; commentLabel.font = [UIFont boldSystemFontOfSize:16];
[self.scrollView addSubview:commentLabel]; [self.scrollView addSubview:commentLabel];
self.commentField = [[UITextView alloc] initWithFrame:CGRectMake(20, 140, self.view.bounds.size.width - 40, 100)]; self.commentField = [[UITextView alloc] initWithFrame:CGRectZero];
self.commentField.layer.borderColor = [UIColor lightGrayColor].CGColor; self.commentField.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.commentField.layer.borderWidth = 1.0; self.commentField.layer.borderWidth = 1.0;
self.commentField.layer.cornerRadius = 8; self.commentField.layer.cornerRadius = 8;
[self.scrollView addSubview:self.commentField]; [self.scrollView addSubview:self.commentField];
self.submitButton = [UIButton buttonWithType:UIButtonTypeSystem]; self.submitButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.submitButton.frame = CGRectMake(20, 260, self.view.bounds.size.width - 40, 48); self.submitButton.frame = CGRectZero;
self.submitButton.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1]; self.submitButton.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1];
[self.submitButton setTitle:@"Submit" forState:UIControlStateNormal]; [self.submitButton setTitle:@"Submit" forState:UIControlStateNormal];
[self.submitButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [self.submitButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
...@@ -73,6 +165,23 @@ ...@@ -73,6 +165,23 @@
[self.scrollView addSubview:self.submitButton]; [self.scrollView addSubview:self.submitButton];
} }
- (void)handleReset {
NSLog(@"🔄 Reset button tapped");
self.locationField.text = @"";
self.commentField.text = @"";
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Fields Cleared"
message:@"All inputs have been reset."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark - Actions
- (void)dismissSelf { - (void)dismissSelf {
[self dismissViewControllerAnimated:YES completion:nil]; [self dismissViewControllerAnimated:YES completion:nil];
} }
...@@ -86,4 +195,3 @@ ...@@ -86,4 +195,3 @@
} }
@end @end
...@@ -29,44 +29,56 @@ ...@@ -29,44 +29,56 @@
- (void)viewDidLayoutSubviews { - (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews]; [super viewDidLayoutSubviews];
// Get safe area + bounds
CGFloat topInset = self.view.safeAreaInsets.top; CGFloat topInset = self.view.safeAreaInsets.top;
CGFloat headerHeight = 48.0; CGFloat headerHeight = 48.0;
// Layout header // Layout header
self.headerView.frame = CGRectMake(0, topInset, self.view.bounds.size.width, headerHeight); self.headerView.frame = CGRectMake(0, topInset, self.view.bounds.size.width, headerHeight);
// Layout title // Layout items within header
self.titleLabel.frame = CGRectMake(0, 8, self.headerView.bounds.size.width, 32);
self.helpButton.frame = CGRectMake(self.headerView.bounds.size.width - 44, 8, 32, 32);
self.backButton.frame = CGRectMake(12, 8, 32, 32); self.backButton.frame = CGRectMake(12, 8, 32, 32);
self.helpButton.frame = CGRectMake(self.headerView.bounds.size.width - 44, 8, 32, 32);
self.titleLabel.frame = CGRectMake(0, 8, self.headerView.bounds.size.width, 32);
// Layout scroll view // Layout scroll view
CGFloat scrollY = topInset + headerHeight; CGFloat scrollY = topInset + headerHeight;
self.scrollView.frame = CGRectMake(0, scrollY, self.view.bounds.size.width, self.scrollView.frame = CGRectMake(0, scrollY, self.view.bounds.size.width, self.view.bounds.size.height - scrollY);
self.view.bounds.size.height - scrollY);
self.planImageView.frame = self.scrollView.bounds; self.planImageView.frame = self.scrollView.bounds;
// Make absolutely sure header is above scroll view
[self.view bringSubviewToFront:self.headerView]; [self.view bringSubviewToFront:self.headerView];
} }
#pragma mark - UI Creation #pragma mark - UI Creation
- (void)createHeader { - (void)createHeader {
// 🟩 Status bar background view
UIView *statusBarBackground = [[UIView alloc] init];
statusBarBackground.backgroundColor = [UIColor colorWithRed:0/255.0
green:109/255.0
blue:141/255.0
alpha:1];
statusBarBackground.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:statusBarBackground];
// 🟦 Header background view
self.headerView = [[UIView alloc] init]; self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1]; self.headerView.backgroundColor = statusBarBackground.backgroundColor;
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerView]; [self.view addSubview:self.headerView];
// Back button // Back button
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom]; self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.backButton setImage:[UIImage imageNamed:@"back24"] forState:UIControlStateNormal]; self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.backButton addTarget:self action:@selector(handleBack) forControlEvents:UIControlEventTouchUpInside]; UIImage *backImage = [[UIImage systemImageNamed:@"chevron.left"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.backButton setImage:backImage forState:UIControlStateNormal];
self.backButton.tintColor = [UIColor whiteColor];
[self.backButton addTarget:self action:@selector(handleBack)
forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:self.backButton]; [self.headerView addSubview:self.backButton];
// Title // Title label
self.titleLabel = [[UILabel alloc] init]; self.titleLabel = [[UILabel alloc] init];
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.titleLabel.text = @"Plan Viewer"; self.titleLabel.text = @"Plan Viewer";
self.titleLabel.textColor = UIColor.whiteColor; self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium]; self.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
...@@ -74,10 +86,47 @@ ...@@ -74,10 +86,47 @@
[self.headerView addSubview:self.titleLabel]; [self.headerView addSubview:self.titleLabel];
// Help button // Help button
self.helpButton = [UIButton buttonWithType:UIButtonTypeCustom]; self.helpButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.helpButton setImage:[UIImage imageNamed:@"btn_white_help_3x"] forState:UIControlStateNormal]; self.helpButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.helpButton addTarget:self action:@selector(showTutorial) forControlEvents:UIControlEventTouchUpInside]; UIImage *helpImage = [[UIImage systemImageNamed:@"questionmark.circle"]
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.helpButton setImage:helpImage forState:UIControlStateNormal];
self.helpButton.tintColor = [UIColor whiteColor];
[self.helpButton addTarget:self action:@selector(showTutorial)
forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:self.helpButton]; [self.headerView addSubview:self.helpButton];
// ✅ Constraints
UILayoutGuide *safe = self.view.safeAreaLayoutGuide;
[NSLayoutConstraint activateConstraints:@[
// Status bar background
[statusBarBackground.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[statusBarBackground.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[statusBarBackground.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[statusBarBackground.bottomAnchor constraintEqualToAnchor:safe.topAnchor],
// Header pinned below safe area
[self.headerView.topAnchor constraintEqualToAnchor:safe.topAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerView.heightAnchor constraintEqualToConstant:48],
// Back button
[self.backButton.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor constant:8],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:44],
[self.backButton.heightAnchor constraintEqualToConstant:44],
// Help button
[self.helpButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-8],
[self.helpButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.helpButton.widthAnchor constraintEqualToConstant:44],
[self.helpButton.heightAnchor constraintEqualToConstant:44],
// Title centered
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
]];
} }
- (void)createScrollView { - (void)createScrollView {
...@@ -94,7 +143,7 @@ ...@@ -94,7 +143,7 @@
UIImage *testImage = [UIImage imageNamed:@"image_placeholder"]; UIImage *testImage = [UIImage imageNamed:@"image_placeholder"];
if (!testImage) { if (!testImage) {
NSLog(@"❌ image_placeholder not found in bundle!"); NSLog(@"❌ image_placeholder not found in bundle!");
self.planImageView.backgroundColor = [UIColor systemTealColor]; self.planImageView.backgroundColor = [UIColor whiteColor];
// 👉 Temporary test button // 👉 Temporary test button
UIButton *testButton = [UIButton buttonWithType:UIButtonTypeSystem]; UIButton *testButton = [UIButton buttonWithType:UIButtonTypeSystem];
...@@ -148,4 +197,9 @@ ...@@ -148,4 +197,9 @@
return self.planImageView; return self.planImageView;
} }
#pragma mark - Status Bar Style
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent; // ✅ White text/icons
}
@end @end
...@@ -7,16 +7,34 @@ ...@@ -7,16 +7,34 @@
DashboardHeaderView *_headerView; DashboardHeaderView *_headerView;
UIScrollView *_scrollView; UIScrollView *_scrollView;
UIView *_contentContainer; UIView *_contentContainer;
NSMutableDictionary *_sectionViews;
} }
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0]; // #F2F2F2 self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0];
_sectionViews = [NSMutableDictionary dictionary];
[self setupHeader]; [self setupHeader];
[self setupScrollContent]; [self setupScrollContent];
[self setupFooter]; [self setupFooter];
[self fetchDashboardData];
}
#pragma mark - Layout
- (void)viewDidLayoutSubviews {
[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 #pragma mark - Header
...@@ -30,52 +48,28 @@ ...@@ -30,52 +48,28 @@
overlayImage:[UIImage imageNamed:@"overlay"]]; overlayImage:[UIImage imageNamed:@"overlay"]];
[self.view addSubview:_headerView]; [self.view addSubview:_headerView];
// Create Back Button
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeSystem]; UIButton *backButton = [UIButton buttonWithType:UIButtonTypeSystem];
backButton.translatesAutoresizingMaskIntoConstraints = NO; backButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *backImage = [[UIImage systemImageNamed:@"chevron.left"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage *backImage = [UIImage systemImageNamed:@"chevron.left"];
backImage = [backImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[backButton setImage:backImage forState:UIControlStateNormal]; [backButton setImage:backImage forState:UIControlStateNormal];
backButton.tintColor = [UIColor whiteColor]; backButton.tintColor = [UIColor whiteColor];
[backButton addTarget:self action:@selector(handleBackButtonTapped) forControlEvents:UIControlEventTouchUpInside];
backButton.layer.cornerRadius = 18;
backButton.backgroundColor = [UIColor clearColor];
backButton.clipsToBounds = YES;
[backButton addTarget:self
action:@selector(handleBackButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:backButton]; [self.view addSubview:backButton];
// Create Menu Button
UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeSystem]; UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeSystem];
menuButton.translatesAutoresizingMaskIntoConstraints = NO; menuButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *menuImage = [[UIImage systemImageNamed:@"line.3.horizontal"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage *menuImage = [UIImage systemImageNamed:@"line.3.horizontal"];
menuImage = [menuImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[menuButton setImage:menuImage forState:UIControlStateNormal]; [menuButton setImage:menuImage forState:UIControlStateNormal];
menuButton.tintColor = [UIColor whiteColor]; menuButton.tintColor = [UIColor whiteColor];
menuButton.backgroundColor = [UIColor clearColor]; [menuButton addTarget:self action:@selector(handleMenuButtonTapped) forControlEvents:UIControlEventTouchUpInside];
menuButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 8, 8);
[menuButton addTarget:self
action:@selector(handleMenuButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:menuButton]; [self.view addSubview:menuButton];
// ✅ Use Auto Layout constraints to respect safe area
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
// Back button - top left
[backButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:8], [backButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:8],
[backButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:4], [backButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:4],
[backButton.widthAnchor constraintEqualToConstant:44], [backButton.widthAnchor constraintEqualToConstant:44],
[backButton.heightAnchor constraintEqualToConstant:44], [backButton.heightAnchor constraintEqualToConstant:44],
// Menu button - top right
[menuButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-8], [menuButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-8],
[menuButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:4], [menuButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:4],
[menuButton.widthAnchor constraintEqualToConstant:44], [menuButton.widthAnchor constraintEqualToConstant:44],
...@@ -84,18 +78,16 @@ ...@@ -84,18 +78,16 @@
} }
- (void)handleBackButtonTapped { - (void)handleBackButtonTapped {
NSLog(@"🔙 Back button tapped – attempting to close DashboardViewController"); NSLog(@"🔙 Back button tapped");
if (self.presentingViewController) { if (self.presentingViewController) {
[self dismissViewControllerAnimated:YES completion:nil]; [self dismissViewControllerAnimated:YES completion:nil];
} else if (self.navigationController) { } else if (self.navigationController) {
[self.navigationController popViewControllerAnimated:YES]; [self.navigationController popViewControllerAnimated:YES];
} else {
NSLog(@"⚠️ No parent VC found to close!");
} }
} }
- (void)handleMenuButtonTapped { - (void)handleMenuButtonTapped {
NSLog(@"🍔 Menu button tapped – (TODO: open side menu or modal)"); NSLog(@"🍔 Menu button tapped");
} }
#pragma mark - Footer #pragma mark - Footer
...@@ -116,145 +108,139 @@ ...@@ -116,145 +108,139 @@
footerView.layer.shadowOffset = CGSizeMake(0, -1); footerView.layer.shadowOffset = CGSizeMake(0, -1);
[self.view addSubview:footerView]; [self.view addSubview:footerView];
// Button info
NSArray *titles = @[ @"Make Appointment", @"Add Issue", @"View Access Item" ]; NSArray *titles = @[ @"Make Appointment", @"Add Issue", @"View Access Item" ];
NSArray *icons = @[ @"calendar", @"plus.circle", @"list.bullet" ]; NSArray *icons = @[ @"calendar", @"plus.circle", @"list.bullet" ];
CGFloat visibleButtonHeight = footerHeight;
CGFloat buttonWidth = self.view.bounds.size.width / titles.count; CGFloat buttonWidth = self.view.bounds.size.width / titles.count;
for (NSInteger i = 0; i < titles.count; i++) { for (NSInteger i = 0; i < titles.count; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(i * buttonWidth, 0, buttonWidth, visibleButtonHeight); button.frame = CGRectMake(i * buttonWidth, 0, buttonWidth, footerHeight);
[button setTitle:titles[i] forState:UIControlStateNormal]; [button setTitle:titles[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0] [button setTitleColor:[UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0] forState:UIControlStateNormal];
forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:13]; button.titleLabel.font = [UIFont boldSystemFontOfSize:13];
button.tintColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0]; button.tintColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
[button setImage:[UIImage systemImageNamed:icons[i]] forState:UIControlStateNormal];
UIImage *icon = [UIImage systemImageNamed:icons[i]];
[button setImage:icon forState:UIControlStateNormal];
// Center icon above title
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
// Adjust spacing between image and text
CGFloat spacing = 6.0; CGFloat spacing = 6.0;
CGSize imageSize = button.imageView.frame.size; CGSize imageSize = button.imageView.frame.size;
CGSize titleSize = button.titleLabel.frame.size; CGSize titleSize = button.titleLabel.frame.size;
button.titleEdgeInsets = UIEdgeInsetsMake( button.titleEdgeInsets = UIEdgeInsetsMake(imageSize.height + spacing, -imageSize.width, 0, 0);
imageSize.height + spacing, // move text below image button.imageEdgeInsets = UIEdgeInsetsMake(-titleSize.height - spacing / 2, 0, 0, -titleSize.width);
-imageSize.width, // center horizontally
0,
0
);
button.imageEdgeInsets = UIEdgeInsetsMake(
-titleSize.height - spacing / 2, // move image up
0,
0,
-titleSize.width
);
button.tag = i; button.tag = i;
[button addTarget:self action:@selector(footerButtonTapped:) [button addTarget:self action:@selector(footerButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
forControlEvents:UIControlEventTouchUpInside];
[footerView addSubview:button]; [footerView addSubview:button];
// Divider line between buttons (except after last one)
if (i < titles.count - 1) { if (i < titles.count - 1) {
UIView *divider = [[UIView alloc] initWithFrame:CGRectMake( UIView *divider = [[UIView alloc] initWithFrame:CGRectMake((i + 1) * buttonWidth - 0.5, 10, 1, footerHeight - 20)];
(i + 1) * buttonWidth - 0.5,
10,
1,
footerHeight - 20
)];
divider.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0]; divider.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
divider.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[footerView addSubview:divider]; [footerView addSubview:divider];
} }
} }
} }
- (void)footerButtonTapped:(UIButton *)sender { - (void)footerButtonTapped:(UIButton *)sender {
NSLog(@"🟢 Footer button tapped with tag: %ld", (long)sender.tag);
NSString *title = sender.titleLabel.text;
NSLog(@"Footer button tapped: %@", title);
switch (sender.tag) { switch (sender.tag) {
case 0:
// Make Appointment
NSLog(@"Make Appointment tapped");
break;
case 1: { case 1: {
// Add Issue
PlanViewController *planVC = [[PlanViewController alloc] init]; PlanViewController *planVC = [[PlanViewController alloc] init];
planVC.modalPresentationStyle = UIModalPresentationFullScreen; planVC.modalPresentationStyle = UIModalPresentationFullScreen;
if (!planVC) {
NSLog(@"❌ PlanViewController class not found!");
return;
}
[self presentViewController:planVC animated:YES completion:nil]; [self presentViewController:planVC animated:YES completion:nil];
break; break;
} }
case 2:
// View Access Item
NSLog(@"View Access Item tapped");
break;
default: default:
break; break;
} }
} }
#pragma mark - Scrollable Content #pragma mark - Scroll Content
- (void)setupScrollContent { - (void)setupScrollContent {
CGFloat topOffset = 220.0; CGFloat topOffset = 220.0;
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, topOffset, self.view.bounds.size.width, self.view.bounds.size.height - topOffset)]; _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, topOffset, self.view.bounds.size.width, self.view.bounds.size.height - topOffset)];
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_scrollView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_scrollView]; [self.view addSubview:_scrollView];
_scrollView.clipsToBounds = NO;
_contentContainer.clipsToBounds = NO; _contentContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _scrollView.bounds.size.width, 0)];
_contentContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _scrollView.bounds.size.width, 800)];
_contentContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth; _contentContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[_scrollView addSubview:_contentContainer]; [_scrollView addSubview:_contentContainer];
CGFloat y = 20; CGFloat y = 20;
y = [self addSectionWithTitle:@"Project Update" text:@"12/10/2025\nAnnouncement Title" y:y];
y = [self addSectionWithTitle:@"Appointments" text:@"You have a joint inspection on 25 Oct 2025" y:y];
y = [self addSectionWithTitle:@"Issue Updates" text:@"Issue REF123 has been lodged." y:y];
_contentContainer.frame = CGRectMake(0, 0, _scrollView.bounds.size.width, y + 20); // Add 3 fixed section titles, store them for later population
_scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width, CGRectGetMaxY(_contentContainer.frame)); NSArray *sectionNames = @[ @"Project Update", @"Appointments", @"Issue Updates" ];
for (NSString *name in sectionNames) {
UILabel *header = [[UILabel alloc] initWithFrame:CGRectMake(16, y, self.view.bounds.size.width - 32, 24)];
header.text = name;
header.font = [UIFont boldSystemFontOfSize:18];
[_contentContainer addSubview:header];
y += 30;
UIView *sectionContainer = [[UIView alloc] initWithFrame:CGRectMake(0, y, self.view.bounds.size.width, 0)];
[_contentContainer addSubview:sectionContainer];
_sectionViews[name] = sectionContainer;
y += 20; // spacing before next section
}
_contentContainer.frame = CGRectMake(0, 0, _scrollView.bounds.size.width, y);
_scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width, y);
} }
- (CGFloat)addSectionWithTitle:(NSString *)title text:(NSString *)text y:(CGFloat)y { #pragma mark - Networking
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, y, self.view.bounds.size.width - 32, 22)];
titleLabel.text = title; - (void)fetchDashboardData {
titleLabel.font = [UIFont boldSystemFontOfSize:18]; NSURL *url = [NSURL URLWithString:@"https://jsonplaceholder.typicode.com/posts?_limit=9"];
[_contentContainer addSubview:titleLabel]; __weak typeof(self) weakSelf = self;
y += 30; [[[NSURLSession sharedSession] dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) return;
NSArray *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf populateSectionsWithData:json];
});
}] resume];
}
- (void)populateSectionsWithData:(NSArray *)data {
NSArray *sectionKeys = @[ @"Project Update", @"Appointments", @"Issue Updates" ];
int itemsPerSection = (int)ceil(data.count / 3.0);
CGFloat sectionBottomY = 0;
for (int i = 0; i < sectionKeys.count; i++) {
NSString *key = sectionKeys[i];
UIView *sectionContainer = _sectionViews[key];
CGFloat y = 0;
NSArray *subset = [data subarrayWithRange:NSMakeRange(i * itemsPerSection,
MIN(itemsPerSection, data.count - i * itemsPerSection))];
for (NSDictionary *item in subset) {
UIView *card = [[UIView alloc] initWithFrame:CGRectMake(16, y, self.view.bounds.size.width - 32, 100)]; UIView *card = [[UIView alloc] initWithFrame:CGRectMake(16, y, self.view.bounds.size.width - 32, 100)];
card.backgroundColor = [UIColor whiteColor]; card.backgroundColor = [UIColor whiteColor];
card.layer.cornerRadius = 8; card.layer.cornerRadius = 8;
card.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor; card.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
card.layer.shadowOpacity = 0.8; card.layer.shadowOpacity = 0.8;
card.layer.shadowOffset = CGSizeMake(0, 1); card.layer.shadowOffset = CGSizeMake(0, 1);
[_contentContainer addSubview:card];
UILabel *body = [[UILabel alloc] initWithFrame:CGRectMake(12, 12, card.bounds.size.width - 24, 80)]; UILabel *body = [[UILabel alloc] initWithFrame:CGRectMake(12, 12, card.bounds.size.width - 24, 80)];
body.text = text; body.text = item[@"title"];
body.numberOfLines = 0; body.numberOfLines = 2;
body.font = [UIFont systemFontOfSize:15]; body.font = [UIFont systemFontOfSize:15];
[card addSubview:body]; [card addSubview:body];
[sectionContainer addSubview:card];
y += 120;
}
sectionContainer.frame = CGRectMake(0, sectionContainer.frame.origin.y, self.view.bounds.size.width, y);
sectionBottomY = CGRectGetMaxY(sectionContainer.frame) + 20;
}
return y + 120; _contentContainer.frame = CGRectMake(0, 0, _scrollView.bounds.size.width, sectionBottomY);
_scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width, sectionBottomY);
} }
@end @end
...@@ -8,32 +8,32 @@ ...@@ -8,32 +8,32 @@
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64</string> <string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
<dict> <dict>
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string> <string>ios-arm64</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
</array> </array>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
......
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