💄 UI Enhancements

This commit is contained in:
2024-06-28 14:10:19 +02:00
parent 621ce23fc7
commit d01363f236
2 changed files with 134 additions and 48 deletions

View File

@@ -1,49 +1,66 @@
import SwiftUI import SwiftUI
struct ContentView: View { struct ContentView: View {
var subs: [Subscription] = [ @State private var showAddSubscriptionSheet = false
Subscription(name: "Test", amount: 9.99, intervall: .monthly), @State private var subs: [Subscription] = [
Subscription(name: "Fitness First", amount: 8, intervall: .weekly) Subscription(name: "Test", payments: [Payment(amount: 9.99, intervall: .monthly)]),
Subscription(name: "Fitness First", payments: [Payment(amount: 8, intervall: .weekly), Payment(amount: 30, intervall: .quarter)])
] ]
var body: some View { var body: some View {
NavigationView { NavigationView {
List { Form {
ForEach(subs) { sub in Section(header: Text("Subscriptions")) {
HStack { ForEach(subs) { sub in
VStack(alignment: .leading, spacing: 8) { VStack(alignment: .leading, spacing: 8) {
HStack { Text(sub.name)
Image(systemName: "arrow.left") .font(.headline)
Text(sub.name) ForEach(sub.payments) { payment in
Spacer() HStack {
Text("\(sub.amount, specifier: "%.2f")€/\(sub.intervall.description)") Text("\(payment.amount, specifier: "%.2f")\(Currency.euro.description)")
Spacer()
Text("/\(payment.intervall.description)")
.foregroundColor(.gray)
}
.font(.subheadline)
} }
} }
.frame(maxWidth: .infinity, alignment: .leading) .padding(.vertical, 8)
.padding(7)
.background(Color.gray.opacity(0.15))
.cornerRadius(10)
.padding(5)
} }
.frame(maxWidth: .infinity) .onDelete(perform: deleteSubscription)
.padding(.vertical, 4)
} }
.listRowInsets(EdgeInsets())
.listRowSeparator(.hidden)
HStack { Section {
Text("Monthly Total: ") HStack {
Spacer() Text("Monthly Total")
Text("\(getMonthlyTotal(subs: subs), specifier: "%.2f€")") Spacer()
Text("\(getMonthlyTotal(subs: subs), specifier: "%.2f")\(Currency.euro.description)")
.foregroundColor(.gray)
}
}
Section {
Button("Add a Subscription") {
showAddSubscriptionSheet.toggle()
}
} }
.padding(.vertical, 4)
Button("Add a Subscription", action: addSub)
} }
.listStyle(PlainListStyle())
.navigationTitle("Subscriptions") .navigationTitle("Subscriptions")
.navigationBarItems(leading: EditButton(), trailing: Button(action: {
showAddSubscriptionSheet.toggle()
}) {
Image(systemName: "plus")
})
.sheet(isPresented: $showAddSubscriptionSheet) {
AddSubscriptionView(subs: $subs)
}
} }
} }
func deleteSubscription(at offsets: IndexSet) {
subs.remove(atOffsets: offsets)
}
func getMonthlyTotal(subs: [Subscription]) -> Float { func getMonthlyTotal(subs: [Subscription]) -> Float {
var monthlyTotal: Float = 0.0 var monthlyTotal: Float = 0.0
for sub in subs { for sub in subs {
@@ -51,9 +68,53 @@ struct ContentView: View {
} }
return monthlyTotal return monthlyTotal
} }
}
struct AddSubscriptionView: View {
@Environment(\.presentationMode) var presentationMode
@Binding var subs: [Subscription]
func addSub() -> Void { @State private var name: String = ""
@State private var amount: String = ""
@State private var intervall: PaymentIntervall = .monthly
var body: some View {
NavigationView {
Form {
Section(header: Text("Subscription Name")) {
TextField("Name", text: $name)
}
Section(header: Text("Amount")) {
TextField("Amount", text: $amount)
.keyboardType(.decimalPad)
}
Section(header: Text("Intervall")) {
Picker("Intervall", selection: $intervall) {
Text("Weekly").tag(PaymentIntervall.weekly)
Text("Monthly").tag(PaymentIntervall.monthly)
Text("Quarter").tag(PaymentIntervall.quarter)
Text("Yearly").tag(PaymentIntervall.yearly)
}
.pickerStyle(SegmentedPickerStyle())
}
Section {
Button("Add Subscription") {
if let amount = Float(amount) {
let newSubscription = Subscription(name: name, payments: [Payment(amount: amount, intervall: intervall)])
subs.append(newSubscription)
presentationMode.wrappedValue.dismiss()
}
}
}
}
.navigationTitle("Add Subscription")
.navigationBarItems(trailing: Button("Cancel") {
presentationMode.wrappedValue.dismiss()
})
}
} }
} }

View File

@@ -1,33 +1,55 @@
//
// Subscription.swift
// AboTracker
//
// Created by Keyvan Atashfaraz on 27.06.24.
//
import Foundation import Foundation
import SwiftUI import SwiftUI
final class Subscription: Identifiable { final class Subscription: Identifiable {
public let id = UUID() public let id = UUID()
var name: String var name: String
var amount: Float var payments: [Payment]
var intervall: PaymentIntervall
init(name: String, amount: Float, intervall: PaymentIntervall) { init(name: String, payments: [Payment]) {
self.name = name self.name = name
self.amount = amount self.payments = payments
self.intervall = intervall
} }
func getMonthlyAmount() -> Float { func getMonthlyAmount() -> Float {
switch intervall { var sum: Float = 0.0
case .weekly: for payment in payments {
return amount/7*30; switch payment.intervall {
case .monthly: case .weekly:
return amount; sum += payment.amount / 7 * 30
case .yearly: case .monthly:
return amount/12; sum += payment.amount
case .quarter:
sum += payment.amount / 3
case .yearly:
sum += payment.amount / 12
}
}
return sum
}
}
final class Payment: Identifiable {
public let id = UUID()
var amount: Float
var intervall: PaymentIntervall
init(amount: Float, intervall: PaymentIntervall) {
self.amount = amount
self.intervall = intervall
}
}
enum Currency: CustomStringConvertible {
case euro
case dollar
var description: String {
switch self {
case .euro:
return ""
case .dollar:
return "$"
} }
} }
} }
@@ -35,6 +57,7 @@ final class Subscription: Identifiable {
enum PaymentIntervall: CustomStringConvertible { enum PaymentIntervall: CustomStringConvertible {
case weekly case weekly
case monthly case monthly
case quarter
case yearly case yearly
var description: String { var description: String {
@@ -43,6 +66,8 @@ enum PaymentIntervall: CustomStringConvertible {
return "week" return "week"
case .monthly: case .monthly:
return "month" return "month"
case .quarter:
return "quarter"
case .yearly: case .yearly:
return "year" return "year"
} }