- Worked on cart icon initialization

- Fixed cart payment
- Handled cc avenue payment web view
- Added analytics and crashlytics.
- Completed add address
- Completed payment , added callback handler
This commit is contained in:
2024-07-30 20:06:57 +05:30
parent 8aefc0fe8c
commit 0e3b43adba
30 changed files with 543 additions and 122 deletions

View File

@@ -93,6 +93,7 @@
527A2BD02C57A2AE0080DF9B /* PaymentWebViewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527A2BCF2C57A2AE0080DF9B /* PaymentWebViewVC.swift */; };
527A2BD22C57B40A0080DF9B /* CartDataCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527A2BD12C57B40A0080DF9B /* CartDataCache.swift */; };
527A2BD52C57D0C20080DF9B /* Address.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 527A2BD42C57D0C20080DF9B /* Address.storyboard */; };
527A2BDB2C58F7EB0080DF9B /* MyOrdersVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527A2BDA2C58F7EB0080DF9B /* MyOrdersVM.swift */; };
527AC6F72C171C8F00434FB7 /* BlogsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527AC6F52C171C8F00434FB7 /* BlogsCell.swift */; };
527AC6F82C171C8F00434FB7 /* BlogsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 527AC6F62C171C8F00434FB7 /* BlogsCell.xib */; };
527AC6FA2C17387300434FB7 /* SongBlogDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527AC6F92C17387300434FB7 /* SongBlogDM.swift */; };
@@ -432,6 +433,7 @@
527A2BCF2C57A2AE0080DF9B /* PaymentWebViewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentWebViewVC.swift; sourceTree = "<group>"; };
527A2BD12C57B40A0080DF9B /* CartDataCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CartDataCache.swift; sourceTree = "<group>"; };
527A2BD42C57D0C20080DF9B /* Address.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Address.storyboard; sourceTree = "<group>"; };
527A2BDA2C58F7EB0080DF9B /* MyOrdersVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyOrdersVM.swift; sourceTree = "<group>"; };
527AC6F52C171C8F00434FB7 /* BlogsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogsCell.swift; sourceTree = "<group>"; };
527AC6F62C171C8F00434FB7 /* BlogsCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BlogsCell.xib; sourceTree = "<group>"; };
527AC6F92C17387300434FB7 /* SongBlogDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SongBlogDM.swift; sourceTree = "<group>"; };
@@ -1654,6 +1656,7 @@
9C7939122C0EFCAE00F5D6E6 /* FaqVM.swift */,
9C1C69FB2C106C240035B2C7 /* ContactSupportVM.swift */,
9CA7C6C12C1095B600D73742 /* ProfileVM.swift */,
527A2BDA2C58F7EB0080DF9B /* MyOrdersVM.swift */,
);
path = ViewModel;
sourceTree = "<group>";
@@ -2168,6 +2171,7 @@
52A6DCAE2C4E5A3900F63C51 /* ShopCategoryVM.swift in Sources */,
52D6A2542C22B93F00145908 /* CategoryListingDM.swift in Sources */,
9C27E1672BDB706700EC1DA9 /* StoryBoard.swift in Sources */,
527A2BDB2C58F7EB0080DF9B /* MyOrdersVM.swift in Sources */,
52C8B0692BDA6E1E003B51D0 /* LocalizedEnum.swift in Sources */,
525954122BE8C84900191286 /* Toast.swift in Sources */,
525954172BE8CAD300191286 /* NetworkManager.swift in Sources */,

View File

@@ -56,7 +56,9 @@ class AddressListVC: UIViewController {
@IBAction func btnTapped(_ sender: LocalisedElementsButton) {
switch sender{
case useSelectedAddBtn:
vm.createOrder()
if let addressID = CartDataCache.addressData.filter({$0.isDefault == true}).first?.id{
vm.createOrder(addressID: addressID, couponCode: vm.couponCodeApplied)
}
case addNewAddressBtn:
let sb = UIStoryboard(name: K.StoryBoard.address, bundle: nil)
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Address.verifyAddressPincodeVC) as! VerifyAddressPincodeVC

View File

@@ -72,7 +72,15 @@ class AddNewAddressVM{
guard let data = data.data else{return}
CartDataCache.addressData.append(data)
//set the newly added address as default
if let updateDefaultIndex = CartDataCache.addressData.lastIndex(where: {$0.id == data.id}){
for index in CartDataCache.addressData.indices {
CartDataCache.addressData[index].isDefault = false
}
CartDataCache.addressData[updateDefaultIndex].isDefault = true
}
guard let navigationController = self.vc.navigationController else {
print("Not in a navigation controller")
return

View File

@@ -11,7 +11,8 @@ import Alamofire
class AddressListVM{
weak var vc : AddressListVC!
var couponCodeApplied = String()
func initView(){
vc.innerView.addBorderView(width: 1, color: .darkGray)
self.vc.title = "ADDRESS DETAILS".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue)
@@ -133,7 +134,7 @@ class AddressListVM{
}
}
func createOrder(){
func createOrder(addressID : Int,couponCode : String?){
var productIDs = [Int]()
for i in CartDataCache.cartListData{
@@ -144,7 +145,8 @@ class AddressListVM{
Utilities.startProgressHUD()
let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()]
let params : Parameters = ["product_ids" : productIDs,
"address_id" : "56"]
"address_id" : addressID,
"coupon_code" : couponCode ?? ""]
struct URLResp : Codable {
var url : String?
}
@@ -182,7 +184,7 @@ class AddressListVM{
Utilities.dismissProgressHUD()
Utilities.alertWithBtnCancelCompletion(title: "Error", msgBody: error.localizedDescription, okBtnStr: "Retry?", vc: self.vc) { isDone in
if isDone{
self.createOrder()
self.createOrder(addressID: addressID, couponCode: couponCode)
}
}
}

View File

@@ -1,17 +1,17 @@
{
"images" : [
{
"filename" : "pause.png",
"filename" : "Pause.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "pause@2x.png",
"filename" : "Pause@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "pause@3x.png",
"filename" : "Pause@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

View File

@@ -5,12 +5,11 @@
"scale" : "1x"
},
{
"filename" : "Group 183@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group 183@3x.png",
"filename" : "web.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -20,24 +20,29 @@ public enum BadgeSize {
case large
}
// Define the notification name
extension Notification.Name {
static let badgeValueDidChange = Notification.Name("badgeValueDidChange")
}
public class BadgedButtonItem: UIBarButtonItem {
public func setBadge(with value: Int?) {
self.badgeValue = value
}
public var badgeTintColor: UIColor? {
didSet {
lblBadge.backgroundColor = badgeTintColor
}
}
public var badgeTextColor: UIColor? {
didSet {
lblBadge.textColor = badgeTextColor
}
}
public var position: BadgePosition? = .right {
didSet {
if position == .left {
@@ -53,7 +58,7 @@ public class BadgedButtonItem: UIBarButtonItem {
}
}
}
public var hasBorder: Bool? {
didSet {
if hasBorder == true {
@@ -61,13 +66,13 @@ public class BadgedButtonItem: UIBarButtonItem {
}
}
}
public var borderColor: UIColor? = .black {
didSet {
lblBadge.layer.borderColor = borderColor?.cgColor
}
}
public var badgeSize: BadgeSize = .medium {
didSet {
switch badgeSize {
@@ -82,20 +87,18 @@ public class BadgedButtonItem: UIBarButtonItem {
}
}
}
public var badgeAnimation: Bool? = false {
didSet {
self.isAnimated = badgeAnimation
}
}
public var tapAction: (() -> Void)?
private var badgeValue: Int? {
didSet {
if let value = badgeValue,
value > 0 {
if let value = badgeValue, value > 0 {
// reducing font size if the value has two digits
if "\(value)".count > 1 {
lblBadge.font = UIFont.systemFont(ofSize: twoDigitsFontSize)
@@ -109,10 +112,11 @@ public class BadgedButtonItem: UIBarButtonItem {
} else {
lblBadge.isHidden = true
}
// Post notification about the change
NotificationCenter.default.post(name: .badgeValueDidChange, object: nil, userInfo: ["badgeValue": badgeValue ?? 0])
}
}
private let filterBtn = UIButton()
private let lblBadge = UILabel()
private var isAnimated: Bool? = false
@@ -121,31 +125,30 @@ public class BadgedButtonItem: UIBarButtonItem {
self.lblBadge.layer.cornerRadius = badgeRadius
}
}
private var oneDigitFontSize: CGFloat {
return badgeRadius + 1
}
private var twoDigitsFontSize: CGFloat {
return badgeRadius
}
override init() {
super.init()
setup()
}
init(with image: UIImage?) {
super.init()
setup(image: image)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup(image: UIImage? = nil) {
self.filterBtn.frame = CGRect(x: 0, y: 0, width: 55, height: 55)
self.filterBtn.adjustsImageWhenHighlighted = false
let scaledImage = UIImage.imageWithImage(image, scaledToSize: CGSize(width: 45, height: 50))
@@ -168,13 +171,13 @@ public class BadgedButtonItem: UIBarButtonItem {
self.filterBtn.addSubview(lblBadge)
self.customView = filterBtn
}
@objc private func buttonPressed() {
if let action = tapAction {
action()
}
}
private func animateBadge(_ animate: Bool?) {
guard animate == true else { return }
lblBadge.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
@@ -196,7 +199,6 @@ public class BadgedButtonItem: UIBarButtonItem {
}
}
}
}
/// Takes an image and returns a new one identical but resized.

View File

@@ -6,10 +6,54 @@
//
import Foundation
import Alamofire
class CartDataCache{
static var cartListData = [CartListingDM.ResultData]()
static var isFetched = false
static var cartCount = 0 {
didSet{
if cartCount == 0{
cartBadgeLabel.text = "0"
cartBadgeLabel.isHidden = true
}else{
cartBadgeLabel.text = cartCount.toString()
cartBadgeLabel.isHidden = false
}
}
}
static var addressData = [AddressListDM]()
static let cartBadgeLabel = UILabel()
static let shareInstance = CartDataCache()
func getCartList(vc : UIViewController){
let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()]
NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Cart.cart_listing, method: .get,headers: headers, queue : QueueHelper.background) { (result : Result<BaseResponseModel<CartListingDM>, NetworkManager.APIError>) in
switch result{
case .success(let data):
switch data.success{
case 0:
/*
Error
*/
Utilities.dismissProgressHUD()
case 1:
Utilities.dismissProgressHUD()
guard let data = data.data?.result else{return}
CartDataCache.cartListData = data
CartDataCache.cartCount = data.count
CartDataCache.isFetched = true
default:
Utilities.dismissProgressHUD()
break
}
case .failure(let error):
Utilities.dismissProgressHUD()
Utilities.alert(title: "Error", message: error.localizedDescription, viewController: vc)
}
}
}
}

View File

@@ -72,6 +72,7 @@ class CartPaymentOptionsVC: UIViewController {
@IBAction func confirmBtnTapped(_ sender: LocalisedElementsButton) {
let sb = UIStoryboard(name: K.StoryBoard.address, bundle: nil)
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Address.addressListVC) as! AddressListVC
vcPush.vm.couponCodeApplied = vm.couponCodeApplied
self.navigationController?.pushViewController(vcPush, animated: true)
// vm.createOrder()
}

View File

@@ -17,6 +17,8 @@ class CartPaymentOptionsVM{
var cartTotalPrice = 0.0
var couponCodeSelected = ""
var couponCodeApplied = String()
func initView(){
vc.couponCodeTF.roundCorner()
addGradient()
@@ -128,6 +130,7 @@ class CartPaymentOptionsVM{
self.vc.discountPrice.text = data.discountValue
self.vc.totalCartPrice.text = data.cartDiscountedAmount
self.vc.couponAplliedStack.isHidden = false
self.couponCodeApplied = code
default:
Utilities.dismissProgressHUD()
break

View File

@@ -122,6 +122,7 @@ struct APIEndPoints {
static let coupon_listing = makeURL(path: "coupon_listing")
static let applied_coupon_discount = makeURL(path: "applied_coupon_discount")
static let create_new_order = makeURL(path: "create_new_order")
static let add_cart = makeURL(path: "add_cart")
}
struct Address{

View File

@@ -55,6 +55,14 @@ class ProductDetailsVC: UIViewController {
}
@IBAction func addToCartBtnTapped(_ sender: LocalisedElementsButton) {
if sender.titleLabel?.text == "Add to Cart"{
if let shopMasterID = vm.productDetails?.id{
vm.addToCart(shopMasterID: shopMasterID)
}
}else{
print("View")
}
}
}

View File

@@ -20,41 +20,67 @@ class ShopListingVC: UIViewController {
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
// Create the button
let backbutton = UIButton(type: .custom)
backbutton.setImage(UIImage(named: "CartIcon"), for: .normal) // Image can be downloaded from the provided link
backbutton.setTitleColor(.black, for: .normal) // You can change the TitleColor
backbutton.addTarget(self, action: #selector(vm.cartBtnTapped), for: .touchUpInside)
// Set button height and width
let buttonHeight: CGFloat = 50
let buttonWidth: CGFloat = 50
backbutton.translatesAutoresizingMaskIntoConstraints = false
backbutton.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
backbutton.heightAnchor.constraint(equalToConstant: buttonHeight).isActive = true
// Create a container view for the button
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: buttonWidth, height: buttonHeight))
containerView.addSubview(backbutton)
// // Create the button
// let backbutton = UIButton(type: .custom)
// backbutton.setImage(UIImage(named: "CartIcon"), for: .normal) // Image can be downloaded from the provided link
// backbutton.setTitleColor(.black, for: .normal) // You can change the TitleColor
// backbutton.addTarget(self, action: #selector(vm.cartBtnTapped), for: .touchUpInside)
//
// // Set button height and width
// let buttonHeight: CGFloat = 50
// let buttonWidth: CGFloat = 50
// backbutton.translatesAutoresizingMaskIntoConstraints = false
// backbutton.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
// backbutton.heightAnchor.constraint(equalToConstant: buttonHeight).isActive = true
//
// // Create the badge label
// CartDataCache.cartBadgeLabel.text = CartDataCache.cartCount.toString() // Set your badge number here
// CartDataCache.cartBadgeLabel.textColor = .white
// CartDataCache.cartBadgeLabel.backgroundColor = .red
// CartDataCache.cartBadgeLabel.font = UIFont.systemFont(ofSize: 12)
// CartDataCache.cartBadgeLabel.textAlignment = .center
// CartDataCache.cartBadgeLabel.layer.cornerRadius = 10
// CartDataCache.cartBadgeLabel.clipsToBounds = true
//
// // Set badge label constraints
// CartDataCache.cartBadgeLabel.translatesAutoresizingMaskIntoConstraints = false
// CartDataCache.cartBadgeLabel.widthAnchor.constraint(equalToConstant: 20).isActive = true
// CartDataCache.cartBadgeLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true
//
// // Create a container view for the button
// let containerView = UIView(frame: CGRect(x: 0, y: 0, width: buttonWidth, height: buttonHeight))
// containerView.backgroundColor = .blue
// containerView.addSubview(backbutton)
//
// containerView.addSubview(CartDataCache.cartBadgeLabel)
//
// // Set constraints for the button inside the container view
// NSLayoutConstraint.activate([
// backbutton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
// backbutton.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
//
// // Position the badge at the top-right corner of the button
// CartDataCache.cartBadgeLabel.topAnchor.constraint(equalTo: backbutton.topAnchor, constant: -3),
// CartDataCache.cartBadgeLabel.rightAnchor.constraint(equalTo: backbutton.rightAnchor, constant: -2)
// ])
//
// // Create a UIBarButtonItem with the custom view
// let customBarButton = UIBarButtonItem(customView: containerView)
//
// // Create a flexible space item to push the custom view to the left
// let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
// flexibleSpace.width = 10
//
// // Create a negative spacer to fine-tune the position
// let negativeSpacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
// negativeSpacer.width = 10 // Adjust this value to move the button to the left
//
// // Add the custom bar button and the spacer to the navigation bar
// self.navigationItem.rightBarButtonItems = [flexibleSpace, negativeSpacer, customBarButton]
// Set constraints for the button inside the container view
NSLayoutConstraint.activate([
backbutton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
backbutton.centerXAnchor.constraint(equalTo: containerView.centerXAnchor)
])
// Create a UIBarButtonItem with the custom view
let customBarButton = UIBarButtonItem(customView: containerView)
// Create a flexible space item to push the custom view to the left
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
flexibleSpace.width = 10
// Create a negative spacer to fine-tune the position
let negativeSpacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
negativeSpacer.width = 10 // Adjust this value to move the button to the left
// Add the custom bar button and the spacer to the navigation bar
self.navigationItem.rightBarButtonItems = [flexibleSpace,negativeSpacer, customBarButton]
}
override func viewWillAppear(_ animated: Bool) {
@@ -105,3 +131,68 @@ extension ShopListingVC : TableViewSRC{
self.navigationController?.pushViewController(vcPush, animated: true)
}
}
extension UIViewController {
func createCartButton(imageName: String,
badgeNumber: Int,
buttonSize: CGSize = CGSize(width: 50, height: 50),
badgeColor: UIColor = .red,
badgeTextColor: UIColor = .white,
buttonColor: UIColor = .blue,
target: Any,
action: Selector) -> UIBarButtonItem {
// Create the button
let button = UIButton(type: .custom)
button.setImage(UIImage(named: imageName), for: .normal)
button.setTitleColor(.black, for: .normal)
button.addTarget(target, action: action, for: .touchUpInside)
button.isEnabled = true
button.isUserInteractionEnabled = true
// Set button height and width
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: buttonSize.width).isActive = true
button.heightAnchor.constraint(equalToConstant: buttonSize.height).isActive = true
// Create the badge label
// let badgeLabel = UILabel()
CartDataCache.cartBadgeLabel.text = "\(badgeNumber)"
CartDataCache.cartBadgeLabel.textColor = badgeTextColor
CartDataCache.cartBadgeLabel.backgroundColor = badgeColor
CartDataCache.cartBadgeLabel.font = UIFont.systemFont(ofSize: 12)
CartDataCache.cartBadgeLabel.textAlignment = .center
CartDataCache.cartBadgeLabel.layer.cornerRadius = 10
CartDataCache.cartBadgeLabel.clipsToBounds = true
badgeNumber == 0 ? (CartDataCache.cartBadgeLabel.isHidden = true) : (CartDataCache.cartBadgeLabel.isHidden = false)
// Set badge label constraints
CartDataCache.cartBadgeLabel.translatesAutoresizingMaskIntoConstraints = false
CartDataCache.cartBadgeLabel.widthAnchor.constraint(equalToConstant: 20).isActive = true
CartDataCache.cartBadgeLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true
// Create a container view for the button
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: buttonSize.width, height: buttonSize.height))
containerView.backgroundColor = buttonColor
containerView.addSubview(button)
containerView.addSubview(CartDataCache.cartBadgeLabel)
containerView.isUserInteractionEnabled = true
// Set constraints for the button inside the container view
NSLayoutConstraint.activate([
button.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
button.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
// Position the badge at the top-right corner of the button
CartDataCache.cartBadgeLabel.topAnchor.constraint(equalTo: button.topAnchor, constant: -3),
CartDataCache.cartBadgeLabel.rightAnchor.constraint(equalTo: button.rightAnchor, constant: -2)
])
// Create a UIBarButtonItem with the custom view
let customBarButton = UIBarButtonItem(customView: containerView)
// Return the custom bar button
return customBarButton
}
}

View File

@@ -100,9 +100,7 @@ extension ShopProductsVC : CollectionViewSRC{
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == subCategoryCV{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: K.CellIdentifier.WebSeries.seasonCategoryCell, for: indexPath) as! SeasonCategoryCell
let data = vm.subCategoryData[indexPath.row]
// cell.setData(title: data.seasonNumber ?? "Season", iselected: data.id == vm.episodeSelectedCateogory)
cell.setSubCategory(data: data, isSelected: data.id == vm.selectedSubCategory)
return cell
}else{
@@ -111,7 +109,6 @@ extension ShopProductsVC : CollectionViewSRC{
cell.setData(data: data)
return cell
}
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
@@ -126,12 +123,26 @@ extension ShopProductsVC : CollectionViewSRC{
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let data = vm.shopProductsData[indexPath.row]
let sb = UIStoryboard(name: K.StoryBoard.shop, bundle: nil)
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Shop.productDetailsVC) as! ProductDetailsVC
vcPush.vm.categoryName = vm.pageTitle ?? "Shop"
vcPush.vm.productDetails = data
self.navigationController?.pushViewController(vcPush, animated: true)
switch collectionView{
case productCV:
let data = vm.shopProductsData[indexPath.row]
let sb = UIStoryboard(name: K.StoryBoard.shop, bundle: nil)
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Shop.productDetailsVC) as! ProductDetailsVC
vcPush.vm.categoryName = vm.pageTitle ?? "Shop"
vcPush.vm.productDetails = data
self.navigationController?.pushViewController(vcPush, animated: true)
case subCategoryCV:
if let selectedSubCategory = vm.subCategoryData[indexPath.row].id{
vm.selectedSubCategory = selectedSubCategory
self.subCategoryCV.reloadData()
Utilities.startProgressHUD()
vm.pageNo = 0
vm.getShopProducts(subCategoryID: selectedSubCategory)
}
default:
break
}
}
}

View File

@@ -27,10 +27,11 @@ struct ShopProductsListingDM: Codable {
let stockStatus: String?
// let taxCategory: JSONNull?
let taxValue: String?
let shopMasterDetail: ShopMasterDetail?
let shopMasterDetail: CartListingDM.ShopMasterDetail?
let shopImage: [String]?
let addedToCart: Bool?
let productFinalPrice : Double?
enum CodingKeys: String, CodingKey {
case id
case skuID = "sku_id"
@@ -46,6 +47,7 @@ struct ShopProductsListingDM: Codable {
case shopMasterDetail = "shop_master_detail"
case shopImage = "shop_image"
case addedToCart = "added_to_cart"
case productFinalPrice = "product_final_price"
}
}

View File

@@ -22,7 +22,8 @@ struct ShopSubCategoryDM: Codable {
let id, categoryMasterID: Int?
let subCategoryName: String?
let subCategoryThumbnail: String?
var isSelected : Bool? = false
enum CodingKeys: String, CodingKey {
case id
case categoryMasterID = "category_master_id"

View File

@@ -31,7 +31,7 @@
<color key="backgroundColor" red="0.82745098039999998" green="0.93725490199999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
</view>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="OrderBottom" translatesAutoresizingMaskIntoConstraints="NO" id="gRK-pM-dPn">
<rect key="frame" x="0.0" y="523.33333333333337" width="393" height="294.66666666666663"/>
<rect key="frame" x="0.0" y="537.33333333333337" width="393" height="294.66666666666663"/>
</imageView>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="UPY-aY-67P">
<rect key="frame" x="0.0" y="59" width="393" height="793"/>
@@ -48,7 +48,7 @@
<constraint firstItem="gRK-pM-dPn" firstAttribute="leading" secondItem="5EZ-qb-Rvc" secondAttribute="leading" id="ICF-iB-ed7"/>
<constraint firstAttribute="trailing" secondItem="gRK-pM-dPn" secondAttribute="trailing" id="Zyn-bA-Fdh"/>
<constraint firstItem="zhb-Th-KAe" firstAttribute="top" secondItem="vDu-zF-Fre" secondAttribute="top" id="bqB-3f-7QW"/>
<constraint firstItem="vDu-zF-Fre" firstAttribute="bottom" secondItem="gRK-pM-dPn" secondAttribute="bottom" id="d2i-QF-oQ4"/>
<constraint firstAttribute="bottom" secondItem="gRK-pM-dPn" secondAttribute="bottom" constant="20" symbolic="YES" id="d2i-QF-oQ4"/>
<constraint firstItem="UPY-aY-67P" firstAttribute="leading" secondItem="vDu-zF-Fre" secondAttribute="leading" id="dTK-fu-JTe"/>
<constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="zhb-Th-KAe" secondAttribute="trailing" id="pxo-3d-4Ob"/>
<constraint firstAttribute="bottom" secondItem="UPY-aY-67P" secondAttribute="bottom" id="vt7-RK-kbR"/>
@@ -250,6 +250,7 @@
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pXa-BI-1Vq">
<rect key="frame" x="134.66666666666663" y="0.0" width="238.33333333333337" height="0.0"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
@@ -266,6 +267,7 @@
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iAp-gN-dq2">
<rect key="frame" x="64.666666666666657" y="0.0" width="308.33333333333337" height="0.0"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" name="ImageDarkBlue"/>
<nil key="highlightedColor"/>
</label>

View File

@@ -21,7 +21,12 @@ class ShopProductsCell: UICollectionViewCell {
}
func setData(data : ShopProductsListingDM.ResultData){
self.productTitle.text = data.productName
if data.subCategoryMasterID == 12{
self.productTitle.text = data.shopMasterDetail?.productNameEnglish
}else{
self.productTitle.text = data.shopMasterDetail?.productNameHindi
}
// self.productTitle.text = data.productName
self.productPrice.text = data.productPrice
if let url = data.shopImage?.first{

View File

@@ -32,7 +32,7 @@
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Qxf-XT-JWX">
<rect key="frame" x="0.0" y="0.0" width="141" height="90"/>
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" systemColor="underPageBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="90" id="Asx-t9-17g"/>
</constraints>
@@ -50,6 +50,7 @@
<string key="text">sadasdasd
sadasdasd
sadasdasdasdsad</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.1058823529" green="0.050980392159999999" blue="0.60392156860000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
@@ -102,5 +103,8 @@ sadasdasdasdsad</string>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="underPageBackgroundColor">
<color red="0.70980392156862748" green="0.71764705882352942" blue="0.74117647058823533" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>

View File

@@ -6,6 +6,7 @@
//
import UIKit
import Alamofire
class ProductDetailsVM{
@@ -17,24 +18,29 @@ class ProductDetailsVM{
func initView(){
addGradient()
setupCell()
// vc.productImageCV.roundCorner(radius: 10)
//
// vc.productImageCV.addBorderView(width: 0.5, color: #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1))
//set details
if let productDetails{
vc.productTitle.text = productDetails.productName
if productDetails.subCategoryMasterID == 12{
vc.productTitle.text = productDetails.shopMasterDetail?.productNameEnglish
if let desc = productDetails.shopMasterDetail?.descriptionEnglish, let htmlText = desc.replacingOccurrences(of: "<br>", with: "").htmlToAttributedString{
let sizeText = NSMutableAttributedString(attributedString: htmlText)
sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 16),color: UIColor.appColor(.TextDarkBlue)!)
vc.productDescription.attributedText = sizeText
}
}else{
vc.productTitle.text = productDetails.shopMasterDetail?.productNameHindi
if let desc = productDetails.shopMasterDetail?.descriptionHindi, let htmlText = desc.replacingOccurrences(of: "<br>", with: "").htmlToAttributedString{
let sizeText = NSMutableAttributedString(attributedString: htmlText)
sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 16),color: UIColor.appColor(.TextDarkBlue)!)
vc.productDescription.attributedText = sizeText
}
}
vc.categoryName.text = categoryName
vc.skuID.text = productDetails.skuID
vc.productPrice.text = productDetails.productPrice
if let desc = productDetails.shopMasterDetail?.descriptionEnglish, let htmlText = desc.replacingOccurrences(of: "<br>", with: "").htmlToAttributedString{
let sizeText = NSMutableAttributedString(attributedString: htmlText)
sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 16),color: UIColor.appColor(.TextDarkBlue)!)
vc.productDescription.attributedText = sizeText
}
vc.pageControl.numberOfPages = productDetails.shopImage?.count ?? 1
vc.pageControl.currentPage = 0
if let addedToCart = productDetails.addedToCart, addedToCart{
@@ -58,4 +64,51 @@ class ProductDetailsVM{
self.vc.view.applyGradient(colors: [color2, color1], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0))
}
// MARK: - Add To Cart
func addToCart(shopMasterID : Int){
Utilities.startProgressHUD()
let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()]
let params : Parameters = ["shop_master_id" : shopMasterID]
// 11 - hindi , 12 - english
NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Cart.add_cart, method: .post,parameters: params,headers: headers) { [weak self](result : Result<CommonResponseModel, NetworkManager.APIError>) in
switch result{
case .success(let data):
guard let self else{
Utilities.dismissProgressHUD()
return
}
switch data.success{
case 0:
/*
Error
*/
Utilities.dismissProgressHUD()
Utilities.alertWithBtnCompletion(title: "Error", msgBody: data.message ?? K.ConstantString.unRecognised, okBtnStr: "Retry?", vc: self.vc) { isDone in
}
case 1:
Utilities.dismissProgressHUD()
self.vc.toast(msg: data.message ?? "Added to cart", time: 2) {
if let productDetails = self.productDetails{
CartDataCache.cartListData.append(CartListingDM.ResultData(id: productDetails.id, skuID: productDetails.skuID, productName: productDetails.productName, categoryMasterID: productDetails.categoryMasterID, subCategoryMasterID: productDetails.subCategoryMasterID, productPrice: productDetails.productPrice, remainStockQuantity: productDetails.remainStockQuantity, stockStatus: productDetails.stockStatus, taxValue: productDetails.taxValue, productQuantity: productDetails.remainStockQuantity, shopMasterDetail: productDetails.shopMasterDetail, shopImage: productDetails.shopImage, productFinalPrice: productDetails.productFinalPrice))
self.vc.addToCartBtn.setTitle("View Cart", for: .normal)
}
}
default:
Utilities.dismissProgressHUD()
break
}
case .failure(let error):
guard let self else{
Utilities.dismissProgressHUD()
return
}
Utilities.dismissProgressHUD()
Utilities.alert(title: "Error", message: error.localizedDescription, viewController: self.vc)
}
}
}
}

View File

@@ -17,8 +17,57 @@ class ShopListingVM{
setupCell()
addGradient()
getSuperCategory()
let filterBtn = UIButton.init(frame: CGRect.init(x: 0, y: 0, width: 45, height: 45))
filterBtn.setImage(UIImage(named: "CartIcon"), for: .normal)
filterBtn.addTarget(self, action: #selector(cartBtnTapped), for: .touchUpInside)
// let lblBadge = type(of: CartDataCache.cartBadgeLabel).init(frame: CGRect.init(x: 30, y: 0, width: 18, height: 18))
CartDataCache.cartBadgeLabel.backgroundColor = UIColor.red
CartDataCache.cartBadgeLabel.isHidden = true
CartDataCache.cartBadgeLabel.clipsToBounds = true
CartDataCache.cartBadgeLabel.layer.cornerRadius = 9
CartDataCache.cartBadgeLabel.textColor = UIColor.white
CartDataCache.cartBadgeLabel.font = FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 10)
CartDataCache.cartBadgeLabel.textAlignment = .center
filterBtn.addSubview(CartDataCache.cartBadgeLabel)
self.vc.navigationItem.rightBarButtonItems = [UIBarButtonItem.init(customView: filterBtn)]
//check if cart is not fetched
if !CartDataCache.isFetched{
CartDataCache.shareInstance.getCartList(vc: self.vc)
}
CartDataCache.cartBadgeLabel.text = "2"
// let btn = BadgedButtonItem(with: UIImage(named: "CartIcon")!)
// btn.setBadge(with: 2)
// self.vc.navigationItem.rightBarButtonItem = btn
//
// btn.tapAction = {
// print("tapped")
// }
// let cartButton = vc.createCartButton(imageName: "CartIcon",
// badgeNumber: CartDataCache.cartCount,
// target: self,
// action: #selector(cartBtnTapped))
//
// // Create a flexible space item to push the custom view to the left
// let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
// flexibleSpace.width = 10
//
// // Create a negative spacer to fine-tune the position
// let negativeSpacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
// negativeSpacer.width = 10 // Adjust this value to move the button to the left
//
// self.vc.navigationItem.rightBarButtonItems = [flexibleSpace, negativeSpacer, cartButton]
}
func setupCell(){
vc.tableView.register(UINib(nibName: K.CellIdentifier.Shop.shopListingCell, bundle: nil), forCellReuseIdentifier: K.CellIdentifier.Shop.shopListingCell)
vc.tableView.delegate = vc.self
@@ -75,3 +124,95 @@ class ShopListingVM{
}
}
}
extension UIBarButtonItem {
convenience init(icon: UIImage, badge: String, _ badgeBackgroundColor: UIColor = #colorLiteral(red: 0.9156965613, green: 0.380413115, blue: 0.2803866267, alpha: 1), target: Any? = UIBarButtonItem.self, action: Selector? = nil) {
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
imageView.image = icon
let label = UILabel(frame: CGRect(x: 8, y: -5, width: 20, height: 20))
label.text = badge
label.backgroundColor = badgeBackgroundColor
label.adjustsFontSizeToFitWidth = true
label.textAlignment = .center
label.font = FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 10)
label.clipsToBounds = true
label.layer.cornerRadius = 20 / 2
label.textColor = .white
let buttonView = UIView(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
buttonView.addSubview(imageView)
buttonView.addSubview(label)
buttonView.addGestureRecognizer(UITapGestureRecognizer.init(target: target, action: action))
self.init(customView: buttonView)
}
}
class BadgedButtonItem1: UIBarButtonItem {
public func setBadge(with value: Int) {
self.badgeValue = value
}
private var badgeValue: Int? {
didSet {
if let value = badgeValue,
value > 0 {
lblBadge.isHidden = false
lblBadge.text = "\(value)"
} else {
lblBadge.isHidden = true
}
}
}
var tapAction: (() -> Void)?
private let filterBtn = UIButton()
private let lblBadge = UILabel()
override init() {
super.init()
setup()
}
init(with image: UIImage?) {
super.init()
setup(image: image)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup(image: UIImage? = nil) {
self.filterBtn.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
self.filterBtn.adjustsImageWhenHighlighted = false
self.filterBtn.setImage(image, for: .normal)
self.filterBtn.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
self.lblBadge.frame = CGRect(x: -5, y: 0, width: 15, height: 15)
self.lblBadge.backgroundColor = .red
self.lblBadge.clipsToBounds = true
self.lblBadge.layer.cornerRadius = 7
self.lblBadge.textColor = UIColor.white
self.lblBadge.font = UIFont.systemFont(ofSize: 10)
self.lblBadge.textAlignment = .center
self.lblBadge.isHidden = true
self.lblBadge.minimumScaleFactor = 0.1
self.lblBadge.adjustsFontSizeToFitWidth = true
self.filterBtn.addSubview(lblBadge)
self.customView = filterBtn
}
@objc func buttonPressed() {
if let action = tapAction {
action()
}
}
}

View File

@@ -73,9 +73,9 @@ class ShopProductsVM{
case 1:
Utilities.dismissProgressHUD()
guard let data = data.data?.result else{return}
self.subCategoryData.append(ShopSubCategoryDM.ResultData(id: 0, categoryMasterID: 0, subCategoryName: " All ", subCategoryThumbnail: ""))
self.subCategoryData.append(ShopSubCategoryDM.ResultData(id: -1, categoryMasterID: 0, subCategoryName: " All ", subCategoryThumbnail: ""))
self.subCategoryData.append(contentsOf: data)
self.selectedSubCategory = data.first?.id ?? 0
self.selectedSubCategory = -1
self.vc.subCategoryCV.reloadData()
if let subCatID = data.first?.id{
Utilities.startProgressHUD()
@@ -104,11 +104,12 @@ class ShopProductsVM{
guard let categoryID else{return}
let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()]
let params : Parameters = ["category_id" : categoryID,
"sub_category_id" : subCategoryID ?? "",
"sub_category_id" : ((subCategoryID == -1) ? "" : subCategoryID?.toString() ) ?? "",
"api_version" : "v2",
"start" : pageNo,
"limit" : 12]
// 11 - hindi , 12 - english
NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Shop.shop_product_listing_v2, method: .post,parameters: params,headers: headers) { [weak self](result : Result<BaseResponseModel<ShopProductsListingDM>, NetworkManager.APIError>) in
switch result{
case .success(let data):
@@ -133,6 +134,9 @@ class ShopProductsVM{
Utilities.dismissProgressHUD()
vc.spinnerView.stopAnimating()
guard let count = data.data?.totalRecords ,let data = data.data?.result else{return}
if pageNo == 0{
self.shopProductsData.removeAll()
}
self.shopProductsData.append(contentsOf: data)
self.vc.productCV.reloadData()
if self.shopProductsData.count == count{

View File

@@ -9,25 +9,13 @@ import UIKit
class MyOrdersVC: UIViewController {
var vm = MyOrdersVM()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "MY ORDERS"
let btn = BadgedButtonItem(with: UIImage(named: "CartIcon"))
btn.badgeTintColor = .red
btn.badgeTextColor = .green
btn.position = .right
btn.hasBorder = true
btn.borderColor = .red
btn.badgeSize = .large
btn.badgeAnimation = true
btn.setBadge(with: 1)
btn.tapAction = {
let sb = UIStoryboard(name: K.StoryBoard.cart, bundle: nil)
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Cart.cartListVC) as! CartListVC
self.navigationController?.pushViewController(vcPush, animated: true)
}
self.navigationItem.rightBarButtonItem = btn
vm.vc = self
vm.initView()
}

View File

@@ -0,0 +1,46 @@
//
// MyOrdersVM.swift
// WOKA
//
// Created by MacBook Pro on 30/07/24.
//
import UIKit
class MyOrdersVM{
weak var vc : MyOrdersVC!
func initView(){
vc.title = "MY ORDERS".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue)
//check if cart is not fetched
if !CartDataCache.isFetched{
CartDataCache.shareInstance.getCartList(vc: self.vc)
}
let cartButton = vc.createCartButton(imageName: "CartIcon",
badgeNumber: CartDataCache.cartCount,
target: self,
action: #selector(cartBtnTapped))
// Create a flexible space item to push the custom view to the left
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
flexibleSpace.width = 10
// Create a negative spacer to fine-tune the position
let negativeSpacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
negativeSpacer.width = 10 // Adjust this value to move the button to the left
self.vc.navigationItem.rightBarButtonItems = [flexibleSpace, negativeSpacer, cartButton]
// Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { _ in
// lblBadge.text = "3"
// }
}
@objc func cartBtnTapped(){
print("cart tapped")
}
}

View File

@@ -99,10 +99,9 @@ class SideMenuVM{
break
}
//set the first name as the name
if let avatar = data.avtar{
//https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar2.png?d=1716889852
vc.avatarImage.imageURL("https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar2.png?d=1716889852",color: .white)
vc.avatarImage.imageURL("https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/storage/app/public/uploads/avtar/avatar2.png?d=1716889852")
// vc.avatarImage.imageURL(avatar)
}
}

View File

@@ -177,8 +177,8 @@ class ThemeOneVM{
}
if let avatar = data.avtar{
//https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar2.png?d=1716889852
vc.avatarImage.imageURL("https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar2.png?d=1716889852")
// vc.avatarImage.imageURL(avatar)
vc.avatarImage.imageURL("https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/storage/app/public/uploads/avtar/avatar2.png?d=1716889852")
}
}

View File

@@ -182,8 +182,8 @@ class ThemeTwoVM{
}
if let avatar = data.avtar{
//https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar2.png?d=1716889852
vc.avatarImage.imageURL("https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar6.png")
vc.avatarImage.imageURL("https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/storage/app/public/uploads/avtar/avatar2.png?d=1716889852")
// vc.avatarImage.imageURL(avatar)
}
}