Commit 09397ebc authored by Wei Han's avatar Wei Han

code update

parent e54ac633
// 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
// AppointmentConfirmationViewController.mm
#import "AppointmentConfirmationViewController.h"
#import <WebKit/WebKit.h>
@interface AppointmentConfirmationViewController ()
// Top Bar
@property (nonatomic, strong) UIView *navBar;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *closeButton;
// Scroll
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *contentView;
// Summary Section
@property (nonatomic, strong) UILabel *unitLabel;
@property (nonatomic, strong) UIView *stepBanner;
@property (nonatomic, strong) UIView *summaryCard;
@property (nonatomic, strong) UILabel *appointmentTypeLabel;
@property (nonatomic, strong) UILabel *dateLabel;
@property (nonatomic, strong) UILabel *timeLabel;
// Representative Section
@property (nonatomic, strong) UIView *representativeSection;
@property (nonatomic, strong) UILabel *repTitleLabel;
@property (nonatomic, strong) UIButton *repToggleButton;
// T&C
@property (nonatomic, strong) UILabel *tcTitleLabel;
@property (nonatomic, strong) WKWebView *htmlView;
// Bottom Buttons
@property (nonatomic, strong) UIView *bottomBar;
@property (nonatomic, strong) UIButton *editButton;
@property (nonatomic, strong) UIButton *confirmButton;
// Modal Placeholder
@property (nonatomic, strong) UIView *dimOverlay;
@end
@implementation AppointmentConfirmationViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
[self setupNavBar];
[self setupScrollView];
[self setupContentUI];
[self setupBottomBar];
}
#pragma mark - Navigation Bar
- (void)setupNavBar {
self.navBar = [[UIView alloc] init];
self.navBar.backgroundColor = [UIColor colorWithRed:0 green:0.45 blue:0.55 alpha:1];
self.navBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.navBar];
// Title
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"Make Appointment";
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.font = [UIFont boldSystemFontOfSize:18];
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.navBar addSubview:self.titleLabel];
// Close Button
self.closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.closeButton setImage:[UIImage imageNamed:@"icon_white_cancel"] forState:UIControlStateNormal];
self.closeButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.navBar addSubview:self.closeButton];
// Constraints
[NSLayoutConstraint activateConstraints:@[
[self.navBar.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.navBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.navBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.navBar.heightAnchor constraintEqualToConstant:48],
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.navBar.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.navBar.centerYAnchor],
[self.closeButton.leadingAnchor constraintEqualToAnchor:self.navBar.leadingAnchor constant:12],
[self.closeButton.centerYAnchor constraintEqualToAnchor:self.navBar.centerYAnchor],
[self.closeButton.widthAnchor constraintEqualToConstant:30],
[self.closeButton.heightAnchor constraintEqualToConstant:30],
]];
}
#pragma mark - ScrollView
- (void)setupScrollView {
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.scrollView];
self.contentView = [[UIView alloc] init];
self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:self.contentView];
[NSLayoutConstraint activateConstraints:@[
[self.scrollView.topAnchor constraintEqualToAnchor:self.navBar.bottomAnchor],
[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.topAnchor],
[self.contentView.leadingAnchor constraintEqualToAnchor:self.scrollView.leadingAnchor],
[self.contentView.trailingAnchor constraintEqualToAnchor:self.scrollView.trailingAnchor],
[self.contentView.bottomAnchor constraintEqualToAnchor:self.scrollView.bottomAnchor],
[self.contentView.widthAnchor constraintEqualToAnchor:self.scrollView.widthAnchor],
]];
}
#pragma mark - Main UI
- (void)setupContentUI {
// Unit Label
self.unitLabel = [[UILabel alloc] init];
self.unitLabel.text = @"ProjectName, Unit 12-34";
self.unitLabel.font = [UIFont boldSystemFontOfSize:20];
self.unitLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.unitLabel];
// Step Banner
self.stepBanner = [[UIView alloc] init];
self.stepBanner.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1];
self.stepBanner.layer.cornerRadius = 12;
self.stepBanner.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.stepBanner];
UILabel *stepLabel = [[UILabel alloc] init];
stepLabel.text = @"Step 3: Appointment Summary";
stepLabel.font = [UIFont systemFontOfSize:15];
stepLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.stepBanner addSubview:stepLabel];
// Summary Card
self.summaryCard = [[UIView alloc] init];
self.summaryCard.backgroundColor = [UIColor colorWithRed:0 green:0.23 blue:0.30 alpha:1];
self.summaryCard.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.summaryCard];
self.appointmentTypeLabel = [[UILabel alloc] init];
self.appointmentTypeLabel.text = @"Inspection";
self.appointmentTypeLabel.textColor = UIColor.whiteColor;
self.appointmentTypeLabel.font = [UIFont boldSystemFontOfSize:22];
self.appointmentTypeLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.summaryCard addSubview:self.appointmentTypeLabel];
self.dateLabel = [[UILabel alloc] init];
self.dateLabel.text = @"20 Jan 2025";
self.dateLabel.textColor = UIColor.whiteColor;
self.dateLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.summaryCard addSubview:self.dateLabel];
self.timeLabel = [[UILabel alloc] init];
self.timeLabel.text = @"09:00 AM";
self.timeLabel.textColor = UIColor.whiteColor;
self.timeLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.summaryCard addSubview:self.timeLabel];
// Representative Section
self.representativeSection = [[UIView alloc] init];
self.representativeSection.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.representativeSection];
self.repTitleLabel = [[UILabel alloc] init];
self.repTitleLabel.text = @"Representative Attending?";
self.repTitleLabel.font = [UIFont boldSystemFontOfSize:17];
self.repTitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.repToggleButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.repToggleButton.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];
self.repToggleButton.layer.cornerRadius = 14;
self.repToggleButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.representativeSection addSubview:self.repTitleLabel];
[self.representativeSection addSubview:self.repToggleButton];
// Terms & Conditions
self.tcTitleLabel = [[UILabel alloc] init];
self.tcTitleLabel.text = @"Terms & Conditions";
self.tcTitleLabel.font = [UIFont boldSystemFontOfSize:16];
self.tcTitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.tcTitleLabel];
self.htmlView = [[WKWebView alloc] init];
self.htmlView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.htmlView];
// Layout
[NSLayoutConstraint activateConstraints:@[
[self.unitLabel.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:20],
[self.unitLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20],
[self.stepBanner.topAnchor constraintEqualToAnchor:self.unitLabel.bottomAnchor constant:20],
[self.stepBanner.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[self.stepBanner.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
[self.stepBanner.heightAnchor constraintEqualToConstant:50],
[stepLabel.centerYAnchor constraintEqualToAnchor:self.stepBanner.centerYAnchor],
[stepLabel.leadingAnchor constraintEqualToAnchor:self.stepBanner.leadingAnchor constant:12],
// Summary Card
[self.summaryCard.topAnchor constraintEqualToAnchor:self.stepBanner.bottomAnchor constant:20],
[self.summaryCard.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.summaryCard.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
[self.appointmentTypeLabel.topAnchor constraintEqualToAnchor:self.summaryCard.topAnchor constant:20],
[self.appointmentTypeLabel.leadingAnchor constraintEqualToAnchor:self.summaryCard.leadingAnchor constant:20],
[self.dateLabel.topAnchor constraintEqualToAnchor:self.appointmentTypeLabel.bottomAnchor constant:16],
[self.dateLabel.leadingAnchor constraintEqualToAnchor:self.summaryCard.leadingAnchor constant:20],
[self.timeLabel.topAnchor constraintEqualToAnchor:self.dateLabel.bottomAnchor constant:8],
[self.timeLabel.leadingAnchor constraintEqualToAnchor:self.summaryCard.leadingAnchor constant:20],
[self.timeLabel.bottomAnchor constraintEqualToAnchor:self.summaryCard.bottomAnchor constant:-20],
// Representative
[self.representativeSection.topAnchor constraintEqualToAnchor:self.summaryCard.bottomAnchor constant:30],
[self.representativeSection.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20],
[self.representativeSection.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-20],
[self.representativeSection.heightAnchor constraintEqualToConstant:50],
[self.repTitleLabel.centerYAnchor constraintEqualToAnchor:self.representativeSection.centerYAnchor],
[self.repTitleLabel.leadingAnchor constraintEqualToAnchor:self.representativeSection.leadingAnchor],
[self.repToggleButton.centerYAnchor constraintEqualToAnchor:self.representativeSection.centerYAnchor],
[self.repToggleButton.trailingAnchor constraintEqualToAnchor:self.representativeSection.trailingAnchor],
[self.repToggleButton.widthAnchor constraintEqualToConstant:28],
[self.repToggleButton.heightAnchor constraintEqualToConstant:28],
// Terms & Conditions
[self.tcTitleLabel.topAnchor constraintEqualToAnchor:self.representativeSection.bottomAnchor constant:30],
[self.tcTitleLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20],
[self.htmlView.topAnchor constraintEqualToAnchor:self.tcTitleLabel.bottomAnchor constant:12],
[self.htmlView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20],
[self.htmlView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-20],
[self.htmlView.heightAnchor constraintEqualToConstant:200],
[self.htmlView.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-40],
]];
}
#pragma mark - Bottom Bar
- (void)setupBottomBar {
self.bottomBar = [[UIView alloc] init];
self.bottomBar.backgroundColor = UIColor.whiteColor;
self.bottomBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.bottomBar];
self.editButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.editButton setTitle:@"Edit" forState:UIControlStateNormal];
self.editButton.layer.borderColor = [UIColor colorWithRed:0 green:0.45 blue:0.55 alpha:1].CGColor;
self.editButton.layer.borderWidth = 1;
self.editButton.layer.cornerRadius = 20;
self.editButton.translatesAutoresizingMaskIntoConstraints = NO;
self.confirmButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.confirmButton setTitle:@"Confirm" forState:UIControlStateNormal];
self.confirmButton.backgroundColor = [UIColor colorWithRed:0 green:0.45 blue:0.55 alpha:1];
[self.confirmButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
self.confirmButton.layer.cornerRadius = 20;
self.confirmButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.bottomBar addSubview:self.editButton];
[self.bottomBar addSubview:self.confirmButton];
[NSLayoutConstraint activateConstraints:@[
[self.bottomBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.bottomBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.bottomBar.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
[self.bottomBar.heightAnchor constraintEqualToConstant:70],
[self.editButton.leadingAnchor constraintEqualToAnchor:self.bottomBar.leadingAnchor constant:20],
[self.editButton.centerYAnchor constraintEqualToAnchor:self.bottomBar.centerYAnchor],
[self.editButton.widthAnchor constraintEqualToAnchor:self.bottomBar.widthAnchor multiplier:0.45],
[self.editButton.heightAnchor constraintEqualToConstant:48],
[self.confirmButton.trailingAnchor constraintEqualToAnchor:self.bottomBar.trailingAnchor constant:-20],
[self.confirmButton.centerYAnchor constraintEqualToAnchor:self.bottomBar.centerYAnchor],
[self.confirmButton.widthAnchor constraintEqualToAnchor:self.bottomBar.widthAnchor multiplier:0.45],
[self.confirmButton.heightAnchor constraintEqualToConstant:48],
]];
}
@end
// AppointmentDetailsViewController.h
#import <UIKit/UIKit.h>
@interface AppointmentDetailsViewController : UIViewController
@property (nonatomic, strong) NSString *appointmentID;
@property (nonatomic, strong) NSDictionary *appointmentData;
@end
// AppointmentDetailsViewController.mm
#import "AppointmentDetailsViewController.h"
#import <WebKit/WebKit.h>
@interface AppointmentDetailsViewController ()
// UI
@property (nonatomic, strong) UIView *navBar;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *contentView;
@property (nonatomic, strong) UIView *statusBanner;
@property (nonatomic, strong) UILabel *statusLabel;
@property (nonatomic, strong) UILabel *reasonLabel;
@property (nonatomic, strong) UIView *summaryCard;
@property (nonatomic, strong) UIView *repCard;
@property (nonatomic, strong) UIView *buttonSection;
@property (nonatomic, strong) UIView *loadingOverlay;
@end
@implementation AppointmentDetailsViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
[self setupNavBar];
[self setupScrollView];
[self setupStatusBanner];
[self setupSummaryCard];
[self setupRepresentativeCard];
[self setupButtonSection];
[self setupLoadingOverlay];
// load appointment details
[self loadAppointmentDetails];
}
#pragma mark - Navigation Bar
- (void)setupNavBar {
self.navBar = [[UIView alloc] init];
self.navBar.backgroundColor = [UIColor colorWithRed:0 green:0.45 blue:0.55 alpha:1];
self.navBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.navBar];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"Appointment Details";
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.font = [UIFont boldSystemFontOfSize:17];
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.navBar addSubview:self.titleLabel];
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.backButton setImage:[UIImage imageNamed:@"icon_white_back"] forState:UIControlStateNormal];
[self.backButton addTarget:self action:@selector(backTapped) forControlEvents:UIControlEventTouchUpInside];
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.navBar addSubview:self.backButton];
[NSLayoutConstraint activateConstraints:@[
[self.navBar.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.navBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.navBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.navBar.heightAnchor constraintEqualToConstant:50],
[self.backButton.leadingAnchor constraintEqualToAnchor:self.navBar.leadingAnchor constant:10],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.navBar.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:30],
[self.backButton.heightAnchor constraintEqualToConstant:30],
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.navBar.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.navBar.centerYAnchor],
]];
}
#pragma mark - ScrollView
- (void)setupScrollView {
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
self.contentView = [[UIView alloc] init];
self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.scrollView];
[self.scrollView addSubview:self.contentView];
[NSLayoutConstraint activateConstraints:@[
[self.scrollView.topAnchor constraintEqualToAnchor:self.navBar.bottomAnchor],
[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.topAnchor],
[self.contentView.leadingAnchor constraintEqualToAnchor:self.scrollView.leadingAnchor],
[self.contentView.trailingAnchor constraintEqualToAnchor:self.scrollView.trailingAnchor],
[self.contentView.bottomAnchor constraintEqualToAnchor:self.scrollView.bottomAnchor],
[self.contentView.widthAnchor constraintEqualToAnchor:self.scrollView.widthAnchor],
]];
}
#pragma mark - Status Banner
- (void)setupStatusBanner {
self.statusBanner = [[UIView alloc] init];
self.statusBanner.layer.cornerRadius = 12;
self.statusBanner.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.statusBanner];
self.statusLabel = [[UILabel alloc] init];
self.statusLabel.font = [UIFont boldSystemFontOfSize:18];
self.statusLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.statusBanner addSubview:self.statusLabel];
self.reasonLabel = [[UILabel alloc] init];
self.reasonLabel.font = [UIFont systemFontOfSize:14];
self.reasonLabel.numberOfLines = 0;
self.reasonLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.statusBanner addSubview:self.reasonLabel];
[NSLayoutConstraint activateConstraints:@[
[self.statusBanner.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:20],
[self.statusBanner.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[self.statusBanner.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
[self.statusLabel.topAnchor constraintEqualToAnchor:self.statusBanner.topAnchor constant:16],
[self.statusLabel.leadingAnchor constraintEqualToAnchor:self.statusBanner.leadingAnchor constant:16],
[self.reasonLabel.topAnchor constraintEqualToAnchor:self.statusLabel.bottomAnchor constant:8],
[self.reasonLabel.leadingAnchor constraintEqualToAnchor:self.statusBanner.leadingAnchor constant:16],
[self.reasonLabel.trailingAnchor constraintEqualToAnchor:self.statusBanner.trailingAnchor constant:-16],
[self.reasonLabel.bottomAnchor constraintEqualToAnchor:self.statusBanner.bottomAnchor constant:-16],
]];
}
#pragma mark - Appointment Summary Card
- (void)setupSummaryCard {
self.summaryCard = [[UIView alloc] init];
self.summaryCard.backgroundColor = UIColor.whiteColor;
self.summaryCard.layer.cornerRadius = 12;
self.summaryCard.layer.borderWidth = 1;
self.summaryCard.layer.borderColor = [UIColor colorWithWhite:0.9 alpha:1].CGColor;
self.summaryCard.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.summaryCard];
UILabel *title = [[UILabel alloc] init];
title.text = @"Appointment Summary";
title.font = [UIFont boldSystemFontOfSize:16];
title.translatesAutoresizingMaskIntoConstraints = NO;
[self.summaryCard addSubview:title];
[NSLayoutConstraint activateConstraints:@[
[self.summaryCard.topAnchor constraintEqualToAnchor:self.statusBanner.bottomAnchor constant:20],
[self.summaryCard.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[self.summaryCard.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
[title.topAnchor constraintEqualToAnchor:self.summaryCard.topAnchor constant:16],
[title.leadingAnchor constraintEqualToAnchor:self.summaryCard.leadingAnchor constant:16],
]];
// Add additional appointment fields later in applyAppointmentDataToUI
}
#pragma mark - Representative Card
- (void)setupRepresentativeCard {
self.repCard = [[UIView alloc] init];
self.repCard.backgroundColor = UIColor.whiteColor;
self.repCard.layer.cornerRadius = 12;
self.repCard.layer.borderColor = [UIColor colorWithWhite:0.9 alpha:1].CGColor;
self.repCard.layer.borderWidth = 1;
self.repCard.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.repCard];
UILabel *title = [[UILabel alloc] init];
title.text = @"Representative";
title.font = [UIFont boldSystemFontOfSize:16];
title.translatesAutoresizingMaskIntoConstraints = NO;
[self.repCard addSubview:title];
[NSLayoutConstraint activateConstraints:@[
[self.repCard.topAnchor constraintEqualToAnchor:self.summaryCard.bottomAnchor constant:20],
[self.repCard.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
[self.repCard.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
[title.topAnchor constraintEqualToAnchor:self.repCard.topAnchor constant:16],
[title.leadingAnchor constraintEqualToAnchor:self.repCard.leadingAnchor constant:16],
]];
}
#pragma mark - Buttons Section
- (void)setupButtonSection {
self.buttonSection = [[UIView alloc] init];
self.buttonSection.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.buttonSection];
[NSLayoutConstraint activateConstraints:@[
[self.buttonSection.topAnchor constraintEqualToAnchor:self.repCard.bottomAnchor constant:30],
[self.buttonSection.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.buttonSection.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
[self.buttonSection.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-40],
[self.buttonSection.heightAnchor constraintEqualToConstant:200], // dynamic later
]];
}
#pragma mark - Loading Overlay
- (void)setupLoadingOverlay {
self.loadingOverlay = [[UIView alloc] initWithFrame:self.view.bounds];
self.loadingOverlay.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
self.loadingOverlay.hidden = YES;
UIActivityIndicatorView *spin = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];
spin.color = UIColor.whiteColor;
spin.center = self.loadingOverlay.center;
[self.loadingOverlay addSubview:spin];
[self.view addSubview:self.loadingOverlay];
[spin startAnimating];
}
#pragma mark - Load Data
- (void)loadAppointmentDetails {
self.loadingOverlay.hidden = NO;
// TODO: call your API here
// Then call:
// [self applyAppointmentDataToUI];
}
#pragma mark - Apply Data
- (void)applyAppointmentDataToUI {
self.loadingOverlay.hidden = YES;
NSString *status = self.appointmentData[@"appointment_status"];
if ([status isEqualToString:@"Pending"]) {
self.statusBanner.backgroundColor = [UIColor colorWithRed:0.95 green:0.8 blue:0.2 alpha:1];
} else if ([status isEqualToString:@"Approved"]) {
self.statusBanner.backgroundColor = [UIColor colorWithRed:0 green:0.7 blue:0.3 alpha:1];
} else if ([status isEqualToString:@"Rejected"]) {
self.statusBanner.backgroundColor = [UIColor colorWithRed:0.9 green:0.2 blue:0.2 alpha:1];
} else {
self.statusBanner.backgroundColor = [UIColor lightGrayColor];
}
self.statusLabel.text = status;
self.reasonLabel.text = self.appointmentData[@"rejected_reason"];
// TODO: fill summary card fields
// TODO: fill representative card fields
// TODO: build action buttons based on status
}
#pragma mark - Actions
- (void)backTapped {
[self.navigationController popViewControllerAnimated:YES];
}
@end
// AppointmentTimeSlotViewController.mm
#import "AppointmentTimeSlotViewController.h"
#import "AppointmentConfirmationViewController.h"
@interface AppointmentTimeSlotViewController ()
......@@ -134,7 +135,7 @@
[self.scrollView.topAnchor constraintEqualToAnchor:self.headerBar.bottomAnchor],
[self.scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:-80] // space for footer
[self.scrollView.bottomAnchor constraintEqualToAnchor:self.footerView.topAnchor] // space for footer
]];
UIView *container = [[UIView alloc] init];
......@@ -163,46 +164,38 @@
[self.contentStack.bottomAnchor constraintLessThanOrEqualToAnchor:container.bottomAnchor constant:-16]
]];
// Unit label
// Move labels into stack
self.unitLabel = [[UILabel alloc] init];
self.unitLabel.text = @"For Unit No.:";
self.unitLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightThin];
self.unitLabel.textColor = [UIColor grayColor];
self.unitLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.unitLabel];
self.unitLabelName = [[UILabel alloc] init];
self.unitLabelName.text = [NSString stringWithFormat:@"%@, %@", self.projectName, self.projectId];
self.unitLabelName.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
self.unitLabelName.textColor = [UIColor blackColor];
self.unitLabelName.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.unitLabelName];
self.stepLabel = [[UILabel alloc] init];
self.stepLabel.text = @"Step 2/3: Select your preferred time";
self.stepLabel.font = [UIFont systemFontOfSize:14];
self.stepLabel.textColor = [UIColor blackColor];
self.stepLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.stepLabel.textAlignment = NSTextAlignmentCenter;
self.stepLabel.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
self.stepLabel.layer.cornerRadius = 6.0;
self.stepLabel.clipsToBounds = YES;
[self.view addSubview:self.stepLabel];
[NSLayoutConstraint activateConstraints:@[
[self.unitLabel.topAnchor constraintEqualToAnchor:self.headerBar.bottomAnchor constant:16],
[self.unitLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.unitLabel.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.unitLabelName.topAnchor constraintEqualToAnchor:self.unitLabel.bottomAnchor constant:8],
[self.unitLabelName.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.unitLabelName.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.stepLabel.topAnchor constraintEqualToAnchor:self.unitLabelName.bottomAnchor constant:16],
[self.stepLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.stepLabel.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.stepLabel.heightAnchor constraintEqualToConstant:30]
]];
[[self.stepLabel.heightAnchor constraintEqualToConstant:30] setActive:YES];
// Section header for time slots
UILabel *timeSlotHeader = [[UILabel alloc] init];
timeSlotHeader.text = @"Available Time Slots";
timeSlotHeader.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
timeSlotHeader.textColor = [UIColor darkGrayColor];
timeSlotHeader.textAlignment = NSTextAlignmentLeft;
[self.contentStack addArrangedSubview:self.unitLabel];
[self.contentStack addArrangedSubview:self.unitLabelName];
[self.contentStack addArrangedSubview:self.stepLabel];
[self.contentStack addArrangedSubview:timeSlotHeader];
}
- (void)setupFooter {
......@@ -283,92 +276,55 @@
}
#pragma mark - Time Slot UI (2-column grid)
- (void)rebuildTimeSlotViews {
// First remove any previously added time-slot views from contentStack (after the step container)
// Find index of step container in contentStack then remove everything after it, or simply remove any arranged subviews that are not the first 3
// We'll remove any arranged subviews after the step container to keep labels intact.
while (self.contentStack.arrangedSubviews.count > 3) {
// Remove previous time slot views (keep first 4: unitLabel, unitLabelName, stepLabel, header)
while (self.contentStack.arrangedSubviews.count > 4) {
UIView *v = self.contentStack.arrangedSubviews.lastObject;
[self.contentStack removeArrangedSubview:v];
[v removeFromSuperview];
}
// Create container for time slots
UIView *slotsContainer = [[UIView alloc] init];
slotsContainer.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentStack addArrangedSubview:slotsContainer];
// Build rows: two items per row
NSInteger count = self.aryTimeSlot.count;
for (NSInteger i = 0; i < count; i += 2) {
UIView *row = [[UIView alloc] init];
row.translatesAutoresizingMaskIntoConstraints = NO;
row.backgroundColor = UIColor.clearColor;
[[row.heightAnchor constraintEqualToConstant:40] setActive:YES];
// Left slot
NSDictionary *left = self.aryTimeSlot[i];
UIButton *leftBtn = [self createTimeSlotButtonForIndex:i slot:left];
leftBtn.translatesAutoresizingMaskIntoConstraints = NO;
[row addSubview:leftBtn];
// Right slot (may not exist)
UIButton *rightBtn = nil;
if (i + 1 < count) {
NSDictionary *right = self.aryTimeSlot[i+1];
rightBtn = [self createTimeSlotButtonForIndex:i+1 slot:right];
rightBtn.translatesAutoresizingMaskIntoConstraints = NO;
[row addSubview:rightBtn];
}
[slotsContainer addSubview:row];
// Layout row children
CGFloat padding = 0;
[NSLayoutConstraint activateConstraints:@[
[row.leadingAnchor constraintEqualToAnchor:slotsContainer.leadingAnchor],
[row.trailingAnchor constraintEqualToAnchor:slotsContainer.trailingAnchor],
// height fixed same as RN (40)
[row.heightAnchor constraintEqualToConstant:40],
]];
[NSLayoutConstraint activateConstraints:@[
[leftBtn.leadingAnchor constraintEqualToAnchor:row.leadingAnchor constant:0],
[leftBtn.topAnchor constraintEqualToAnchor:row.topAnchor constant:0],
[leftBtn.bottomAnchor constraintEqualToAnchor:row.bottomAnchor constant:0],
[leftBtn.leadingAnchor constraintEqualToAnchor:row.leadingAnchor],
[leftBtn.topAnchor constraintEqualToAnchor:row.topAnchor],
[leftBtn.bottomAnchor constraintEqualToAnchor:row.bottomAnchor],
[leftBtn.widthAnchor constraintEqualToAnchor:row.widthAnchor multiplier:0.5 constant:-10]
]];
if (rightBtn) {
// Right slot
if (i + 1 < count) {
NSDictionary *right = self.aryTimeSlot[i+1];
UIButton *rightBtn = [self createTimeSlotButtonForIndex:i+1 slot:right];
[row addSubview:rightBtn];
[NSLayoutConstraint activateConstraints:@[
[rightBtn.trailingAnchor constraintEqualToAnchor:row.trailingAnchor constant:0],
[rightBtn.topAnchor constraintEqualToAnchor:row.topAnchor constant:0],
[rightBtn.bottomAnchor constraintEqualToAnchor:row.bottomAnchor constant:0],
[rightBtn.leadingAnchor constraintEqualToAnchor:leftBtn.trailingAnchor constant:20],
[rightBtn.trailingAnchor constraintEqualToAnchor:row.trailingAnchor],
[rightBtn.topAnchor constraintEqualToAnchor:row.topAnchor],
[rightBtn.bottomAnchor constraintEqualToAnchor:row.bottomAnchor],
[rightBtn.widthAnchor constraintEqualToAnchor:leftBtn.widthAnchor]
]];
} else {
// if right missing, fill space with empty view to keep alignment
UIView *filler = [[UIView alloc] init];
filler.translatesAutoresizingMaskIntoConstraints = NO;
[row addSubview:filler];
[NSLayoutConstraint activateConstraints:@[
[filler.leadingAnchor constraintEqualToAnchor:leftBtn.trailingAnchor constant:20],
[filler.trailingAnchor constraintEqualToAnchor:row.trailingAnchor constant:0],
[filler.topAnchor constraintEqualToAnchor:row.topAnchor constant:0],
[filler.bottomAnchor constraintEqualToAnchor:row.bottomAnchor constant:0]
]];
}
// Add spacing below each row
[self.contentStack addArrangedSubview:row];
// Spacer between rows
UIView *spacer = [[UIView alloc] init];
spacer.translatesAutoresizingMaskIntoConstraints = NO;
spacer.backgroundColor = UIColor.clearColor;
[self.contentStack addArrangedSubview:row];
[spacer.heightAnchor constraintEqualToConstant:8].active = YES;
[self.contentStack addArrangedSubview:spacer];
[NSLayoutConstraint activateConstraints:@[
[spacer.heightAnchor constraintEqualToConstant:8]
]];
}
}
......@@ -421,8 +377,13 @@
}
- (void)nextTapped:(id)sender {
if (self.selectedSlotID.length == 0 || self.selectedStartDate.length == 0 || self.selectedStartTime.length == 0) {
UIAlertController *a = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Please select a time slot to continue." preferredStyle:UIAlertControllerStyleAlert];
if (self.selectedSlotID.length == 0 ||
self.selectedStartDate.length == 0 ||
self.selectedStartTime.length == 0) {
UIAlertController *a = [UIAlertController alertControllerWithTitle:@"Alert"
message:@"Please select a time slot to continue."
preferredStyle:UIAlertControllerStyleAlert];
[a addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:a animated:YES completion:nil];
return;
......@@ -435,21 +396,16 @@
if (self.didSelectAppointment) {
self.didSelectAppointment([obj copy]);
} else {
// push AppointmentConfirmationViewController (assumes it exists)
// You must replace the below lines with your app's confirmation screen push
UIViewController *conf = [NSClassFromString(@"AppointmentConfirmationViewController") new];
if (conf) {
if ([conf respondsToSelector:@selector(setAppointmentInfo:)]) {
// prefer setter if exists
[conf setValue:[obj copy] forKey:@"appointmentInfo"];
}
[self.navigationController pushViewController:conf animated:YES];
} else {
// fallback: just log
NSLog(@"Next tapped - appointment object: %@", obj);
}
return;
}
AppointmentConfirmationViewController *appointVC = [[AppointmentConfirmationViewController alloc] init];
appointVC.slotId = self.selectedSlotID;
appointVC.startDate = self.selectedStartDate;
appointVC.startTime = self.selectedStartTime;
appointVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:appointVC animated:YES completion:nil];
}
- (void)timeSlotTapped:(UIButton *)sender {
......
......@@ -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;
......
// AppointmentViewMoreViewController.h
#import <UIKit/UIKit.h>
@interface AppointmentViewMoreViewController : UIViewController
@end
// 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
......@@ -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 {
......
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