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
02bbb1d6
Commit
02bbb1d6
authored
Feb 03, 2026
by
Wei Han
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code update
parent
227d7a6d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
551 additions
and
64 deletions
+551
-64
Contents.json
...amework/Images.xcassets/star_empty.imageset/Contents.json
+21
-0
star_empty.png
...mework/Images.xcassets/star_empty.imageset/star_empty.png
+0
-0
Contents.json
...ramework/Images.xcassets/star_full.imageset/Contents.json
+21
-0
star_full.png
...ramework/Images.xcassets/star_full.imageset/star_full.png
+0
-0
DashboardViewController.h
...rk/QmsPluginFramework/Dashboard/DashboardViewController.h
+1
-0
DashboardViewController.mm
...k/QmsPluginFramework/Dashboard/DashboardViewController.mm
+121
-5
GeneralInfoViewController.h
.../QmsPluginFramework/Dashboard/GeneralInfoViewController.h
+1
-0
GeneralInfoViewController.mm
...QmsPluginFramework/Dashboard/GeneralInfoViewController.mm
+42
-56
UnitViewController.mm
...mework/QmsPluginFramework/Dashboard/UnitViewController.mm
+3
-0
OwnerAcceptanceViewController.h
...Framework/OwnerAcceptance/OwnerAcceptanceViewController.h
+14
-0
OwnerAcceptanceViewController.mm
...ramework/OwnerAcceptance/OwnerAcceptanceViewController.mm
+72
-0
POAViewController.h
...rk/QmsPluginFramework/OwnerAcceptance/POAViewController.h
+13
-0
POAViewController.mm
...k/QmsPluginFramework/OwnerAcceptance/POAViewController.mm
+70
-0
SinglePoaViewController.h
...PluginFramework/OwnerAcceptance/SinglePoaViewController.h
+15
-0
SinglePoaViewController.mm
...luginFramework/OwnerAcceptance/SinglePoaViewController.mm
+72
-0
SurveyViewController.h
...ramework/QmsPluginFramework/Survey/SurveyViewController.h
+9
-0
SurveyViewController.mm
...amework/QmsPluginFramework/Survey/SurveyViewController.mm
+0
-0
APIClient.h
...ginFramework/QmsPluginFramework/Utilities/API/APIClient.h
+2
-0
APIClient.mm
...inFramework/QmsPluginFramework/Utilities/API/APIClient.mm
+74
-3
No files found.
framework/QmsPluginFramework/Images.xcassets/star_empty.imageset/Contents.json
0 → 100644
View file @
02bbb1d6
{
"images"
:
[
{
"filename"
:
"star_empty.png"
,
"idiom"
:
"universal"
,
"scale"
:
"1x"
},
{
"idiom"
:
"universal"
,
"scale"
:
"2x"
},
{
"idiom"
:
"universal"
,
"scale"
:
"3x"
}
],
"info"
:
{
"author"
:
"xcode"
,
"version"
:
1
}
}
framework/QmsPluginFramework/Images.xcassets/star_empty.imageset/star_empty.png
0 → 100644
View file @
02bbb1d6
3.55 KB
framework/QmsPluginFramework/Images.xcassets/star_full.imageset/Contents.json
0 → 100644
View file @
02bbb1d6
{
"images"
:
[
{
"filename"
:
"star_full.png"
,
"idiom"
:
"universal"
,
"scale"
:
"1x"
},
{
"idiom"
:
"universal"
,
"scale"
:
"2x"
},
{
"idiom"
:
"universal"
,
"scale"
:
"3x"
}
],
"info"
:
{
"author"
:
"xcode"
,
"version"
:
1
}
}
framework/QmsPluginFramework/Images.xcassets/star_full.imageset/star_full.png
0 → 100644
View file @
02bbb1d6
2.35 KB
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/DashboardViewController.h
View file @
02bbb1d6
...
...
@@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
@property
(
nonatomic
,
copy
)
NSString
*
drawingPlanId
;
@property
(
nonatomic
,
copy
)
NSString
*
projectLogo
;
@property
(
nonatomic
,
copy
)
NSString
*
lotId
;
@property
(
nonatomic
,
assign
)
BOOL
canShowSurvey
;
@end
...
...
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/DashboardViewController.mm
View file @
02bbb1d6
...
...
@@ -16,6 +16,7 @@
#import "APIConfig.h"
#import "ImageCacheHelper.h"
#import "ThirdPartyViewController.h"
#import "SurveyViewController.h"
@interface DashboardViewController () <UIScrollViewDelegate>
...
...
@@ -23,7 +24,6 @@
@property (nonatomic, strong) NSArray *issues;
@property (nonatomic, assign) BOOL hasPendingAccess;
@property (nonatomic, assign) BOOL hasSignOff;
@property (nonatomic, strong) NSString *strContactlessHandoverStatus;
@property (nonatomic, strong) NSString *strContactlessFormUrl;
@property (nonatomic, strong) NSString *strPendingAccessReminder;
@property (nonatomic, assign) BOOL bln_Block_Handover;
...
...
@@ -48,7 +48,10 @@
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *contentView;
@property (nonatomic, strong) UIView *stickyBar;
@property (nonatomic, assign) BOOL hasSubmittedSurvey;
@property (nonatomic, assign) BOOL shouldShowSurveyBanner;
@property (nonatomic, assign) NSDictionary *generalInfo;
@property (nonatomic, strong) NSString *handoverStatus;
@end
...
...
@@ -93,7 +96,8 @@
#pragma mark - Refresh Logic
- (void)refreshDashboardContent {
NSLog(@"🔁 Refreshing dashboard content...");
[self requestGeneralInfo];
dispatch_group_t group = dispatch_group_create();
__block NSDictionary *dashboardData = nil;
__block NSDictionary *announcementData = nil;
...
...
@@ -664,13 +668,20 @@
NSLog(@"⚠️ Dashboard status not success: %@", appData[@"message"]);
return;
}
NSNumber *surveySubmission = mainData[@"survey_submission"];
BOOL hasSubmittedSurvey = NO;
if (surveySubmission && surveySubmission.intValue == 1) {
hasSubmittedSurvey = YES;
}
self.hasSubmittedSurvey = hasSubmittedSurvey;
NSArray *appointments = mainData[@"appointment"] ?: @[];
NSArray *issues = mainData[@"issue_update"] ?: @[];
NSNumber *paCount = mainData[@"pa_count"];
NSNumber *poaCount = mainData[@"poa_count"];
NSString *accessMessage = mainData[@"access_item_message"];
NSString *handoverStatus = mainData[@"contactlessHandoverTempStatus"];
NSString *handoverURL = mainData[@"contactlessHandoverTempURL"];
BOOL hasPendingAccess = (paCount && paCount.intValue > 0);
...
...
@@ -710,7 +721,6 @@
self.bln_Block_Handover = blockHandover;
self.bln_Block_Inspection = blockInspection;
self.strPendingAccessReminder = accessMessage ?: @"";
self.strContactlessHandoverStatus = handoverStatus ?: @"";
self.strContactlessFormUrl = handoverURL ?: @"";
NSLog(@"✅ Dashboard parsed:");
...
...
@@ -772,6 +782,18 @@
[self.contentContainer removeArrangedSubview:view];
[view removeFromSuperview];
}
// === Handover Survey ===
if ([self shouldDisplaySurvey]) {
NSLog(@"Displaying Survey");
UIView *surveyRow = [self buildSurveyRow];
[self.contentContainer addArrangedSubview:surveyRow];
[NSLayoutConstraint activateConstraints:@[
[surveyRow.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[surveyRow.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
]];
}
// === PROJECT UPDATES ===
NSArray *announcements = self.announcements;
...
...
@@ -806,6 +828,24 @@
[self.contentContainer addArrangedSubview:bottomSpacer];
}
- (void)requestGeneralInfo{
[APIClient requestGeneralInfo:^(BOOL success, NSDictionary *data, NSError *error) {
if (error || !data) {
NSLog(@"❌ General info error: %@", error.localizedDescription);
return;
}
NSString *plainText = [NSString stringWithFormat:@"%@", data];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *filePath = [docsPath stringByAppendingPathComponent:@"generalData.txt"];
[plainText writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"📁 appointData saved as plain text to: %@", filePath);
self.handoverStatus = data[@"Data"][@"handover_status"];
self.generalInfo = data;
}];
}
#pragma mark - Announcement Section
- (UIView *)buildAnnouncementSection:(NSArray *)announcements {
UIView *section = [[UIView alloc] init];
...
...
@@ -1519,6 +1559,7 @@
nextVC.modalPresentationStyle = UIModalPresentationFullScreen;
nextVC.unitID = self.projectCode;
nextVC.unitName = self.projectName;
nextVC.data = self.generalInfo;
[self presentViewController:nextVC animated:YES completion:nil];
}
...
...
@@ -1657,4 +1698,79 @@
compatibleWithTraitCollection:nil];
}
- (BOOL)shouldDisplaySurvey {
BOOL handedOver =
[self.handoverStatus.lowercaseString isEqualToString:@"handed over"];
return self.canShowSurvey &&
!self.hasSubmittedSurvey &&
handedOver;
}
- (UIView *)buildSurveyRow {
UIView *row = [[UIView alloc] init];
row.translatesAutoresizingMaskIntoConstraints = NO;
row.backgroundColor =
[UIColor colorWithRed:255.0/255.0
green:100.0/255.0
blue:100.0/255.0
alpha:1.0];
row.layer.cornerRadius = 12;
row.clipsToBounds = YES;
[row.heightAnchor constraintEqualToConstant:56].active = YES;
// Tap
UITapGestureRecognizer *tap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleSurveyTap)];
[row addGestureRecognizer:tap];
// Icon
UIImageView *icon = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:@"poa_icon_white"]];
icon.translatesAutoresizingMaskIntoConstraints = NO;
icon.contentMode = UIViewContentModeScaleAspectFit;
[row addSubview:icon];
// Title
UILabel *title = [[UILabel alloc] init];
title.translatesAutoresizingMaskIntoConstraints = NO;
title.text = @"Handover Survey";
title.font = [UIFont boldSystemFontOfSize:16];
title.textColor = UIColor.whiteColor;
[row addSubview:title];
// Chevron
UIImageView *arrow = [[UIImageView alloc]
initWithImage:[UIImage systemImageNamed:@"chevron.right"]];
arrow.translatesAutoresizingMaskIntoConstraints = NO;
arrow.tintColor = UIColor.whiteColor;
[row addSubview:arrow];
[NSLayoutConstraint activateConstraints:@[
[icon.leadingAnchor constraintEqualToAnchor:row.leadingAnchor constant:16],
[icon.centerYAnchor constraintEqualToAnchor:row.centerYAnchor],
[icon.widthAnchor constraintEqualToConstant:24],
[icon.heightAnchor constraintEqualToConstant:24],
[title.leadingAnchor constraintEqualToAnchor:icon.trailingAnchor constant:12],
[title.centerYAnchor constraintEqualToAnchor:row.centerYAnchor],
[arrow.trailingAnchor constraintEqualToAnchor:row.trailingAnchor constant:-16],
[arrow.centerYAnchor constraintEqualToAnchor:row.centerYAnchor],
[arrow.widthAnchor constraintEqualToConstant:16],
[arrow.heightAnchor constraintEqualToConstant:16],
]];
return row;
}
- (void)handleSurveyTap {
NSLog(@"📝 Survey tapped");
SurveyViewController *vc = [[SurveyViewController alloc] init];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:vc animated:YES completion:nil];
}
@end
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/GeneralInfoViewController.h
View file @
02bbb1d6
...
...
@@ -6,5 +6,6 @@
@property
(
nonatomic
,
strong
)
NSString
*
unitID
;
@property
(
nonatomic
,
strong
)
NSString
*
unitName
;
@property
(
nonatomic
,
strong
)
NSDictionary
*
data
;
@end
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/GeneralInfoViewController.mm
View file @
02bbb1d6
...
...
@@ -85,7 +85,7 @@ typedef struct {
self.documentsContainer.clipsToBounds = YES;
self.formsContainer.clipsToBounds = YES;
[self
request
GeneralInfo];
[self
handle
GeneralInfo];
[self setupTopBar];
[self setupTabControl];
[self setupScrollView];
...
...
@@ -542,67 +542,53 @@ typedef struct {
}
#pragma mark - api
- (void)requestGeneralInfo {
[APIClient requestGeneralInfo:^(BOOL success, NSDictionary *data, NSError *error) {
if (error || !data) {
NSLog(@"❌ General info error: %@", error.localizedDescription);
return;
}
NSLog(@"📦 Received General Info Data: %@", data);
NSDictionary *general = data[@"Data"];
// 1️⃣ Write to file for debugging (your existing logic)
NSString *plainText = [NSString stringWithFormat:@"%@", data];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *filePath = [docsPath stringByAppendingPathComponent:@"generalData.txt"];
[plainText writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"📁 appointData saved as plain text to: %@", filePath);
// 2️⃣ Safely extract each field
self.owners = general[@"unit_owner"] ?: @[];
self.jointOwners = general[@"joint_unit_owner"] ?: @[];
self.layoutDocuments = general[@"owner_document_phase"] ?: @[];
self.generalDocuments = general[@"owner_document_project"] ?: @[];
NSArray *rawUnitDocs = general[@"owner_document_unit"];
NSMutableArray *unitDocs = rawUnitDocs ? [rawUnitDocs mutableCopy] : [NSMutableArray array];
// clearance_letter_attachment is a DICTIONARY
NSDictionary *clearanceDict = general[@"clearance_letter_attachment"];
if (clearanceDict &&
[clearanceDict isKindOfClass:[NSDictionary class]] &&
[clearanceDict[@"file"] isKindOfClass:[NSString class]] &&
[clearanceDict[@"file"] length] > 0)
{
[unitDocs addObject:clearanceDict];
}
- (void)handleGeneralInfo {
NSLog(@"📦 Received General Info Data: %@", self.data);
NSDictionary *general = self.data[@"Data"];
self.unitDocuments = unitDocs;
// 2️⃣ Safely extract each field
self.owners = general[@"unit_owner"] ?: @[];
self.jointOwners = general[@"joint_unit_owner"] ?: @[];
self.forms = general[@"contactless_form"] ?: @[];
self.layoutDocuments = general[@"owner_document_phase"] ?: @[];
self.generalDocuments = general[@"owner_document_project"] ?: @[];
NSArray *rawUnitDocs = general[@"owner_document_unit"];
NSMutableArray *unitDocs = rawUnitDocs ? [rawUnitDocs mutableCopy] : [NSMutableArray array];
self.layoutType = general[@"layout"] ?: @"";
self.layoutImage = general[@"image"] ?: @"";
self.layoutThumbImage = general[@"thumb_image"] ?: @"";
// clearance_letter_attachment is a DICTIONARY
NSDictionary *clearanceDict = general[@"clearance_letter_attachment"];
self.spaDate = general[@"spa_date"] ?: @"";
self.vpDate = general[@"vp_date"] ?: general[@"vp_date"][@"date"] ?: @"";
if (clearanceDict &&
[clearanceDict isKindOfClass:[NSDictionary class]] &&
[clearanceDict[@"file"] isKindOfClass:[NSString class]] &&
[clearanceDict[@"file"] length] > 0)
{
[unitDocs addObject:clearanceDict];
}
self.dlpStartDate = general[@"dlp_start_date"] ?: @"";
self.dlpExpiryDate = general[@"dlp_expiry_date"] ?: @"";
self.unitDocuments = unitDocs;
self.handoverDocument = general[@"handover_document"] ?: @"";
self.handoverStatus = general[@"handover_status"];
self.clearanceLetter = general[@"clearance_letter_attachment"] ?: @"";
// 3️⃣ Update UI on main thread
dispatch_async(dispatch_get_main_queue(), ^{
[self refreshUI];
});
}];
self.forms = general[@"contactless_form"] ?: @[];
self.layoutType = general[@"layout"] ?: @"";
self.layoutImage = general[@"image"] ?: @"";
self.layoutThumbImage = general[@"thumb_image"] ?: @"";
self.spaDate = general[@"spa_date"] ?: @"";
self.vpDate = general[@"vp_date"] ?: general[@"vp_date"][@"date"] ?: @"";
self.dlpStartDate = general[@"dlp_start_date"] ?: @"";
self.dlpExpiryDate = general[@"dlp_expiry_date"] ?: @"";
self.handoverDocument = general[@"handover_document"] ?: @"";
self.handoverStatus = general[@"handover_status"];
self.clearanceLetter = general[@"clearance_letter_attachment"] ?: @"";
// 3️⃣ Update UI on main thread
dispatch_async(dispatch_get_main_queue(), ^{
[self refreshUI];
});
}
- (void)refreshUI {
...
...
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/UnitViewController.mm
View file @
02bbb1d6
...
...
@@ -276,6 +276,8 @@ didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *drawingPlanId = [unit[@"id"] description];
[APIConfig setDrawingPlanId:drawingPlanId];
NSLog(@"lotid: %@", unit[@"lot_id"]);
NSNumber *ownerSurvey = unit[@"owner_survey"];
BOOL canShowSurvey = (ownerSurvey != nil && ownerSurvey.intValue == 1);
NSLog(@"self.projectLogo: %@", self.projectLogo);
DashboardViewController *vc = [[DashboardViewController alloc] init];
...
...
@@ -286,6 +288,7 @@ didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
vc.drawerController = self.drawerController;
vc.projectLogo = self.projectLogo;
vc.lotId = unit[@"lot_id"] ?: @"";
vc.canShowSurvey = canShowSurvey;
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self.navigationController pushViewController:vc animated:YES];
}
...
...
framework/QmsPluginFramework/QmsPluginFramework/OwnerAcceptance/OwnerAcceptanceViewController.h
0 → 100644
View file @
02bbb1d6
// OwnerAcceptanceViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface
OwnerAcceptanceViewController
:
UIViewController
@end
NS_ASSUME_NONNULL_END
framework/QmsPluginFramework/QmsPluginFramework/OwnerAcceptance/OwnerAcceptanceViewController.mm
0 → 100644
View file @
02bbb1d6
// OwnerAcceptanceViewController.mm
#import "APIClient.h"
#import "OwnerAcceptanceViewController.h"
@interface OwnerAcceptanceViewController ()
// Header
@property (nonatomic, strong) UIView *headerBar;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *backButton;
@end
@implementation OwnerAcceptanceViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
[self setupHeader];
}
#pragma mark - Header
- (void)setupHeader {
UILayoutGuide *safe = self.view.safeAreaLayoutGuide;
self.headerBar = [[UIView alloc] init];
self.headerBar.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
self.headerBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerBar];
[NSLayoutConstraint activateConstraints:@[
[self.headerBar.topAnchor constraintEqualToAnchor:safe.topAnchor],
[self.headerBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerBar.heightAnchor constraintEqualToConstant:44],
]];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"Handover Survey";
self.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"] forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
[self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
for (UIView *sub in @[self.titleLabel, self.backButton]) {
sub.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerBar addSubview:sub];
}
[NSLayoutConstraint activateConstraints:@[
[self.backButton.leadingAnchor constraintEqualToAnchor:self.headerBar.leadingAnchor constant:16],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.headerBar.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:24],
[self.backButton.heightAnchor constraintEqualToConstant:24],
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerBar.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerBar.centerYAnchor],
]];
}
- (void)onBack {
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
framework/QmsPluginFramework/QmsPluginFramework/OwnerAcceptance/POAViewController.h
0 → 100644
View file @
02bbb1d6
// POAViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface
POAViewController
:
UIViewController
@end
NS_ASSUME_NONNULL_END
framework/QmsPluginFramework/QmsPluginFramework/OwnerAcceptance/POAViewController.mm
0 → 100644
View file @
02bbb1d6
// POAViewController.mm
#import "APIClient.h"
#import "POAViewController.h"
@interface POAViewController ()
// Header
@property (nonatomic, strong) UIView *headerBar;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *backButton;
@end
@implementation POAViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
[self setupHeader];
}
#pragma mark - Header
- (void)setupHeader {
UILayoutGuide *safe = self.view.safeAreaLayoutGuide;
self.headerBar = [[UIView alloc] init];
self.headerBar.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
self.headerBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerBar];
[NSLayoutConstraint activateConstraints:@[
[self.headerBar.topAnchor constraintEqualToAnchor:safe.topAnchor],
[self.headerBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerBar.heightAnchor constraintEqualToConstant:44],
]];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"Handover Survey";
self.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"] forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
[self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
for (UIView *sub in @[self.titleLabel, self.backButton]) {
sub.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerBar addSubview:sub];
}
[NSLayoutConstraint activateConstraints:@[
[self.backButton.leadingAnchor constraintEqualToAnchor:self.headerBar.leadingAnchor constant:16],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.headerBar.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:24],
[self.backButton.heightAnchor constraintEqualToConstant:24],
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerBar.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerBar.centerYAnchor],
]];
}
- (void)onBack {
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
framework/QmsPluginFramework/QmsPluginFramework/OwnerAcceptance/SinglePoaViewController.h
0 → 100644
View file @
02bbb1d6
//
// SinglePoaViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface
SinglePOAViewController
:
UIViewController
@end
NS_ASSUME_NONNULL_END
framework/QmsPluginFramework/QmsPluginFramework/OwnerAcceptance/SinglePoaViewController.mm
0 → 100644
View file @
02bbb1d6
// SinglePoaViewController.mm
#import "APIClient.h"
#import "SinglePOAViewController.h"
@interface SinglePOAViewController ()
// Header
@property (nonatomic, strong) UIView *headerBar;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *backButton;
@end
@implementation SinglePOAViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
[self setupHeader];
}
#pragma mark - Header
- (void)setupHeader {
UILayoutGuide *safe = self.view.safeAreaLayoutGuide;
self.headerBar = [[UIView alloc] init];
self.headerBar.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
self.headerBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerBar];
[NSLayoutConstraint activateConstraints:@[
[self.headerBar.topAnchor constraintEqualToAnchor:safe.topAnchor],
[self.headerBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerBar.heightAnchor constraintEqualToConstant:44],
]];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"Handover Survey";
self.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"] forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
[self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
for (UIView *sub in @[self.titleLabel, self.backButton]) {
sub.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerBar addSubview:sub];
}
[NSLayoutConstraint activateConstraints:@[
[self.backButton.leadingAnchor constraintEqualToAnchor:self.headerBar.leadingAnchor constant:16],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.headerBar.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:24],
[self.backButton.heightAnchor constraintEqualToConstant:24],
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerBar.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerBar.centerYAnchor],
]];
}
- (void)onBack {
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
framework/QmsPluginFramework/QmsPluginFramework/Survey/SurveyViewController.h
View file @
02bbb1d6
// SurveyViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface
SurveyViewController
:
UIViewController
@end
NS_ASSUME_NONNULL_END
framework/QmsPluginFramework/QmsPluginFramework/Survey/SurveyViewController.mm
View file @
02bbb1d6
This diff is collapsed.
Click to expand it.
framework/QmsPluginFramework/QmsPluginFramework/Utilities/API/APIClient.h
View file @
02bbb1d6
...
...
@@ -106,6 +106,8 @@ NS_ASSUME_NONNULL_BEGIN
NSDictionary
*
_Nullable
response
,
NSError
*
_Nullable
error
))
completion
;
+
(
void
)
requestSurvey
:(
void
(
^
)(
BOOL
success
,
NSDictionary
*
_Nullable
response
,
NSError
*
_Nullable
error
))
completion
;
@end
NS_ASSUME_NONNULL_END
framework/QmsPluginFramework/QmsPluginFramework/Utilities/API/APIClient.mm
View file @
02bbb1d6
...
...
@@ -1585,9 +1585,10 @@
+ (void)requestDefectMatrix:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
// if ([APIConfig handleOfflineForAPI:@"DefectMatrix" completion:completion]) {
// return;
// }
// if ([APIConfig handleOfflineForAPI:@"DefectMatrix" completion:completion]) {
// return;
// }
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/framework/issue/getGeneralSettingByUnit"];
...
...
@@ -2553,6 +2554,76 @@
[task resume];
}
+ (void)requestSurvey:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
if ([APIConfig handleOfflineForAPI:@"Survey" completion:completion]) {
return;
}
NSURL *url = [APIConfig urlWithPath:@"/framework/owner/survey/getSurvey"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
NSDictionary *jsonBody = @{
@"data": @{
@"os": [APIConfig os],
@"drawing_plan_id": [APIConfig drawingPlanId] ?: @"",
}
};
NSLog(@"🌍 request survey: %@", url.absoluteString);
NSLog(@"📦 request survey json: %@", jsonBody);
NSError *jsonError;
NSData *bodyData = [NSJSONSerialization dataWithJSONObject:jsonBody options:0 error:&jsonError];
if (jsonError) {
NSLog(@"❌ JSON Serialization Error: %@", jsonError);
if (completion) completion(NO, nil, jsonError);
return;
}
request.HTTPBody = bodyData;
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(), ^{
completion(NO, nil, error);
});
return;
}
NSError *parseError;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (parseError) {
NSLog(@"⚠️ JSON Parse Error: %@", parseError);
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO, nil, parseError);
});
return;
}
NSString *cacheKey = [NSString stringWithFormat:@"Survey_%@", [APIConfig projectId]];
NSDictionary *safeJson = [APIConfig dictionaryByReplacingNullsWithBlanks:json];
[LocalStorage saveDictionary:safeJson forKey:cacheKey];
NSLog(@"💾 Saved to cache: %@", cacheKey);
dispatch_async(dispatch_get_main_queue(), ^{
completion(YES, json, nil);
});
}];
[task resume];
}
#pragma mark - Helper Methods
+ (NSString *)multipartFormField:(NSString *)name value:(NSString *)value boundary:(NSString *)boundary {
return [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"data[%@]\"\r\n\r\n%@\r\n", boundary, name, value];
...
...
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