Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
weihan-plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Wei Han
weihan-plugin
Commits
09397ebc
Commit
09397ebc
authored
Nov 21, 2025
by
Wei Han
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code update
parent
e54ac633
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
278 additions
and
24 deletions
+278
-24
AppointmentConfirmationViewController.h
...ework/Appointment/AppointmentConfirmationViewController.h
+12
-0
AppointmentConfirmationViewController.mm
...work/Appointment/AppointmentConfirmationViewController.mm
+0
-0
AppointmentDetailsViewController.h
...nFramework/Appointment/AppointmentDetailsViewController.h
+11
-0
AppointmentDetailsViewController.mm
...Framework/Appointment/AppointmentDetailsViewController.mm
+0
-0
AppointmentTimeSlotViewController.mm
...ramework/Appointment/AppointmentTimeSlotViewController.mm
+0
-0
AppointmentViewController.h
...msPluginFramework/Appointment/AppointmentViewController.h
+2
-2
AppointmentViewMoreViewController.h
...Framework/Appointment/AppointmentViewMoreViewController.h
+8
-0
AppointmentViewMoreViewController.mm
...ramework/Appointment/AppointmentViewMoreViewController.mm
+208
-0
DashboardViewController.mm
...k/QmsPluginFramework/Dashboard/DashboardViewController.mm
+37
-22
No files found.
framework/QmsPluginFramework/QmsPluginFramework/Appointment/AppointmentConfirmationViewController.h
0 → 100644
View file @
09397ebc
// AppointmentConfirmationViewController.h
#import <UIKit/UIKit.h>
@interface
AppointmentConfirmationViewController
:
UIViewController
@property
(
nonatomic
,
strong
)
NSString
*
slotId
;
@property
(
nonatomic
,
strong
)
NSString
*
startDate
;
@property
(
nonatomic
,
strong
)
NSString
*
startTime
;
@end
framework/QmsPluginFramework/QmsPluginFramework/Appointment/AppointmentConfirmationViewController.mm
0 → 100644
View file @
09397ebc
This diff is collapsed.
Click to expand it.
framework/QmsPluginFramework/QmsPluginFramework/Appointment/AppointmentDetailsViewController.h
0 → 100644
View file @
09397ebc
// AppointmentDetailsViewController.h
#import <UIKit/UIKit.h>
@interface
AppointmentDetailsViewController
:
UIViewController
@property
(
nonatomic
,
strong
)
NSString
*
appointmentID
;
@property
(
nonatomic
,
strong
)
NSDictionary
*
appointmentData
;
@end
framework/QmsPluginFramework/QmsPluginFramework/Appointment/AppointmentDetailsViewController.mm
0 → 100644
View file @
09397ebc
This diff is collapsed.
Click to expand it.
framework/QmsPluginFramework/QmsPluginFramework/Appointment/AppointmentTimeSlotViewController.mm
View file @
09397ebc
This diff is collapsed.
Click to expand it.
framework/QmsPluginFramework/QmsPluginFramework/Appointment/AppointmentViewController.h
View file @
09397ebc
...
...
@@ -9,8 +9,8 @@ NS_ASSUME_NONNULL_BEGIN
@property
(
nonatomic
,
strong
)
NSString
*
projectName
;
@property
(
nonatomic
,
strong
)
NSString
*
projectId
;
@property
(
nonatomic
,
strong
)
NSArray
*
allSlots
;
// Equivalent to rawSlots
@property
(
nonatomic
,
strong
)
NSMutableArray
*
aryTimeSlot
;
// Equivalent to aryTimeSlotTemp
@property
(
nonatomic
,
strong
)
NSArray
*
allSlots
;
@property
(
nonatomic
,
strong
)
NSMutableArray
*
aryTimeSlot
;
@property
(
nonatomic
,
strong
)
NSString
*
selectedDateString
;
@property
(
nonatomic
,
strong
)
NSDictionary
*
markedDates
;
...
...
framework/QmsPluginFramework/QmsPluginFramework/Appointment/AppointmentViewMoreViewController.h
0 → 100644
View file @
09397ebc
// AppointmentViewMoreViewController.h
#import <UIKit/UIKit.h>
@interface
AppointmentViewMoreViewController
:
UIViewController
@end
framework/QmsPluginFramework/QmsPluginFramework/Appointment/AppointmentViewMoreViewController.mm
0 → 100644
View file @
09397ebc
// AppointmentViewMoreViewController.mm
#import "AppointmentViewMoreViewController.h"
@interface AppointmentViewMoreViewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UIView *topBar;
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *toggleTabButton;
@property (nonatomic, strong) UIView *filterBar;
@property (nonatomic, strong) UILabel *filterLabel;
@property (nonatomic, strong) UIButton *filterButton;
@property (nonatomic, strong) UIView *calendarContainer;
@property (nonatomic, strong) UIView *listingContainer;
@property (nonatomic, strong) UITableView *listingTable;
@property (nonatomic, strong) UIView *bottomButtonContainer;
@property (nonatomic, strong) UIButton *makeAppointmentButton;
@property (nonatomic, strong) UIView *filterOverlay;
@property (nonatomic, strong) UIActivityIndicatorView *loadingView;
@property (nonatomic, assign) BOOL showingCalendar;
@end
@implementation AppointmentViewMoreViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.showingCalendar = YES;
[self setupTopBar];
[self setupFilterBar];
[self setupCalendarView];
[self setupListingView];
[self setupBottomButton];
[self setupFilterOverlay];
[self setupLoadingOverlay];
}
#pragma mark - Top Bar
- (void)setupTopBar {
self.topBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 48)];
self.topBar.backgroundColor = [UIColor colorWithRed:0 green:0.4 blue:0.55 alpha:1];
[self.view addSubview:self.topBar];
self.backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 48, 48)];
[self.backButton setImage:[UIImage imageNamed:@"back24"] forState:UIControlStateNormal];
[self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
[self.topBar addSubview:self.backButton];
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(48, 0,
self.view.bounds.size.width - 96, 48)];
self.titleLabel.text = @"Appointment";
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self.topBar addSubview:self.titleLabel];
self.toggleTabButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.bounds.size.width - 48, 0, 48, 48)];
[self.toggleTabButton setImage:[UIImage imageNamed:@"listing_icon_white"] forState:UIControlStateNormal];
[self.toggleTabButton addTarget:self action:@selector(onToggleTab) forControlEvents:UIControlEventTouchUpInside];
[self.topBar addSubview:self.toggleTabButton];
}
#pragma mark - Filter Bar
- (void)setupFilterBar {
self.filterBar = [[UIView alloc] initWithFrame:CGRectMake(0, 48, self.view.bounds.size.width, 48)];
self.filterBar.backgroundColor = [UIColor colorWithWhite:0.6 alpha:1];
[self.view addSubview:self.filterBar];
self.filterLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, 0, self.view.bounds.size.width - 64, 48)];
self.filterLabel.text = @"Filter by All (Upcoming)";
self.filterLabel.textColor = UIColor.whiteColor;
[self.filterBar addSubview:self.filterLabel];
self.filterButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.bounds.size.width - 48, 0, 48, 48)];
[self.filterButton setImage:[UIImage imageNamed:@"filter_icon"] forState:UIControlStateNormal];
[self.filterButton addTarget:self action:@selector(onFilterButton) forControlEvents:UIControlEventTouchUpInside];
[self.filterBar addSubview:self.filterButton];
}
#pragma mark - Calendar (placeholder container)
- (void)setupCalendarView {
CGFloat top = CGRectGetMaxY(self.filterBar.frame);
self.calendarContainer = [[UIView alloc] initWithFrame:CGRectMake(0, top,
self.view.bounds.size.width,
self.view.bounds.size.height - top - 62)];
self.calendarContainer.backgroundColor = UIColor.whiteColor;
UILabel *placeholder = [[UILabel alloc] initWithFrame:self.calendarContainer.bounds];
placeholder.text = @"CALENDAR VIEW PLACEHOLDER";
placeholder.textAlignment = NSTextAlignmentCenter;
placeholder.textColor = UIColor.darkGrayColor;
[self.calendarContainer addSubview:placeholder];
[self.view addSubview:self.calendarContainer];
}
#pragma mark - Listing Table
- (void)setupListingView {
CGFloat top = CGRectGetMaxY(self.filterBar.frame);
self.listingContainer = [[UIView alloc] initWithFrame:CGRectMake(0, top,
self.view.bounds.size.width,
self.view.bounds.size.height - top - 62)];
self.listingContainer.backgroundColor = UIColor.whiteColor;
self.listingContainer.hidden = YES;
self.listingTable = [[UITableView alloc] initWithFrame:self.listingContainer.bounds style:UITableViewStyleGrouped];
self.listingTable.delegate = self;
self.listingTable.dataSource = self;
[self.listingContainer addSubview:self.listingTable];
[self.view addSubview:self.listingContainer];
}
#pragma mark - Bottom Button
- (void)setupBottomButton {
CGFloat h = 62;
self.bottomButtonContainer = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - h, self.view.bounds.size.width, h)];
self.bottomButtonContainer.backgroundColor = [UIColor colorWithRed:0 green:0.4 blue:0.55 alpha:1];
[self.view addSubview:self.bottomButtonContainer];
self.makeAppointmentButton = [[UIButton alloc] initWithFrame:self.bottomButtonContainer.bounds];
[self.makeAppointmentButton setTitle:@"Make Appointment" forState:UIControlStateNormal];
[self.makeAppointmentButton addTarget:self action:@selector(onMakeAppointment) forControlEvents:UIControlEventTouchUpInside];
[self.bottomButtonContainer addSubview:self.makeAppointmentButton];
}
#pragma mark - Filter Overlay
- (void)setupFilterOverlay {
self.filterOverlay = [[UIView alloc] initWithFrame:self.view.bounds];
self.filterOverlay.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
self.filterOverlay.hidden = YES;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 40)];
label.text = @"FILTER OPTIONS PLACEHOLDER";
label.textAlignment = NSTextAlignmentCenter;
[self.filterOverlay addSubview:label];
[self.view addSubview:self.filterOverlay];
}
#pragma mark - Loading Overlay
- (void)setupLoadingOverlay {
self.loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];
self.loadingView.center = self.view.center;
self.loadingView.hidesWhenStopped = YES;
[self.view addSubview:self.loadingView];
}
#pragma mark - Actions
- (void)onBack {
[self.navigationController popViewControllerAnimated:YES];
}
- (void)onToggleTab {
self.showingCalendar = !self.showingCalendar;
self.calendarContainer.hidden = !self.showingCalendar;
self.listingContainer.hidden = self.showingCalendar;
}
- (void)onFilterButton {
self.filterOverlay.hidden = !self.filterOverlay.hidden;
}
- (void)onMakeAppointment {
NSLog(@"Make appointment tapped");
}
#pragma mark - TableView placeholder methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3; // placeholder
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2; // placeholder
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellId = @"listingCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
cell.textLabel.text = @"Unit No";
cell.detailTextLabel.text = @"Owner Name";
return cell;
}
@end
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/DashboardViewController.mm
View file @
09397ebc
...
...
@@ -8,6 +8,7 @@
#import "IssueDetailViewController.h"
#import "IssuesViewController.h"
#import "AppointmentViewController.h"
#import "AppointmentDetailsViewController.h"
@interface DashboardViewController ()
...
...
@@ -691,7 +692,6 @@
return card;
}
- (UIView *)makeAppointmentCard:(NSDictionary *)item width:(CGFloat)width {
UIView *card = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 90)];
card.backgroundColor = UIColor.whiteColor;
...
...
@@ -699,13 +699,13 @@
card.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
card.layer.shadowOpacity = 0.3;
card.layer.shadowOffset = CGSizeMake(0, 1);
// Extract fields
NSString *appointmentType = item[@"appointment_type"] ?: @"-";
NSString *status = item[@"status"] ?: @"-";
NSString *startDate = item[@"start_date"] ?: @"-";
NSString *startTime = item[@"start_time"] ?: @"-";
NSString *buyerName = @"-";
NSArray *buyers = item[@"primary_buyer"];
if ([buyers isKindOfClass:[NSArray class]] && buyers.count > 0) {
...
...
@@ -714,49 +714,50 @@
buyerName = buyer[@"name"];
}
}
// Notification Icon
UIView *iconCircle = [[UIView alloc] initWithFrame:CGRectMake(12, 14, 24, 24)];
iconCircle.backgroundColor = [UIColor colorWithRed:1.0 green:0.4 blue:0.4 alpha:1.0];
// red tone
iconCircle.backgroundColor = [UIColor colorWithRed:1.0 green:0.4 blue:0.4 alpha:1.0];
iconCircle.layer.cornerRadius = 12;
UIImageView *bell = [[UIImageView alloc] initWithImage:[UIImage systemImageNamed:@"bell.fill"]];
bell.tintColor = UIColor.whiteColor;
bell.frame = CGRectMake(4, 4, 16, 16);
[iconCircle addSubview:bell];
[card addSubview:iconCircle];
//
=== Status ===
//
Status
UILabel *statusLabel = [[UILabel alloc] initWithFrame:CGRectMake(44, 12, 180, 26)];
statusLabel.text = status;
statusLabel.font = [UIFont boldSystemFontOfSize:17];
statusLabel.textColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
// teal
statusLabel.textColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
[card addSubview:statusLabel];
//
=== Time (right aligned) ===
//
Time
UILabel *timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(width - 90, 12, 80, 26)];
timeLabel.textAlignment = NSTextAlignmentRight;
timeLabel.text = startTime;
timeLabel.font = [UIFont boldSystemFontOfSize:15];
timeLabel.textColor = [UIColor grayColor];
[card addSubview:timeLabel];
// === Description text ===
NSString *desc = [NSString stringWithFormat:
@"You have a %@ appointment on %@, %@",
appointmentType, startDate, buyerName];
// Description
NSString *desc = [NSString stringWithFormat:@"You have a %@ appointment on %@, %@", appointmentType, startDate, buyerName];
UILabel *descLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, 46, width - 32, 36)];
descLabel.text = desc;
descLabel.font = [UIFont systemFontOfSize:15];
descLabel.numberOfLines = 2;
descLabel.textColor = [UIColor blackColor];
[card addSubview:descLabel];
// === Tap animation ===
// Store appointment data so tap handler can retrieve it
objc_setAssociatedObject(card, "appointmentData", item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// Tap
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleAppointmentTap:)];
[card addGestureRecognizer:tap];
return card;
}
...
...
@@ -971,8 +972,22 @@
- (void)handleAppointmentTap:(UITapGestureRecognizer *)gesture {
UIView *card = gesture.view;
[self animateTapForView:card];
NSLog(@"📅 Appointment card tapped");
// TODO: open AppointmentDetails in future
NSDictionary *appointmentData = objc_getAssociatedObject(card, "appointmentData");
if (!appointmentData) {
NSLog(@"⚠️ No appointment data found");
return;
}
NSLog(@"📅 Opening AppointmentDetails with: %@", appointmentData);
AppointmentDetailsViewController *vc = [[AppointmentDetailsViewController alloc] init];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
//vc.something = something;
[self presentViewController:vc animated:YES completion:nil];
}
- (void)handleIssueTap:(UITapGestureRecognizer *)gesture {
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment