Showing
2 changed files
with
68 additions
and
64 deletions
| ... | @@ -2287,7 +2287,7 @@ public final class WarplySDK { | ... | @@ -2287,7 +2287,7 @@ public final class WarplySDK { |
| 2287 | let dateFormatter = DateFormatter() | 2287 | let dateFormatter = DateFormatter() |
| 2288 | dateFormatter.dateFormat = "dd/MM/yyyy" | 2288 | dateFormatter.dateFormat = "dd/MM/yyyy" |
| 2289 | 2289 | ||
| 2290 | - activeCoupons.sort { coupon1, coupon2 in | 2290 | + couponsArray.sort { coupon1, coupon2 in |
| 2291 | let date1 = dateFormatter.date(from: coupon1.expiration ?? "") | 2291 | let date1 = dateFormatter.date(from: coupon1.expiration ?? "") |
| 2292 | let date2 = dateFormatter.date(from: coupon2.expiration ?? "") | 2292 | let date2 = dateFormatter.date(from: coupon2.expiration ?? "") |
| 2293 | 2293 | ||
| ... | @@ -2297,7 +2297,7 @@ public final class WarplySDK { | ... | @@ -2297,7 +2297,7 @@ public final class WarplySDK { |
| 2297 | return false | 2297 | return false |
| 2298 | } | 2298 | } |
| 2299 | 2299 | ||
| 2300 | - completion(activeCoupons) | 2300 | + completion(couponsArray) |
| 2301 | } | 2301 | } |
| 2302 | } else { | 2302 | } else { |
| 2303 | let dynatraceEvent = LoyaltySDKDynatraceEventModel() | 2303 | let dynatraceEvent = LoyaltySDKDynatraceEventModel() | ... | ... |
| ... | @@ -26,6 +26,9 @@ public class ProfileCouponTableViewCell: UITableViewCell { | ... | @@ -26,6 +26,9 @@ public class ProfileCouponTableViewCell: UITableViewCell { |
| 26 | @IBOutlet weak var arrowView: UIView! | 26 | @IBOutlet weak var arrowView: UIView! |
| 27 | @IBOutlet weak var arrowImage: UIImageView! | 27 | @IBOutlet weak var arrowImage: UIImageView! |
| 28 | 28 | ||
| 29 | + // Cached width constraint for expirationImage — zeroed out in expired state to collapse the gap | ||
| 30 | + private var expirationImageWidthConstraint: NSLayoutConstraint? | ||
| 31 | + | ||
| 29 | public override func awakeFromNib() { | 32 | public override func awakeFromNib() { |
| 30 | super.awakeFromNib() | 33 | super.awakeFromNib() |
| 31 | // Initialization code | 34 | // Initialization code |
| ... | @@ -42,8 +45,10 @@ public class ProfileCouponTableViewCell: UITableViewCell { | ... | @@ -42,8 +45,10 @@ public class ProfileCouponTableViewCell: UITableViewCell { |
| 42 | arrowImage.image = UIImage(named: "ic_forward", in: Bundle.frameworkResourceBundle, compatibleWith: nil) | 45 | arrowImage.image = UIImage(named: "ic_forward", in: Bundle.frameworkResourceBundle, compatibleWith: nil) |
| 43 | expirationImage.image = UIImage(named: "clock", in: Bundle.frameworkResourceBundle, compatibleWith: nil) | 46 | expirationImage.image = UIImage(named: "clock", in: Bundle.frameworkResourceBundle, compatibleWith: nil) |
| 44 | 47 | ||
| 45 | - // discountView.layer.cornerRadius = 42.0 | 48 | + // Cache the fixed-width constraint on expirationImage (XIB: width = 14) |
| 46 | - | 49 | + expirationImageWidthConstraint = expirationImage.constraints.first { |
| 50 | + $0.firstAttribute == .width && $0.secondItem == nil | ||
| 51 | + } | ||
| 47 | } | 52 | } |
| 48 | 53 | ||
| 49 | // MARK: - Image Loading Helpers | 54 | // MARK: - Image Loading Helpers |
| ... | @@ -116,91 +121,90 @@ public class ProfileCouponTableViewCell: UITableViewCell { | ... | @@ -116,91 +121,90 @@ public class ProfileCouponTableViewCell: UITableViewCell { |
| 116 | // MARK: - Configure with CouponItemModel (dynamic data) | 121 | // MARK: - Configure with CouponItemModel (dynamic data) |
| 117 | 122 | ||
| 118 | func configureCell(data: CouponItemModel) { | 123 | func configureCell(data: CouponItemModel) { |
| 119 | - // Banner image — load from couponset_data img_preview (remote URL) | 124 | + // Shared content — always set regardless of status |
| 120 | - // if let imgPreview = data.couponset_data?._img_preview, !imgPreview.isEmpty { | ||
| 121 | - // self.bannerImageURL = imgPreview | ||
| 122 | - // } else { | ||
| 123 | - // bannerImage.image = nil | ||
| 124 | - // } | ||
| 125 | - | ||
| 126 | - // Favorite — default to not favorite for now | ||
| 127 | - // favoriteImage.image = UIImage(named: "favorite_empty", in: Bundle.frameworkResourceBundle, compatibleWith: nil) | ||
| 128 | - | ||
| 129 | - // // Discount label — use coupon discount or couponset discount | ||
| 130 | - // let discountText = data.discount ?? data.couponset_data?._discount ?? "" | ||
| 131 | - // discountLabel.text = discountText | ||
| 132 | - // discountLabel.font = UIFont(name: "PingLCG-Bold", size: 25) | ||
| 133 | - // discountLabel.textColor = UIColor(rgb: 0xF2F2F2) | ||
| 134 | - | ||
| 135 | - // // Discount view color based on discount type | ||
| 136 | - // let discountType = data.couponset_data?._discount_type ?? "" | ||
| 137 | - // let discountColor: UInt = { | ||
| 138 | - // switch discountType { | ||
| 139 | - // case "percentage": | ||
| 140 | - // return 0xFF6B35 | ||
| 141 | - // case "value": | ||
| 142 | - // return 0x28A745 | ||
| 143 | - // case "plus_one": | ||
| 144 | - // return 0x007AFF | ||
| 145 | - // default: | ||
| 146 | - // return 0xEE417D | ||
| 147 | - // } | ||
| 148 | - // }() | ||
| 149 | - // discountView.backgroundColor = UIColor(rgb: discountColor) | ||
| 150 | - | ||
| 151 | merchantNameLabel.font = UIFont(name: "PingLCG-Bold", size: 14) | 125 | merchantNameLabel.font = UIFont(name: "PingLCG-Bold", size: 14) |
| 152 | - merchantNameLabel.textColor = UIColor(rgb: 0x5C6369) | ||
| 153 | merchantNameLabel.text = data.merchant_details?._name | 126 | merchantNameLabel.text = data.merchant_details?._name |
| 154 | 127 | ||
| 155 | - // Title — from couponset_data name | ||
| 156 | - titleLabel.text = data.couponset_data?._name ?? "" | ||
| 157 | titleLabel.font = UIFont(name: "PingLCG-Bold", size: 22) | 128 | titleLabel.font = UIFont(name: "PingLCG-Bold", size: 22) |
| 158 | - titleLabel.textColor = UIColor(rgb: 0x1D2023) | 129 | + titleLabel.text = data.couponset_data?._name ?? "" |
| 159 | 130 | ||
| 160 | - // Subtitle — from couponset_data short_description | ||
| 161 | - subtitleLabel.text = data.couponset_data?._short_description ?? "" | ||
| 162 | subtitleLabel.font = UIFont(name: "PingLCG-Regular", size: 13) | 131 | subtitleLabel.font = UIFont(name: "PingLCG-Regular", size: 13) |
| 163 | - subtitleLabel.textColor = UIColor(rgb: 0x5C6369) | 132 | + subtitleLabel.text = data.couponset_data?._short_description ?? "" |
| 164 | 133 | ||
| 165 | expirationView.layer.cornerRadius = 6.0 | 134 | expirationView.layer.cornerRadius = 6.0 |
| 166 | expirationView.layer.borderWidth = 1.0 | 135 | expirationView.layer.borderWidth = 1.0 |
| 136 | + expirationLabel.font = UIFont(name: "PingLCG-Bold", size: 13) | ||
| 137 | + | ||
| 138 | + logoImageView.backgroundColor = UIColor(rgb: 0xFFFFFF) | ||
| 139 | + logoImageView.layer.cornerRadius = 10.0 | ||
| 140 | + | ||
| 141 | + if let merchantImgPreview = data.merchant_details?._img_preview, !merchantImgPreview.isEmpty { | ||
| 142 | + self.logoImageURL = merchantImgPreview | ||
| 143 | + } else { | ||
| 144 | + logoImage.image = nil | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + // Branch on expired vs active/expiring-soon | ||
| 148 | + if data.status == -1 { | ||
| 149 | + applyExpiredStyle() | ||
| 150 | + } else { | ||
| 151 | + applyActiveStyle(data: data) | ||
| 152 | + } | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + // MARK: - Expired Style | ||
| 156 | + | ||
| 157 | + private func applyExpiredStyle() { | ||
| 158 | + parentView.backgroundColor = UIColor(rgb: 0xF1F2F4) | ||
| 159 | + parentView.layer.borderColor = UIColor(rgb: 0xD2D6D9).cgColor | ||
| 160 | + | ||
| 161 | + merchantNameLabel.textColor = UIColor(rgb: 0xADB3B8) | ||
| 162 | + titleLabel.textColor = UIColor(rgb: 0xADB3B8) | ||
| 163 | + subtitleLabel.textColor = UIColor(rgb: 0xADB3B8) | ||
| 164 | + | ||
| 165 | + // Hide clock icon and collapse its width so the label has no leading gap | ||
| 166 | + expirationImage.isHidden = true | ||
| 167 | + expirationImageWidthConstraint?.constant = 0 | ||
| 168 | + | ||
| 169 | + expirationView.backgroundColor = UIColor(rgb: 0xF1F2F4) | ||
| 170 | + expirationView.layer.borderColor = UIColor(rgb: 0xD2D6D9).cgColor | ||
| 171 | + expirationLabel.text = "Expired" | ||
| 172 | + expirationLabel.textColor = UIColor(rgb: 0x393E42) | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + // MARK: - Active / Expiring-Soon Style | ||
| 176 | + | ||
| 177 | + private func applyActiveStyle(data: CouponItemModel) { | ||
| 178 | + parentView.backgroundColor = UIColor(rgb: 0xDDEFFB) | ||
| 179 | + parentView.layer.borderColor = UIColor(rgb: 0xA5DAF8).cgColor | ||
| 180 | + | ||
| 181 | + merchantNameLabel.textColor = UIColor(rgb: 0x5C6369) | ||
| 182 | + titleLabel.textColor = UIColor(rgb: 0x1D2023) | ||
| 183 | + subtitleLabel.textColor = UIColor(rgb: 0x5C6369) | ||
| 184 | + | ||
| 185 | + // Restore clock icon and its original width | ||
| 186 | + expirationImage.isHidden = false | ||
| 187 | + expirationImageWidthConstraint?.constant = 14 | ||
| 167 | 188 | ||
| 168 | - let isExpiringSoon: Bool | ||
| 169 | if let expirationDate = data.expirationDate { | 189 | if let expirationDate = data.expirationDate { |
| 170 | let today = Calendar.current.startOfDay(for: Date()) | 190 | let today = Calendar.current.startOfDay(for: Date()) |
| 171 | let expDay = Calendar.current.startOfDay(for: expirationDate) | 191 | let expDay = Calendar.current.startOfDay(for: expirationDate) |
| 172 | let daysLeft = Calendar.current.dateComponents([.day], from: today, to: expDay).day ?? Int.max | 192 | let daysLeft = Calendar.current.dateComponents([.day], from: today, to: expDay).day ?? Int.max |
| 173 | if daysLeft <= 3 { | 193 | if daysLeft <= 3 { |
| 174 | - isExpiringSoon = true | ||
| 175 | expirationLabel.text = "\(daysLeft) days left" | 194 | expirationLabel.text = "\(daysLeft) days left" |
| 195 | + expirationView.backgroundColor = UIColor(rgb: 0xFFF5DA) | ||
| 196 | + expirationView.layer.borderColor = UIColor(rgb: 0xFFEABA).cgColor | ||
| 176 | } else { | 197 | } else { |
| 177 | - isExpiringSoon = false | ||
| 178 | expirationLabel.text = "Valid until " + data.formattedExpiration(format: "MMMM d, yyyy") | 198 | expirationLabel.text = "Valid until " + data.formattedExpiration(format: "MMMM d, yyyy") |
| 199 | + expirationView.backgroundColor = UIColor(rgb: 0xF1F2F4) | ||
| 200 | + expirationView.layer.borderColor = UIColor(rgb: 0xD2D6D9).cgColor | ||
| 179 | } | 201 | } |
| 180 | } else { | 202 | } else { |
| 181 | - isExpiringSoon = false | ||
| 182 | expirationLabel.text = "" | 203 | expirationLabel.text = "" |
| 183 | - } | ||
| 184 | - | ||
| 185 | - if isExpiringSoon { | ||
| 186 | - expirationView.backgroundColor = UIColor(rgb: 0xFFF5DA) | ||
| 187 | - expirationView.layer.borderColor = UIColor(rgb: 0xFFEABA).cgColor | ||
| 188 | - } else { | ||
| 189 | expirationView.backgroundColor = UIColor(rgb: 0xF1F2F4) | 204 | expirationView.backgroundColor = UIColor(rgb: 0xF1F2F4) |
| 190 | expirationView.layer.borderColor = UIColor(rgb: 0xD2D6D9).cgColor | 205 | expirationView.layer.borderColor = UIColor(rgb: 0xD2D6D9).cgColor |
| 191 | } | 206 | } |
| 192 | - expirationLabel.font = UIFont(name: "PingLCG-Bold", size: 13) | ||
| 193 | expirationLabel.textColor = UIColor(rgb: 0x002430) | 207 | expirationLabel.textColor = UIColor(rgb: 0x002430) |
| 194 | - | ||
| 195 | - logoImageView.backgroundColor = UIColor(rgb: 0xFFFFFF) | ||
| 196 | - logoImageView.layer.cornerRadius = 10.0 | ||
| 197 | - | ||
| 198 | - // Logo — load from merchant_details img_preview (remote URL) | ||
| 199 | - if let merchantImgPreview = data.merchant_details?._img_preview, !merchantImgPreview.isEmpty { | ||
| 200 | - self.logoImageURL = merchantImgPreview | ||
| 201 | - } else { | ||
| 202 | - logoImage.image = nil | ||
| 203 | - } | ||
| 204 | } | 208 | } |
| 205 | 209 | ||
| 206 | public override func setSelected(_ selected: Bool, animated: Bool) { | 210 | public override func setSelected(_ selected: Bool, animated: Bool) { | ... | ... |
-
Please register or login to post a comment