Add categories with icons and colors for transactions. Update transaction views with new category UI
This commit is contained in:
parent
9b407e7195
commit
30afdbb5f5
5 changed files with 78 additions and 29 deletions
|
|
@ -1,16 +1,16 @@
|
|||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
@State private var transactions = TransactionModel.sampleData
|
||||
@StateObject private var transactionsStore = TransactionsStore()
|
||||
|
||||
var body: some View {
|
||||
TabView {
|
||||
DashboardView(transactions: transactions)
|
||||
DashboardView(transactions: transactionsStore.transactions)
|
||||
.tabItem {
|
||||
Label("Dashboard", systemImage: "chart.pie.fill")
|
||||
}
|
||||
|
||||
TransactionsView()
|
||||
TransactionsView(store: transactionsStore)
|
||||
.tabItem {
|
||||
Label("Transactions", systemImage: "list.bullet")
|
||||
}
|
||||
|
|
|
|||
31
Coinly/Features/Models/CategoryModel.swift
Normal file
31
Coinly/Features/Models/CategoryModel.swift
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// CategoryModel.swift
|
||||
// Coinly
|
||||
//
|
||||
// Created by Vadym Samoilenko on 02/03/2025.
|
||||
//
|
||||
|
||||
|
||||
import Foundation
|
||||
|
||||
struct CategoryModel: Identifiable {
|
||||
let id = UUID()
|
||||
let name: String
|
||||
let icon: String // SF Symbols name
|
||||
let color: String // Будем хранить как строку
|
||||
}
|
||||
|
||||
extension CategoryModel {
|
||||
static let categories = [
|
||||
CategoryModel(name: "Food", icon: "cart.fill", color: "red"),
|
||||
CategoryModel(name: "Transport", icon: "car.fill", color: "blue"),
|
||||
CategoryModel(name: "Entertainment", icon: "tv.fill", color: "purple"),
|
||||
CategoryModel(name: "Shopping", icon: "bag.fill", color: "orange"),
|
||||
CategoryModel(name: "Salary", icon: "dollarsign.circle.fill", color: "green"),
|
||||
CategoryModel(name: "Other", icon: "square.fill", color: "gray")
|
||||
]
|
||||
|
||||
static func category(for name: String) -> CategoryModel {
|
||||
categories.first { $0.name == name } ?? categories.last!
|
||||
}
|
||||
}
|
||||
|
|
@ -4,11 +4,10 @@ struct AddTransactionView: View {
|
|||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var amount: String = ""
|
||||
@State private var note: String = ""
|
||||
@State private var category: String = "Food"
|
||||
@State private var category: String = CategoryModel.categories[0].name
|
||||
@State private var date = Date()
|
||||
@State private var type: TransactionType = .expense
|
||||
|
||||
let categories = ["Food", "Transport", "Entertainment", "Shopping", "Salary", "Other"]
|
||||
let addTransaction: (TransactionModel) -> Void
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -29,8 +28,13 @@ struct AddTransactionView: View {
|
|||
|
||||
Section("Details") {
|
||||
Picker("Category", selection: $category) {
|
||||
ForEach(categories, id: \.self) { category in
|
||||
Text(category).tag(category)
|
||||
ForEach(CategoryModel.categories) { category in
|
||||
HStack {
|
||||
Image(systemName: category.icon)
|
||||
.foregroundColor(Color(category.color))
|
||||
Text(category.name)
|
||||
}
|
||||
.tag(category.name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,9 +72,3 @@ struct AddTransactionView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AddTransactionView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AddTransactionView(addTransaction: { _ in })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
import SwiftUI
|
||||
|
||||
struct TransactionsView: View {
|
||||
@State private var transactions = TransactionModel.sampleData
|
||||
@ObservedObject var store: TransactionsStore
|
||||
@State private var showingAddTransaction = false
|
||||
|
||||
func addTransaction(_ transaction: TransactionModel) {
|
||||
transactions.insert(transaction, at: 0)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
List {
|
||||
ForEach(transactions) { transaction in
|
||||
ForEach(store.transactions) { transaction in
|
||||
TransactionRowView(transaction: transaction)
|
||||
}
|
||||
.onDelete(perform: deleteTransactions)
|
||||
.onDelete { indexSet in
|
||||
store.deleteTransaction(at: indexSet)
|
||||
}
|
||||
}
|
||||
.navigationTitle("Transactions")
|
||||
.toolbar {
|
||||
|
|
@ -25,12 +23,8 @@ struct TransactionsView: View {
|
|||
}
|
||||
}
|
||||
.sheet(isPresented: $showingAddTransaction) {
|
||||
AddTransactionView(addTransaction: addTransaction)
|
||||
AddTransactionView(addTransaction: store.addTransaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func deleteTransactions(at offsets: IndexSet) {
|
||||
transactions.remove(atOffsets: offsets)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,34 @@ import SwiftUI
|
|||
struct TransactionRowView: View {
|
||||
let transaction: TransactionModel
|
||||
|
||||
private var category: CategoryModel {
|
||||
CategoryModel.category(for: transaction.category)
|
||||
}
|
||||
|
||||
private var categoryColor: Color {
|
||||
switch category.color {
|
||||
case "red": return .red
|
||||
case "blue": return .blue
|
||||
case "purple": return .purple
|
||||
case "orange": return .orange
|
||||
case "green": return .green
|
||||
case "gray": return .gray
|
||||
default: return .gray
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
VStack(alignment: .leading) {
|
||||
HStack(spacing: 12) {
|
||||
// Category Icon
|
||||
Image(systemName: category.icon)
|
||||
.font(.title2)
|
||||
.foregroundColor(.white)
|
||||
.frame(width: 40, height: 40)
|
||||
.background(categoryColor)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
|
||||
// Transaction Details
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(transaction.category)
|
||||
.font(.headline)
|
||||
if let note = transaction.note {
|
||||
|
|
@ -25,7 +50,8 @@ struct TransactionRowView: View {
|
|||
|
||||
Spacer()
|
||||
|
||||
VStack(alignment: .trailing) {
|
||||
// Amount and Date
|
||||
VStack(alignment: .trailing, spacing: 4) {
|
||||
Text(String(format: "%.2f", transaction.amount))
|
||||
.font(.headline)
|
||||
.foregroundColor(transaction.isExpense ? .red : .green)
|
||||
|
|
@ -44,4 +70,4 @@ struct TransactionRowView_Previews: PreviewProvider {
|
|||
.previewLayout(.sizeThatFits)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue