💄 UI Enhancements
This commit is contained in:
@@ -1,49 +1,66 @@
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
var subs: [Subscription] = [
|
||||
Subscription(name: "Test", amount: 9.99, intervall: .monthly),
|
||||
Subscription(name: "Fitness First", amount: 8, intervall: .weekly)
|
||||
@State private var showAddSubscriptionSheet = false
|
||||
@State private var subs: [Subscription] = [
|
||||
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 {
|
||||
NavigationView {
|
||||
List {
|
||||
ForEach(subs) { sub in
|
||||
HStack {
|
||||
Form {
|
||||
Section(header: Text("Subscriptions")) {
|
||||
ForEach(subs) { sub in
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
HStack {
|
||||
Image(systemName: "arrow.left")
|
||||
Text(sub.name)
|
||||
Spacer()
|
||||
Text("\(sub.amount, specifier: "%.2f")€/\(sub.intervall.description)")
|
||||
Text(sub.name)
|
||||
.font(.headline)
|
||||
ForEach(sub.payments) { payment in
|
||||
HStack {
|
||||
Text("\(payment.amount, specifier: "%.2f")\(Currency.euro.description)")
|
||||
Spacer()
|
||||
Text("/\(payment.intervall.description)")
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
.font(.subheadline)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(7)
|
||||
.background(Color.gray.opacity(0.15))
|
||||
.cornerRadius(10)
|
||||
.padding(5)
|
||||
.padding(.vertical, 8)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 4)
|
||||
.onDelete(perform: deleteSubscription)
|
||||
}
|
||||
.listRowInsets(EdgeInsets())
|
||||
.listRowSeparator(.hidden)
|
||||
|
||||
HStack {
|
||||
Text("Monthly Total: ")
|
||||
Spacer()
|
||||
Text("\(getMonthlyTotal(subs: subs), specifier: "%.2f€")")
|
||||
Section {
|
||||
HStack {
|
||||
Text("Monthly Total")
|
||||
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")
|
||||
.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 {
|
||||
var monthlyTotal: Float = 0.0
|
||||
for sub in subs {
|
||||
@@ -51,9 +68,53 @@ struct ContentView: View {
|
||||
}
|
||||
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()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +1,55 @@
|
||||
//
|
||||
// Subscription.swift
|
||||
// AboTracker
|
||||
//
|
||||
// Created by Keyvan Atashfaraz on 27.06.24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
final class Subscription: Identifiable {
|
||||
public let id = UUID()
|
||||
var name: String
|
||||
var amount: Float
|
||||
var intervall: PaymentIntervall
|
||||
var payments: [Payment]
|
||||
|
||||
init(name: String, amount: Float, intervall: PaymentIntervall) {
|
||||
init(name: String, payments: [Payment]) {
|
||||
self.name = name
|
||||
self.amount = amount
|
||||
self.intervall = intervall
|
||||
self.payments = payments
|
||||
}
|
||||
|
||||
func getMonthlyAmount() -> Float {
|
||||
switch intervall {
|
||||
case .weekly:
|
||||
return amount/7*30;
|
||||
case .monthly:
|
||||
return amount;
|
||||
case .yearly:
|
||||
return amount/12;
|
||||
var sum: Float = 0.0
|
||||
for payment in payments {
|
||||
switch payment.intervall {
|
||||
case .weekly:
|
||||
sum += payment.amount / 7 * 30
|
||||
case .monthly:
|
||||
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 {
|
||||
case weekly
|
||||
case monthly
|
||||
case quarter
|
||||
case yearly
|
||||
|
||||
var description: String {
|
||||
@@ -43,6 +66,8 @@ enum PaymentIntervall: CustomStringConvertible {
|
||||
return "week"
|
||||
case .monthly:
|
||||
return "month"
|
||||
case .quarter:
|
||||
return "quarter"
|
||||
case .yearly:
|
||||
return "year"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user