Commit d5fc7ec0 authored by Wei Han's avatar Wei Han

code update

parent 01266f51
// DashboardViewController.h // DashboardViewController.h
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "DrawerController.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
...@@ -8,6 +9,11 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -8,6 +9,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy) NSString *ClientID; @property (nonatomic, copy) NSString *ClientID;
@property (nonatomic, copy) NSString *ClientCode; @property (nonatomic, copy) NSString *ClientCode;
@property (nonatomic, copy) NSString *user_token; @property (nonatomic, copy) NSString *user_token;
@property (nonatomic, weak) DrawerController *drawerController;
- (instancetype)initWithClientID:(NSString *)clientID
clientCode:(NSString *)clientCode
userToken:(NSString *)userToken;
@end @end
......
...@@ -49,6 +49,18 @@ ...@@ -49,6 +49,18 @@
CGFloat _currentY; CGFloat _currentY;
} }
- (instancetype)initWithClientID:(NSString *)clientID
clientCode:(NSString *)clientCode
userToken:(NSString *)userToken {
self = [super initWithNibName:nil bundle:nil];
if (self) {
_ClientID = [clientID copy];
_ClientCode = [clientCode copy];
_user_token = [userToken copy];
}
return self;
}
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0]; self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0];
...@@ -61,8 +73,9 @@ ...@@ -61,8 +73,9 @@
self.projectCode = @"PTD197656"; self.projectCode = @"PTD197656";
self.projectName = @"Ara E`Residence Dev"; self.projectName = @"Ara E`Residence Dev";
[self refreshDashboardContent]; [self checkAndRefreshAPIs];
NSLog(@"in viewDidLoad ClientID: %@, ClientCode: %@, user_token: %@", self.ClientID, self.ClientCode, self.user_token); NSLog(@"in viewDidLoad ClientID: %@, ClientCode: %@, user_token: %@", self.ClientID, self.ClientCode, self.user_token);
NSLog(@"dashboard.drawerController = %@", self.drawerController);
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
...@@ -73,6 +86,16 @@ ...@@ -73,6 +86,16 @@
NSLog(@"in viewWillAppear ClientID: %@, ClientCode: %@, user_token: %@", self.ClientID, self.ClientCode, self.user_token); NSLog(@"in viewWillAppear ClientID: %@, ClientCode: %@, user_token: %@", self.ClientID, self.ClientCode, self.user_token);
} }
- (void)checkAndRefreshAPIs {
// Only trigger API calls when all props are set and not the placeholder
if (![_ClientID isEqualToString:@"clientID_loading"] &&
![_ClientCode isEqualToString:@"clientCode_loading"] &&
![_user_token isEqualToString:@"userToken_loading"]) {
NSLog(@"in checkAndRefreshApis ClientID: %@, ClientCode: %@, user_token: %@", self.ClientID, self.ClientCode, self.user_token);
[self refreshDashboardContent]; // Your API call method
}
}
#pragma mark - Refresh Logic #pragma mark - Refresh Logic
- (void)refreshDashboardContent { - (void)refreshDashboardContent {
NSLog(@"🔁 Refreshing dashboard content..."); NSLog(@"🔁 Refreshing dashboard content...");
...@@ -205,6 +228,21 @@ ...@@ -205,6 +228,21 @@
[self.projectNameLabel.centerYAnchor constraintEqualToAnchor:headerBar.centerYAnchor] [self.projectNameLabel.centerYAnchor constraintEqualToAnchor:headerBar.centerYAnchor]
]]; ]];
// --- Menu Button (Top Right) ---
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],
]];
// ----------------------- // -----------------------
// Unit name bottom-left // Unit name bottom-left
// ----------------------- // -----------------------
...@@ -265,10 +303,6 @@ ...@@ -265,10 +303,6 @@
} }
} }
- (void)handleMenuButtonTapped {
NSLog(@"🍔 Menu button tapped");
}
#pragma mark - Footer #pragma mark - Footer
- (void)setupFooter { - (void)setupFooter {
CGFloat footerHeight = 80.0; CGFloat footerHeight = 80.0;
...@@ -1206,4 +1240,29 @@ ...@@ -1206,4 +1240,29 @@
self.spinner = nil; self.spinner = nil;
} }
- (void)handleMenuButtonTapped {
NSLog(@"🍔 Menu button tapped");
if (self.drawerController) {
[self.drawerController toggleDrawer];
} else {
NSLog(@"⚠️ drawerController not set on DashboardViewController");
}
}
#pragma mark - prop setter
- (void)setClientID:(NSString *)ClientID {
_ClientID = [ClientID copy];
[self checkAndRefreshAPIs];
}
- (void)setClientCode:(NSString *)ClientCode {
_ClientCode = [ClientCode copy];
[self checkAndRefreshAPIs];
}
- (void)setUser_token:(NSString *)user_token {
_user_token = [user_token copy];
[self checkAndRefreshAPIs];
}
@end @end
// DrawerController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
extern NSString * const DrawerDidSelectItemNotification; // posted when an item is tapped
@interface DrawerController : UIViewController
@property (nonatomic, strong, readonly) UIViewController *mainViewController;
@property (nonatomic, strong, readonly) UIViewController *drawerViewController;
// ✅ New initializer: pass drawer + client props directly
- (instancetype)initWithDrawerViewController:(UIViewController *)drawer
clientID:(NSString *)clientID
clientCode:(NSString *)clientCode
userToken:(NSString *)user_token;
// Drawer actions
- (void)openDrawer;
- (void)closeDrawer;
- (void)toggleDrawer;
- (BOOL)isDrawerOpen;
// Optional: keep setters if props can change later
@property (nonatomic, copy) NSString *ClientID;
@property (nonatomic, copy) NSString *ClientCode;
@property (nonatomic, copy) NSString *user_token;
@end
NS_ASSUME_NONNULL_END
// DrawerController.m
#import "DrawerController.h"
#import "DashboardViewController.h"
NSString * const DrawerDidSelectItemNotification = @"DrawerDidSelectItemNotification";
@interface DrawerController () <UIGestureRecognizerDelegate>
@property (nonatomic, strong) DashboardViewController *mainVC;
@property (nonatomic, strong) UIViewController *drawerVC;
@property (nonatomic, strong) UIView *overlayView;
@property (nonatomic, assign) BOOL drawerOpen;
@property (nonatomic, assign) CGFloat drawerWidth;
@property (nonatomic, strong) UIPanGestureRecognizer *panGR;
@property (nonatomic, strong) NSLayoutConstraint *drawerLeadingConstraint;
@end
@implementation DrawerController
#pragma mark - Initializer
- (instancetype)initWithDrawerViewController:(UIViewController *)drawer
clientID:(NSString *)clientID
clientCode:(NSString *)clientCode
userToken:(NSString *)user_token {
self = [super initWithNibName:nil bundle:nil];
if (!self) return nil;
// 1️⃣ Initialize DashboardViewController with props
_mainVC = [[DashboardViewController alloc] initWithClientID:clientID
clientCode:clientCode
userToken:user_token];
// 2️⃣ Set back-reference to drawerController
_mainVC.drawerController = self;
// 3️⃣ Save props locally
_ClientID = [clientID copy];
_ClientCode = [clientCode copy];
_user_token = [user_token copy];
// 4️⃣ Set drawer VC and drawer width
_drawerVC = drawer;
_drawerWidth = MIN([UIScreen mainScreen].bounds.size.width * 0.78, 360);
return self;
}
#pragma mark - View Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self setupDrawer];
[self setupOverlay];
[self setupMainVC];
[self setupPanGesture];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(menuItemSelected:)
name:DrawerDidSelectItemNotification
object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Getters
- (UIViewController *)mainViewController {
return _mainVC;
}
- (UIViewController *)drawerViewController {
return _drawerVC;
}
#pragma mark - Setup UI
- (void)setupDrawer {
[self addChildViewController:self.drawerVC];
self.drawerVC.view.translatesAutoresizingMaskIntoConstraints = NO;
self.drawerVC.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.drawerVC.view];
[self.drawerVC didMoveToParentViewController:self];
self.drawerLeadingConstraint =
[self.drawerVC.view.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:-self.drawerWidth];
[self.drawerVC.view.widthAnchor constraintEqualToConstant:self.drawerWidth].active = YES;
[self.drawerVC.view.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES;
[self.drawerVC.view.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
self.drawerLeadingConstraint.active = YES;
}
- (void)setupOverlay {
// Overlay only covers the mainVC, not the drawer
self.overlayView = [[UIView alloc] initWithFrame:self.mainVC.view.frame];
self.overlayView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
self.overlayView.alpha = 0.0;
self.overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// Tap gesture to close drawer
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeDrawer)];
[self.overlayView addGestureRecognizer:tap];
// Add overlay **below** the drawer so it doesn't block menu interactions
[self.view insertSubview:self.overlayView belowSubview:self.drawerVC.view];
}
- (void)setupMainVC {
[self addChildViewController:self.mainVC];
self.mainVC.view.frame = self.view.bounds;
self.mainVC.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.mainVC.view];
[self.mainVC didMoveToParentViewController:self];
}
- (void)setupPanGesture {
self.panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
self.panGR.delegate = self;
[self.mainVC.view addGestureRecognizer:self.panGR];
}
#pragma mark - Drawer Actions
- (void)openDrawer {
// Make sure overlay and drawer are on top
[self.view bringSubviewToFront:self.overlayView];
[self.view bringSubviewToFront:self.drawerVC.view];
self.drawerLeadingConstraint.constant = 0;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
self.overlayView.alpha = 1.0;
}];
self.drawerOpen = YES;
}
- (void)closeDrawer {
self.drawerLeadingConstraint.constant = -self.drawerWidth;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
self.overlayView.alpha = 0.0;
}];
self.drawerOpen = NO;
}
- (void)toggleDrawer {
if (self.drawerOpen) [self closeDrawer];
else [self openDrawer];
}
- (BOOL)isDrawerOpen {
return self.drawerOpen;
}
#pragma mark - Pan Gesture
- (void)handlePan:(UIPanGestureRecognizer *)pan {
CGPoint translation = [pan translationInView:self.view];
CGFloat x = translation.x;
static CGFloat startX;
if (pan.state == UIGestureRecognizerStateBegan) {
startX = self.mainVC.view.transform.tx;
} else if (pan.state == UIGestureRecognizerStateChanged) {
CGFloat newTx = startX + x;
newTx = MAX(0, newTx);
newTx = MIN(self.drawerWidth, newTx);
CGFloat progress = newTx / self.drawerWidth;
self.mainVC.view.transform = CGAffineTransformMakeTranslation(newTx, 0);
self.drawerLeadingConstraint.constant = -self.drawerWidth + newTx;
[self.view layoutIfNeeded];
self.overlayView.alpha = progress;
} else if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled) {
CGFloat velocityX = [pan velocityInView:self.view].x;
CGFloat currentTx = self.mainVC.view.transform.tx;
BOOL shouldOpen = NO;
if (fabs(velocityX) > 400) {
shouldOpen = (velocityX > 0);
} else {
shouldOpen = currentTx > (self.drawerWidth * 0.45);
}
if (shouldOpen) [self openDrawer];
else [self closeDrawer];
}
}
#pragma mark - Notification
- (void)menuItemSelected:(NSNotification *)note {
[self closeDrawer];
}
#pragma mark - Gesture Delegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == self.panGR) {
CGPoint v = [self.panGR velocityInView:self.view];
return fabs(v.x) > fabs(v.y);
}
return YES;
}
#pragma mark - Prop Setters
- (void)setClientID:(NSString *)ClientID {
_ClientID = [ClientID copy];
if ([self.mainVC respondsToSelector:NSSelectorFromString(@"setClientID:")]) {
[self.mainVC setValue:_ClientID forKey:@"ClientID"];
}
}
- (void)setClientCode:(NSString *)ClientCode {
_ClientCode = [ClientCode copy];
if ([self.mainVC respondsToSelector:NSSelectorFromString(@"setClientCode:")]) {
[self.mainVC setValue:_ClientCode forKey:@"ClientCode"];
}
}
- (void)setUser_token:(NSString *)user_token {
_user_token = [user_token copy];
if ([self.mainVC respondsToSelector:NSSelectorFromString(@"setUser_token:")]) {
[self.mainVC setValue:_user_token forKey:@"user_token"];
}
}
@end
// DrawerViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface DrawerViewController : UIViewController
// Data to populate (you can set these from GLOBALS or app state)
@property (nonatomic, strong) NSString *profileName;
@property (nonatomic, strong) NSString *profileEmail;
@property (nonatomic, strong) NSURL *profileImageURL;
@property (nonatomic, strong) NSArray<NSDictionary *> *menuItems; // array of { @"title":..., @"action":... }
@end
NS_ASSUME_NONNULL_END
// DrawerViewController.m
#import "DrawerViewController.h"
#import "DrawerController.h"
#import "SyncScreenViewController.h"
@interface DrawerViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) UIImageView *avatarView;
@property (nonatomic, strong) UILabel *nameLabel;
@property (nonatomic, strong) UILabel *emailLabel;
@property (nonatomic, strong) UITableView *table;
@property (nonatomic, strong) UIView *headerContainer;
@end
@implementation DrawerViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:0.02 green:0.36 blue:0.47 alpha:1.0]; // #035E79-ish
[self buildUI];
[self loadDefaultsIfNeeded];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleDrawerAction:)
name:DrawerDidSelectItemNotification
object:nil];
}
- (void)buildUI {
self.view.backgroundColor = [UIColor colorWithRed:0.02 green:0.36 blue:0.47 alpha:1.0];
CGFloat topHeight = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 180 : 120;
// HEADER CONTAINER
self.headerContainer = [[UIView alloc] init];
self.headerContainer.translatesAutoresizingMaskIntoConstraints = NO;
self.headerContainer.backgroundColor = [UIColor colorWithRed:0 green:0.42 blue:0.55 alpha:1.0];
[self.view addSubview:self.headerContainer];
[NSLayoutConstraint activateConstraints:@[
[self.headerContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerContainer.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.headerContainer.heightAnchor constraintEqualToConstant:topHeight],
]];
// TOUCHABLE HEADER
UIButton *profileTap = [UIButton buttonWithType:UIButtonTypeCustom];
profileTap.translatesAutoresizingMaskIntoConstraints = NO;
[profileTap addTarget:self action:@selector(profileTapped) forControlEvents:UIControlEventTouchUpInside];
[self.headerContainer addSubview:profileTap];
[NSLayoutConstraint activateConstraints:@[
[profileTap.leadingAnchor constraintEqualToAnchor:self.headerContainer.leadingAnchor],
[profileTap.trailingAnchor constraintEqualToAnchor:self.headerContainer.trailingAnchor],
[profileTap.topAnchor constraintEqualToAnchor:self.headerContainer.topAnchor],
[profileTap.bottomAnchor constraintEqualToAnchor:self.headerContainer.bottomAnchor],
]];
// AVATAR
CGFloat avatarSize = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 100 : 50;
self.avatarView = [[UIImageView alloc] init];
self.avatarView.translatesAutoresizingMaskIntoConstraints = NO;
self.avatarView.layer.cornerRadius = avatarSize / 2.0;
self.avatarView.clipsToBounds = YES;
self.avatarView.layer.borderColor = [UIColor whiteColor].CGColor;
self.avatarView.layer.borderWidth = 1.0;
self.avatarView.contentMode = UIViewContentModeScaleAspectFill;
[self.headerContainer addSubview:self.avatarView];
[NSLayoutConstraint activateConstraints:@[
[self.avatarView.leadingAnchor constraintEqualToAnchor:self.headerContainer.leadingAnchor constant:18],
[self.avatarView.centerYAnchor constraintEqualToAnchor:self.headerContainer.centerYAnchor],
[self.avatarView.widthAnchor constraintEqualToConstant:avatarSize],
[self.avatarView.heightAnchor constraintEqualToConstant:avatarSize],
]];
// NAME LABEL
self.nameLabel = [[UILabel alloc] init];
self.nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.nameLabel.textColor = UIColor.whiteColor;
self.nameLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightRegular];
self.nameLabel.numberOfLines = 2;
[self.headerContainer addSubview:self.nameLabel];
// EMAIL LABEL
self.emailLabel = [[UILabel alloc] init];
self.emailLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.emailLabel.textColor = UIColor.whiteColor;
self.emailLabel.font = [UIFont systemFontOfSize:14];
[self.headerContainer addSubview:self.emailLabel];
[NSLayoutConstraint activateConstraints:@[
[self.nameLabel.leadingAnchor constraintEqualToAnchor:self.avatarView.trailingAnchor constant:16],
[self.nameLabel.trailingAnchor constraintEqualToAnchor:self.headerContainer.trailingAnchor constant:-18],
[self.nameLabel.bottomAnchor constraintEqualToAnchor:self.headerContainer.centerYAnchor constant:-4],
[self.emailLabel.leadingAnchor constraintEqualToAnchor:self.nameLabel.leadingAnchor],
[self.emailLabel.trailingAnchor constraintEqualToAnchor:self.nameLabel.trailingAnchor],
[self.emailLabel.topAnchor constraintEqualToAnchor:self.nameLabel.bottomAnchor constant:4],
]];
// MENU TABLE
self.table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
self.table.translatesAutoresizingMaskIntoConstraints = NO;
self.table.dataSource = self;
self.table.delegate = self;
self.table.backgroundColor = UIColor.clearColor;
self.table.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:self.table];
[NSLayoutConstraint activateConstraints:@[
[self.table.topAnchor constraintEqualToAnchor:self.headerContainer.bottomAnchor],
[self.table.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.table.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.table.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
]];
}
- (void)loadDefaultsIfNeeded {
if (!self.profileName) self.profileName = @"Guest User";
if (!self.profileEmail) self.profileEmail = @"guest@example.com";
if (!self.profileImageURL) self.profileImageURL = nil;
self.nameLabel.text = self.profileName;
self.emailLabel.text = self.profileEmail;
if (self.profileImageURL) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *d = [NSData dataWithContentsOfURL:self.profileImageURL];
UIImage *img = d ? [UIImage imageWithData:d] : [UIImage imageNamed:@"small_placeholder"];
dispatch_async(dispatch_get_main_queue(), ^{
self.avatarView.image = img;
});
});
} else {
self.avatarView.image = [UIImage imageNamed:@"small_placeholder"];
}
if (!self.menuItems) {
self.menuItems = @[
@{@"title": @"Project List", @"action": @"projectList"},
@{@"title": @"Notification", @"action": @"notification"},
@{@"title": @"Announcement", @"action": @"announcement"},
@{@"title": @"Help", @"action": @"help"},
@{@"title": @"Sync", @"action": @"sync"},
@{@"title": @"Logout", @"action": @"logout"}
];
}
[self.table reloadData];
}
#pragma mark - Profile tap
- (void)profileTapped {
// Post a notification to navigate
[[NSNotificationCenter defaultCenter] postNotificationName:DrawerDidSelectItemNotification object:nil userInfo:@{@"action": @"profile"}];
}
#pragma mark - Table datasource/delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.menuItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellId = @"drawerCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont systemFontOfSize:16];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSDictionary *item = self.menuItems[indexPath.row];
cell.textLabel.text = item[@"title"] ?: @"";
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 56; }
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *item = self.menuItems[indexPath.row];
NSString *action = item[@"action"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"DrawerDidSelectItemNotification"
object:action];
}
- (void)handleDrawerAction:(NSNotification *)notification {
NSString *action = notification.object;
if ([action isEqualToString:@"projectList"]) {
// [self openProjectList];
NSLog(@"navigating to Project List");
}
else if ([action isEqualToString:@"notification"]) {
// [self openNotification];
NSLog(@"navigating to Notification");
}
else if ([action isEqualToString:@"announcement"]) {
// [self openAnnouncement];
NSLog(@"navigating to Announcement");
}
else if ([action isEqualToString:@"help"]) {
// [self openHelp];
NSLog(@"navigating to Help");
}
else if ([action isEqualToString:@"sync"]) {
NSLog(@"navigating to Sync");
SyncScreenViewController *nextVC = [[SyncScreenViewController alloc] init];
nextVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:nextVC animated:YES completion:nil];
}
else if ([action isEqualToString:@"logout"]) {
// [self performLogout];
NSLog(@"navigating to Logout");
}
}
@end
//QmsPlugin.mm // QmsPlugin.mm
#import "QmsPlugin.h" #import "QmsPlugin.h"
#import "DashboardViewController.h" #import "DashboardViewController.h"
#import "DrawerViewController.h"
#import "DrawerController.h"
@implementation QmsPluginUI @implementation QmsPluginUI
+ (UIViewController *)makeViewController { + (UIViewController *)makeViewController {
DashboardViewController *vc = [[DashboardViewController alloc] init];
return vc; // 1. Create main dashboard screen (props will be set via DrawerController)
DrawerViewController *drawer = [[DrawerViewController alloc] init];
drawer.profileName = @"placeholder";
drawer.profileEmail = @"placeholder";
// 2. Set client props (replace with actual values from your globals or RN)
NSString *clientID = @"clientID_loading";
NSString *clientCode = @"clientCode_loading";
NSString *userToken = @"userToken_loading";
// 3. Create DrawerController with drawer + props
DrawerController *drawerController =
[[DrawerController alloc] initWithDrawerViewController:drawer
clientID:clientID
clientCode:clientCode
userToken:userToken];
// 4. Allow dashboard to call openDrawer() via drawerController.mainViewController
if ([drawerController.mainViewController isKindOfClass:[DashboardViewController class]]) {
((DashboardViewController *)drawerController.mainViewController).drawerController = drawerController;
}
NSLog(@"drawerController.mainViewController = %@", drawerController.mainViewController);
return drawerController;
} }
@end @end
// SyncViewController.h
#import <UIKit/UIKit.h>
@interface SyncScreenViewController : UIViewController
@end
// SyncViewController.m
#import "SyncScreenViewController.h"
@interface SyncScreenViewController ()
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *lastUpdatedLabel;
@property (nonatomic, strong) UIStackView *cardStack;
@property (nonatomic, strong) UIView *offlineUnitCard;
@property (nonatomic, strong) UIView *pendingItemsCard;
@property (nonatomic, strong) UIView *historyCard;
@property (nonatomic, strong) UIButton *syncButton;
@end
@implementation SyncScreenViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
[self setupHeader];
[self setupMainContent];
[self setupSyncButton];
}
#pragma mark - Header
- (void)setupHeader {
self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerView];
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.backButton setImage:[UIImage imageNamed:@"back24"] forState:UIControlStateNormal];
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:self.backButton];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"SYNC";
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.font = [UIFont boldSystemFontOfSize:18];
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:self.titleLabel];
// Constraints
[NSLayoutConstraint activateConstraints:@[
[self.headerView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerView.heightAnchor constraintEqualToConstant:48],
[self.backButton.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor constant:8],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:32],
[self.backButton.heightAnchor constraintEqualToConstant:32],
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
]];
}
#pragma mark - Main Content
- (void)setupMainContent {
UIView *content = [[UIView alloc] init];
content.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:content];
[NSLayoutConstraint activateConstraints:@[
[content.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:16],
[content.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[content.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
]];
// Last Updated
self.lastUpdatedLabel = [[UILabel alloc] init];
self.lastUpdatedLabel.numberOfLines = 2;
self.lastUpdatedLabel.text = @"Last Updated:\n--";
self.lastUpdatedLabel.textColor = [UIColor grayColor];
self.lastUpdatedLabel.font = [UIFont boldSystemFontOfSize:16];
self.lastUpdatedLabel.translatesAutoresizingMaskIntoConstraints = NO;
[content addSubview:self.lastUpdatedLabel];
[NSLayoutConstraint activateConstraints:@[
[self.lastUpdatedLabel.topAnchor constraintEqualToAnchor:content.topAnchor],
[self.lastUpdatedLabel.leadingAnchor constraintEqualToAnchor:content.leadingAnchor],
[self.lastUpdatedLabel.trailingAnchor constraintEqualToAnchor:content.trailingAnchor],
]];
// Cards Stack
self.cardStack = [[UIStackView alloc] init];
self.cardStack.axis = UILayoutConstraintAxisVertical;
self.cardStack.spacing = 16;
self.cardStack.translatesAutoresizingMaskIntoConstraints = NO;
[content addSubview:self.cardStack];
[NSLayoutConstraint activateConstraints:@[
[self.cardStack.topAnchor constraintEqualToAnchor:self.lastUpdatedLabel.bottomAnchor constant:16],
[self.cardStack.leadingAnchor constraintEqualToAnchor:content.leadingAnchor],
[self.cardStack.trailingAnchor constraintEqualToAnchor:content.trailingAnchor],
]];
// Add 3 cards
[self.cardStack addArrangedSubview:[self createCardWithTitle:@"Offline Units" count:@"0"]];
[self.cardStack addArrangedSubview:[self createCardWithTitle:@"Pending Items" count:@"0"]];
[self.cardStack addArrangedSubview:[self createCardWithTitle:@"History" count:@"0"]];
}
#pragma mark - Card Factory
- (UIView *)createCardWithTitle:(NSString *)title count:(NSString *)countText {
UIView *card = [[UIView alloc] init];
card.backgroundColor = UIColor.whiteColor;
card.layer.borderWidth = 1;
card.layer.borderColor = [UIColor lightGrayColor].CGColor;
card.layer.cornerRadius = 10;
card.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[card.heightAnchor constraintEqualToConstant:120]
]];
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = title;
titleLabel.font = [UIFont boldSystemFontOfSize:20];
titleLabel.textColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
UILabel *countLabel = [[UILabel alloc] init];
countLabel.text = countText;
countLabel.font = [UIFont boldSystemFontOfSize:28];
countLabel.textColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
countLabel.textAlignment = NSTextAlignmentRight;
countLabel.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:titleLabel];
[card addSubview:countLabel];
[NSLayoutConstraint activateConstraints:@[
[titleLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
[titleLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:16],
[countLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-16],
[countLabel.bottomAnchor constraintEqualToAnchor:card.bottomAnchor constant:-16],
]];
return card;
}
#pragma mark - Sync Button
- (void)setupSyncButton {
self.syncButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.syncButton.backgroundColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
[self.syncButton setTitle:@"SYNC" forState:UIControlStateNormal];
[self.syncButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
self.syncButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
self.syncButton.layer.cornerRadius = 8;
self.syncButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.syncButton];
[NSLayoutConstraint activateConstraints:@[
[self.syncButton.topAnchor constraintEqualToAnchor:self.cardStack.bottomAnchor constant:16],
[self.syncButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.syncButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.syncButton.heightAnchor constraintEqualToConstant:50],
[self.syncButton.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:-16],
]];
}
@end
//QmsDashboardViewManager.mm
#import <React/RCTViewManager.h> #import <React/RCTViewManager.h>
#import <QmsPluginFramework/QmsPluginFramework.h> #import <QmsPluginFramework/QmsPluginFramework.h>
#import <QmsPluginFramework/QmsPlugin.h> #import <QmsPluginFramework/QmsPlugin.h>
......
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