Created
October 16, 2023 04:41
-
-
Save allfinlir/c0aa6b47c63a0a78fec51198091d8785 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 | |
struct AddBettorDataModel: Identifiable { | |
var id = UUID() | |
var newBettor: String | |
} |
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 AddBettorView: View { | |
@EnvironmentObject var betViewModel: BetViewModel | |
@State var addNewBettor: String | |
@Binding var presentAddBettorView: Bool | |
// @Binding var bettorArray: [String] | |
var body: some View { | |
VStack { | |
Text("Add new bettor") | |
TextField("Name", text: $addNewBettor) | |
Button(action: { | |
betViewModel.newBettorAdded(bettor: addNewBettor) | |
presentAddBettorView = false | |
}, label: { | |
Text("Add") | |
}) | |
} | |
} | |
} |
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 AddBetView: View { | |
@Environment(\.presentationMode) var presentationMode | |
@EnvironmentObject var betViewModel: BetViewModel | |
@AppStorage("savehometeam") var homeTeamData: String = "Home Team" | |
@AppStorage("saveawayteam") var awayTeamData: String = "Away Team" | |
@AppStorage("Rikard") var startNewBettorArray: String = "" | |
@State var chooseLeague: Leagues = .chooseleague | |
@State var homeTeam: String = "" | |
@State var awayTeam: String = "" | |
@State var selectDate = Date() | |
@State var typeOfBetInput: String = "" | |
@State var oddsOnBet: String = "" | |
@State var bettedAmount: String = "" | |
@State var bettorSelected: String = "" | |
@State var potentialWinnings: String = "" | |
@State var countBets: Int = 0 | |
@State var descriptionInput: String = "" | |
@State var addNewBettor: String = "" | |
@State private var presentAddBettorView: Bool = false | |
var body: some View { | |
Form { | |
Group { | |
Section(header: Text("New bet")) { | |
Picker("League", selection: $chooseLeague) { | |
ForEach(Leagues.allCases, id: \.self) { league in | |
Text(league.localName) | |
} | |
} | |
Picker("Home team", selection: $homeTeam) { | |
ForEach(selectLeague(league: chooseLeague), id: \.self) { selectedHomeTeam in | |
Text(selectedHomeTeam) | |
} | |
} | |
.onChange(of: homeTeam) { _ in | |
homeTeamData = homeTeam | |
} | |
Picker("Away team", selection: $awayTeam) { | |
ForEach(selectLeague(league: chooseLeague), id: \.self) { selectedAwayTeam in | |
Text(selectedAwayTeam) | |
} | |
} | |
.onChange(of: awayTeam) { _ in | |
awayTeamData = awayTeam | |
} | |
DatePicker("Game starts", selection: $selectDate, displayedComponents: [.date, .hourAndMinute]) | |
.datePickerStyle(.compact) | |
TextField("Type of bet: 1X2, O/U, DC, HT/FT....", text: $typeOfBetInput) | |
// .keyboardType(.decimalPad) // not needed because not only numbers here to be inputed | |
TextField("Odds?", text: $oddsOnBet) | |
.keyboardType(.decimalPad) | |
TextField("Amount/Units on bet..", text: $bettedAmount) | |
.keyboardType(.decimalPad) | |
HStack { | |
Picker("Bettor", selection: $addNewBettor) { | |
ForEach(betViewModel.newBettors) { bettor in | |
NewBettorView(bettor: bettor) | |
} | |
} | |
HStack { | |
Text("") | |
} | |
.contentShape(Rectangle()) | |
.padding(.leading, 16) | |
.overlay { | |
HStack { | |
// Spacer() | |
Button(action: { | |
presentAddBettorView = true | |
}, label: { | |
Image(systemName: "plus.circle") | |
.foregroundStyle(.blue) | |
}) | |
.buttonStyle(PlainButtonStyle()) | |
} | |
} | |
.layoutPriority(1) | |
} | |
} | |
Section(header: Text("Motivate bet: ")) { | |
TextEditor(text: $descriptionInput) | |
.frame(height: 200) | |
Button(action: { | |
pressSaveButton() | |
}, label: { | |
Text("Save bet") | |
.foregroundColor(.green) | |
}) | |
} | |
} | |
} | |
.sheet(isPresented: $presentAddBettorView, content: { | |
AddBettorView(addNewBettor: addNewBettor, presentAddBettorView: $presentAddBettorView) | |
}) | |
} | |
var oddsOnBetReplaceComma: String { | |
oddsOnBet.replacingOccurrences(of: ",", with: ".") | |
} | |
var bettedAmountReplaceComma: String { | |
bettedAmount.replacingOccurrences(of: ",", with: ".") | |
} | |
func pressSaveButton() { | |
betViewModel.addBet(league: chooseLeague.rawValue, homeTeam: homeTeam, awayTeam: awayTeam, dateForBet: selectDate, typeOfBet: typeOfBetInput, odds: Double(oddsOnBetReplaceComma) ?? 0.0, betAmount: Double(bettedAmountReplaceComma) ?? 0.0, bettor: [addNewBettor], potentialWin: Double(potentialWinnings) ?? 0.0, betCount: countBets, description: descriptionInput) | |
// betViewModel.newBettorAdded(bettor: addNewBettor) | |
presentationMode.wrappedValue.dismiss() | |
} | |
} |
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 bettor: [String] | |
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, bettor: [String], 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.bettor = bettor | |
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, bettor: bettor, 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, bettor: bettor, 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, bettor: bettor, 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 Foundation | |
class BetViewModel: ObservableObject { | |
@Published var betItems: [BetModel] = [] | |
@Published var newBettors: [AddBettorDataModel] = [] | |
init() { | |
getBets() // fetches my data from getBets() function | |
} | |
public var totalWinningsLosses: Double { | |
return betItems.reduce(0) { sum, betResults in | |
sum + betResults.potentialWin | |
} | |
} | |
func newBettorAdded(bettor: String) { | |
let newBettor = AddBettorDataModel(newBettor: bettor) | |
newBettors.insert(newBettor, at: 0) | |
// saveBet() | |
} | |
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.sorted(by: { $0.dateForBet > $1.dateForBet }) // this will sort all bets in the array by date. | |
} | |
// 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 | |
} | |
// func addBettor() -> [String] { | |
//} | |
// 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, bettor: [String], potentialWin: Double, betCount: Int, description: String) { | |
let newBet = BetModel(league: league, homeTeam: homeTeam, awayTeam: awayTeam, dateForBEt: dateForBet, typeOfBet: typeOfBet, odds: odds, betAmount: betAmount, bettor: bettor, 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) | |
getBets() // by adding the function here, all new items in the array will be sorted on date as well. | |
} else { | |
print("Couldn't save bet") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment