You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
PadelClub/PadelClub/Views/Subscription/PurchaseListView.swift

115 lines
3.3 KiB

//
// PurchaseListView.swift
// PadelClub
//
// Created by Laurent Morvillier on 22/04/2024.
//
import SwiftUI
import StoreKit
import LeStorage
class PurchaseManager: ObservableObject {
static let main: PurchaseManager = PurchaseManager()
fileprivate var _products: [Product] = []
fileprivate var _purchases: [Purchase] = []
@Published var purchaseRows: [PurchaseRow] = []
init() {
NotificationCenter.default.addObserver(self, selector: #selector(_purchasesChanged(notification:)), name: NSNotification.Name.CollectionDidChange, object: Guard.main.purchases)
let identifiers: [String] = StoreItem.allCases.map { $0.rawValue }
Task {
do {
self._products = try await Product.products(for: identifiers)
self._buildRows()
} catch {
Logger.error(error)
}
}
}
@objc fileprivate func _purchasesChanged(notification: Notification) {
guard let collection = notification.object as? StoredCollection<Purchase> else {
return
}
self._purchases.removeAll()
self._purchases.append(contentsOf: collection)
self._buildRows()
}
fileprivate func _buildRows() {
DispatchQueue.main.async {
var rows: [PurchaseRow] = []
let userPurchases: [StoreKit.Transaction] = Guard.main.userFilteredPurchases()
for userPurchase in userPurchases {
if let item = StoreItem(rawValue: userPurchase.productID),
let product = self._products.first(where: { $0.id == item.rawValue } ) {
switch item {
case .unit:
let remainingTournaments = Guard.main.remainingTournaments
if remainingTournaments > 0 {
rows.append(PurchaseRow(name: product.displayName, item: item, quantity: remainingTournaments))
}
default:
rows.append(PurchaseRow(name: product.displayName, item: item))
}
}
}
self.purchaseRows = rows
}
}
}
struct PurchaseListView: View {
@ObservedObject var manager = PurchaseManager()
var body: some View {
if self.manager.purchaseRows.count > 0 {
Section {
ForEach(self.manager.purchaseRows) { purchaseRow in
Link(destination: URLs.subscriptions.url) {
PurchaseView(purchaseRow: purchaseRow)
}
}
} header: {
Text("Vos achats")
}
}
}
}
struct PurchaseView: View {
var purchaseRow: PurchaseRow
var body: some View {
HStack {
Image(systemName: self.purchaseRow.item.systemImage)
.foregroundColor(.accentColor)
Text(self.purchaseRow.name)
Spacer()
if let quantity = purchaseRow.quantity {
let remaining = Guard.main.remainingTournaments
Text("\(remaining) / \(quantity.formatted())")
}
}
}
}
#Preview {
PurchaseListView()
}