Showing
4 changed files
with
238 additions
and
170 deletions
| ... | @@ -10,44 +10,58 @@ import UIKit | ... | @@ -10,44 +10,58 @@ import UIKit |
| 10 | @objc(ProfileCouponTableViewCell) | 10 | @objc(ProfileCouponTableViewCell) |
| 11 | public class ProfileCouponTableViewCell: UITableViewCell { | 11 | public class ProfileCouponTableViewCell: UITableViewCell { |
| 12 | @IBOutlet weak var parentView: UIView! | 12 | @IBOutlet weak var parentView: UIView! |
| 13 | - @IBOutlet weak var bannerImage: UIImageView! | 13 | + // @IBOutlet weak var bannerImage: UIImageView! |
| 14 | - @IBOutlet weak var favoriteImage: UIImageView! | 14 | + // @IBOutlet weak var favoriteImage: UIImageView! |
| 15 | - @IBOutlet weak var discountView: UIView! | 15 | + // @IBOutlet weak var discountView: UIView! |
| 16 | - @IBOutlet weak var discountLabel: UILabel! | 16 | + // @IBOutlet weak var discountLabel: UILabel! |
| 17 | + | ||
| 18 | + @IBOutlet weak var logoImageView: UIView! | ||
| 19 | + @IBOutlet weak var logoImage: UIImageView! | ||
| 20 | + @IBOutlet weak var expirationView: UIView! | ||
| 21 | + @IBOutlet weak var expirationImage: UIImageView! | ||
| 22 | + @IBOutlet weak var expirationLabel: UILabel! | ||
| 23 | + @IBOutlet weak var merchantNameLabel: UILabel! | ||
| 17 | @IBOutlet weak var titleLabel: UILabel! | 24 | @IBOutlet weak var titleLabel: UILabel! |
| 18 | @IBOutlet weak var subtitleLabel: UILabel! | 25 | @IBOutlet weak var subtitleLabel: UILabel! |
| 19 | - @IBOutlet weak var expirationLabel: UILabel! | 26 | + @IBOutlet weak var arrowView: UIView! |
| 20 | - @IBOutlet weak var logoImage: UIImageView! | 27 | + @IBOutlet weak var arrowImage: UIImageView! |
| 21 | 28 | ||
| 22 | public override func awakeFromNib() { | 29 | public override func awakeFromNib() { |
| 23 | super.awakeFromNib() | 30 | super.awakeFromNib() |
| 24 | // Initialization code | 31 | // Initialization code |
| 25 | 32 | ||
| 26 | - parentView.layer.borderWidth = 1.0 | 33 | + parentView.backgroundColor = UIColor(rgb: 0xDDEFFB) |
| 27 | - parentView.layer.borderColor = UIColor(rgb: 0xCCCCCC).cgColor | 34 | + parentView.layer.borderWidth = 2.0 |
| 28 | - parentView.layer.cornerRadius = 8.0 | 35 | + parentView.layer.borderColor = UIColor(rgb: 0xA5DAF8).cgColor |
| 36 | + parentView.layer.cornerRadius = 12.0 | ||
| 29 | parentView.clipsToBounds = true | 37 | parentView.clipsToBounds = true |
| 38 | + | ||
| 39 | + arrowView.backgroundColor = UIColor(rgb: 0xFFFFFF) | ||
| 40 | + arrowView.layer.cornerRadius = arrowView.bounds.height / 2 | ||
| 30 | 41 | ||
| 31 | - discountView.layer.cornerRadius = 42.0 | 42 | + arrowImage.image = UIImage(named: "ic_forward", in: Bundle.frameworkResourceBundle, compatibleWith: nil) |
| 43 | + expirationImage.image = UIImage(named: "clock", in: Bundle.frameworkResourceBundle, compatibleWith: nil) | ||
| 44 | + | ||
| 45 | + // discountView.layer.cornerRadius = 42.0 | ||
| 32 | 46 | ||
| 33 | } | 47 | } |
| 34 | 48 | ||
| 35 | // MARK: - Image Loading Helpers | 49 | // MARK: - Image Loading Helpers |
| 36 | 50 | ||
| 37 | - private var bannerImageURL: String? { | 51 | + // private var bannerImageURL: String? { |
| 38 | - didSet { | 52 | + // didSet { |
| 39 | - if let url = bannerImageURL, !url.isEmpty { | 53 | + // if let url = bannerImageURL, !url.isEmpty { |
| 40 | - self.bannerImage.image = UIImage() | 54 | + // self.bannerImage.image = UIImage() |
| 41 | - UIImage.loadImageUsingCacheWithUrlString(url) { [weak self] image in | 55 | + // UIImage.loadImageUsingCacheWithUrlString(url) { [weak self] image in |
| 42 | - if url == self?.bannerImageURL { | 56 | + // if url == self?.bannerImageURL { |
| 43 | - self?.bannerImage.image = image | 57 | + // self?.bannerImage.image = image |
| 44 | - } | 58 | + // } |
| 45 | - } | 59 | + // } |
| 46 | - } else { | 60 | + // } else { |
| 47 | - self.bannerImage.image = nil | 61 | + // self.bannerImage.image = nil |
| 48 | - } | 62 | + // } |
| 49 | - } | 63 | + // } |
| 50 | - } | 64 | + // } |
| 51 | 65 | ||
| 52 | private var logoImageURL: String? { | 66 | private var logoImageURL: String? { |
| 53 | didSet { | 67 | didSet { |
| ... | @@ -67,22 +81,22 @@ public class ProfileCouponTableViewCell: UITableViewCell { | ... | @@ -67,22 +81,22 @@ public class ProfileCouponTableViewCell: UITableViewCell { |
| 67 | // MARK: - Configure with OfferModel (legacy, kept for backward compatibility) | 81 | // MARK: - Configure with OfferModel (legacy, kept for backward compatibility) |
| 68 | 82 | ||
| 69 | func configureCell(data: OfferModel) { | 83 | func configureCell(data: OfferModel) { |
| 70 | - bannerImage.image = UIImage(named: data.bannerImage, in: Bundle.frameworkResourceBundle, compatibleWith: nil) | 84 | + // bannerImage.image = UIImage(named: data.bannerImage, in: Bundle.frameworkResourceBundle, compatibleWith: nil) |
| 71 | - favoriteImage.image = UIImage(named: data.isFavorite ? "favorite_filled" : "favorite_empty", in: Bundle.frameworkResourceBundle, compatibleWith: nil) | 85 | + // favoriteImage.image = UIImage(named: data.isFavorite ? "favorite_filled" : "favorite_empty", in: Bundle.frameworkResourceBundle, compatibleWith: nil) |
| 72 | 86 | ||
| 73 | - let discountSymbol = | 87 | + // let discountSymbol = |
| 74 | - data.discountType == "percentage" ? "%" | 88 | + // data.discountType == "percentage" ? "%" |
| 75 | - : data.discountType == "price" ? "€" | 89 | + // : data.discountType == "price" ? "€" |
| 76 | - : data.discountType == "buyOneGetOne" ? "1+1" | 90 | + // : data.discountType == "buyOneGetOne" ? "1+1" |
| 77 | - : data.discountType == "free" ? "Δωρεάν" | 91 | + // : data.discountType == "free" ? "Δωρεάν" |
| 78 | - : "" | 92 | + // : "" |
| 79 | 93 | ||
| 80 | -// discountLabel.text = "\(data.discount)\(discountSymbol)" | 94 | +// // discountLabel.text = "\(data.discount)\(discountSymbol)" |
| 81 | - discountLabel.text = data.discount | 95 | +// discountLabel.text = data.discount |
| 82 | - discountLabel.font = UIFont(name: "PingLCG-Bold", size: 25) | 96 | +// discountLabel.font = UIFont(name: "PingLCG-Bold", size: 25) |
| 83 | - discountLabel.textColor = UIColor(rgb: 0xF2F2F2) | 97 | +// discountLabel.textColor = UIColor(rgb: 0xF2F2F2) |
| 84 | 98 | ||
| 85 | - discountView.backgroundColor = UIColor(rgb: data.color) | 99 | + // discountView.backgroundColor = UIColor(rgb: data.color) |
| 86 | 100 | ||
| 87 | titleLabel.text = data.title | 101 | titleLabel.text = data.title |
| 88 | titleLabel.font = UIFont(name: "PingLCG-Bold", size: 22) | 102 | titleLabel.font = UIFont(name: "PingLCG-Bold", size: 22) |
| ... | @@ -103,56 +117,84 @@ public class ProfileCouponTableViewCell: UITableViewCell { | ... | @@ -103,56 +117,84 @@ public class ProfileCouponTableViewCell: UITableViewCell { |
| 103 | 117 | ||
| 104 | func configureCell(data: CouponItemModel) { | 118 | func configureCell(data: CouponItemModel) { |
| 105 | // Banner image — load from couponset_data img_preview (remote URL) | 119 | // Banner image — load from couponset_data img_preview (remote URL) |
| 106 | - if let imgPreview = data.couponset_data?._img_preview, !imgPreview.isEmpty { | 120 | + // if let imgPreview = data.couponset_data?._img_preview, !imgPreview.isEmpty { |
| 107 | - self.bannerImageURL = imgPreview | 121 | + // self.bannerImageURL = imgPreview |
| 108 | - } else { | 122 | + // } else { |
| 109 | - bannerImage.image = nil | 123 | + // bannerImage.image = nil |
| 110 | - } | 124 | + // } |
| 111 | 125 | ||
| 112 | // Favorite — default to not favorite for now | 126 | // Favorite — default to not favorite for now |
| 113 | - favoriteImage.image = UIImage(named: "favorite_empty", in: Bundle.frameworkResourceBundle, compatibleWith: nil) | 127 | + // favoriteImage.image = UIImage(named: "favorite_empty", in: Bundle.frameworkResourceBundle, compatibleWith: nil) |
| 114 | - | 128 | + |
| 115 | - // Discount label — use coupon discount or couponset discount | 129 | + // // Discount label — use coupon discount or couponset discount |
| 116 | - let discountText = data.discount ?? data.couponset_data?._discount ?? "" | 130 | + // let discountText = data.discount ?? data.couponset_data?._discount ?? "" |
| 117 | - discountLabel.text = discountText | 131 | + // discountLabel.text = discountText |
| 118 | - discountLabel.font = UIFont(name: "PingLCG-Bold", size: 25) | 132 | + // discountLabel.font = UIFont(name: "PingLCG-Bold", size: 25) |
| 119 | - discountLabel.textColor = UIColor(rgb: 0xF2F2F2) | 133 | + // discountLabel.textColor = UIColor(rgb: 0xF2F2F2) |
| 120 | - | 134 | + |
| 121 | - // Discount view color based on discount type | 135 | + // // Discount view color based on discount type |
| 122 | - let discountType = data.couponset_data?._discount_type ?? "" | 136 | + // let discountType = data.couponset_data?._discount_type ?? "" |
| 123 | - let discountColor: UInt = { | 137 | + // let discountColor: UInt = { |
| 124 | - switch discountType { | 138 | + // switch discountType { |
| 125 | - case "percentage": | 139 | + // case "percentage": |
| 126 | - return 0xFF6B35 | 140 | + // return 0xFF6B35 |
| 127 | - case "value": | 141 | + // case "value": |
| 128 | - return 0x28A745 | 142 | + // return 0x28A745 |
| 129 | - case "plus_one": | 143 | + // case "plus_one": |
| 130 | - return 0x007AFF | 144 | + // return 0x007AFF |
| 131 | - default: | 145 | + // default: |
| 132 | - return 0xEE417D | 146 | + // return 0xEE417D |
| 133 | - } | 147 | + // } |
| 134 | - }() | 148 | + // }() |
| 135 | - discountView.backgroundColor = UIColor(rgb: discountColor) | 149 | + // discountView.backgroundColor = UIColor(rgb: discountColor) |
| 150 | + | ||
| 151 | + merchantNameLabel.font = UIFont(name: "PingLCG-Bold", size: 14) | ||
| 152 | + merchantNameLabel.textColor = UIColor(rgb: 0x5C6369) | ||
| 153 | + merchantNameLabel.text = data.merchant_details?._name | ||
| 136 | 154 | ||
| 137 | // Title — from couponset_data name | 155 | // Title — from couponset_data name |
| 138 | titleLabel.text = data.couponset_data?._name ?? "" | 156 | titleLabel.text = data.couponset_data?._name ?? "" |
| 139 | titleLabel.font = UIFont(name: "PingLCG-Bold", size: 22) | 157 | titleLabel.font = UIFont(name: "PingLCG-Bold", size: 22) |
| 140 | - titleLabel.textColor = UIColor(rgb: 0x000F1E) | 158 | + titleLabel.textColor = UIColor(rgb: 0x1D2023) |
| 141 | 159 | ||
| 142 | // Subtitle — from couponset_data short_description | 160 | // Subtitle — from couponset_data short_description |
| 143 | subtitleLabel.text = data.couponset_data?._short_description ?? "" | 161 | subtitleLabel.text = data.couponset_data?._short_description ?? "" |
| 144 | - subtitleLabel.font = UIFont(name: "PingLCG-Regular", size: 16) | 162 | + subtitleLabel.font = UIFont(name: "PingLCG-Regular", size: 13) |
| 145 | - subtitleLabel.textColor = UIColor(rgb: 0x00111B) | 163 | + subtitleLabel.textColor = UIColor(rgb: 0x5C6369) |
| 146 | 164 | ||
| 147 | - // Expiration — already formatted as "dd/MM/yyyy" by CouponItemModel | 165 | + expirationView.layer.cornerRadius = 6.0 |
| 148 | - if let expiration = data.expiration, !expiration.isEmpty { | 166 | + expirationView.layer.borderWidth = 1.0 |
| 149 | - expirationLabel.text = "έως " + expiration | 167 | + |
| 168 | + let isExpiringSoon: Bool | ||
| 169 | + if let expirationDate = data.expirationDate { | ||
| 170 | + let today = Calendar.current.startOfDay(for: Date()) | ||
| 171 | + let expDay = Calendar.current.startOfDay(for: expirationDate) | ||
| 172 | + let daysLeft = Calendar.current.dateComponents([.day], from: today, to: expDay).day ?? Int.max | ||
| 173 | + if daysLeft <= 3 { | ||
| 174 | + isExpiringSoon = true | ||
| 175 | + expirationLabel.text = "\(daysLeft) days left" | ||
| 176 | + } else { | ||
| 177 | + isExpiringSoon = false | ||
| 178 | + expirationLabel.text = "Valid until " + data.formattedExpiration(format: "MMMM d, yyyy") | ||
| 179 | + } | ||
| 150 | } else { | 180 | } else { |
| 181 | + isExpiringSoon = false | ||
| 151 | expirationLabel.text = "" | 182 | expirationLabel.text = "" |
| 152 | } | 183 | } |
| 153 | - expirationLabel.font = UIFont(name: "PingLCG-Regular", size: 13) | 184 | + |
| 154 | - expirationLabel.textColor = UIColor(rgb: 0x00111B) | 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) | ||
| 190 | + expirationView.layer.borderColor = UIColor(rgb: 0xD2D6D9).cgColor | ||
| 191 | + } | ||
| 192 | + expirationLabel.font = UIFont(name: "PingLCG-Bold", size: 13) | ||
| 193 | + expirationLabel.textColor = UIColor(rgb: 0x002430) | ||
| 155 | 194 | ||
| 195 | + logoImageView.backgroundColor = UIColor(rgb: 0xFFFFFF) | ||
| 196 | + logoImageView.layer.cornerRadius = 10.0 | ||
| 197 | + | ||
| 156 | // Logo — load from merchant_details img_preview (remote URL) | 198 | // Logo — load from merchant_details img_preview (remote URL) |
| 157 | if let merchantImgPreview = data.merchant_details?._img_preview, !merchantImgPreview.isEmpty { | 199 | if let merchantImgPreview = data.merchant_details?._img_preview, !merchantImgPreview.isEmpty { |
| 158 | self.logoImageURL = merchantImgPreview | 200 | self.logoImageURL = merchantImgPreview | ... | ... |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> | 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"/> | 3 | <device id="retina6_12" orientation="portrait" appearance="light"/> |
| 4 | <dependencies> | 4 | <dependencies> |
| 5 | - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> | 5 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24504"/> |
| 6 | <capability name="Safe area layout guides" minToolsVersion="9.0"/> | 6 | <capability name="Safe area layout guides" minToolsVersion="9.0"/> |
| 7 | <capability name="System colors in document resources" minToolsVersion="11.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"/> | 8 | <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> |
| ... | @@ -18,153 +18,157 @@ | ... | @@ -18,153 +18,157 @@ |
| 18 | <autoresizingMask key="autoresizingMask"/> | 18 | <autoresizingMask key="autoresizingMask"/> |
| 19 | <subviews> | 19 | <subviews> |
| 20 | <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="x0X-za-HZ9" userLabel="Parent View"> | 20 | <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="x0X-za-HZ9" userLabel="Parent View"> |
| 21 | - <rect key="frame" x="22" y="0.0" width="276" height="292"/> | 21 | + <rect key="frame" x="18" y="0.0" width="284" height="175"/> |
| 22 | <subviews> | 22 | <subviews> |
| 23 | - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8Ht-7Z-jiW" userLabel="Top View"> | 23 | + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fZ6-8K-DXr" userLabel="Bottom View"> |
| 24 | - <rect key="frame" x="0.0" y="0.0" width="276" height="171"/> | 24 | + <rect key="frame" x="0.0" y="0.0" width="284" height="175"/> |
| 25 | <subviews> | 25 | <subviews> |
| 26 | - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="09g-Nj-HG4"> | 26 | + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Fcn-J9-gqq" userLabel="LogoImageView"> |
| 27 | - <rect key="frame" x="0.0" y="0.0" width="276" height="171"/> | 27 | + <rect key="frame" x="10" y="10" width="67" height="67"/> |
| 28 | - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 29 | - </imageView> | ||
| 30 | - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4xy-g8-Ukx" userLabel="Fav View"> | ||
| 31 | - <rect key="frame" x="16" y="13" width="46" height="46"/> | ||
| 32 | <subviews> | 28 | <subviews> |
| 33 | - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="T91-Ra-dmT"> | 29 | + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="hM2-8T-4vX"> |
| 34 | - <rect key="frame" x="0.0" y="0.0" width="46" height="46"/> | 30 | + <rect key="frame" x="10" y="10" width="47" height="47"/> |
| 31 | + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 35 | </imageView> | 32 | </imageView> |
| 36 | </subviews> | 33 | </subviews> |
| 37 | - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | 34 | + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| 38 | <constraints> | 35 | <constraints> |
| 39 | - <constraint firstAttribute="width" constant="46" id="Cc2-q8-pqb"/> | 36 | + <constraint firstAttribute="width" constant="67" id="9pk-g2-gcB"/> |
| 40 | - <constraint firstAttribute="trailing" secondItem="T91-Ra-dmT" secondAttribute="trailing" id="FHe-DH-ghP"/> | 37 | + <constraint firstAttribute="bottom" secondItem="hM2-8T-4vX" secondAttribute="bottom" constant="10" id="AQa-wS-Zt5"/> |
| 41 | - <constraint firstItem="T91-Ra-dmT" firstAttribute="top" secondItem="4xy-g8-Ukx" secondAttribute="top" id="HMT-10-TaU"/> | 38 | + <constraint firstAttribute="height" constant="67" id="FfF-lB-tUl"/> |
| 42 | - <constraint firstAttribute="bottom" secondItem="T91-Ra-dmT" secondAttribute="bottom" id="K7M-Vf-uo8"/> | 39 | + <constraint firstItem="hM2-8T-4vX" firstAttribute="top" secondItem="Fcn-J9-gqq" secondAttribute="top" constant="10" id="gus-oR-l57"/> |
| 43 | - <constraint firstItem="T91-Ra-dmT" firstAttribute="leading" secondItem="4xy-g8-Ukx" secondAttribute="leading" id="diD-2x-xIG"/> | 40 | + <constraint firstItem="hM2-8T-4vX" firstAttribute="leading" secondItem="Fcn-J9-gqq" secondAttribute="leading" constant="10" id="pn8-ti-KXs"/> |
| 44 | - <constraint firstAttribute="height" constant="46" id="gtM-XV-LnS"/> | 41 | + <constraint firstAttribute="trailing" secondItem="hM2-8T-4vX" secondAttribute="trailing" constant="10" id="qbD-TE-zfq"/> |
| 45 | </constraints> | 42 | </constraints> |
| 46 | </view> | 43 | </view> |
| 47 | - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dnZ-fa-M3o" userLabel="Discount View"> | 44 | + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9ju-6P-k6F" userLabel="Expiration View"> |
| 48 | - <rect key="frame" x="179" y="14" width="84" height="84"/> | 45 | + <rect key="frame" x="197.66666666666666" y="10" width="76.333333333333343" height="34.333333333333336"/> |
| 49 | <subviews> | 46 | <subviews> |
| 50 | - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XeI-PB-wG7"> | 47 | + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="wkd-wh-r1w" userLabel="Expiration Image"> |
| 51 | - <rect key="frame" x="5" y="31.666666666666664" width="74" height="21"/> | 48 | + <rect key="frame" x="10" y="10.333333333333332" width="14" height="14"/> |
| 49 | + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 50 | + <constraints> | ||
| 51 | + <constraint firstAttribute="height" constant="14" id="6zU-V6-H7S"/> | ||
| 52 | + <constraint firstAttribute="width" constant="14" id="vf0-mS-97Q"/> | ||
| 53 | + </constraints> | ||
| 54 | + </imageView> | ||
| 55 | + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZgP-Qt-8og" userLabel="Expiration Label"> | ||
| 56 | + <rect key="frame" x="28.000000000000004" y="6.9999999999999982" width="41.333333333333343" height="20.333333333333329"/> | ||
| 52 | <fontDescription key="fontDescription" type="system" pointSize="17"/> | 57 | <fontDescription key="fontDescription" type="system" pointSize="17"/> |
| 53 | <nil key="textColor"/> | 58 | <nil key="textColor"/> |
| 54 | <nil key="highlightedColor"/> | 59 | <nil key="highlightedColor"/> |
| 55 | </label> | 60 | </label> |
| 56 | </subviews> | 61 | </subviews> |
| 57 | - <color key="backgroundColor" systemColor="systemBackgroundColor"/> | 62 | + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| 58 | <constraints> | 63 | <constraints> |
| 59 | - <constraint firstAttribute="height" constant="84" id="8gp-O1-LgD"/> | 64 | + <constraint firstAttribute="trailing" secondItem="ZgP-Qt-8og" secondAttribute="trailing" constant="7" id="AwZ-gG-3PO"/> |
| 60 | - <constraint firstAttribute="width" constant="84" id="Mve-Yl-rsU"/> | 65 | + <constraint firstItem="wkd-wh-r1w" firstAttribute="centerY" secondItem="9ju-6P-k6F" secondAttribute="centerY" id="CnU-ts-AtX"/> |
| 61 | - <constraint firstItem="XeI-PB-wG7" firstAttribute="centerY" secondItem="dnZ-fa-M3o" secondAttribute="centerY" id="Rlp-4Z-urE"/> | 66 | + <constraint firstItem="ZgP-Qt-8og" firstAttribute="leading" secondItem="wkd-wh-r1w" secondAttribute="trailing" constant="4" id="PXB-bc-eTM"/> |
| 62 | - <constraint firstAttribute="trailing" secondItem="XeI-PB-wG7" secondAttribute="trailing" constant="5" id="dyI-UO-uvn"/> | 67 | + <constraint firstAttribute="bottom" secondItem="ZgP-Qt-8og" secondAttribute="bottom" constant="7" id="Wab-ed-1oR"/> |
| 63 | - <constraint firstItem="XeI-PB-wG7" firstAttribute="leading" secondItem="dnZ-fa-M3o" secondAttribute="leading" constant="5" id="eon-8Y-X7c"/> | 68 | + <constraint firstItem="wkd-wh-r1w" firstAttribute="leading" secondItem="9ju-6P-k6F" secondAttribute="leading" constant="10" id="e2L-4Z-2xN"/> |
| 69 | + <constraint firstItem="ZgP-Qt-8og" firstAttribute="top" secondItem="9ju-6P-k6F" secondAttribute="top" constant="7" id="gYV-rG-X6r"/> | ||
| 64 | </constraints> | 70 | </constraints> |
| 65 | </view> | 71 | </view> |
| 66 | - </subviews> | 72 | + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YtM-Db-ygP" userLabel="InfoView"> |
| 67 | - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | 73 | + <rect key="frame" x="17" y="93" width="260" height="65"/> |
| 68 | - <constraints> | ||
| 69 | - <constraint firstItem="09g-Nj-HG4" firstAttribute="leading" secondItem="8Ht-7Z-jiW" secondAttribute="leading" id="1AO-0a-ZpN"/> | ||
| 70 | - <constraint firstItem="dnZ-fa-M3o" firstAttribute="top" secondItem="8Ht-7Z-jiW" secondAttribute="top" constant="14" id="AC6-zX-rmc"/> | ||
| 71 | - <constraint firstItem="09g-Nj-HG4" firstAttribute="top" secondItem="8Ht-7Z-jiW" secondAttribute="top" id="DYc-4B-bTE"/> | ||
| 72 | - <constraint firstAttribute="bottom" secondItem="09g-Nj-HG4" secondAttribute="bottom" id="Rsg-ZQ-0bM"/> | ||
| 73 | - <constraint firstItem="4xy-g8-Ukx" firstAttribute="leading" secondItem="8Ht-7Z-jiW" secondAttribute="leading" constant="16" id="U8A-vw-Pca"/> | ||
| 74 | - <constraint firstItem="4xy-g8-Ukx" firstAttribute="top" secondItem="8Ht-7Z-jiW" secondAttribute="top" constant="13" id="ZGF-7X-iSN"/> | ||
| 75 | - <constraint firstAttribute="trailing" secondItem="09g-Nj-HG4" secondAttribute="trailing" id="qwK-yM-rD6"/> | ||
| 76 | - <constraint firstAttribute="trailing" secondItem="dnZ-fa-M3o" secondAttribute="trailing" constant="13" id="zAy-FM-iqd"/> | ||
| 77 | - </constraints> | ||
| 78 | - </view> | ||
| 79 | - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fZ6-8K-DXr" userLabel="Bottom View"> | ||
| 80 | - <rect key="frame" x="0.0" y="171" width="276" height="121"/> | ||
| 81 | - <subviews> | ||
| 82 | - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YtM-Db-ygP"> | ||
| 83 | - <rect key="frame" x="16" y="17" width="130" height="93"/> | ||
| 84 | <subviews> | 74 | <subviews> |
| 85 | - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="63p-dI-yTa"> | 75 | + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mO2-Xp-IVu" userLabel="Merchant Name Label"> |
| 86 | - <rect key="frame" x="0.0" y="0.0" width="130" height="21"/> | 76 | + <rect key="frame" x="0.0" y="0.0" width="260" height="20.333333333333332"/> |
| 87 | <fontDescription key="fontDescription" type="system" pointSize="17"/> | 77 | <fontDescription key="fontDescription" type="system" pointSize="17"/> |
| 88 | <nil key="textColor"/> | 78 | <nil key="textColor"/> |
| 89 | <nil key="highlightedColor"/> | 79 | <nil key="highlightedColor"/> |
| 90 | </label> | 80 | </label> |
| 91 | - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="z30-VZ-8h3"> | 81 | + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="63p-dI-yTa"> |
| 92 | - <rect key="frame" x="0.0" y="23" width="130" height="20.333333333333329"/> | 82 | + <rect key="frame" x="0.0" y="22.333333333333343" width="211" height="21"/> |
| 93 | <fontDescription key="fontDescription" type="system" pointSize="17"/> | 83 | <fontDescription key="fontDescription" type="system" pointSize="17"/> |
| 94 | <nil key="textColor"/> | 84 | <nil key="textColor"/> |
| 95 | <nil key="highlightedColor"/> | 85 | <nil key="highlightedColor"/> |
| 96 | </label> | 86 | </label> |
| 97 | - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PZ3-qH-3XH"> | 87 | + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="z30-VZ-8h3"> |
| 98 | - <rect key="frame" x="0.0" y="72" width="130" height="21"/> | 88 | + <rect key="frame" x="0.0" y="45.333333333333329" width="211" height="20.333333333333329"/> |
| 99 | <fontDescription key="fontDescription" type="system" pointSize="17"/> | 89 | <fontDescription key="fontDescription" type="system" pointSize="17"/> |
| 100 | <nil key="textColor"/> | 90 | <nil key="textColor"/> |
| 101 | <nil key="highlightedColor"/> | 91 | <nil key="highlightedColor"/> |
| 102 | </label> | 92 | </label> |
| 93 | + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cko-1v-wDx" userLabel="ArrowView"> | ||
| 94 | + <rect key="frame" x="221" y="26" width="39" height="39"/> | ||
| 95 | + <subviews> | ||
| 96 | + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZRF-CC-IKd"> | ||
| 97 | + <rect key="frame" x="11" y="13" width="17" height="13"/> | ||
| 98 | + <constraints> | ||
| 99 | + <constraint firstAttribute="height" constant="13" id="ZR7-aH-0zM"/> | ||
| 100 | + <constraint firstAttribute="width" constant="17" id="lGj-BM-N9w"/> | ||
| 101 | + </constraints> | ||
| 102 | + </imageView> | ||
| 103 | + </subviews> | ||
| 104 | + <color key="backgroundColor" systemColor="systemBackgroundColor"/> | ||
| 105 | + <constraints> | ||
| 106 | + <constraint firstAttribute="height" constant="39" id="Zh7-U5-7dh"/> | ||
| 107 | + <constraint firstAttribute="width" constant="39" id="eIh-Ke-CJw"/> | ||
| 108 | + <constraint firstItem="ZRF-CC-IKd" firstAttribute="centerY" secondItem="cko-1v-wDx" secondAttribute="centerY" id="jyW-Ir-XED"/> | ||
| 109 | + <constraint firstItem="ZRF-CC-IKd" firstAttribute="centerX" secondItem="cko-1v-wDx" secondAttribute="centerX" id="sdA-PR-KMw"/> | ||
| 110 | + </constraints> | ||
| 111 | + </view> | ||
| 103 | </subviews> | 112 | </subviews> |
| 104 | <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | 113 | <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| 105 | <constraints> | 114 | <constraints> |
| 115 | + <constraint firstItem="63p-dI-yTa" firstAttribute="top" secondItem="mO2-Xp-IVu" secondAttribute="bottom" constant="2" id="1rR-YP-pAJ"/> | ||
| 116 | + <constraint firstItem="mO2-Xp-IVu" firstAttribute="top" secondItem="YtM-Db-ygP" secondAttribute="top" id="28l-ae-BOD"/> | ||
| 117 | + <constraint firstAttribute="bottom" secondItem="z30-VZ-8h3" secondAttribute="bottom" id="6k0-Nw-BSn"/> | ||
| 106 | <constraint firstItem="z30-VZ-8h3" firstAttribute="leading" secondItem="YtM-Db-ygP" secondAttribute="leading" id="DHf-fQ-lXA"/> | 118 | <constraint firstItem="z30-VZ-8h3" firstAttribute="leading" secondItem="YtM-Db-ygP" secondAttribute="leading" id="DHf-fQ-lXA"/> |
| 107 | - <constraint firstAttribute="trailing" secondItem="z30-VZ-8h3" secondAttribute="trailing" id="DnI-99-e8v"/> | 119 | + <constraint firstAttribute="trailing" secondItem="mO2-Xp-IVu" secondAttribute="trailing" id="QeV-2c-rkN"/> |
| 108 | - <constraint firstAttribute="trailing" secondItem="PZ3-qH-3XH" secondAttribute="trailing" id="JA5-Am-dmE"/> | 120 | + <constraint firstItem="cko-1v-wDx" firstAttribute="leading" secondItem="z30-VZ-8h3" secondAttribute="trailing" constant="10" id="ZCX-vU-yAg"/> |
| 109 | - <constraint firstItem="63p-dI-yTa" firstAttribute="top" secondItem="YtM-Db-ygP" secondAttribute="top" id="Kfa-m3-rWW"/> | 121 | + <constraint firstAttribute="trailing" secondItem="cko-1v-wDx" secondAttribute="trailing" id="bMz-0j-PnH"/> |
| 110 | - <constraint firstAttribute="trailing" secondItem="63p-dI-yTa" secondAttribute="trailing" id="bxa-5c-OE6"/> | ||
| 111 | <constraint firstItem="63p-dI-yTa" firstAttribute="leading" secondItem="YtM-Db-ygP" secondAttribute="leading" id="gk1-Zr-MIl"/> | 122 | <constraint firstItem="63p-dI-yTa" firstAttribute="leading" secondItem="YtM-Db-ygP" secondAttribute="leading" id="gk1-Zr-MIl"/> |
| 112 | - <constraint firstItem="PZ3-qH-3XH" firstAttribute="leading" secondItem="YtM-Db-ygP" secondAttribute="leading" id="hE4-2m-iZk"/> | ||
| 113 | <constraint firstItem="z30-VZ-8h3" firstAttribute="top" secondItem="63p-dI-yTa" secondAttribute="bottom" constant="2" id="hfr-Gi-omT"/> | 123 | <constraint firstItem="z30-VZ-8h3" firstAttribute="top" secondItem="63p-dI-yTa" secondAttribute="bottom" constant="2" id="hfr-Gi-omT"/> |
| 114 | - <constraint firstAttribute="bottom" secondItem="PZ3-qH-3XH" secondAttribute="bottom" id="xMs-dh-ybb"/> | 124 | + <constraint firstItem="mO2-Xp-IVu" firstAttribute="leading" secondItem="YtM-Db-ygP" secondAttribute="leading" id="hkf-Ek-pmr"/> |
| 125 | + <constraint firstItem="cko-1v-wDx" firstAttribute="leading" secondItem="63p-dI-yTa" secondAttribute="trailing" constant="10" id="m2R-vr-DCQ"/> | ||
| 126 | + <constraint firstAttribute="bottom" secondItem="cko-1v-wDx" secondAttribute="bottom" id="pND-ei-iWF"/> | ||
| 115 | </constraints> | 127 | </constraints> |
| 116 | </view> | 128 | </view> |
| 117 | - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="hM2-8T-4vX"> | ||
| 118 | - <rect key="frame" x="164" y="17" width="84" height="84"/> | ||
| 119 | - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
| 120 | - <constraints> | ||
| 121 | - <constraint firstAttribute="width" constant="84" id="6to-Dv-ukR"/> | ||
| 122 | - <constraint firstAttribute="height" constant="84" id="QjU-rO-Uqx"/> | ||
| 123 | - </constraints> | ||
| 124 | - </imageView> | ||
| 125 | </subviews> | 129 | </subviews> |
| 126 | - <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | 130 | + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| 127 | <constraints> | 131 | <constraints> |
| 128 | - <constraint firstAttribute="bottom" secondItem="YtM-Db-ygP" secondAttribute="bottom" constant="11" id="6ul-bC-Jpj"/> | 132 | + <constraint firstAttribute="bottom" secondItem="YtM-Db-ygP" secondAttribute="bottom" constant="17" id="6ul-bC-Jpj"/> |
| 129 | - <constraint firstItem="YtM-Db-ygP" firstAttribute="leading" secondItem="fZ6-8K-DXr" secondAttribute="leading" constant="16" id="C7J-bI-8ap"/> | 133 | + <constraint firstItem="YtM-Db-ygP" firstAttribute="top" secondItem="Fcn-J9-gqq" secondAttribute="bottom" constant="16" id="8dr-sO-7qI"/> |
| 130 | - <constraint firstItem="hM2-8T-4vX" firstAttribute="top" secondItem="fZ6-8K-DXr" secondAttribute="top" constant="17" id="HBF-J2-ed0"/> | 134 | + <constraint firstItem="YtM-Db-ygP" firstAttribute="leading" secondItem="fZ6-8K-DXr" secondAttribute="leading" constant="17" id="C7J-bI-8ap"/> |
| 131 | - <constraint firstItem="hM2-8T-4vX" firstAttribute="leading" secondItem="YtM-Db-ygP" secondAttribute="trailing" constant="18" id="WML-nR-cLh"/> | 135 | + <constraint firstItem="Fcn-J9-gqq" firstAttribute="top" secondItem="fZ6-8K-DXr" secondAttribute="top" constant="10" id="KVH-GO-BRe"/> |
| 132 | - <constraint firstItem="YtM-Db-ygP" firstAttribute="top" secondItem="fZ6-8K-DXr" secondAttribute="top" constant="17" id="f0H-m3-OAP"/> | 136 | + <constraint firstItem="Fcn-J9-gqq" firstAttribute="leading" secondItem="fZ6-8K-DXr" secondAttribute="leading" constant="10" id="Oph-8j-Guf"/> |
| 133 | - <constraint firstAttribute="trailing" secondItem="hM2-8T-4vX" secondAttribute="trailing" constant="28" id="jKa-nW-g41"/> | 137 | + <constraint firstAttribute="trailing" secondItem="9ju-6P-k6F" secondAttribute="trailing" constant="10" id="aON-Fo-H1J"/> |
| 134 | - <constraint firstAttribute="height" constant="121" id="ptz-uq-5rq"/> | 138 | + <constraint firstAttribute="trailing" secondItem="YtM-Db-ygP" secondAttribute="trailing" constant="7" id="ghj-41-twp"/> |
| 139 | + <constraint firstItem="9ju-6P-k6F" firstAttribute="top" secondItem="fZ6-8K-DXr" secondAttribute="top" constant="10" id="uXH-9L-517"/> | ||
| 135 | </constraints> | 140 | </constraints> |
| 136 | </view> | 141 | </view> |
| 137 | </subviews> | 142 | </subviews> |
| 138 | <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | 143 | <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| 139 | <constraints> | 144 | <constraints> |
| 140 | <constraint firstItem="fZ6-8K-DXr" firstAttribute="leading" secondItem="x0X-za-HZ9" secondAttribute="leading" id="DKa-9V-lma"/> | 145 | <constraint firstItem="fZ6-8K-DXr" firstAttribute="leading" secondItem="x0X-za-HZ9" secondAttribute="leading" id="DKa-9V-lma"/> |
| 141 | - <constraint firstAttribute="trailing" secondItem="8Ht-7Z-jiW" secondAttribute="trailing" id="LK1-Cz-JUh"/> | 146 | + <constraint firstItem="fZ6-8K-DXr" firstAttribute="top" secondItem="x0X-za-HZ9" secondAttribute="top" id="cdY-T8-x47"/> |
| 142 | - <constraint firstItem="8Ht-7Z-jiW" firstAttribute="top" secondItem="x0X-za-HZ9" secondAttribute="top" id="P9v-fu-Mhs"/> | 147 | + <constraint firstAttribute="height" constant="175" id="lA6-op-vsG"/> |
| 143 | - <constraint firstAttribute="height" constant="292" id="lA6-op-vsG"/> | ||
| 144 | <constraint firstAttribute="trailing" secondItem="fZ6-8K-DXr" secondAttribute="trailing" id="lAU-n1-MKy"/> | 148 | <constraint firstAttribute="trailing" secondItem="fZ6-8K-DXr" secondAttribute="trailing" id="lAU-n1-MKy"/> |
| 145 | - <constraint firstItem="8Ht-7Z-jiW" firstAttribute="leading" secondItem="x0X-za-HZ9" secondAttribute="leading" id="sK9-Tw-Yqn"/> | ||
| 146 | <constraint firstAttribute="bottom" secondItem="fZ6-8K-DXr" secondAttribute="bottom" id="u4z-JD-qby"/> | 149 | <constraint firstAttribute="bottom" secondItem="fZ6-8K-DXr" secondAttribute="bottom" id="u4z-JD-qby"/> |
| 147 | - <constraint firstItem="fZ6-8K-DXr" firstAttribute="top" secondItem="8Ht-7Z-jiW" secondAttribute="bottom" id="v5X-nL-hKm"/> | ||
| 148 | </constraints> | 150 | </constraints> |
| 149 | </view> | 151 | </view> |
| 150 | </subviews> | 152 | </subviews> |
| 151 | <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | 153 | <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| 152 | <constraints> | 154 | <constraints> |
| 153 | - <constraint firstItem="x0X-za-HZ9" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="22" id="SzO-Fk-ZCB"/> | 155 | + <constraint firstItem="x0X-za-HZ9" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="18" id="SzO-Fk-ZCB"/> |
| 154 | <constraint firstItem="x0X-za-HZ9" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="uQN-BA-o6w"/> | 156 | <constraint firstItem="x0X-za-HZ9" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="uQN-BA-o6w"/> |
| 155 | - <constraint firstAttribute="trailing" secondItem="x0X-za-HZ9" secondAttribute="trailing" constant="22" id="vi4-dI-lx3"/> | 157 | + <constraint firstAttribute="trailing" secondItem="x0X-za-HZ9" secondAttribute="trailing" constant="18" id="vi4-dI-lx3"/> |
| 156 | - <constraint firstAttribute="bottom" secondItem="x0X-za-HZ9" secondAttribute="bottom" constant="19" id="zsL-aX-JRL"/> | 158 | + <constraint firstAttribute="bottom" secondItem="x0X-za-HZ9" secondAttribute="bottom" constant="16" id="zsL-aX-JRL"/> |
| 157 | </constraints> | 159 | </constraints> |
| 158 | </tableViewCellContentView> | 160 | </tableViewCellContentView> |
| 159 | <viewLayoutGuide key="safeArea" id="njF-e1-oar"/> | 161 | <viewLayoutGuide key="safeArea" id="njF-e1-oar"/> |
| 160 | <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | 162 | <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| 161 | <connections> | 163 | <connections> |
| 162 | - <outlet property="bannerImage" destination="09g-Nj-HG4" id="1Ux-ZI-rVQ"/> | 164 | + <outlet property="arrowImage" destination="ZRF-CC-IKd" id="9Wh-O0-Lzr"/> |
| 163 | - <outlet property="discountLabel" destination="XeI-PB-wG7" id="Kyy-aE-GgR"/> | 165 | + <outlet property="arrowView" destination="cko-1v-wDx" id="mMW-Dp-q6K"/> |
| 164 | - <outlet property="discountView" destination="dnZ-fa-M3o" id="fht-MW-ToM"/> | 166 | + <outlet property="expirationImage" destination="wkd-wh-r1w" id="5ng-6x-HtH"/> |
| 165 | - <outlet property="expirationLabel" destination="PZ3-qH-3XH" id="vIb-60-EVp"/> | 167 | + <outlet property="expirationLabel" destination="ZgP-Qt-8og" id="bNv-Rl-m7b"/> |
| 166 | - <outlet property="favoriteImage" destination="T91-Ra-dmT" id="leZ-Tz-zo8"/> | 168 | + <outlet property="expirationView" destination="9ju-6P-k6F" id="YiF-Z5-Q6s"/> |
| 167 | <outlet property="logoImage" destination="hM2-8T-4vX" id="Zqv-yp-lrD"/> | 169 | <outlet property="logoImage" destination="hM2-8T-4vX" id="Zqv-yp-lrD"/> |
| 170 | + <outlet property="logoImageView" destination="Fcn-J9-gqq" id="mAE-fP-e6I"/> | ||
| 171 | + <outlet property="merchantNameLabel" destination="mO2-Xp-IVu" id="Don-n2-JqF"/> | ||
| 168 | <outlet property="parentView" destination="x0X-za-HZ9" id="OE0-tT-IPd"/> | 172 | <outlet property="parentView" destination="x0X-za-HZ9" id="OE0-tT-IPd"/> |
| 169 | <outlet property="subtitleLabel" destination="z30-VZ-8h3" id="s40-MP-4Jn"/> | 173 | <outlet property="subtitleLabel" destination="z30-VZ-8h3" id="s40-MP-4Jn"/> |
| 170 | <outlet property="titleLabel" destination="63p-dI-yTa" id="YOe-I2-Cly"/> | 174 | <outlet property="titleLabel" destination="63p-dI-yTa" id="YOe-I2-Cly"/> | ... | ... |
| ... | @@ -96,7 +96,7 @@ public class CouponSetItemModel { | ... | @@ -96,7 +96,7 @@ public class CouponSetItemModel { |
| 96 | /// Try multiple date formats and return the first successful parse | 96 | /// Try multiple date formats and return the first successful parse |
| 97 | /// - Parameter dateString: The date string to parse | 97 | /// - Parameter dateString: The date string to parse |
| 98 | /// - Returns: Parsed Date or nil if no format matched | 98 | /// - Returns: Parsed Date or nil if no format matched |
| 99 | - private static func parseDate(_ dateString: String) -> Date? { | 99 | + static func parseDate(_ dateString: String) -> Date? { |
| 100 | let formatter = DateFormatter() | 100 | let formatter = DateFormatter() |
| 101 | for format in supportedDateFormats { | 101 | for format in supportedDateFormats { |
| 102 | formatter.dateFormat = format | 102 | formatter.dateFormat = format |
| ... | @@ -411,7 +411,8 @@ public class CouponItemModel { | ... | @@ -411,7 +411,8 @@ public class CouponItemModel { |
| 411 | public let couponset_uuid: String? | 411 | public let couponset_uuid: String? |
| 412 | public let name: String? | 412 | public let name: String? |
| 413 | public let image: String? | 413 | public let image: String? |
| 414 | - public let expiration: String? | 414 | + public let expiration: String? // raw string from API e.g. "2026-06-30 11:59:00" |
| 415 | + public let expiration_formatted: String? // pre-formatted "dd/MM/yyyy" for display | ||
| 415 | public let created: String? | 416 | public let created: String? |
| 416 | public let description: String? | 417 | public let description: String? |
| 417 | public let discount: String? | 418 | public let discount: String? |
| ... | @@ -495,15 +496,16 @@ public class CouponItemModel { | ... | @@ -495,15 +496,16 @@ public class CouponItemModel { |
| 495 | } | 496 | } |
| 496 | // <== | 497 | // <== |
| 497 | 498 | ||
| 498 | - let expirationString = dictionary["expiration"] as? String? ?? "" | 499 | + let expirationString = dictionary["expiration"] as? String ?? "" |
| 500 | + self.expiration = expirationString | ||
| 501 | + | ||
| 499 | let dateFormatter = DateFormatter() | 502 | let dateFormatter = DateFormatter() |
| 500 | dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" | 503 | dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" |
| 501 | - if let date = dateFormatter.date(from: expirationString ?? "") { | 504 | + if let date = dateFormatter.date(from: expirationString) { |
| 502 | dateFormatter.dateFormat = "dd/MM/yyyy" | 505 | dateFormatter.dateFormat = "dd/MM/yyyy" |
| 503 | - let resultString = dateFormatter.string(from: date) | 506 | + self.expiration_formatted = dateFormatter.string(from: date) |
| 504 | - self.expiration = resultString | ||
| 505 | } else { | 507 | } else { |
| 506 | - self.expiration = "" | 508 | + self.expiration_formatted = "" |
| 507 | } | 509 | } |
| 508 | 510 | ||
| 509 | // Extract created date: try changes_dates.created first (universal coupons), then top-level created | 511 | // Extract created date: try changes_dates.created first (universal coupons), then top-level created |
| ... | @@ -558,6 +560,26 @@ public class CouponItemModel { | ... | @@ -558,6 +560,26 @@ public class CouponItemModel { |
| 558 | public func setCouponSetData(_ couponSet: CouponSetItemModel) { | 560 | public func setCouponSetData(_ couponSet: CouponSetItemModel) { |
| 559 | self.couponset_data = couponSet | 561 | self.couponset_data = couponSet |
| 560 | } | 562 | } |
| 563 | + | ||
| 564 | + /// Returns the expiration as a Date object for date comparisons (e.g. days-left calculation) | ||
| 565 | + public var expirationDate: Date? { | ||
| 566 | + guard let raw = self.expiration, !raw.isEmpty else { return nil } | ||
| 567 | + return CouponSetItemModel.parseDate(raw) | ||
| 568 | + } | ||
| 569 | + | ||
| 570 | + /// Format expiration date with a custom output format. | ||
| 571 | + /// Uses the same multi-format parser as CouponSetItemModel. | ||
| 572 | + /// - Parameter format: DateFormatter format string (e.g. "MMMM d, yyyy", "dd/MM/yyyy") | ||
| 573 | + /// - Returns: Formatted date string, or empty string if expiration is absent or unparseable | ||
| 574 | + public func formattedExpiration(format: String) -> String { | ||
| 575 | + guard let raw = self.expiration, !raw.isEmpty else { return "" } | ||
| 576 | + if let date = CouponSetItemModel.parseDate(raw) { | ||
| 577 | + let formatter = DateFormatter() | ||
| 578 | + formatter.dateFormat = format | ||
| 579 | + return formatter.string(from: date) | ||
| 580 | + } | ||
| 581 | + return "" | ||
| 582 | + } | ||
| 561 | } | 583 | } |
| 562 | 584 | ||
| 563 | public class RedeemedSMHistoryModel { | 585 | public class RedeemedSMHistoryModel { | ... | ... |
| ... | @@ -383,7 +383,7 @@ extension MyCouponsViewController: UITableViewDelegate, UITableViewDataSource { | ... | @@ -383,7 +383,7 @@ extension MyCouponsViewController: UITableViewDelegate, UITableViewDataSource { |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | 385 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { |
| 386 | - if (indexPath.section <= 3) { | 386 | + if (indexPath.section <= 1) { |
| 387 | // Do nothing | 387 | // Do nothing |
| 388 | } else { | 388 | } else { |
| 389 | if let items = self.filteredOffersSection?.items, | 389 | if let items = self.filteredOffersSection?.items, | ... | ... |
-
Please register or login to post a comment