Created
October 11, 2023 18:18
-
-
Save allfinlir/8adb397a8ffcab0715d94ac7fd366fa8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| import SwiftUI | |
| struct BetModel: Identifiable, Codable { // Identifiable so we have id on each item and codable so it can handle JSON data | |
| let id: String | |
| var league: String | |
| let homeTeam: String | |
| let awayTeam: String | |
| var dateForBet: Date | |
| let typeOfBet: String | |
| let odds: Double | |
| let betAmount: Double | |
| var potentialWin: Double | |
| var winBet: Bool | |
| var looseBet: Bool | |
| var pushBet: Bool | |
| var betCount: Int | |
| let description: String | |
| init(id: String = UUID().uuidString, league: String, homeTeam: String, awayTeam: String, dateForBEt: Date, typeOfBet: String, odds: Double, betAmount: Double, potentialWin: Double, winBet: Bool, looseBet: Bool, pushBet: Bool, betCount: Int, description: String) { | |
| self.id = id | |
| self.league = league | |
| self.homeTeam = homeTeam | |
| self.awayTeam = awayTeam | |
| self.dateForBet = dateForBEt | |
| self.typeOfBet = typeOfBet | |
| self.odds = odds | |
| self.betAmount = betAmount | |
| self.potentialWin = potentialWin | |
| self.winBet = winBet | |
| self.looseBet = looseBet | |
| self.pushBet = pushBet | |
| self.betCount = betCount | |
| self.description = description | |
| } | |
| func updateWinCompletion() -> BetModel { | |
| return BetModel(id: id, league: league, homeTeam: homeTeam, awayTeam: awayTeam, dateForBEt: dateForBet, typeOfBet: typeOfBet, odds: odds, betAmount: betAmount, potentialWin: winBet ? 0.0 : (odds * betAmount) - betAmount, winBet: !winBet, looseBet: looseBet, pushBet: pushBet, betCount: betCount, description: description) | |
| } | |
| func updateLostCompletion() -> BetModel { | |
| return BetModel(id: id, league: league, homeTeam: homeTeam, awayTeam: awayTeam, dateForBEt: dateForBet, typeOfBet: typeOfBet, odds: odds, betAmount: betAmount, potentialWin: looseBet ? 0.0 : -betAmount, winBet: winBet, looseBet: !looseBet, pushBet: pushBet, betCount: betCount, description: description) | |
| } | |
| func updatePushCompletion() -> BetModel { | |
| return BetModel(id: id, league: league, homeTeam: homeTeam, awayTeam: awayTeam, dateForBEt: dateForBet, typeOfBet: typeOfBet, odds: odds, betAmount: betAmount, potentialWin: 0.0, winBet: winBet, looseBet: looseBet, pushBet: !pushBet, betCount: betCount, description: description) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import SwiftUI | |
| struct BetView: View { | |
| @EnvironmentObject var betViewModel: BetViewModel | |
| var body: some View { | |
| NavigationView { | |
| VStack { | |
| if betViewModel.betItems.isEmpty { | |
| NoBetView() | |
| } else { | |
| ZStack { | |
| List { | |
| ForEach(betViewModel.sortListofBetsByDate()) { bet in | |
| BetRowView(bet: bet) | |
| .background { | |
| NavigationLink("", destination: BetDetailsView(betDetail: bet)) | |
| .opacity(0) | |
| } | |
| } | |
| // .onDelete(perform: betViewModel.deleteBet) | |
| .onDelete(perform: { indexSet in | |
| for index in indexSet { | |
| let dateToDelet = betViewModel.betItems[index].dateForBet | |
| betViewModel.deleteBet(forDate: dateToDelet) | |
| } | |
| }) | |
| .onMove(perform: betViewModel.moveBet) | |
| //.listRowSeparator(.hidden) | |
| } | |
| .listStyle(.inset) | |
| // .scrollContentBackground(.hidden) | |
| // .background( | |
| // Color.green | |
| // .opacity(0.1) | |
| // .edgesIgnoringSafeArea(.top) | |
| // ) If you want to add a background to the list. Think you need iOS 16 for this. | |
| VStack { | |
| Spacer() | |
| HStack { | |
| Spacer() | |
| NavigationLink(destination: AddBetView(), label: { | |
| Image(systemName: "plus") | |
| .foregroundColor(.white) | |
| .font(.system(size: 30)) | |
| .padding() | |
| .background( | |
| Circle() | |
| .foregroundColor(.green) | |
| .shadow(color: .black.opacity(0.2), radius: 1, x: 1, y: 1) | |
| ) | |
| }) | |
| .padding(20) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| .navigationBarItems(leading: EditButton(), trailing: NavigationLink("Add", destination: AddBetView())) | |
| // .navigationTitle("Bets") | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| class BetViewModel: ObservableObject { | |
| @Published var betItems: [BetModel] = [] | |
| init() { | |
| getBets() // fetches my dat from getBets() function | |
| } | |
| public var totalWinningsLosses: Double { | |
| return betItems.reduce(0) { sum, betResults in | |
| sum + betResults.potentialWin | |
| } | |
| } | |
| func makeChartData(from bets: [BetModel]) -> [BetDataPoint] { | |
| let sortedBets = betItems.sorted { $0.dateForBet < $1.dateForBet } | |
| var currentTotal = 0.0 | |
| let dataPoints = sortedBets.map { bet in | |
| currentTotal += bet.potentialWin | |
| return BetDataPoint(date: bet.dateForBet, total: currentTotal, league: bet.league) | |
| } | |
| return dataPoints | |
| } | |
| func chartDataPerWeek(from bets: [BetModel]) -> [BetDataPointPerWeek] { | |
| let lastWeek = Calendar.current.date(byAdding: .day, value: -7, to: Date()) ?? Date() | |
| let sortedBetsLastWeek = betItems.filter { $0.dateForBet >= lastWeek }.sorted(by: { $0.dateForBet < $1.dateForBet }) | |
| // let sortedBetsLastWeek = betItems.sorted { $0.dateForBet < $1.dateForBet } | |
| var currentWeekTotal = 0.0 | |
| let weekDataPoints = sortedBetsLastWeek.map { weekBets in | |
| currentWeekTotal += weekBets.potentialWin | |
| return BetDataPointPerWeek(date: weekBets.dateForBet, totalLastWeek: currentWeekTotal) | |
| } | |
| return weekDataPoints | |
| } | |
| let betItemKey: String = "Bets" | |
| func getBets() { | |
| guard let data = UserDefaults.standard.data(forKey: betItemKey), | |
| let savedBetItems = try? JSONDecoder().decode([BetModel].self, from: data) | |
| else { return } | |
| self.betItems = savedBetItems | |
| } | |
| // MARK: Sorts all bets by date in the WinChart View | |
| func sortListofBetsByDate() -> [BetModel] { | |
| betItems.sorted(by: { $0.dateForBet > $1.dateForBet }) | |
| } | |
| // MARK: sorts the bets to only the latest 7 days bet results | |
| func resultsLastWeek() -> [BetModel] { | |
| let lastWeek = Calendar.current.date(byAdding: .day, value: -7, to: Date()) ?? Date() | |
| return betItems.filter { $0.dateForBet >= lastWeek }.sorted(by: { $0.dateForBet < $1.dateForBet}) | |
| } | |
| // MARK: So you can delete bets from the list | |
| /* func deleteBet(indexSet: IndexSet) { | |
| betItems.remove(atOffsets: indexSet) | |
| saveBet() | |
| } */ | |
| func deleteBet(forDate dateToDelete: Date) { | |
| var indicesToDelete: [Int] = [] | |
| for (index, item) in betItems.enumerated() { | |
| if item.dateForBet == dateToDelete { | |
| indicesToDelete.insert(index, at: 0) | |
| } | |
| } | |
| for index in indicesToDelete.reversed() { | |
| betItems.remove(at: index) | |
| } | |
| } | |
| // MARK: So you can move items in the bet list | |
| func moveBet(from: IndexSet, to: Int) { | |
| betItems.move(fromOffsets: from, toOffset: to) | |
| } | |
| // MARK: Counts all winning bets | |
| func winningBets() -> Int { | |
| betItems.filter { $0.winBet == true }.count | |
| } | |
| // MARK: Counts all loosing bets. | |
| func loosingBets() -> Int { | |
| betItems.filter { $0.looseBet == true }.count | |
| } | |
| // MARK: counts all bet that are push bets | |
| func pushBets() -> Int { | |
| betItems.filter { $0.pushBet == true }.count | |
| } | |
| // MARK: calculates all bets that have not been decided yet, those that are ongoing | |
| func ongoingBets() -> Int { | |
| betItems.filter { $0.winBet == false && $0.looseBet == false && $0.pushBet == false }.count | |
| } | |
| // MARK: So you can add a bet in the bet view, save saveBet() is there so the list is saved when app is closed by user. | |
| func addBet(league: String, homeTeam: String, awayTeam: String, dateForBet: Date, typeOfBet: String, odds: Double, betAmount: Double, potentialWin: Double, betCount: Int, description: String) { | |
| let newBet = BetModel(league: league, homeTeam: homeTeam, awayTeam: awayTeam, dateForBEt: dateForBet, typeOfBet: typeOfBet, odds: odds, betAmount: betAmount, potentialWin: potentialWin, winBet: false, looseBet: false, pushBet: false, betCount: betCount, description: description) | |
| // betItems.append(newBet) | |
| betItems.insert(newBet, at: 0) // use this instead if you want your bet to append at the top of your list | |
| saveBet() | |
| } | |
| // MARK: Updates the bet row view and toggles the winbet boolean from false to true. | |
| func updateWinBet(bet: BetModel) { | |
| if let betWinIndex = betItems.firstIndex(where: {$0.id == bet.id }) { | |
| betItems[betWinIndex] = bet.updateWinCompletion() // updateWinCompletion sätter vi ju in vår BetModel | |
| } | |
| } | |
| // MARK: Updates the bet row view and toggles the loosebet boolean from false to true. | |
| func updateLooseBet(bet: BetModel) { | |
| if let betLooseIndex = betItems.firstIndex(where: {$0.id == bet.id }) { | |
| betItems[betLooseIndex] = bet.updateLostCompletion() // updateLostCompletion sätter vi ju in vår BetModel | |
| } | |
| } | |
| // MARK: Updates the bet row view and toggles the pushbet boolean from false to true. | |
| func updatePushBet(bet: BetModel) { | |
| if let betPushIndex = betItems.firstIndex(where: {$0.id == bet.id}) { | |
| betItems[betPushIndex] = bet.updatePushCompletion() | |
| } | |
| } | |
| // MARK: So data get saved once the app is closed by the user, | |
| func saveBet() { | |
| if let encodedBetData = try? JSONEncoder().encode(betItems) { | |
| UserDefaults.standard.set(encodedBetData, forKey: betItemKey) | |
| } else { | |
| print("Couldn't save bet") | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment