Commit 61c8d727 authored by Wei Han's avatar Wei Han

code update

parent 9a381188
...@@ -8,32 +8,32 @@ ...@@ -8,32 +8,32 @@
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64</string> <string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
<dict> <dict>
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string> <string>ios-arm64</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
</array> </array>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
......
// HistoryApiClient.h
#import <Foundation/Foundation.h>
@interface HistoryAPIClient : NSObject
+ (void)fetchHistory:(NSString *)issueID
completion:(void (^)(NSDictionary *data, NSError *error))completion;
@end
// HistoryApiClient.mm
#import "HistoryAPIClient.h"
@implementation HistoryAPIClient
+ (void)fetchHistory:(NSString *)issueID
completion:(void (^)(NSDictionary *data, NSError *error))completion {
// ✅ URL
NSString *urlString = @"https://kitadev.commudesk.com/api/owner/issue/getIssueHistory?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6ImF0aGlyYWh6YWlkaUBjb252ZXAuY29tIiwicGFzc3dvcmQiOiIkMnkkMTAkNU9xYklqMnZ6UHJwckJrcVd5c3I2LmJCc1hVYS9Hd014eUhnL3RhUUhPUkNQcGdmTG8yakciLCJzdWIiOjIxNzAsImlzcyI6Imh0dHBzOi8va2l0YWRldi5jb21tdWRlc2suY29tL2FwaS9vd25lci9hdXRoL3Bhc3N3b3JkbGVzc19sb2dpbiIsImlhdCI6MTc2MDMxNTM1MiwiZXhwIjoyMDc1ODg0ODcyLCJuYmYiOjE3NjAzMTUzNTIsImp0aSI6IktoQmNyQnJEdDVNdDZlWmMifQ.JnxGbZ7hTeoOr6oibIzZMphgyKtTo2Aq9Efx6mrGfFA";
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
// ✅ JSON headers
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
// ✅ Build JSON body
NSDictionary *deviceInfo = @{
@"OS": @"AND",
@"IMEI": @"AND:2a2f13ff17b1cbb5",
@"OS_VERSION": @"35",
@"MODEL": @"2306EPN60G",
@"APP_VERSION": @"1.22.26"
};
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"issue_id": issueID,
@"information": deviceInfo
}
};
// ✅ Convert dictionary → NSData
NSError *jsonError;
NSData *bodyData = [NSJSONSerialization dataWithJSONObject:jsonBody options:0 error:&jsonError];
if (jsonError) {
NSLog(@"❌ JSON Serialization Error: %@", jsonError);
if (completion) completion(nil, jsonError);
return;
}
request.HTTPBody = bodyData;
// 🧭 Debug logs
NSLog(@"🌍 URL: %@", urlString);
NSLog(@"📦 Body JSON: %@", jsonBody);
// ✅ Make request
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"❌ Network Error: %@", error);
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(nil, error);
});
return;
}
NSError *jsonParseError;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParseError];
if (jsonParseError) {
NSLog(@"⚠️ JSON Parse Error: %@", jsonParseError);
} else {
NSLog(@"✅ Issues API Response:\n%@", jsonResponse);
}
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(jsonResponse, jsonParseError);
});
}];
[task resume];
}
@end
// HistoryViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface HistoryViewController : UIViewController
@property (nonatomic, strong) NSString *issueID;
@property (nonatomic, strong) NSString *planID;
@property (nonatomic, strong) NSString *status;
@property (nonatomic, strong) NSString *unitName;
@property (nonatomic, strong) NSString *reference;
@end
NS_ASSUME_NONNULL_END
// HistoryViewController.mm
#import "HistoryViewController.h"
#import "HistoryAPIClient.h"
@interface HistoryViewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *addInfoButton;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSArray *historyItems;
@property (nonatomic, strong) NSArray *sortedDates;
@property (nonatomic, strong) NSDictionary *groupedHistory;
@end
@implementation HistoryViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor systemGroupedBackgroundColor];
[self setupHeader];
[self setupTableView];
[self handleIssues];
NSLog(@"📦 Data received by History:\n issueID: %@\n planID: %@\n status: %@\n unitName: %@\n reference: %@",
self.issueID,
self.planID,
self.status,
self.unitName,
self.reference);
}
#pragma mark - Header
- (void)setupHeader {
self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerView];
self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.left"] forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.backButton addTarget:self action:@selector(backTapped) forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:self.backButton];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"Issue History";
self.titleLabel.font = [UIFont boldSystemFontOfSize:18];
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:self.titleLabel];
self.addInfoButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.addInfoButton setImage:[UIImage systemImageNamed:@"plus"] forState:UIControlStateNormal];
self.addInfoButton.tintColor = UIColor.whiteColor;
self.addInfoButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.addInfoButton addTarget:self action:@selector(addInfoTapped) forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:self.addInfoButton];
[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:56],
[self.backButton.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor constant:12],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.addInfoButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-12],
[self.addInfoButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
]];
}
#pragma mark - TableView
- (void)setupTableView {
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleInsetGrouped];
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:self.tableView];
[NSLayoutConstraint activateConstraints:@[
[self.tableView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor],
[self.tableView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.tableView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.tableView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
]];
}
#pragma mark - API request/response
- (void)handleIssues {
[HistoryAPIClient fetchHistory:self.issueID
completion:^(NSDictionary *data, NSError *error) {
if (error) {
NSLog(@"❌ Error fetching history: %@", error);
return;
}
NSLog(@"✅ Raw history response received");
// 🔸 Save raw JSON for debugging
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:nil];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *filePath = [docsPath stringByAppendingPathComponent:@"getHistory.txt"];
[jsonData writeToFile:filePath atomically:YES];
NSLog(@"📁 History saved to %@", filePath);
NSDictionary *appData = data[@"AppData"];
NSArray *mainData = data[@"Data"];
// 1️⃣ Handle server error codes
if (appData[@"error_code"] && [appData[@"error_code"] integerValue] == 503) {
NSLog(@"⚠️ Maintenance mode");
return;
}
// 2️⃣ Handle non-success responses
NSString *status = appData[@"status"];
if (![status isEqualToString:@"success"]) {
NSString *msg = appData[@"message"] ?: @"Unknown server error.";
NSLog(@"⚠️ Server error: %@", msg);
return;
}
// 3️⃣ Success → process data
if (mainData && [mainData isKindOfClass:[NSArray class]] && mainData.count > 0) {
NSLog(@"✅ History data found (%lu items)", (unsigned long)mainData.count);
NSMutableDictionary *grouped = [NSMutableDictionary dictionary];
NSArray *reversed = [[mainData reverseObjectEnumerator] allObjects];
for (NSDictionary *item in reversed) {
NSString *datePost = item[@"date_post"] ?: @"";
// Extract only date part ("02 Jul 2025")
NSArray *parts = [datePost componentsSeparatedByString:@","];
NSString *dateOnly = parts.count > 0 ? [parts.firstObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"Unknown Date";
if (!grouped[dateOnly]) grouped[dateOnly] = [NSMutableArray array];
[grouped[dateOnly] addObject:item];
}
self.groupedHistory = grouped;
self.sortedDates = [[grouped allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *a, NSString *b) {
return [b compare:a options:NSNumericSearch]; // newest first
}];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
} else {
NSLog(@"⚠️ No history records found");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"No Data, No history records found for this issue");
});
}
}];
}
#pragma mark - Table Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.sortedDates.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *dateKey = self.sortedDates[section];
return [self.groupedHistory[dateKey] count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 230;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"HistoryCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *card = [[UIView alloc] init];
card.tag = 100;
card.layer.cornerRadius = 12;
card.backgroundColor = UIColor.whiteColor;
card.layer.shadowColor = [UIColor blackColor].CGColor;
card.layer.shadowOpacity = 0.1;
card.layer.shadowOffset = CGSizeMake(0, 1);
card.layer.shadowRadius = 2;
card.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:card];
UILabel *userLabel = [[UILabel alloc] init];
userLabel.tag = 101;
userLabel.font = [UIFont boldSystemFontOfSize:16];
userLabel.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:userLabel];
UILabel *remarkLabel = [[UILabel alloc] init];
remarkLabel.tag = 102;
remarkLabel.numberOfLines = 0;
remarkLabel.font = [UIFont systemFontOfSize:14];
remarkLabel.textColor = UIColor.darkGrayColor;
remarkLabel.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:remarkLabel];
UILabel *dateLabel = [[UILabel alloc] init];
dateLabel.tag = 104;
dateLabel.font = [UIFont italicSystemFontOfSize:12];
dateLabel.textColor = [UIColor grayColor];
dateLabel.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:dateLabel];
UILabel *statusLabel = [[UILabel alloc] init];
statusLabel.tag = 103;
statusLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightSemibold];
statusLabel.textAlignment = NSTextAlignmentCenter;
statusLabel.textColor = UIColor.whiteColor;
statusLabel.layer.cornerRadius = 12;
statusLabel.clipsToBounds = YES;
statusLabel.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:statusLabel];
UIScrollView *thumbScroll = [[UIScrollView alloc] init];
thumbScroll.tag = 105;
thumbScroll.showsHorizontalScrollIndicator = NO;
thumbScroll.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:thumbScroll];
UIView *timelineLine = [[UIView alloc] init];
timelineLine.tag = 200;
timelineLine.backgroundColor = [UIColor colorWithWhite:0.85 alpha:1];
timelineLine.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:timelineLine];
UIView *circleNode = [[UIView alloc] init];
circleNode.tag = 201;
circleNode.backgroundColor = [UIColor blackColor];
circleNode.layer.cornerRadius = 6;
circleNode.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:circleNode];
UILabel *timeLabel = [[UILabel alloc] init];
timeLabel.tag = 202;
timeLabel.backgroundColor = [UIColor blackColor];
timeLabel.textColor = [UIColor whiteColor];
timeLabel.font = [UIFont boldSystemFontOfSize:12];
timeLabel.textAlignment = NSTextAlignmentCenter;
timeLabel.layer.cornerRadius = 10;
timeLabel.clipsToBounds = YES;
timeLabel.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:timeLabel];
[NSLayoutConstraint activateConstraints:@[
[card.topAnchor constraintEqualToAnchor:cell.contentView.topAnchor constant:8],
[card.leadingAnchor constraintEqualToAnchor:timelineLine.trailingAnchor constant:20],
[card.trailingAnchor constraintEqualToAnchor:cell.contentView.trailingAnchor constant:-16],
[card.bottomAnchor constraintEqualToAnchor:cell.contentView.bottomAnchor constant:-8],
[userLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[userLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[remarkLabel.topAnchor constraintEqualToAnchor:userLabel.bottomAnchor constant:6],
[remarkLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[remarkLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[dateLabel.topAnchor constraintEqualToAnchor:remarkLabel.bottomAnchor constant:6],
[dateLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[statusLabel.topAnchor constraintEqualToAnchor:dateLabel.bottomAnchor constant:10],
[statusLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[statusLabel.widthAnchor constraintEqualToConstant:100],
[statusLabel.heightAnchor constraintEqualToConstant:24],
[thumbScroll.topAnchor constraintEqualToAnchor:statusLabel.bottomAnchor constant:10],
[thumbScroll.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[thumbScroll.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[thumbScroll.heightAnchor constraintEqualToConstant:60],
[thumbScroll.bottomAnchor constraintEqualToAnchor:card.bottomAnchor constant:-12],
// Timeline line runs vertically through entire cell
[timelineLine.widthAnchor constraintEqualToConstant:2],
[card.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:80],
[timelineLine.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:90],
[timelineLine.topAnchor constraintEqualToAnchor:cell.contentView.topAnchor],
[timelineLine.bottomAnchor constraintEqualToAnchor:cell.contentView.bottomAnchor],
// Align the circle vertically with the card’s middle
[circleNode.centerXAnchor constraintEqualToAnchor:timelineLine.centerXAnchor],
[circleNode.centerYAnchor constraintEqualToAnchor:card.centerYAnchor],
[circleNode.widthAnchor constraintEqualToConstant:12],
[circleNode.heightAnchor constraintEqualToConstant:12],
// Align time capsule left of circle
[timeLabel.centerYAnchor constraintEqualToAnchor:circleNode.centerYAnchor],
[timeLabel.trailingAnchor constraintEqualToAnchor:timelineLine.leadingAnchor constant:-8],
[timeLabel.widthAnchor constraintEqualToConstant:70],
[timeLabel.heightAnchor constraintEqualToConstant:22],
]];
}
NSString *dateKey = self.sortedDates[indexPath.section];
NSArray *sectionItems = self.groupedHistory[dateKey];
NSDictionary *item = sectionItems[indexPath.row];
UILabel *userLabel = [cell viewWithTag:101];
UILabel *remarkLabel = [cell viewWithTag:102];
UILabel *statusLabel = [cell viewWithTag:103];
UILabel *dateLabel = [cell viewWithTag:104];
UIScrollView *thumbScroll = [cell viewWithTag:105];
NSDictionary *user = item[@"user"];
NSString *userName = [self safeString:user[@"name"]];
NSString *remark = [self safeString:item[@"remarks"]];
NSString *status = [self safeString:item[@"status_external"]];
NSString *colorHex = [self safeString:item[@"status_ex_color"]];
NSString *datePost = [self safeString:item[@"date_post"]];
NSArray *images = item[@"image"];
UILabel *timeLabel = [cell viewWithTag:202];
// Extract the time portion after the comma
NSString *timePart = @"";
NSArray *parts = [datePost componentsSeparatedByString:@","];
if (parts.count > 1) {
timePart = [parts.lastObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
timeLabel.text = timePart.length > 0 ? timePart : @"--";
userLabel.text = userName;
remarkLabel.text = remark;
dateLabel.text = datePost;
statusLabel.text = status;
statusLabel.backgroundColor = [self colorFromHex:colorHex ?: @"#888888"];
// 🧹 Remove previous image views (since cells are reused)
for (UIView *subview in thumbScroll.subviews) {
[subview removeFromSuperview];
}
// 🖼️ Add thumbnails
CGFloat x = 0;
CGFloat imageSize = 56;
CGFloat spacing = 8;
for (NSDictionary *imgDict in images) {
NSString *thumbURL = imgDict[@"thumb_image"];
if (thumbURL.length == 0) continue;
UIImageView *thumbView = [[UIImageView alloc] initWithFrame:CGRectMake(x, 0, imageSize, imageSize)];
thumbView.layer.cornerRadius = 8;
thumbView.layer.masksToBounds = YES;
thumbView.contentMode = UIViewContentModeScaleAspectFill;
thumbView.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];
// Load async
NSURL *url = [NSURL URLWithString:thumbURL];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:url];
if (data) {
UIImage *img = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
thumbView.image = img;
});
}
});
[thumbScroll addSubview:thumbView];
x += imageSize + spacing;
}
thumbScroll.contentSize = CGSizeMake(x, imageSize);
return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *label = [[UILabel alloc] init];
label.text = self.sortedDates[section];
label.font = [UIFont boldSystemFontOfSize:15];
label.textColor = [UIColor darkGrayColor];
label.backgroundColor = UIColor.clearColor;
label.textAlignment = NSTextAlignmentLeft;
return label;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30;
}
#pragma mark - Utils
- (UIColor *)colorFromHex:(NSString *)hex {
unsigned int rgbValue = 0;
NSScanner *scanner = [NSScanner scannerWithString:hex];
if ([hex hasPrefix:@"#"]) scanner.scanLocation = 1;
[scanner scanHexInt:&rgbValue];
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
green:((rgbValue & 0x00FF00) >> 8)/255.0
blue:(rgbValue & 0x0000FF)/255.0
alpha:1.0];
}
#pragma mark - Actions
- (void)backTapped {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)addInfoTapped {
NSLog(@"➕ Add Info tapped");
}
#pragma mark - helper
- (NSString *)safeString:(id)value {
if ([value isKindOfClass:[NSString class]]) return value;
if ([value isKindOfClass:[NSNumber class]]) return [value stringValue];
return @"–";
}
@end
#import "IssueDetailViewController.h" #import "IssueDetailViewController.h"
#import "HistoryViewController.h"
@interface IssueDetailViewController () @interface IssueDetailViewController ()
...@@ -22,6 +23,18 @@ ...@@ -22,6 +23,18 @@
self.title = @"Issue Details"; self.title = @"Issue Details";
NSLog(@"📦 Received Issue Data: %@", self.issueData); NSLog(@"📦 Received Issue Data: %@", self.issueData);
NSString *text = [NSString stringWithFormat:@"%@", self.issueData];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *filePath = [docsPath stringByAppendingPathComponent:@"issueData.txt"];
// Convert issueData to a readable string
NSString *plainText = [NSString stringWithFormat:@"%@", self.issueData];
// Write as plain UTF-8 text
[plainText writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
// Log the path so you can find it
NSLog(@"📁 issueData saved as plain text to: %@", filePath);
[self setupHeader]; [self setupHeader];
[self setupScrollView]; [self setupScrollView];
...@@ -162,7 +175,7 @@ ...@@ -162,7 +175,7 @@
} }
- (void)setupButtons { - (void)setupButtons {
CGFloat y = CGRectGetMaxY(self.detailsCard.frame) + 16; CGFloat y = CGRectGetMaxY(self.detailsCard.frame) + 4;
CGFloat buttonWidth = (self.view.bounds.size.width - 60) / 2; CGFloat buttonWidth = (self.view.bounds.size.width - 60) / 2;
// --- Edit Button --- // --- Edit Button ---
...@@ -170,6 +183,7 @@ ...@@ -170,6 +183,7 @@
self.editButton.frame = CGRectMake(20, y, buttonWidth, 44); self.editButton.frame = CGRectMake(20, y, buttonWidth, 44);
[self.editButton setTitle:@"Edit Issue" forState:UIControlStateNormal]; [self.editButton setTitle:@"Edit Issue" forState:UIControlStateNormal];
[self.editButton setTitleColor:[UIColor colorWithRed:0/255.0 green:115/255.0 blue:130/255.0 alpha:1] forState:UIControlStateNormal]; [self.editButton setTitleColor:[UIColor colorWithRed:0/255.0 green:115/255.0 blue:130/255.0 alpha:1] forState:UIControlStateNormal];
[self.editButton addTarget:self action:@selector(editIssueTapped) forControlEvents:UIControlEventTouchUpInside];
self.editButton.layer.cornerRadius = 8; self.editButton.layer.cornerRadius = 8;
self.editButton.layer.borderWidth = 1; self.editButton.layer.borderWidth = 1;
self.editButton.layer.borderColor = [UIColor colorWithRed:0/255.0 green:115/255.0 blue:130/255.0 alpha:1].CGColor; self.editButton.layer.borderColor = [UIColor colorWithRed:0/255.0 green:115/255.0 blue:130/255.0 alpha:1].CGColor;
...@@ -180,6 +194,7 @@ ...@@ -180,6 +194,7 @@
self.deleteButton.frame = CGRectMake(CGRectGetMaxX(self.editButton.frame) + 20, y, buttonWidth, 44); self.deleteButton.frame = CGRectMake(CGRectGetMaxX(self.editButton.frame) + 20, y, buttonWidth, 44);
[self.deleteButton setTitle:@"Delete Issue" forState:UIControlStateNormal]; [self.deleteButton setTitle:@"Delete Issue" forState:UIControlStateNormal];
[self.deleteButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [self.deleteButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
[self.deleteButton addTarget:self action:@selector(deleteIssueTapped) forControlEvents:UIControlEventTouchUpInside];
self.deleteButton.backgroundColor = [UIColor systemRedColor]; self.deleteButton.backgroundColor = [UIColor systemRedColor];
self.deleteButton.layer.cornerRadius = 8; self.deleteButton.layer.cornerRadius = 8;
[self.scrollView addSubview:self.deleteButton]; [self.scrollView addSubview:self.deleteButton];
...@@ -188,12 +203,22 @@ ...@@ -188,12 +203,22 @@
self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, totalHeight); self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, totalHeight);
} }
- (void)editIssueTapped {
NSLog(@"✏️ Edit Issue tapped");
// You can later navigate to an edit screen or present a modal here
}
- (void)deleteIssueTapped {
NSLog(@"🗑️ Delete Issue tapped");
// need to fill up later
}
#pragma mark - Data #pragma mark - Data
- (void)populateData { - (void)populateData {
if (!self.issueData) return; if (!self.issueData) return;
NSString *ref = self.issueData[@"issue_reference"] ?: @"Unknown Reference"; NSString *ref = self.issueData[@"issue_reference"] ?: self.issueData[@"reference"] ?: @"Unknown Reference";
NSString *status = self.issueData[@"status_external"] ?: @"No Status"; NSString *status = self.issueData[@"status_external"] ?: @"No Status";
NSString *statusColor = self.issueData[@"status_ex_color"] ?: @"#999999"; NSString *statusColor = self.issueData[@"status_ex_color"] ?: @"#999999";
NSString *imageURL = self.issueData[@"image"]; NSString *imageURL = self.issueData[@"image"];
...@@ -237,7 +262,6 @@ ...@@ -237,7 +262,6 @@
} }
#pragma mark - Helper #pragma mark - Helper
- (UIColor *)colorFromHex:(NSString *)hexString { - (UIColor *)colorFromHex:(NSString *)hexString {
if (!hexString || hexString.length < 6) return [UIColor grayColor]; if (!hexString || hexString.length < 6) return [UIColor grayColor];
unsigned int rgbValue = 0; unsigned int rgbValue = 0;
...@@ -256,8 +280,24 @@ ...@@ -256,8 +280,24 @@
} }
- (void)handleHistoryTap { - (void)handleHistoryTap {
NSLog(@"🕓 History tapped"); NSLog(@"🕓 Navigating to History");
// TODO: Navigate to issue history screen later
HistoryViewController *nextVC = [[HistoryViewController alloc] init];
nextVC.modalPresentationStyle = UIModalPresentationFullScreen;
nextVC.issueID = self.issueData[@"issue_reference_id"];
nextVC.planID = self.issueData[@"plan_id"];
nextVC.status = self.issueData[@"status_external"];
nextVC.unitName = self.issueData[@"plan_unit"];
nextVC.reference = self.issueData[@"reference"] ?: self.issueData[@"issue_reference"];
NSLog(@"📦 Data being sent to History:\n issueID: %@\n planID: %@\n status: %@\n unitName: %@\n reference: %@",
nextVC.issueID,
nextVC.planID,
nextVC.status,
nextVC.unitName,
nextVC.reference);
[self presentViewController:nextVC animated:YES completion:nil];
} }
@end @end
...@@ -8,32 +8,32 @@ ...@@ -8,32 +8,32 @@
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64</string> <string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
<dict> <dict>
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string> <string>ios-arm64</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
</array> </array>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment