💄 UI Enhancements
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func addSub() -> Void {
|
struct AddSubscriptionView: View {
|
||||||
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
@Binding var subs: [Subscription]
|
||||||
|
|
||||||
|
@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 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"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user