diff --git a/SynchronyFinancial/SynchronyFinancial WatchKit App/Base.lproj/Interface.storyboard b/SynchronyFinancial/SynchronyFinancial WatchKit App/Base.lproj/Interface.storyboard index 10ce75c..d1254a2 100644 --- a/SynchronyFinancial/SynchronyFinancial WatchKit App/Base.lproj/Interface.storyboard +++ b/SynchronyFinancial/SynchronyFinancial WatchKit App/Base.lproj/Interface.storyboard @@ -1,12 +1,12 @@ - + - - + + @@ -100,7 +100,6 @@ - @@ -113,10 +112,10 @@ - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + @@ -164,7 +241,10 @@ - + + + + diff --git a/SynchronyFinancial/SynchronyFinancial WatchKit Extension/AccountDetailsInterfaceController.swift b/SynchronyFinancial/SynchronyFinancial WatchKit Extension/AccountDetailsInterfaceController.swift index cacf7c1..2019c6a 100644 --- a/SynchronyFinancial/SynchronyFinancial WatchKit Extension/AccountDetailsInterfaceController.swift +++ b/SynchronyFinancial/SynchronyFinancial WatchKit Extension/AccountDetailsInterfaceController.swift @@ -11,15 +11,26 @@ import Foundation class AccountDetailsInterfaceController: WKInterfaceController { var selectedAccount: Account? + var dictForAcct: [String: Account] = [:] + @IBOutlet weak var transactionsButton: WKInterfaceButton! + @IBOutlet weak var payButton: WKInterfaceButton! @IBOutlet weak var balanceLabel: WKInterfaceLabel! @IBOutlet weak var availableFundsLabel: WKInterfaceLabel! @IBOutlet weak var accountNameLabel: WKInterfaceLabel! @IBOutlet weak var nextPaymentDueLabel: WKInterfaceLabel! + @IBAction func payBillTapped() { + if let acct = selectedAccount { + dictForAcct.updateValue(acct, forKey: "acct") + } + pushController(withName: "PayMinimum", context: dictForAcct) + } + override func awake(withContext context: Any?) { super.awake(withContext: context) - + payButton.setWidth(self.contentFrame.width / 2) + transactionsButton.setWidth(self.contentFrame.width / 2) guard let data = context as? [String: Account] else { NSLog("Error receiving context containing selected account in AccountDetailInterfaceController") return @@ -39,6 +50,17 @@ class AccountDetailsInterfaceController: WKInterfaceController { super.didDeactivate() } + override func contextForSegue(withIdentifier segueIdentifier: String) -> Any? { + if segueIdentifier == "payBill" { + if let acct = selectedAccount { + dictForAcct.updateValue(acct, forKey: "acct") + return dictForAcct + } + } + + return nil + } + private func configureForAccount() { guard selectedAccount != nil, let acct = selectedAccount else { NSLog("Error configuring AccountDetails. selectedAccount is nil") diff --git a/SynchronyFinancial/SynchronyFinancial WatchKit Extension/AccountTableInterfaceController.swift b/SynchronyFinancial/SynchronyFinancial WatchKit Extension/AccountTableInterfaceController.swift index baa7b73..9f5694c 100644 --- a/SynchronyFinancial/SynchronyFinancial WatchKit Extension/AccountTableInterfaceController.swift +++ b/SynchronyFinancial/SynchronyFinancial WatchKit Extension/AccountTableInterfaceController.swift @@ -12,6 +12,7 @@ import Foundation class AccountTableInterfaceController: WKInterfaceController { var accounts: [Account] = [] var acctDict: [String: Account] = [:] + var transactionDict: [String: [Transaction]] = [:] @IBOutlet weak var accountTable: WKInterfaceTable! override func awake(withContext context: Any?) { @@ -41,6 +42,12 @@ class AccountTableInterfaceController: WKInterfaceController { return nil } + override func table(_ table: WKInterfaceTable, didSelectRowAt rowIndex: Int) { + acctDict.updateValue(accounts[rowIndex], forKey: "acct") + self.pushController(withName: "AccountDetails", context: self.acctDict) +// self.presentController(withNames: ["AccountDetails", "Transactions"], contexts: [self.acctDict, self.transactionDict]) + } + private func configureRows() { accountTable.setNumberOfRows(accounts.count, withRowType: "account") diff --git a/SynchronyFinancial/SynchronyFinancial WatchKit Extension/PayBillInterfaceController.swift b/SynchronyFinancial/SynchronyFinancial WatchKit Extension/PayBillInterfaceController.swift new file mode 100644 index 0000000..c9b4b1f --- /dev/null +++ b/SynchronyFinancial/SynchronyFinancial WatchKit Extension/PayBillInterfaceController.swift @@ -0,0 +1,65 @@ +// +// PayBillInterfaceController.swift +// SynchronyFinancial +// +// Created by Alan Maynard on 3/13/19. +// Copyright © 2019 Alan Maynard. All rights reserved. +// + +import WatchKit +import Foundation + +class PayBillInterfaceController: WKInterfaceController { + var acct: Account? + var payDict: [String: Any] = [:] + + @IBOutlet weak var balanceLabel: WKInterfaceLabel! + @IBOutlet weak var payBalanceButton: WKInterfaceButton! + @IBOutlet weak var minimumLabel: WKInterfaceLabel! + @IBOutlet weak var payMinimumButton: WKInterfaceButton! + + override func awake(withContext context: Any?) { + super.awake(withContext: context) + + // Configure interface objects here. + guard let data = context as? [String: Account] else { + NSLog("Error receiving context containing selected account in AccountDetailInterfaceController") + return + } + + acct = data["acct"] + configure() + } + + override func willActivate() { + // This method is called when watch view controller is about to be visible to user + super.willActivate() + } + + override func didDeactivate() { + // This method is called when watch view controller is no longer visible + super.didDeactivate() + } + + override func contextForSegue(withIdentifier segueIdentifier: String) -> Any? { + if segueIdentifier == "PayMinimum" { + payDict.updateValue(Double(acct?.minimumPayment ?? 0.0), forKey: "payment_amount") + } else if segueIdentifier == "PayAll" { + payDict.updateValue(Double(acct?.balance ?? 0.0), forKey: "payment_amount") + } + return payDict + } + + private func configure() { + if let valid = acct { + payDict.updateValue(valid, forKey: "acct") + let balanceFormatted = String(format: "$%.2f", valid.balance) + balanceLabel.setText("Balance: \(balanceFormatted)") + payBalanceButton.setTitle("Pay \(balanceFormatted)") + + let minimumFormatted = String(format: "$%.2f", valid.minimumPayment) + minimumLabel.setText("Minimum Payment: \(minimumFormatted)") + payMinimumButton.setTitle("Pay \(minimumFormatted)") + } + } +} diff --git a/SynchronyFinancial/SynchronyFinancial WatchKit Extension/PaymentDetailInterfaceController.swift b/SynchronyFinancial/SynchronyFinancial WatchKit Extension/PaymentDetailInterfaceController.swift new file mode 100644 index 0000000..30ed7b8 --- /dev/null +++ b/SynchronyFinancial/SynchronyFinancial WatchKit Extension/PaymentDetailInterfaceController.swift @@ -0,0 +1,57 @@ +// +// PaymentDetailInterfaceController.swift +// SynchronyFinancial +// +// Created by Monday on 2019/03/24. +// Copyright © 2019 Alan Maynard. All rights reserved. +// + +import WatchKit +import Foundation + +class PaymentDetailInterfaceController: WKInterfaceController { + var selectedAccount: Account? + var dictForAcct: [String: Account] = [:] + var paymentButtonArmed: Bool = false + var paymentAmount: Double = 0.0 + + @IBOutlet weak var detailButton: WKInterfaceButton! + @IBOutlet weak var amount: WKInterfaceLabel! + @IBOutlet weak var paymentButton: WKInterfaceButton! + + override func awake(withContext context: Any?) { + super.awake(withContext: context) + guard let data = context as? [String: Any], let acct = data["acct"] as? Account, let amount = data["payment_amount"] as? Double else { + NSLog("Error getting account object and payment amount") + return + } + + self.paymentAmount = amount + self.selectedAccount = acct + paymentButton.setTitle(String(format: "Pay $%.2f", amount)) + } + + @IBAction func paymentAction() { + if paymentButtonArmed { + popToRootController() + } else { +// animate(withDuration: 0.75) { +// self.paymentButton.setBackgroundColor(UIColor.init(red: 141, green: 241, blue: 48, alpha: 1.0)) +// } + + paymentButton.setBackgroundColor(#colorLiteral(red: 0.6092301607, green: 0.9366738796, blue: 0.2432599962, alpha: 1)) + paymentButtonArmed = true + paymentButton.setTitle("Pay Now") + } + } + + override func willActivate() { + // This method is called when watch view controller is about to be visible to user + super.willActivate() + } + + override func didDeactivate() { + // This method is called when watch view controller is no longer visible + super.didDeactivate() + } +} diff --git a/SynchronyFinancial/SynchronyFinancial.xcodeproj/project.pbxproj b/SynchronyFinancial/SynchronyFinancial.xcodeproj/project.pbxproj index 4e8fcf6..dbb6a36 100644 --- a/SynchronyFinancial/SynchronyFinancial.xcodeproj/project.pbxproj +++ b/SynchronyFinancial/SynchronyFinancial.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 281283568A34D3C5D9C7B383 /* libPods-SynchronyFinancial WatchKit Extension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAA6D46F907ADAABF49FD409 /* libPods-SynchronyFinancial WatchKit Extension.a */; }; + 481864A8224802BB0059CF7A /* PaymentDetailInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481864A7224802BB0059CF7A /* PaymentDetailInterfaceController.swift */; }; + 481864A9224802BB0059CF7A /* PaymentDetailInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481864A7224802BB0059CF7A /* PaymentDetailInterfaceController.swift */; }; 48DA0058221D12E70081A500 /* AccountCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48DA0057221D12E70081A500 /* AccountCell.swift */; }; 48F243072214C98600B9C894 /* AccountTableInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48F243062214C98600B9C894 /* AccountTableInterfaceController.swift */; }; 48F243082214CA9600B9C894 /* AccountTableInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48F243062214C98600B9C894 /* AccountTableInterfaceController.swift */; }; @@ -17,6 +19,8 @@ 48F2430F2214CC2200B9C894 /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48F2430C2214CBF700B9C894 /* Transaction.swift */; }; 673F396E21A644570051469E /* MainMenuInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673F396C21A644460051469E /* MainMenuInterfaceController.swift */; }; 673F397021A652A00051469E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 673F396F21A652A00051469E /* Assets.xcassets */; }; + 674BD1532239A39D0076AFD6 /* PayBillInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 674BD1522239A39D0076AFD6 /* PayBillInterfaceController.swift */; }; + 674BD1542239A39D0076AFD6 /* PayBillInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 674BD1522239A39D0076AFD6 /* PayBillInterfaceController.swift */; }; 676392B422429DC800740A8C /* TransactionsInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676392B322429DC800740A8C /* TransactionsInterfaceController.swift */; }; 676392B62242A3F800740A8C /* TransactionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676392B52242A3F800740A8C /* TransactionCell.swift */; }; 678C38842230950100FEAAF6 /* AccountDetailsInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678C38832230950100FEAAF6 /* AccountDetailsInterfaceController.swift */; }; @@ -80,6 +84,7 @@ 1BEF4B8BF190D117CA6104E5 /* Pods-SynchronyFinancial WatchKit App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SynchronyFinancial WatchKit App.release.xcconfig"; path = "Pods/Target Support Files/Pods-SynchronyFinancial WatchKit App/Pods-SynchronyFinancial WatchKit App.release.xcconfig"; sourceTree = ""; }; 250BDAF6AD4E1CCA82995E30 /* Pods-SynchronyFinancial WatchKit Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SynchronyFinancial WatchKit Extension.release.xcconfig"; path = "Pods/Target Support Files/Pods-SynchronyFinancial WatchKit Extension/Pods-SynchronyFinancial WatchKit Extension.release.xcconfig"; sourceTree = ""; }; 396A16E056D05DEC937A07DA /* Pods-SynchronyFinancial.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SynchronyFinancial.release.xcconfig"; path = "Pods/Target Support Files/Pods-SynchronyFinancial/Pods-SynchronyFinancial.release.xcconfig"; sourceTree = ""; }; + 481864A7224802BB0059CF7A /* PaymentDetailInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentDetailInterfaceController.swift; sourceTree = ""; }; 48DA0057221D12E70081A500 /* AccountCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountCell.swift; sourceTree = ""; }; 48F243062214C98600B9C894 /* AccountTableInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTableInterfaceController.swift; sourceTree = ""; }; 48F2430B2214CBF700B9C894 /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; @@ -87,6 +92,7 @@ 4EA10823B2E5A7A4FEF31740 /* libPods-SynchronyFinancial WatchKit App.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SynchronyFinancial WatchKit App.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 673F396C21A644460051469E /* MainMenuInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenuInterfaceController.swift; sourceTree = ""; }; 673F396F21A652A00051469E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 674BD1522239A39D0076AFD6 /* PayBillInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayBillInterfaceController.swift; sourceTree = ""; }; 676392B322429DC800740A8C /* TransactionsInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsInterfaceController.swift; sourceTree = ""; }; 676392B52242A3F800740A8C /* TransactionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCell.swift; sourceTree = ""; }; 678C38832230950100FEAAF6 /* AccountDetailsInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDetailsInterfaceController.swift; sourceTree = ""; }; @@ -187,6 +193,8 @@ 67BAC28A219E254900713FEF /* SynchronyFinancial WatchKit Extension */ = { isa = PBXGroup; children = ( + 674BD1522239A39D0076AFD6 /* PayBillInterfaceController.swift */, + 481864A7224802BB0059CF7A /* PaymentDetailInterfaceController.swift */, 676392B322429DC800740A8C /* TransactionsInterfaceController.swift */, 673F396C21A644460051469E /* MainMenuInterfaceController.swift */, 67BAC28D219E254900713FEF /* ExtensionDelegate.swift */, @@ -446,8 +454,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 674BD1532239A39D0076AFD6 /* PayBillInterfaceController.swift in Sources */, 48F2430D2214CBF700B9C894 /* Account.swift in Sources */, 678C388622309F7D00FEAAF6 /* AccountCell.swift in Sources */, + 481864A8224802BB0059CF7A /* PaymentDetailInterfaceController.swift in Sources */, 48F2430E2214CBF700B9C894 /* Transaction.swift in Sources */, 67BAC269219E254700713FEF /* AppDelegate.swift in Sources */, 48F243082214CA9600B9C894 /* AccountTableInterfaceController.swift in Sources */, @@ -460,6 +470,7 @@ files = ( 678C3885223098C400FEAAF6 /* Account.swift in Sources */, 67BAC28E219E254900713FEF /* ExtensionDelegate.swift in Sources */, + 674BD1542239A39D0076AFD6 /* PayBillInterfaceController.swift in Sources */, 678C38842230950100FEAAF6 /* AccountDetailsInterfaceController.swift in Sources */, 673F396E21A644570051469E /* MainMenuInterfaceController.swift in Sources */, 48F243072214C98600B9C894 /* AccountTableInterfaceController.swift in Sources */, @@ -467,6 +478,7 @@ 48F2430F2214CC2200B9C894 /* Transaction.swift in Sources */, 676392B422429DC800740A8C /* TransactionsInterfaceController.swift in Sources */, 48DA0058221D12E70081A500 /* AccountCell.swift in Sources */, + 481864A9224802BB0059CF7A /* PaymentDetailInterfaceController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SynchronyFinancial/SynchronyFinancial/Account.swift b/SynchronyFinancial/SynchronyFinancial/Account.swift index 3aa4941..4dbf388 100644 --- a/SynchronyFinancial/SynchronyFinancial/Account.swift +++ b/SynchronyFinancial/SynchronyFinancial/Account.swift @@ -14,6 +14,7 @@ class Account: NSObject { var transactions: [Transaction] var paymentDueDate: Date var cycleEndDate: Date + var minimumPayment: Double init(accountNumber: String, limit: Double, transactions: [Transaction], paymentDueDate: Date, cycleEndDate: Date) { self.accountNumber = accountNumber @@ -22,5 +23,6 @@ class Account: NSObject { self.balance = transactions.map { $0.amount }.reduce(0.0, +) self.paymentDueDate = paymentDueDate self.cycleEndDate = cycleEndDate + self.minimumPayment = 25.00 } }