Skip to content

Instantly share code, notes, and snippets.

@allfinlir
Created October 11, 2023 18:18
Show Gist options
  • Select an option

  • Save allfinlir/8adb397a8ffcab0715d94ac7fd366fa8 to your computer and use it in GitHub Desktop.

Select an option

Save allfinlir/8adb397a8ffcab0715d94ac7fd366fa8 to your computer and use it in GitHub Desktop.
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)
}
}
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")
}
}
}
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