Showing
18 changed files
with
681 additions
and
0 deletions
| ... | @@ -73,6 +73,10 @@ | ... | @@ -73,6 +73,10 @@ |
| 73 | 1EDD0AC62E0D68B6005E162B /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = 1EDD0AC52E0D68B6005E162B /* SQLite */; }; | 73 | 1EDD0AC62E0D68B6005E162B /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = 1EDD0AC52E0D68B6005E162B /* SQLite */; }; |
| 74 | 622DA0AE2F51CAEE00308AB8 /* CouponsetViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 622DA0AD2F51CAEE00308AB8 /* CouponsetViewController.xib */; }; | 74 | 622DA0AE2F51CAEE00308AB8 /* CouponsetViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 622DA0AD2F51CAEE00308AB8 /* CouponsetViewController.xib */; }; |
| 75 | 622DA0AF2F51CAEE00308AB8 /* CouponsetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 622DA0AC2F51CAEE00308AB8 /* CouponsetViewController.swift */; }; | 75 | 622DA0AF2F51CAEE00308AB8 /* CouponsetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 622DA0AC2F51CAEE00308AB8 /* CouponsetViewController.swift */; }; |
| 76 | + 62A0A6D32F67FEDC00508534 /* MyCouponsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A0A6D12F67FEDC00508534 /* MyCouponsViewController.swift */; }; | ||
| 77 | + 62A0A6D42F67FEDC00508534 /* MyCouponsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 62A0A6D22F67FEDC00508534 /* MyCouponsViewController.xib */; }; | ||
| 78 | + 62A0A6D82F680C6A00508534 /* MyCouponsHeaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A0A6D62F680C6A00508534 /* MyCouponsHeaderTableViewCell.swift */; }; | ||
| 79 | + 62A0A6D92F680C6A00508534 /* MyCouponsHeaderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 62A0A6D72F680C6A00508534 /* MyCouponsHeaderTableViewCell.xib */; }; | ||
| 76 | 7630AD9A6242D60846D6750C /* Pods_SwiftWarplyFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0D5F56DD4E5371A50AD2D87 /* Pods_SwiftWarplyFramework.framework */; }; | 80 | 7630AD9A6242D60846D6750C /* Pods_SwiftWarplyFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0D5F56DD4E5371A50AD2D87 /* Pods_SwiftWarplyFramework.framework */; }; |
| 77 | A07936762885E9CC00064122 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07936752885E9CC00064122 /* UIColorExtensions.swift */; }; | 81 | A07936762885E9CC00064122 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07936752885E9CC00064122 /* UIColorExtensions.swift */; }; |
| 78 | E6A77853282933340045BBA8 /* SwiftWarplyFramework.docc in Sources */ = {isa = PBXBuildFile; fileRef = E6A77852282933340045BBA8 /* SwiftWarplyFramework.docc */; }; | 82 | E6A77853282933340045BBA8 /* SwiftWarplyFramework.docc in Sources */ = {isa = PBXBuildFile; fileRef = E6A77852282933340045BBA8 /* SwiftWarplyFramework.docc */; }; |
| ... | @@ -150,6 +154,10 @@ | ... | @@ -150,6 +154,10 @@ |
| 150 | 1EDD0ABC2E0D308A005E162B /* XIBLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XIBLoader.swift; sourceTree = "<group>"; }; | 154 | 1EDD0ABC2E0D308A005E162B /* XIBLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XIBLoader.swift; sourceTree = "<group>"; }; |
| 151 | 622DA0AC2F51CAEE00308AB8 /* CouponsetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CouponsetViewController.swift; sourceTree = "<group>"; }; | 155 | 622DA0AC2F51CAEE00308AB8 /* CouponsetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CouponsetViewController.swift; sourceTree = "<group>"; }; |
| 152 | 622DA0AD2F51CAEE00308AB8 /* CouponsetViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CouponsetViewController.xib; sourceTree = "<group>"; }; | 156 | 622DA0AD2F51CAEE00308AB8 /* CouponsetViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CouponsetViewController.xib; sourceTree = "<group>"; }; |
| 157 | + 62A0A6D12F67FEDC00508534 /* MyCouponsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCouponsViewController.swift; sourceTree = "<group>"; }; | ||
| 158 | + 62A0A6D22F67FEDC00508534 /* MyCouponsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyCouponsViewController.xib; sourceTree = "<group>"; }; | ||
| 159 | + 62A0A6D62F680C6A00508534 /* MyCouponsHeaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCouponsHeaderTableViewCell.swift; sourceTree = "<group>"; }; | ||
| 160 | + 62A0A6D72F680C6A00508534 /* MyCouponsHeaderTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyCouponsHeaderTableViewCell.xib; sourceTree = "<group>"; }; | ||
| 153 | A07936752885E9CC00064122 /* UIColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = "<group>"; }; | 161 | A07936752885E9CC00064122 /* UIColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = "<group>"; }; |
| 154 | A9B7BE01A4E812DE49866EF8 /* Pods-SwiftWarplyFramework.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftWarplyFramework.debug.xcconfig"; path = "Target Support Files/Pods-SwiftWarplyFramework/Pods-SwiftWarplyFramework.debug.xcconfig"; sourceTree = "<group>"; }; | 162 | A9B7BE01A4E812DE49866EF8 /* Pods-SwiftWarplyFramework.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftWarplyFramework.debug.xcconfig"; path = "Target Support Files/Pods-SwiftWarplyFramework/Pods-SwiftWarplyFramework.debug.xcconfig"; sourceTree = "<group>"; }; |
| 155 | B9EB8A451EF0C5AD75094EEE /* Pods-SwiftWarplyFramework.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftWarplyFramework.release.xcconfig"; path = "Target Support Files/Pods-SwiftWarplyFramework/Pods-SwiftWarplyFramework.release.xcconfig"; sourceTree = "<group>"; }; | 163 | B9EB8A451EF0C5AD75094EEE /* Pods-SwiftWarplyFramework.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftWarplyFramework.release.xcconfig"; path = "Target Support Files/Pods-SwiftWarplyFramework/Pods-SwiftWarplyFramework.release.xcconfig"; sourceTree = "<group>"; }; |
| ... | @@ -328,6 +336,7 @@ | ... | @@ -328,6 +336,7 @@ |
| 328 | 1E917CD32DDF6472002221D8 /* MyRewardsViewController */, | 336 | 1E917CD32DDF6472002221D8 /* MyRewardsViewController */, |
| 329 | 1E917CD82DDF687E002221D8 /* CouponViewController */, | 337 | 1E917CD82DDF687E002221D8 /* CouponViewController */, |
| 330 | 1E917CDD2DDF68D8002221D8 /* ProfileViewController */, | 338 | 1E917CDD2DDF68D8002221D8 /* ProfileViewController */, |
| 339 | + 62A0A6D02F67FE8100508534 /* MyCouponsViewController */, | ||
| 331 | ); | 340 | ); |
| 332 | path = screens; | 341 | path = screens; |
| 333 | sourceTree = "<group>"; | 342 | sourceTree = "<group>"; |
| ... | @@ -335,6 +344,7 @@ | ... | @@ -335,6 +344,7 @@ |
| 335 | 1EA8E5BC2DDF34FB00CD3418 /* cells */ = { | 344 | 1EA8E5BC2DDF34FB00CD3418 /* cells */ = { |
| 336 | isa = PBXGroup; | 345 | isa = PBXGroup; |
| 337 | children = ( | 346 | children = ( |
| 347 | + 62A0A6D52F680C1E00508534 /* MyCouponsHeaderTableViewCell */, | ||
| 338 | 1EDBAF122DE844C500911E79 /* ProfileFilterCollectionViewCell */, | 348 | 1EDBAF122DE844C500911E79 /* ProfileFilterCollectionViewCell */, |
| 339 | 1EDBAF012DE8439000911E79 /* ProfileCouponTableViewCell */, | 349 | 1EDBAF012DE8439000911E79 /* ProfileCouponTableViewCell */, |
| 340 | 1EDBAF002DE842A700911E79 /* ProfileCouponFiltersTableViewCell */, | 350 | 1EDBAF002DE842A700911E79 /* ProfileCouponFiltersTableViewCell */, |
| ... | @@ -439,6 +449,24 @@ | ... | @@ -439,6 +449,24 @@ |
| 439 | path = CouponsetViewController; | 449 | path = CouponsetViewController; |
| 440 | sourceTree = "<group>"; | 450 | sourceTree = "<group>"; |
| 441 | }; | 451 | }; |
| 452 | + 62A0A6D02F67FE8100508534 /* MyCouponsViewController */ = { | ||
| 453 | + isa = PBXGroup; | ||
| 454 | + children = ( | ||
| 455 | + 62A0A6D12F67FEDC00508534 /* MyCouponsViewController.swift */, | ||
| 456 | + 62A0A6D22F67FEDC00508534 /* MyCouponsViewController.xib */, | ||
| 457 | + ); | ||
| 458 | + path = MyCouponsViewController; | ||
| 459 | + sourceTree = "<group>"; | ||
| 460 | + }; | ||
| 461 | + 62A0A6D52F680C1E00508534 /* MyCouponsHeaderTableViewCell */ = { | ||
| 462 | + isa = PBXGroup; | ||
| 463 | + children = ( | ||
| 464 | + 62A0A6D62F680C6A00508534 /* MyCouponsHeaderTableViewCell.swift */, | ||
| 465 | + 62A0A6D72F680C6A00508534 /* MyCouponsHeaderTableViewCell.xib */, | ||
| 466 | + ); | ||
| 467 | + path = MyCouponsHeaderTableViewCell; | ||
| 468 | + sourceTree = "<group>"; | ||
| 469 | + }; | ||
| 442 | 98AD36FA62350CEABCD961A7 /* Frameworks */ = { | 470 | 98AD36FA62350CEABCD961A7 /* Frameworks */ = { |
| 443 | isa = PBXGroup; | 471 | isa = PBXGroup; |
| 444 | children = ( | 472 | children = ( |
| ... | @@ -611,12 +639,14 @@ | ... | @@ -611,12 +639,14 @@ |
| 611 | E6A77A38282BC3530045BBA8 /* Media.xcassets in Resources */, | 639 | E6A77A38282BC3530045BBA8 /* Media.xcassets in Resources */, |
| 612 | 1E116F682DE845B1009AE791 /* ProfileFilterCollectionViewCell.xib in Resources */, | 640 | 1E116F682DE845B1009AE791 /* ProfileFilterCollectionViewCell.xib in Resources */, |
| 613 | 1EB4F4252DE09AAC00D934C0 /* MyRewardsBannerOffersScrollTableViewCell.xib in Resources */, | 641 | 1EB4F4252DE09AAC00D934C0 /* MyRewardsBannerOffersScrollTableViewCell.xib in Resources */, |
| 642 | + 62A0A6D92F680C6A00508534 /* MyCouponsHeaderTableViewCell.xib in Resources */, | ||
| 614 | 1EA8E5C02DDF427A00CD3418 /* PingLCG-Bold.otf in Resources */, | 643 | 1EA8E5C02DDF427A00CD3418 /* PingLCG-Bold.otf in Resources */, |
| 615 | 622DA0AE2F51CAEE00308AB8 /* CouponsetViewController.xib in Resources */, | 644 | 622DA0AE2F51CAEE00308AB8 /* CouponsetViewController.xib in Resources */, |
| 616 | 1E64E1832DE48E0600543217 /* MyRewardsOfferCollectionViewCell.xib in Resources */, | 645 | 1E64E1832DE48E0600543217 /* MyRewardsOfferCollectionViewCell.xib in Resources */, |
| 617 | 1EA8E5C12DDF427A00CD3418 /* PingLCG-Light.otf in Resources */, | 646 | 1EA8E5C12DDF427A00CD3418 /* PingLCG-Light.otf in Resources */, |
| 618 | 1EA8E5C22DDF427A00CD3418 /* PingLCG-Regular.otf in Resources */, | 647 | 1EA8E5C22DDF427A00CD3418 /* PingLCG-Regular.otf in Resources */, |
| 619 | 1EB4F42B2DE0A0AF00D934C0 /* MyRewardsOffersScrollTableViewCell.xib in Resources */, | 648 | 1EB4F42B2DE0A0AF00D934C0 /* MyRewardsOffersScrollTableViewCell.xib in Resources */, |
| 649 | + 62A0A6D42F67FEDC00508534 /* MyCouponsViewController.xib in Resources */, | ||
| 620 | 1E66E4972E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.xib in Resources */, | 650 | 1E66E4972E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.xib in Resources */, |
| 621 | 1EDBAF102DE8443B00911E79 /* ProfileHeaderTableViewCell.xib in Resources */, | 651 | 1EDBAF102DE8443B00911E79 /* ProfileHeaderTableViewCell.xib in Resources */, |
| 622 | 1E917CDB2DDF68C7002221D8 /* CouponViewController.xib in Resources */, | 652 | 1E917CDB2DDF68C7002221D8 /* CouponViewController.xib in Resources */, |
| ... | @@ -678,6 +708,7 @@ | ... | @@ -678,6 +708,7 @@ |
| 678 | 622DA0AF2F51CAEE00308AB8 /* CouponsetViewController.swift in Sources */, | 708 | 622DA0AF2F51CAEE00308AB8 /* CouponsetViewController.swift in Sources */, |
| 679 | 1E089DFE2DF87C39007459F1 /* Coupon.swift in Sources */, | 709 | 1E089DFE2DF87C39007459F1 /* Coupon.swift in Sources */, |
| 680 | 1E089DFF2DF87C39007459F1 /* OfferModel.swift in Sources */, | 710 | 1E089DFF2DF87C39007459F1 /* OfferModel.swift in Sources */, |
| 711 | + 62A0A6D82F680C6A00508534 /* MyCouponsHeaderTableViewCell.swift in Sources */, | ||
| 681 | 1ED41E4C2DE0C24D00836ABA /* MyRewardsBannerOfferCollectionViewCell.swift in Sources */, | 712 | 1ED41E4C2DE0C24D00836ABA /* MyRewardsBannerOfferCollectionViewCell.swift in Sources */, |
| 682 | E6A778E6282933E60045BBA8 /* MyEmptyClass.swift in Sources */, | 713 | E6A778E6282933E60045BBA8 /* MyEmptyClass.swift in Sources */, |
| 683 | 1E917CE12DDF6909002221D8 /* ProfileViewController.swift in Sources */, | 714 | 1E917CE12DDF6909002221D8 /* ProfileViewController.swift in Sources */, |
| ... | @@ -689,6 +720,7 @@ | ... | @@ -689,6 +720,7 @@ |
| 689 | E6A77955282933E70045BBA8 /* ViewControllerExtensions.swift in Sources */, | 720 | E6A77955282933E70045BBA8 /* ViewControllerExtensions.swift in Sources */, |
| 690 | A07936762885E9CC00064122 /* UIColorExtensions.swift in Sources */, | 721 | A07936762885E9CC00064122 /* UIColorExtensions.swift in Sources */, |
| 691 | 1EB4F42C2DE0A0AF00D934C0 /* MyRewardsOffersScrollTableViewCell.swift in Sources */, | 722 | 1EB4F42C2DE0A0AF00D934C0 /* MyRewardsOffersScrollTableViewCell.swift in Sources */, |
| 723 | + 62A0A6D32F67FEDC00508534 /* MyCouponsViewController.swift in Sources */, | ||
| 692 | 1E089E022DF87CCF007459F1 /* WarplySDK.swift in Sources */, | 724 | 1E089E022DF87CCF007459F1 /* WarplySDK.swift in Sources */, |
| 693 | 1E0E723B2E0C3AE400BC926F /* DatabaseConfiguration.swift in Sources */, | 725 | 1E0E723B2E0C3AE400BC926F /* DatabaseConfiguration.swift in Sources */, |
| 694 | 1E0E723C2E0C3AE400BC926F /* WarplyConfiguration.swift in Sources */, | 726 | 1E0E723C2E0C3AE400BC926F /* WarplyConfiguration.swift in Sources */, | ... | ... |
No preview for this file type
SwiftWarplyFramework/SwiftWarplyFramework/Media.xcassets/ic_forward.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "filename" : "ic_forward.png", | ||
| 5 | + "idiom" : "universal", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "filename" : "ic_forward 1.png", | ||
| 10 | + "idiom" : "universal", | ||
| 11 | + "scale" : "2x" | ||
| 12 | + }, | ||
| 13 | + { | ||
| 14 | + "filename" : "ic_forward 2.png", | ||
| 15 | + "idiom" : "universal", | ||
| 16 | + "scale" : "3x" | ||
| 17 | + } | ||
| 18 | + ], | ||
| 19 | + "info" : { | ||
| 20 | + "author" : "xcode", | ||
| 21 | + "version" : 1 | ||
| 22 | + } | ||
| 23 | +} |
SwiftWarplyFramework/SwiftWarplyFramework/Media.xcassets/ic_forward.imageset/ic_forward 1.png
0 → 100644
1.98 KB
SwiftWarplyFramework/SwiftWarplyFramework/Media.xcassets/ic_forward.imageset/ic_forward 2.png
0 → 100644
1.98 KB
SwiftWarplyFramework/SwiftWarplyFramework/Media.xcassets/ic_forward.imageset/ic_forward.png
0 → 100644
1.98 KB
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "filename" : "search.png", | ||
| 5 | + "idiom" : "universal", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "filename" : "search 1.png", | ||
| 10 | + "idiom" : "universal", | ||
| 11 | + "scale" : "2x" | ||
| 12 | + }, | ||
| 13 | + { | ||
| 14 | + "filename" : "search 2.png", | ||
| 15 | + "idiom" : "universal", | ||
| 16 | + "scale" : "3x" | ||
| 17 | + } | ||
| 18 | + ], | ||
| 19 | + "info" : { | ||
| 20 | + "author" : "xcode", | ||
| 21 | + "version" : 1 | ||
| 22 | + } | ||
| 23 | +} |
1.23 KB
1.23 KB
1.23 KB
SwiftWarplyFramework/SwiftWarplyFramework/Media.xcassets/search_circle.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "filename" : "search_circle.png", | ||
| 5 | + "idiom" : "universal", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "filename" : "search_circle 1.png", | ||
| 10 | + "idiom" : "universal", | ||
| 11 | + "scale" : "2x" | ||
| 12 | + }, | ||
| 13 | + { | ||
| 14 | + "filename" : "search_circle 2.png", | ||
| 15 | + "idiom" : "universal", | ||
| 16 | + "scale" : "3x" | ||
| 17 | + } | ||
| 18 | + ], | ||
| 19 | + "info" : { | ||
| 20 | + "author" : "xcode", | ||
| 21 | + "version" : 1 | ||
| 22 | + } | ||
| 23 | +} |
SwiftWarplyFramework/SwiftWarplyFramework/Media.xcassets/search_circle.imageset/search_circle 1.png
0 → 100644
4.79 KB
SwiftWarplyFramework/SwiftWarplyFramework/Media.xcassets/search_circle.imageset/search_circle 2.png
0 → 100644
4.79 KB
SwiftWarplyFramework/SwiftWarplyFramework/Media.xcassets/search_circle.imageset/search_circle.png
0 → 100644
4.79 KB
| 1 | +// | ||
| 2 | +// MyCouponsHeaderTableViewCell.swift | ||
| 3 | +// SwiftWarplyFramework | ||
| 4 | +// | ||
| 5 | +// Created by Manos Chorianopoulos on 16/3/26. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +import UIKit | ||
| 9 | + | ||
| 10 | +// protocol MyCouponsHeaderTableViewCellDelegate: AnyObject { | ||
| 11 | +// func didTapSearchButton() | ||
| 12 | +// } | ||
| 13 | + | ||
| 14 | +@objc(MyCouponsHeaderTableViewCell) | ||
| 15 | +public class MyCouponsHeaderTableViewCell: UITableViewCell { | ||
| 16 | + | ||
| 17 | + // MARK: - IBOutlets | ||
| 18 | + @IBOutlet weak var titleLabel: UILabel! | ||
| 19 | + @IBOutlet weak var searchButton: UIButton! | ||
| 20 | + | ||
| 21 | + // MARK: - Delegate | ||
| 22 | + | ||
| 23 | + // weak var delegate: MyCouponsHeaderTableViewCellDelegate? | ||
| 24 | + | ||
| 25 | + // MARK: - Lifecycle | ||
| 26 | + | ||
| 27 | + public override func awakeFromNib() { | ||
| 28 | + super.awakeFromNib() | ||
| 29 | + | ||
| 30 | + selectionStyle = .none | ||
| 31 | + | ||
| 32 | + // Title | ||
| 33 | + titleLabel.font = UIFont(name: "PingLCG-Bold", size: 26) | ||
| 34 | + ?? UIFont.boldSystemFont(ofSize: 26) | ||
| 35 | + titleLabel.textColor = UIColor(rgb: 0x1D2023) | ||
| 36 | + titleLabel.text = "My Coupons" | ||
| 37 | + | ||
| 38 | + // Gear button: render image as-is (no tint) so the gray circle style is preserved | ||
| 39 | + let gearImage = UIImage(named: "search_circle", in: Bundle.frameworkResourceBundle, compatibleWith: nil)? | ||
| 40 | + .withRenderingMode(.alwaysOriginal) | ||
| 41 | + searchButton.setImage(gearImage, for: .normal) | ||
| 42 | + searchButton.setTitle("", for: .normal) | ||
| 43 | + // searchButton.addTarget(self, action: #selector(searchButtonTapped), for: .touchUpInside) | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public override func setSelected(_ selected: Bool, animated: Bool) { | ||
| 47 | + super.setSelected(selected, animated: animated) | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + // MARK: - Actions | ||
| 51 | + | ||
| 52 | + // @objc private func searchButtonTapped() { | ||
| 53 | + // delegate?.didTapSearchButton() | ||
| 54 | + // } | ||
| 55 | +} |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="24506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> | ||
| 3 | + <device id="retina6_12" orientation="portrait" appearance="light"/> | ||
| 4 | + <dependencies> | ||
| 5 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24504"/> | ||
| 6 | + <capability name="Safe area layout guides" minToolsVersion="9.0"/> | ||
| 7 | + <capability name="System colors in document resources" minToolsVersion="11.0"/> | ||
| 8 | + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
| 9 | + </dependencies> | ||
| 10 | + <objects> | ||
| 11 | + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> | ||
| 12 | + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> | ||
| 13 | + <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="KGk-i7-Jjw" customClass="MyCouponsHeaderTableViewCell" customModule="SwiftWarplyFramework" customModuleProvider="target"> | ||
| 14 | + <rect key="frame" x="0.0" y="0.0" width="320" height="44"/> | ||
| 15 | + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> | ||
| 16 | + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM"> | ||
| 17 | + <rect key="frame" x="0.0" y="0.0" width="320" height="44"/> | ||
| 18 | + <autoresizingMask key="autoresizingMask"/> | ||
| 19 | + <subviews> | ||
| 20 | + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9zr-3O-Ndy" userLabel="ParentView"> | ||
| 21 | + <rect key="frame" x="0.0" y="0.0" width="320" height="30"/> | ||
| 22 | + <subviews> | ||
| 23 | + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="My Coupons" textAlignment="natural" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QuH-xv-rPx" userLabel="TitleLabel"> | ||
| 24 | + <rect key="frame" x="18" y="-0.66666666666666607" width="156.33333333333334" height="31.333333333333329"/> | ||
| 25 | + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 26 | + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="26"/> | ||
| 27 | + <color key="textColor" red="0.067000000000000004" green="0.067000000000000004" blue="0.067000000000000004" alpha="1" colorSpace="calibratedRGB"/> | ||
| 28 | + <nil key="highlightedColor"/> | ||
| 29 | + </label> | ||
| 30 | + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NOc-fo-goN" userLabel="SearchButton"> | ||
| 31 | + <rect key="frame" x="254" y="0.0" width="48" height="30"/> | ||
| 32 | + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 33 | + <constraints> | ||
| 34 | + <constraint firstAttribute="width" constant="48" id="Ubc-A7-ncs"/> | ||
| 35 | + <constraint firstAttribute="height" constant="48" id="boQ-lu-bZd"/> | ||
| 36 | + </constraints> | ||
| 37 | + <state key="normal" title=""/> | ||
| 38 | + </button> | ||
| 39 | + </subviews> | ||
| 40 | + <color key="backgroundColor" systemColor="systemBackgroundColor"/> | ||
| 41 | + <constraints> | ||
| 42 | + <constraint firstItem="QuH-xv-rPx" firstAttribute="centerY" secondItem="NOc-fo-goN" secondAttribute="centerY" id="7Xg-4c-pen"/> | ||
| 43 | + <constraint firstItem="NOc-fo-goN" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="QuH-xv-rPx" secondAttribute="trailing" constant="8" id="Bd4-gD-OFp"/> | ||
| 44 | + <constraint firstItem="NOc-fo-goN" firstAttribute="top" secondItem="9zr-3O-Ndy" secondAttribute="top" id="G0c-Iw-ghG"/> | ||
| 45 | + <constraint firstAttribute="bottom" secondItem="NOc-fo-goN" secondAttribute="bottom" id="gG3-2v-iwZ"/> | ||
| 46 | + <constraint firstAttribute="trailing" secondItem="NOc-fo-goN" secondAttribute="trailing" constant="18" id="o71-Y7-vdQ"/> | ||
| 47 | + <constraint firstItem="QuH-xv-rPx" firstAttribute="leading" secondItem="9zr-3O-Ndy" secondAttribute="leading" constant="18" id="pLn-uL-UNA"/> | ||
| 48 | + </constraints> | ||
| 49 | + </view> | ||
| 50 | + </subviews> | ||
| 51 | + <constraints> | ||
| 52 | + <constraint firstAttribute="bottom" secondItem="9zr-3O-Ndy" secondAttribute="bottom" id="Icc-z0-HGG"/> | ||
| 53 | + <constraint firstAttribute="trailing" secondItem="9zr-3O-Ndy" secondAttribute="trailing" id="Inc-8d-l15"/> | ||
| 54 | + <constraint firstItem="9zr-3O-Ndy" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="UT5-S3-Caq"/> | ||
| 55 | + <constraint firstItem="9zr-3O-Ndy" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="xZK-RL-O9W"/> | ||
| 56 | + </constraints> | ||
| 57 | + </tableViewCellContentView> | ||
| 58 | + <viewLayoutGuide key="safeArea" id="njF-e1-oar"/> | ||
| 59 | + <connections> | ||
| 60 | + <outlet property="searchButton" destination="NOc-fo-goN" id="vyT-JX-Kgo"/> | ||
| 61 | + <outlet property="titleLabel" destination="QuH-xv-rPx" id="q9e-Nt-mZk"/> | ||
| 62 | + </connections> | ||
| 63 | + <point key="canvasLocation" x="141" y="154"/> | ||
| 64 | + </tableViewCell> | ||
| 65 | + </objects> | ||
| 66 | + <resources> | ||
| 67 | + <systemColor name="systemBackgroundColor"> | ||
| 68 | + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 69 | + </systemColor> | ||
| 70 | + </resources> | ||
| 71 | +</document> |
| 1 | +// | ||
| 2 | +// MyCouponsViewController.swift | ||
| 3 | +// SwiftWarplyFramework | ||
| 4 | +// | ||
| 5 | +// Created by Manos Chorianopoulos on 16/3/26. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +import UIKit | ||
| 9 | + | ||
| 10 | +@objc public class MyCouponsViewController: UIViewController { | ||
| 11 | + @IBOutlet weak var tableView: UITableView! | ||
| 12 | + | ||
| 13 | + // MARK: - Initializers | ||
| 14 | + public convenience init() { | ||
| 15 | + self.init(nibName: "MyCouponsViewController", bundle: Bundle.frameworkBundle) | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { | ||
| 19 | + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + required init?(coder: NSCoder) { | ||
| 23 | + super.init(coder: coder) | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + // MARK: - Dynamic Data | ||
| 27 | + var allCoupons: [CouponItemModel] = [] | ||
| 28 | + | ||
| 29 | + // MARK: - Loading State | ||
| 30 | + private var isLoading: Bool = true | ||
| 31 | + private var loadingIndicator: UIActivityIndicatorView? | ||
| 32 | + | ||
| 33 | + let couponFilters: [CouponFilterModel] = [ | ||
| 34 | + CouponFilterModel(title: "Ενεργά"), | ||
| 35 | + CouponFilterModel(title: "Αγαπημένα"), | ||
| 36 | + CouponFilterModel(title: "Εξαργυρωμένα") | ||
| 37 | + ] | ||
| 38 | + | ||
| 39 | + var couponFilterSelected: CouponFilterModel = CouponFilterModel(title: "Ενεργά") | ||
| 40 | + | ||
| 41 | + var forYouOffersSection: SectionModel? | ||
| 42 | + var activeOffersSection: SectionModel? | ||
| 43 | + var favoriteOffersSection: SectionModel? | ||
| 44 | + var redeemedOffersSection: SectionModel? | ||
| 45 | + var filteredOffersSection: SectionModel? | ||
| 46 | + | ||
| 47 | + public override func viewDidLoad() { | ||
| 48 | + super.viewDidLoad() | ||
| 49 | + | ||
| 50 | + // Show navigation bar for this screen (with back button) | ||
| 51 | + self.navigationController?.setNavigationBarHidden(false, animated: false) | ||
| 52 | + setBackButton() | ||
| 53 | + setNavigationTitle("Το προφίλ μου") | ||
| 54 | + | ||
| 55 | + // UPDATED: Safe XIB registration with error handling | ||
| 56 | + registerTableViewCells() | ||
| 57 | + | ||
| 58 | + // Set up table view | ||
| 59 | + tableView.delegate = self | ||
| 60 | + tableView.dataSource = self | ||
| 61 | + tableView.separatorStyle = .none | ||
| 62 | + tableView.estimatedRowHeight = 200 | ||
| 63 | + tableView.rowHeight = UITableView.automaticDimension | ||
| 64 | + | ||
| 65 | + // Set up loading indicator | ||
| 66 | + setupLoadingIndicator() | ||
| 67 | + | ||
| 68 | + // Fetch coupons from API | ||
| 69 | + fetchCoupons() | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + // NEW: Safe XIB registration method | ||
| 73 | + private func registerTableViewCells() { | ||
| 74 | + let cellConfigs = [ | ||
| 75 | + ("MyCouponsHeaderTableViewCell", "MyCouponsHeaderTableViewCell"), | ||
| 76 | + ("ProfileQuestionnaireTableViewCell", "ProfileQuestionnaireTableViewCell"), | ||
| 77 | + ("MyRewardsOffersScrollTableViewCell", "MyRewardsOffersScrollTableViewCell"), | ||
| 78 | + ("ProfileCouponFiltersTableViewCell", "ProfileCouponFiltersTableViewCell"), | ||
| 79 | + ("ProfileCouponTableViewCell", "ProfileCouponTableViewCell") | ||
| 80 | + ] | ||
| 81 | + | ||
| 82 | + for (nibName, identifier) in cellConfigs { | ||
| 83 | + XIBLoader.registerTableViewCell( | ||
| 84 | + tableView, | ||
| 85 | + cellClass: UITableViewCell.self, | ||
| 86 | + nibName: nibName, | ||
| 87 | + identifier: identifier | ||
| 88 | + ) | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + // MARK: - Loading Indicator | ||
| 94 | + | ||
| 95 | + private func setupLoadingIndicator() { | ||
| 96 | + let indicator = UIActivityIndicatorView(style: .large) | ||
| 97 | + indicator.color = UIColor(rgb: 0x000F1E) | ||
| 98 | + indicator.translatesAutoresizingMaskIntoConstraints = false | ||
| 99 | + indicator.hidesWhenStopped = true | ||
| 100 | + view.addSubview(indicator) | ||
| 101 | + | ||
| 102 | + NSLayoutConstraint.activate([ | ||
| 103 | + indicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), | ||
| 104 | + indicator.centerYAnchor.constraint(equalTo: view.centerYAnchor) | ||
| 105 | + ]) | ||
| 106 | + | ||
| 107 | + self.loadingIndicator = indicator | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + private func showLoading() { | ||
| 111 | + isLoading = true | ||
| 112 | + loadingIndicator?.startAnimating() | ||
| 113 | + tableView.alpha = 0.3 | ||
| 114 | + tableView.isUserInteractionEnabled = false | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + private func hideLoading() { | ||
| 118 | + isLoading = false | ||
| 119 | + loadingIndicator?.stopAnimating() | ||
| 120 | + tableView.alpha = 1.0 | ||
| 121 | + tableView.isUserInteractionEnabled = true | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + // MARK: - Data Fetching | ||
| 125 | + | ||
| 126 | + private func fetchCoupons() { | ||
| 127 | + showLoading() | ||
| 128 | + | ||
| 129 | + // Initialize sections with empty data first (so table view can render skeleton) | ||
| 130 | + initializeSections() | ||
| 131 | + | ||
| 132 | + WarplySDK.shared.getCouponsUniversal({ [weak self] couponsData in | ||
| 133 | + guard let self = self else { return } | ||
| 134 | + | ||
| 135 | + if let coupons = couponsData { | ||
| 136 | + self.allCoupons = coupons | ||
| 137 | + print("✅ [MyCouponsVC] Fetched \(coupons.count) coupons") | ||
| 138 | + | ||
| 139 | + // Debug: Print coupon statuses | ||
| 140 | + let activeCount = coupons.filter { $0.status == 1 }.count | ||
| 141 | + let redeemedCount = coupons.filter { $0.status == 0 }.count | ||
| 142 | + let expiredCount = coupons.filter { $0.status == -1 }.count | ||
| 143 | + print(" Active: \(activeCount), Redeemed: \(redeemedCount), Expired: \(expiredCount)") | ||
| 144 | + } else { | ||
| 145 | + self.allCoupons = [] | ||
| 146 | + print("⚠️ [MyCouponsVC] No coupons received") | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + self.initializeSections() | ||
| 150 | + self.hideLoading() | ||
| 151 | + }, failureCallback: { [weak self] errorCode in | ||
| 152 | + guard let self = self else { return } | ||
| 153 | + | ||
| 154 | + print("❌ [MyCouponsVC] Failed to fetch coupons, error: \(errorCode)") | ||
| 155 | + self.allCoupons = [] | ||
| 156 | + self.initializeSections() | ||
| 157 | + self.hideLoading() | ||
| 158 | + }) | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + // MARK: - Section Initialization | ||
| 162 | + | ||
| 163 | + func initializeSections() { | ||
| 164 | + // Προτάσεις για εσένα — empty for now | ||
| 165 | + let forYouOffers: [CouponItemModel] = [] | ||
| 166 | + forYouOffersSection = SectionModel( | ||
| 167 | + sectionType: .myRewardsHorizontalCouponsets, | ||
| 168 | + title: "Προτάσεις για εσένα", | ||
| 169 | + items: forYouOffers, | ||
| 170 | + itemType: .coupons | ||
| 171 | + ) | ||
| 172 | + | ||
| 173 | + // Active Coupons — status == 1 | ||
| 174 | + let activeCoupons = allCoupons.filter { $0.status == 1 } | ||
| 175 | + activeOffersSection = SectionModel( | ||
| 176 | + sectionType: .profileCoupon, | ||
| 177 | + title: "Ενεργά", | ||
| 178 | + items: activeCoupons, | ||
| 179 | + itemType: .coupons | ||
| 180 | + ) | ||
| 181 | + | ||
| 182 | + // Set initial filtered section to active | ||
| 183 | + filteredOffersSection = activeOffersSection | ||
| 184 | + | ||
| 185 | + // Favorite Coupons — empty for now | ||
| 186 | + let favoriteCoupons: [CouponItemModel] = [] | ||
| 187 | + favoriteOffersSection = SectionModel( | ||
| 188 | + sectionType: .profileCoupon, | ||
| 189 | + title: "Αγαπημένα", | ||
| 190 | + items: favoriteCoupons, | ||
| 191 | + itemType: .coupons | ||
| 192 | + ) | ||
| 193 | + | ||
| 194 | + // Redeemed Coupons — status == 0 | ||
| 195 | + let redeemedCoupons = allCoupons.filter { $0.status == 0 } | ||
| 196 | + redeemedOffersSection = SectionModel( | ||
| 197 | + sectionType: .profileCoupon, | ||
| 198 | + title: "Εξαργυρωμένα", | ||
| 199 | + items: redeemedCoupons, | ||
| 200 | + itemType: .coupons | ||
| 201 | + ) | ||
| 202 | + | ||
| 203 | + self.tableView.reloadData() | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + private func openCouponViewController(with coupon: CouponItemModel) { | ||
| 207 | + let vc = SwiftWarplyFramework.CouponViewController(nibName: "CouponViewController", bundle: Bundle.frameworkBundle) | ||
| 208 | + vc.coupon = coupon | ||
| 209 | + | ||
| 210 | + self.navigationController?.pushViewController(vc, animated: true) | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + private func handleFilterPress(with filter: CouponFilterModel) { | ||
| 214 | + switch (filter.title) { | ||
| 215 | + case "Ενεργά": | ||
| 216 | + self.filteredOffersSection = activeOffersSection | ||
| 217 | + case "Αγαπημένα": | ||
| 218 | + self.filteredOffersSection = favoriteOffersSection | ||
| 219 | + case "Εξαργυρωμένα": | ||
| 220 | + self.filteredOffersSection = redeemedOffersSection | ||
| 221 | + default: | ||
| 222 | + self.filteredOffersSection = activeOffersSection | ||
| 223 | + } | ||
| 224 | + } | ||
| 225 | + | ||
| 226 | + // MARK: - Empty State Helper | ||
| 227 | + | ||
| 228 | + private func getEmptyStateMessage() -> String { | ||
| 229 | + switch couponFilterSelected.title { | ||
| 230 | + case "Ενεργά": | ||
| 231 | + return "Δεν υπάρχουν διαθέσιμα ενεργά κουπόνια" | ||
| 232 | + case "Αγαπημένα": | ||
| 233 | + return "Δεν υπάρχουν διαθέσιμα αγαπημένα κουπόνια" | ||
| 234 | + case "Εξαργυρωμένα": | ||
| 235 | + return "Δεν υπάρχουν διαθέσιμα εξαργυρωμένα κουπόνια" | ||
| 236 | + default: | ||
| 237 | + return "Δεν υπάρχουν διαθέσιμα κουπόνια" | ||
| 238 | + } | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + private func createEmptyStateCell(_ tableView: UITableView, indexPath: IndexPath) -> UITableViewCell { | ||
| 242 | + let cell = UITableViewCell(style: .default, reuseIdentifier: "EmptyStateCell") | ||
| 243 | + cell.selectionStyle = .none | ||
| 244 | + cell.backgroundColor = .clear | ||
| 245 | + cell.contentView.backgroundColor = .clear | ||
| 246 | + | ||
| 247 | + // Remove any existing subviews | ||
| 248 | + cell.contentView.subviews.forEach { $0.removeFromSuperview() } | ||
| 249 | + | ||
| 250 | + let label = UILabel() | ||
| 251 | + label.text = getEmptyStateMessage() | ||
| 252 | + label.font = UIFont(name: "PingLCG-Regular", size: 16) | ||
| 253 | + label.textColor = UIColor(rgb: 0x8B8B8B) | ||
| 254 | + label.textAlignment = .center | ||
| 255 | + label.numberOfLines = 0 | ||
| 256 | + label.translatesAutoresizingMaskIntoConstraints = false | ||
| 257 | + | ||
| 258 | + cell.contentView.addSubview(label) | ||
| 259 | + | ||
| 260 | + NSLayoutConstraint.activate([ | ||
| 261 | + label.topAnchor.constraint(equalTo: cell.contentView.topAnchor, constant: 40), | ||
| 262 | + label.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: -40), | ||
| 263 | + label.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 24), | ||
| 264 | + label.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: -24) | ||
| 265 | + ]) | ||
| 266 | + | ||
| 267 | + return cell | ||
| 268 | + } | ||
| 269 | +} | ||
| 270 | + | ||
| 271 | +// MARK: - TableView | ||
| 272 | +extension MyCouponsViewController: UITableViewDelegate, UITableViewDataSource { | ||
| 273 | + | ||
| 274 | + public func numberOfSections(in tableView: UITableView) -> Int { | ||
| 275 | + // return 4 + (filteredOffersSection?.offers.count ?? 0) | ||
| 276 | + return 5 | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | ||
| 280 | + // return 1 | ||
| 281 | + if (section == 2) { | ||
| 282 | + if (forYouOffersSection?.count ?? 0 > 0) { | ||
| 283 | + return 1 | ||
| 284 | + } else { | ||
| 285 | + return 0 | ||
| 286 | + } | ||
| 287 | + } | ||
| 288 | + if (section <= 3) { | ||
| 289 | + return 1 | ||
| 290 | + } else { | ||
| 291 | + let itemCount = filteredOffersSection?.itemCount ?? 0 | ||
| 292 | + // Show at least 1 row for empty state message when no coupons | ||
| 293 | + return itemCount > 0 ? itemCount : 1 | ||
| 294 | + } | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { | ||
| 298 | + return UITableView.automaticDimension | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { | ||
| 302 | + return nil | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | + public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { | ||
| 306 | + return 0.0 | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { | ||
| 310 | + return 0.0 | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { | ||
| 314 | + return nil | ||
| 315 | + } | ||
| 316 | + | ||
| 317 | + public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | ||
| 318 | + if (indexPath.section == 0) { | ||
| 319 | + let cell = tableView.dequeueReusableCell(withIdentifier: "MyCouponsHeaderTableViewCell", for: indexPath) as! MyCouponsHeaderTableViewCell | ||
| 320 | + return cell | ||
| 321 | + | ||
| 322 | + } else if (indexPath.section == 1) { | ||
| 323 | + let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileQuestionnaireTableViewCell", for: indexPath) as! ProfileQuestionnaireTableViewCell | ||
| 324 | + return cell | ||
| 325 | + | ||
| 326 | + } else if (indexPath.section == 2) { | ||
| 327 | + let cell = tableView.dequeueReusableCell(withIdentifier: "MyRewardsOffersScrollTableViewCell", for: indexPath) as! MyRewardsOffersScrollTableViewCell | ||
| 328 | + | ||
| 329 | + cell.delegate = self // Set the offers delegate | ||
| 330 | + cell.configureCell(data: self.forYouOffersSection, isInProfile: true) | ||
| 331 | + | ||
| 332 | + return cell | ||
| 333 | + | ||
| 334 | + } else if (indexPath.section == 3) { | ||
| 335 | + let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileCouponFiltersTableViewCell", for: indexPath) as! ProfileCouponFiltersTableViewCell | ||
| 336 | + | ||
| 337 | + cell.delegate = self // Set the offers delegate | ||
| 338 | + cell.configureCell(data: self.couponFilters, couponFilterSelected: self.couponFilterSelected) | ||
| 339 | + | ||
| 340 | + return cell | ||
| 341 | + | ||
| 342 | + } else { | ||
| 343 | + // Check if the filtered section is empty — show empty state | ||
| 344 | + let itemCount = filteredOffersSection?.itemCount ?? 0 | ||
| 345 | + if itemCount == 0 { | ||
| 346 | + return createEmptyStateCell(tableView, indexPath: indexPath) | ||
| 347 | + } | ||
| 348 | + | ||
| 349 | + let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileCouponTableViewCell", for: indexPath) as! ProfileCouponTableViewCell | ||
| 350 | + if let items = self.filteredOffersSection?.items, | ||
| 351 | + indexPath.row < items.count, | ||
| 352 | + let coupon = items[indexPath.row] as? CouponItemModel { | ||
| 353 | + cell.configureCell(data: coupon) | ||
| 354 | + } | ||
| 355 | + return cell | ||
| 356 | + } | ||
| 357 | + | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | ||
| 361 | + if (indexPath.section <= 3) { | ||
| 362 | + // Do nothing | ||
| 363 | + } else { | ||
| 364 | + if let items = self.filteredOffersSection?.items, | ||
| 365 | + indexPath.row < items.count, | ||
| 366 | + let coupon = items[indexPath.row] as? CouponItemModel { | ||
| 367 | + openCouponViewController(with: coupon) | ||
| 368 | + } | ||
| 369 | + } | ||
| 370 | + } | ||
| 371 | +} | ||
| 372 | + | ||
| 373 | +// Add delegate conformance | ||
| 374 | +extension MyCouponsViewController: MyRewardsOffersScrollTableViewCellDelegate { | ||
| 375 | + func didSelectOffer(_ offer: OfferModel) { | ||
| 376 | + // Legacy OfferModel handling — no longer used but kept for protocol conformance | ||
| 377 | + print("⚠️ [MyCouponsVC] didSelectOffer called with legacy OfferModel — should not happen") | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + func didSelectCouponSet(_ couponSet: CouponSetItemModel) { | ||
| 381 | + // MyCouponsViewController doesn't handle coupon sets, so just log | ||
| 382 | + print("CouponSet selected in MyCouponsViewController: \(couponSet._name)") | ||
| 383 | + } | ||
| 384 | +} | ||
| 385 | + | ||
| 386 | +// Add delegate conformance | ||
| 387 | +extension MyCouponsViewController: ProfileCouponFiltersTableViewCellDelegate { | ||
| 388 | + func didSelectFilter(_ filter: CouponFilterModel) { | ||
| 389 | + self.couponFilterSelected = filter | ||
| 390 | + handleFilterPress(with: filter) | ||
| 391 | + self.tableView.reloadData() | ||
| 392 | + } | ||
| 393 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="24506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> | ||
| 3 | + <device id="retina6_12" orientation="portrait" appearance="light"/> | ||
| 4 | + <dependencies> | ||
| 5 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24504"/> | ||
| 6 | + <capability name="Safe area layout guides" minToolsVersion="9.0"/> | ||
| 7 | + <capability name="System colors in document resources" minToolsVersion="11.0"/> | ||
| 8 | + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
| 9 | + </dependencies> | ||
| 10 | + <objects> | ||
| 11 | + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MyCouponsViewController" customModule="SwiftWarplyFramework" customModuleProvider="target"> | ||
| 12 | + <connections> | ||
| 13 | + <outlet property="tableView" destination="5Lc-C5-PjX" id="pay-eD-2GR"/> | ||
| 14 | + <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> | ||
| 15 | + </connections> | ||
| 16 | + </placeholder> | ||
| 17 | + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> | ||
| 18 | + <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> | ||
| 19 | + <rect key="frame" x="0.0" y="0.0" width="393" height="852"/> | ||
| 20 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
| 21 | + <subviews> | ||
| 22 | + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3MR-Lq-Ca1" userLabel="Main View"> | ||
| 23 | + <rect key="frame" x="0.0" y="118" width="393" height="734"/> | ||
| 24 | + <subviews> | ||
| 25 | + <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" estimatedSectionHeaderHeight="-1" sectionFooterHeight="28" estimatedSectionFooterHeight="-1" contentViewInsetsToSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5Lc-C5-PjX"> | ||
| 26 | + <rect key="frame" x="0.0" y="0.0" width="393" height="734"/> | ||
| 27 | + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 28 | + <color key="separatorColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 29 | + <color key="sectionIndexBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 30 | + <connections> | ||
| 31 | + <outlet property="dataSource" destination="-1" id="yKP-hs-r89"/> | ||
| 32 | + <outlet property="delegate" destination="-1" id="hPq-MZ-iBl"/> | ||
| 33 | + </connections> | ||
| 34 | + </tableView> | ||
| 35 | + </subviews> | ||
| 36 | + <color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/> | ||
| 37 | + <constraints> | ||
| 38 | + <constraint firstItem="5Lc-C5-PjX" firstAttribute="leading" secondItem="3MR-Lq-Ca1" secondAttribute="leading" id="E1N-Fh-MGi"/> | ||
| 39 | + <constraint firstItem="5Lc-C5-PjX" firstAttribute="top" secondItem="3MR-Lq-Ca1" secondAttribute="top" id="oMH-QW-fBP"/> | ||
| 40 | + <constraint firstAttribute="trailing" secondItem="5Lc-C5-PjX" secondAttribute="trailing" id="qGu-bT-w0t"/> | ||
| 41 | + <constraint firstAttribute="bottom" secondItem="5Lc-C5-PjX" secondAttribute="bottom" id="yQw-1D-xi9"/> | ||
| 42 | + </constraints> | ||
| 43 | + </view> | ||
| 44 | + </subviews> | ||
| 45 | + <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> | ||
| 46 | + <color key="backgroundColor" systemColor="systemBackgroundColor"/> | ||
| 47 | + <constraints> | ||
| 48 | + <constraint firstItem="3MR-Lq-Ca1" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="3RG-QL-Pay"/> | ||
| 49 | + <constraint firstAttribute="bottom" secondItem="3MR-Lq-Ca1" secondAttribute="bottom" id="H7T-5I-z6N"/> | ||
| 50 | + <constraint firstAttribute="trailing" secondItem="3MR-Lq-Ca1" secondAttribute="trailing" id="c03-MD-sDl"/> | ||
| 51 | + <constraint firstItem="3MR-Lq-Ca1" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" id="hPa-2m-0vn"/> | ||
| 52 | + </constraints> | ||
| 53 | + <point key="canvasLocation" x="140" y="154"/> | ||
| 54 | + </view> | ||
| 55 | + </objects> | ||
| 56 | + <resources> | ||
| 57 | + <systemColor name="systemBackgroundColor"> | ||
| 58 | + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 59 | + </systemColor> | ||
| 60 | + </resources> | ||
| 61 | +</document> |
-
Please register or login to post a comment