Last active
October 10, 2023 21:07
-
-
Save allfinlir/525e54599210192c1be571aba3f180aa to your computer and use it in GitHub Desktop.
This file contains 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 | |
struct BetDataPoint: Identifiable { | |
var id = UUID() | |
let date: Date | |
let total: Double | |
let league: String | |
} |
This file contains 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
struct BetDataPointPerWeek: Identifiable { | |
var id = UUID() | |
let date: Date | |
let totalLastWeek: Double | |
} |
This file contains 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 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() | |
} | |
// 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") | |
} | |
} | |
} |
This file contains 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
Then presented in a tabview like this. | |
@EnvironmentObject var betViewModel: BetViewModel | |
TabView { | |
WinChart(resultData: betViewModel.sortListofBetsByDate()) | |
WinChartByWeek(resultData: betViewModel.resultsLastWeek()) | |
} | |
.frame(height: 250) | |
.tabViewStyle(.page(indexDisplayMode: .never)) |
This file contains 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 | |
import Charts | |
struct WinChart: View { | |
@EnvironmentObject var betCharts: BetViewModel | |
let resultData: [BetModel] | |
var body: some View { | |
VStack { | |
GroupBox("3 Month Results") { | |
Chart(betCharts.makeChartData(from: resultData)) { result in | |
LineMark(x: .value("Day", result.date), y: .value("Result", result.total)) | |
.interpolationMethod(.catmullRom) | |
.lineStyle(StrokeStyle(lineWidth: 2, dash: [5, 10])) | |
// .foregroundStyle(by: .value("League", result.league)) | |
} | |
} | |
.groupBoxStyle(YellowGroupBoxStyle()) | |
/* Chart(betCharts.makeChartData(from: resultData)) { result in | |
LineMark(x: .value("Day", result.date), y: .value("Result", result.total)) | |
.foregroundStyle(by: .value("League", result.league)) | |
} | |
.chartLegend(position: .leading, alignment: .top, spacing: 10) */ | |
} | |
} | |
} | |
//struct WinChart_Previews: PreviewProvider { | |
// static var previews: some View { | |
// WinChart() | |
// } | |
//} | |
struct YellowGroupBoxStyle: GroupBoxStyle { | |
func makeBody(configuration: Configuration) -> some View { | |
configuration.content | |
.padding(.top, 30) | |
.padding(20) | |
.background(Color(hue: 0.10, saturation: 0.10, brightness: 0.98)) | |
.cornerRadius(20) | |
.overlay( | |
configuration.label.padding(10), | |
alignment: .topLeading | |
) | |
} | |
} |
This file contains 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 | |
import Charts | |
struct WinChartByWeek: View { | |
@EnvironmentObject var betCharts: BetViewModel | |
let resultData: [BetModel] | |
var body: some View { | |
VStack { | |
Chart(betCharts.chartDataPerWeek(from: resultData)) { result in | |
LineMark(x: .value("Day", result.date), y: .value("Result", result.totalLastWeek)) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment