Manos Chorianopoulos

MyRewards dynamic profile info

...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 <key>Pods-SwiftWarplyFramework.xcscheme_^#shared#^_</key> 7 <key>Pods-SwiftWarplyFramework.xcscheme_^#shared#^_</key>
8 <dict> 8 <dict>
9 <key>orderHint</key> 9 <key>orderHint</key>
10 - <integer>0</integer> 10 + <integer>1</integer>
11 </dict> 11 </dict>
12 </dict> 12 </dict>
13 </dict> 13 </dict>
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
40 1E4C4CFB2DE6014500279AAD /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4C4CFA2DE6014500279AAD /* CopyableLabel.swift */; }; 40 1E4C4CFB2DE6014500279AAD /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4C4CFA2DE6014500279AAD /* CopyableLabel.swift */; };
41 1E64E1832DE48E0600543217 /* MyRewardsOfferCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E64E1822DE48E0600543217 /* MyRewardsOfferCollectionViewCell.xib */; }; 41 1E64E1832DE48E0600543217 /* MyRewardsOfferCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E64E1822DE48E0600543217 /* MyRewardsOfferCollectionViewCell.xib */; };
42 1E64E1842DE48E0600543217 /* MyRewardsOfferCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E64E1812DE48E0600543217 /* MyRewardsOfferCollectionViewCell.swift */; }; 42 1E64E1842DE48E0600543217 /* MyRewardsOfferCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E64E1812DE48E0600543217 /* MyRewardsOfferCollectionViewCell.swift */; };
43 + 1E66E4972E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E66E4962E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.xib */; };
44 + 1E66E4982E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E66E4952E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.swift */; };
43 1E917CD62DDF64B2002221D8 /* MyRewardsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E917CD52DDF64B2002221D8 /* MyRewardsViewController.xib */; }; 45 1E917CD62DDF64B2002221D8 /* MyRewardsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E917CD52DDF64B2002221D8 /* MyRewardsViewController.xib */; };
44 1E917CD72DDF64B2002221D8 /* MyRewardsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E917CD42DDF64B2002221D8 /* MyRewardsViewController.swift */; }; 46 1E917CD72DDF64B2002221D8 /* MyRewardsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E917CD42DDF64B2002221D8 /* MyRewardsViewController.swift */; };
45 1E917CDB2DDF68C7002221D8 /* CouponViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E917CDA2DDF68C7002221D8 /* CouponViewController.xib */; }; 47 1E917CDB2DDF68C7002221D8 /* CouponViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E917CDA2DDF68C7002221D8 /* CouponViewController.xib */; };
...@@ -116,6 +118,8 @@ ...@@ -116,6 +118,8 @@
116 1E4C4CFA2DE6014500279AAD /* CopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLabel.swift; sourceTree = "<group>"; }; 118 1E4C4CFA2DE6014500279AAD /* CopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLabel.swift; sourceTree = "<group>"; };
117 1E64E1812DE48E0600543217 /* MyRewardsOfferCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyRewardsOfferCollectionViewCell.swift; sourceTree = "<group>"; }; 119 1E64E1812DE48E0600543217 /* MyRewardsOfferCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyRewardsOfferCollectionViewCell.swift; sourceTree = "<group>"; };
118 1E64E1822DE48E0600543217 /* MyRewardsOfferCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyRewardsOfferCollectionViewCell.xib; sourceTree = "<group>"; }; 120 1E64E1822DE48E0600543217 /* MyRewardsOfferCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyRewardsOfferCollectionViewCell.xib; sourceTree = "<group>"; };
121 + 1E66E4952E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyRewardsProfileInfoTableViewCell.swift; sourceTree = "<group>"; };
122 + 1E66E4962E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyRewardsProfileInfoTableViewCell.xib; sourceTree = "<group>"; };
119 1E917CD42DDF64B2002221D8 /* MyRewardsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyRewardsViewController.swift; sourceTree = "<group>"; }; 123 1E917CD42DDF64B2002221D8 /* MyRewardsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyRewardsViewController.swift; sourceTree = "<group>"; };
120 1E917CD52DDF64B2002221D8 /* MyRewardsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyRewardsViewController.xib; sourceTree = "<group>"; }; 124 1E917CD52DDF64B2002221D8 /* MyRewardsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyRewardsViewController.xib; sourceTree = "<group>"; };
121 1E917CD92DDF68C7002221D8 /* CouponViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CouponViewController.swift; sourceTree = "<group>"; }; 125 1E917CD92DDF68C7002221D8 /* CouponViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CouponViewController.swift; sourceTree = "<group>"; };
...@@ -276,6 +280,15 @@ ...@@ -276,6 +280,15 @@
276 path = MyRewardsOfferCollectionViewCell; 280 path = MyRewardsOfferCollectionViewCell;
277 sourceTree = "<group>"; 281 sourceTree = "<group>";
278 }; 282 };
283 + 1E66E4942E30F8C600BCEF9D /* MyRewardsProfileInfoTableViewCell */ = {
284 + isa = PBXGroup;
285 + children = (
286 + 1E66E4952E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.swift */,
287 + 1E66E4962E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.xib */,
288 + );
289 + path = MyRewardsProfileInfoTableViewCell;
290 + sourceTree = "<group>";
291 + };
279 1E917CD32DDF6472002221D8 /* MyRewardsViewController */ = { 292 1E917CD32DDF6472002221D8 /* MyRewardsViewController */ = {
280 isa = PBXGroup; 293 isa = PBXGroup;
281 children = ( 294 children = (
...@@ -326,6 +339,7 @@ ...@@ -326,6 +339,7 @@
326 1ED41E492DE0C21800836ABA /* MyRewardsBannerOfferCollectionViewCell */, 339 1ED41E492DE0C21800836ABA /* MyRewardsBannerOfferCollectionViewCell */,
327 1EB4F4282DE0A09500D934C0 /* MyRewardsOffersScrollTableViewCell */, 340 1EB4F4282DE0A09500D934C0 /* MyRewardsOffersScrollTableViewCell */,
328 1EB4F4222DE09A4300D934C0 /* MyRewardsBannerOffersScrollTableViewCell */, 341 1EB4F4222DE09A4300D934C0 /* MyRewardsBannerOffersScrollTableViewCell */,
342 + 1E66E4942E30F8C600BCEF9D /* MyRewardsProfileInfoTableViewCell */,
329 ); 343 );
330 path = cells; 344 path = cells;
331 sourceTree = "<group>"; 345 sourceTree = "<group>";
...@@ -588,6 +602,7 @@ ...@@ -588,6 +602,7 @@
588 1EA8E5C12DDF427A00CD3418 /* PingLCG-Light.otf in Resources */, 602 1EA8E5C12DDF427A00CD3418 /* PingLCG-Light.otf in Resources */,
589 1EA8E5C22DDF427A00CD3418 /* PingLCG-Regular.otf in Resources */, 603 1EA8E5C22DDF427A00CD3418 /* PingLCG-Regular.otf in Resources */,
590 1EB4F42B2DE0A0AF00D934C0 /* MyRewardsOffersScrollTableViewCell.xib in Resources */, 604 1EB4F42B2DE0A0AF00D934C0 /* MyRewardsOffersScrollTableViewCell.xib in Resources */,
605 + 1E66E4972E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.xib in Resources */,
591 1EDBAF102DE8443B00911E79 /* ProfileHeaderTableViewCell.xib in Resources */, 606 1EDBAF102DE8443B00911E79 /* ProfileHeaderTableViewCell.xib in Resources */,
592 1E917CDB2DDF68C7002221D8 /* CouponViewController.xib in Resources */, 607 1E917CDB2DDF68C7002221D8 /* CouponViewController.xib in Resources */,
593 1E917CE02DDF6909002221D8 /* ProfileViewController.xib in Resources */, 608 1E917CE02DDF6909002221D8 /* ProfileViewController.xib in Resources */,
...@@ -668,6 +683,7 @@ ...@@ -668,6 +683,7 @@
668 E6A77853282933340045BBA8 /* SwiftWarplyFramework.docc in Sources */, 683 E6A77853282933340045BBA8 /* SwiftWarplyFramework.docc in Sources */,
669 1EDBAF092DE843FB00911E79 /* ProfileCouponFiltersTableViewCell.swift in Sources */, 684 1EDBAF092DE843FB00911E79 /* ProfileCouponFiltersTableViewCell.swift in Sources */,
670 E6A778DF282933E60045BBA8 /* WarplyReactMethods.m in Sources */, 685 E6A778DF282933E60045BBA8 /* WarplyReactMethods.m in Sources */,
686 + 1E66E4982E30F9F200BCEF9D /* MyRewardsProfileInfoTableViewCell.swift in Sources */,
671 1E917CD72DDF64B2002221D8 /* MyRewardsViewController.swift in Sources */, 687 1E917CD72DDF64B2002221D8 /* MyRewardsViewController.swift in Sources */,
672 1E917CDC2DDF68C7002221D8 /* CouponViewController.swift in Sources */, 688 1E917CDC2DDF68C7002221D8 /* CouponViewController.swift in Sources */,
673 1E4C4CFB2DE6014500279AAD /* CopyableLabel.swift in Sources */, 689 1E4C4CFB2DE6014500279AAD /* CopyableLabel.swift in Sources */,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 <key>SwiftWarplyFramework.xcscheme_^#shared#^_</key> 7 <key>SwiftWarplyFramework.xcscheme_^#shared#^_</key>
8 <dict> 8 <dict>
9 <key>orderHint</key> 9 <key>orderHint</key>
10 - <integer>1</integer> 10 + <integer>0</integer>
11 </dict> 11 </dict>
12 </dict> 12 </dict>
13 </dict> 13 </dict>
......
...@@ -9,7 +9,7 @@ import UIKit ...@@ -9,7 +9,7 @@ import UIKit
9 9
10 protocol MyRewardsBannerOffersScrollTableViewCellDelegate: AnyObject { 10 protocol MyRewardsBannerOffersScrollTableViewCellDelegate: AnyObject {
11 func didSelectBannerOffer(_ index: Int) 11 func didSelectBannerOffer(_ index: Int)
12 - func didTapProfileButton() 12 +// func didTapProfileButton()
13 } 13 }
14 14
15 @objc(MyRewardsBannerOffersScrollTableViewCell) 15 @objc(MyRewardsBannerOffersScrollTableViewCell)
...@@ -103,7 +103,7 @@ public class MyRewardsBannerOffersScrollTableViewCell: UITableViewCell { ...@@ -103,7 +103,7 @@ public class MyRewardsBannerOffersScrollTableViewCell: UITableViewCell {
103 103
104 @objc private func profileButtonTapped() { 104 @objc private func profileButtonTapped() {
105 // TODO: UNCOMMENT 105 // TODO: UNCOMMENT
106 - delegate?.didTapProfileButton() 106 +// delegate?.didTapProfileButton()
107 } 107 }
108 } 108 }
109 109
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 <autoresizingMask key="autoresizingMask"/> 17 <autoresizingMask key="autoresizingMask"/>
18 <subviews> 18 <subviews>
19 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VzF-dQ-3Wa" userLabel="Parent View"> 19 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VzF-dQ-3Wa" userLabel="Parent View">
20 - <rect key="frame" x="0.0" y="0.0" width="413" height="465"/> 20 + <rect key="frame" x="0.0" y="0.0" width="413" height="349"/>
21 <subviews> 21 <subviews>
22 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JTs-J5-DO2" userLabel="Top View"> 22 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JTs-J5-DO2" userLabel="Top View">
23 <rect key="frame" x="24" y="36" width="365" height="35"/> 23 <rect key="frame" x="24" y="36" width="365" height="35"/>
...@@ -106,7 +106,7 @@ ...@@ -106,7 +106,7 @@
106 </constraints> 106 </constraints>
107 </view> 107 </view>
108 <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="I7z-Fz-SNP"> 108 <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="I7z-Fz-SNP">
109 - <rect key="frame" x="0.0" y="91" width="413" height="348"/> 109 + <rect key="frame" x="0.0" y="-25" width="413" height="348"/>
110 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> 110 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
111 <constraints> 111 <constraints>
112 <constraint firstAttribute="height" constant="348" id="aEf-Xl-A2C"/> 112 <constraint firstAttribute="height" constant="348" id="aEf-Xl-A2C"/>
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
124 </connections> 124 </connections>
125 </collectionView> 125 </collectionView>
126 <pageControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="3" translatesAutoresizingMaskIntoConstraints="NO" id="lOm-CZ-dVG"> 126 <pageControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="3" translatesAutoresizingMaskIntoConstraints="NO" id="lOm-CZ-dVG">
127 - <rect key="frame" x="170" y="439" width="73" height="26"/> 127 + <rect key="frame" x="170" y="323" width="73" height="26"/>
128 </pageControl> 128 </pageControl>
129 </subviews> 129 </subviews>
130 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> 130 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
...@@ -136,9 +136,14 @@ ...@@ -136,9 +136,14 @@
136 <constraint firstAttribute="trailing" secondItem="JTs-J5-DO2" secondAttribute="trailing" constant="24" id="Rdi-FK-2Ft"/> 136 <constraint firstAttribute="trailing" secondItem="JTs-J5-DO2" secondAttribute="trailing" constant="24" id="Rdi-FK-2Ft"/>
137 <constraint firstAttribute="trailing" secondItem="I7z-Fz-SNP" secondAttribute="trailing" id="avB-Gc-ttI"/> 137 <constraint firstAttribute="trailing" secondItem="I7z-Fz-SNP" secondAttribute="trailing" id="avB-Gc-ttI"/>
138 <constraint firstItem="I7z-Fz-SNP" firstAttribute="leading" secondItem="VzF-dQ-3Wa" secondAttribute="leading" id="pTY-7d-s1S"/> 138 <constraint firstItem="I7z-Fz-SNP" firstAttribute="leading" secondItem="VzF-dQ-3Wa" secondAttribute="leading" id="pTY-7d-s1S"/>
139 - <constraint firstItem="I7z-Fz-SNP" firstAttribute="top" secondItem="JTs-J5-DO2" secondAttribute="bottom" constant="20" id="vJF-jy-p83"/> 139 + <constraint firstItem="I7z-Fz-SNP" firstAttribute="top" secondItem="VzF-dQ-3Wa" secondAttribute="top" constant="20" id="vJF-jy-p83"/>
140 <constraint firstItem="lOm-CZ-dVG" firstAttribute="centerX" secondItem="VzF-dQ-3Wa" secondAttribute="centerX" id="xpw-tV-NcW"/> 140 <constraint firstItem="lOm-CZ-dVG" firstAttribute="centerX" secondItem="VzF-dQ-3Wa" secondAttribute="centerX" id="xpw-tV-NcW"/>
141 </constraints> 141 </constraints>
142 + <variation key="default">
143 + <mask key="subviews">
144 + <exclude reference="JTs-J5-DO2"/>
145 + </mask>
146 + </variation>
142 </view> 147 </view>
143 </subviews> 148 </subviews>
144 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> 149 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
......
1 +//
2 +// MyRewardsProfileInfoTableViewCell.swift
3 +// SwiftWarplyFramework
4 +//
5 +// Created by Manos Chorianopoulos on 23/7/25.
6 +//
7 +
8 +import UIKit
9 +
10 +protocol MyRewardsProfileInfoTableViewCellDelegate: AnyObject {
11 + func didTapProfileButton()
12 +}
13 +
14 +@objc(MyRewardsProfileInfoTableViewCell)
15 +public class MyRewardsProfileInfoTableViewCell: UITableViewCell {
16 + @IBOutlet weak var tagView1: UIView!
17 + @IBOutlet weak var tagLabel1: UILabel!
18 + @IBOutlet weak var tagView2: UIView!
19 + @IBOutlet weak var tagLabel2: UILabel!
20 + @IBOutlet weak var profileImage: UIImageView!
21 + @IBOutlet weak var profileButton: UIButton!
22 +
23 + weak var delegate: MyRewardsProfileInfoTableViewCellDelegate?
24 +
25 + // MARK: - Properties
26 + private var profileModel: ProfileModel?
27 +
28 + public override func awakeFromNib() {
29 + super.awakeFromNib()
30 + // Initialization code
31 +
32 + profileImage.image = UIImage(named: "profile_pic_default", in: Bundle.frameworkResourceBundle, compatibleWith: nil)
33 +
34 + profileButton.addTarget(self, action: #selector(profileButtonTapped), for: .touchUpInside)
35 +
36 + tagView1.backgroundColor = UIColor(rgb: 0x09914E)
37 + tagView1.layer.cornerRadius = 4.0
38 + tagLabel1.font = UIFont(name: "PingLCG-Regular", size: 17)
39 + tagLabel1.textColor = UIColor(rgb: 0xFFFFFF)
40 +
41 + tagView2.backgroundColor = UIColor(rgb: 0xFC9F25)
42 + tagView2.layer.cornerRadius = 4.0
43 + tagLabel2.font = UIFont(name: "PingLCG-Regular", size: 17)
44 + tagLabel2.textColor = UIColor(rgb: 0xFFFFFF)
45 +
46 + }
47 +
48 + public override func setSelected(_ selected: Bool, animated: Bool) {
49 + super.setSelected(selected, animated: animated)
50 +
51 + // Configure the view for the selected state
52 + }
53 +
54 + @objc private func profileButtonTapped() {
55 + delegate?.didTapProfileButton()
56 + }
57 +
58 + // MARK: - Configuration Methods
59 +
60 + public func configureCell(data: SectionModel?) {
61 + guard let data = data,
62 + let itemType = data.itemType,
63 + itemType == .profile else {
64 + configureDefaultState()
65 + return
66 + }
67 +
68 + // Check if we have real profile data
69 + if let metadata = data.metadata,
70 + let profile = metadata["profile"] as? ProfileModel {
71 + // Configure with real profile data
72 + configureCell(profile: profile)
73 + } else {
74 + // Configure with default state (no profile data)
75 + configureDefaultState()
76 + }
77 + }
78 +
79 + public func configureCell(profile: ProfileModel) {
80 + self.profileModel = profile
81 +
82 + // TODO: Configure tag labels with profile data
83 + // We need to determine what data should populate tagView1 and tagView2
84 + // Possible options from ProfileModel:
85 + // - _user_points (loyalty points)
86 + // - _badge (user badge/tier)
87 + // - _verified (verification status)
88 + // - Custom business logic based on profile data
89 +
90 + // For now, keep tags visible with current static styling
91 + tagView1.isHidden = false
92 + tagView2.isHidden = false
93 +
94 + // Load profile image if available
95 + if !profile._image_url.isEmpty {
96 + loadProfileImage(from: profile._image_url)
97 + } else {
98 + profileImage.image = UIImage(named: "profile_pic_default", in: Bundle.frameworkResourceBundle, compatibleWith: nil)
99 + }
100 + }
101 +
102 + private func configureDefaultState() {
103 + // Default state: no profile data available
104 + self.profileModel = nil
105 +
106 + // Keep tags visible even in default state
107 + tagView1.isHidden = false
108 + tagView2.isHidden = false
109 +
110 + profileImage.image = UIImage(named: "profile_pic_default", in: Bundle.frameworkResourceBundle, compatibleWith: nil)
111 + }
112 +
113 + private func loadProfileImage(from urlString: String) {
114 + // For now, use default image - can be enhanced later with URL loading
115 + profileImage.image = UIImage(named: "profile_pic_default", in: Bundle.frameworkResourceBundle, compatibleWith: nil)
116 + }
117 +}
...@@ -11,6 +11,7 @@ import Foundation ...@@ -11,6 +11,7 @@ import Foundation
11 // MARK: - Section Types 11 // MARK: - Section Types
12 12
13 enum SectionType { 13 enum SectionType {
14 + case myRewardsProfileInfo // MyRewardsProfileInfoTableViewCell
14 case myRewardsBannerOffers // MyRewardsBannerOffersScrollTableViewCell 15 case myRewardsBannerOffers // MyRewardsBannerOffersScrollTableViewCell
15 case myRewardsHorizontalCouponsets // MyRewardsOffersScrollTableViewCell 16 case myRewardsHorizontalCouponsets // MyRewardsOffersScrollTableViewCell
16 case profileHeader // ProfileHeaderTableViewCell (no items) 17 case profileHeader // ProfileHeaderTableViewCell (no items)
...@@ -21,6 +22,7 @@ enum SectionType { ...@@ -21,6 +22,7 @@ enum SectionType {
21 } 22 }
22 23
23 enum ItemType { 24 enum ItemType {
25 + case profile // ProfileModel
24 case campaigns // [CampaignItemModel] 26 case campaigns // [CampaignItemModel]
25 case couponSets // [CouponSetItemModel] 27 case couponSets // [CouponSetItemModel]
26 case coupons // [CouponItemModel] 28 case coupons // [CouponItemModel]
......
...@@ -40,6 +40,10 @@ import UIKit ...@@ -40,6 +40,10 @@ import UIKit
40 // Campaign data for banners 40 // Campaign data for banners
41 var bannerCampaigns: [CampaignItemModel] = [] 41 var bannerCampaigns: [CampaignItemModel] = []
42 42
43 + // Profile data
44 + var profileModel: ProfileModel?
45 + var profileSection: SectionModel?
46 +
43 public override func viewDidLoad() { 47 public override func viewDidLoad() {
44 super.viewDidLoad() 48 super.viewDidLoad()
45 49
...@@ -56,13 +60,18 @@ import UIKit ...@@ -56,13 +60,18 @@ import UIKit
56 tableView.estimatedRowHeight = 200 60 tableView.estimatedRowHeight = 200
57 tableView.rowHeight = UITableView.automaticDimension 61 tableView.rowHeight = UITableView.automaticDimension
58 62
59 - // Start with empty sections - will be populated dynamically by API calls 63 + // Always create profile section first (with default state)
60 - loadCampaigns() 64 + createDefaultProfileSection()
65 +
66 + // Load data
67 + loadProfile() // Try to populate profile with real data
68 + loadCampaigns() // Load campaigns
61 } 69 }
62 70
63 // NEW: Safe XIB registration method 71 // NEW: Safe XIB registration method
64 private func registerTableViewCells() { 72 private func registerTableViewCells() {
65 let cellConfigs = [ 73 let cellConfigs = [
74 + ("MyRewardsProfileInfoTableViewCell", "MyRewardsProfileInfoTableViewCell"),
66 ("MyRewardsBannerOffersScrollTableViewCell", "MyRewardsBannerOffersScrollTableViewCell"), 75 ("MyRewardsBannerOffersScrollTableViewCell", "MyRewardsBannerOffersScrollTableViewCell"),
67 ("MyRewardsOffersScrollTableViewCell", "MyRewardsOffersScrollTableViewCell") 76 ("MyRewardsOffersScrollTableViewCell", "MyRewardsOffersScrollTableViewCell")
68 ] 77 ]
...@@ -127,6 +136,66 @@ import UIKit ...@@ -127,6 +136,66 @@ import UIKit
127 } 136 }
128 } 137 }
129 138
139 + // MARK: - Profile Loading
140 + public func loadProfile() {
141 + // Always attempt to load profile, regardless of authentication status
142 + // If not authenticated, the API call will fail gracefully and we keep the default state
143 +
144 + WarplySDK.shared.getProfile { [weak self] profile in
145 + guard let self = self else { return }
146 +
147 + if let profile = profile {
148 + // Success: Update with real profile data
149 + self.profileModel = profile
150 + self.updateProfileSectionWithData(profile)
151 + print("✅ [MyRewardsViewController] Profile loaded successfully")
152 + } else {
153 + // No profile data: Keep default state
154 + print("ℹ️ [MyRewardsViewController] No profile data received - keeping default state")
155 + }
156 +
157 + } failureCallback: { [weak self] errorCode in
158 + print("⚠️ [MyRewardsViewController] Profile loading failed with error: \(errorCode) - keeping default state")
159 + // Don't remove section - just keep the default state
160 + // The profile section remains visible with default profile pic
161 + }
162 + }
163 +
164 + private func createDefaultProfileSection() {
165 + // Create profile section with default/empty state
166 + let defaultProfileSection = SectionModel(
167 + sectionType: .myRewardsProfileInfo,
168 + title: nil,
169 + count: 1,
170 + metadata: ["profile": nil] // nil profile = default state
171 + )
172 +
173 + // Always insert at index 0 (top of the list)
174 + sections.insert(defaultProfileSection, at: 0)
175 + profileSection = defaultProfileSection
176 + }
177 +
178 + private func updateProfileSectionWithData(_ profile: ProfileModel) {
179 + // Create updated profile section with real data
180 + let updatedProfileSection = SectionModel(
181 + sectionType: .myRewardsProfileInfo,
182 + title: nil,
183 + count: 1,
184 + metadata: ["profile": profile]
185 + )
186 +
187 + // Find and update the profile section
188 + if let profileIndex = sections.firstIndex(where: { $0.sectionType == .myRewardsProfileInfo }) {
189 + sections[profileIndex] = updatedProfileSection
190 + profileSection = updatedProfileSection
191 +
192 + // Reload only the profile section
193 + DispatchQueue.main.async {
194 + self.tableView.reloadSections(IndexSet(integer: profileIndex), with: .none)
195 + }
196 + }
197 + }
198 +
130 private func openCampaignViewController(with index: Int) { 199 private func openCampaignViewController(with index: Int) {
131 // Validate index bounds 200 // Validate index bounds
132 guard index < bannerCampaigns.count else { 201 guard index < bannerCampaigns.count else {
...@@ -203,6 +272,12 @@ extension MyRewardsViewController: UITableViewDelegate, UITableViewDataSource{ ...@@ -203,6 +272,12 @@ extension MyRewardsViewController: UITableViewDelegate, UITableViewDataSource{
203 let sectionModel = sections[indexPath.section] 272 let sectionModel = sections[indexPath.section]
204 273
205 switch sectionModel.sectionType { 274 switch sectionModel.sectionType {
275 + case .myRewardsProfileInfo:
276 + let cell = tableView.dequeueReusableCell(withIdentifier: "MyRewardsProfileInfoTableViewCell", for: indexPath) as! MyRewardsProfileInfoTableViewCell
277 + cell.delegate = self
278 + cell.configureCell(data: sectionModel)
279 + return cell
280 +
206 case .myRewardsBannerOffers: 281 case .myRewardsBannerOffers:
207 let cell = tableView.dequeueReusableCell(withIdentifier: "MyRewardsBannerOffersScrollTableViewCell", for: indexPath) as! MyRewardsBannerOffersScrollTableViewCell 282 let cell = tableView.dequeueReusableCell(withIdentifier: "MyRewardsBannerOffersScrollTableViewCell", for: indexPath) as! MyRewardsBannerOffersScrollTableViewCell
208 cell.delegate = self 283 cell.delegate = self
...@@ -232,16 +307,24 @@ extension MyRewardsViewController: UITableViewDelegate, UITableViewDataSource{ ...@@ -232,16 +307,24 @@ extension MyRewardsViewController: UITableViewDelegate, UITableViewDataSource{
232 } 307 }
233 308
234 // Add delegate conformance 309 // Add delegate conformance
310 +extension MyRewardsViewController: MyRewardsProfileInfoTableViewCellDelegate {
311 + func didTapProfileButton() {
312 + // Navigate to ProfileViewController
313 + openProfileViewController()
314 + }
315 +}
316 +
317 +// Add delegate conformance
235 extension MyRewardsViewController: MyRewardsBannerOffersScrollTableViewCellDelegate { 318 extension MyRewardsViewController: MyRewardsBannerOffersScrollTableViewCellDelegate {
236 func didSelectBannerOffer(_ index: Int) { 319 func didSelectBannerOffer(_ index: Int) {
237 // Navigate to CampaignViewController 320 // Navigate to CampaignViewController
238 openCampaignViewController(with: index) 321 openCampaignViewController(with: index)
239 } 322 }
240 323
241 - func didTapProfileButton() { 324 +// func didTapProfileButton() {
242 - // Navigate to ProfileViewController 325 +// // Navigate to ProfileViewController
243 - openProfileViewController() 326 +// openProfileViewController()
244 - } 327 +// }
245 } 328 }
246 329
247 // Add delegate conformance 330 // Add delegate conformance
......