Fix categories tab, remove navbar from profile tab
This commit is contained in:
parent
d6bc8cbb4b
commit
e4caef826c
9 changed files with 53 additions and 44 deletions
|
@ -15,4 +15,5 @@ struct Category: Identifiable, Hashable, Codable {
|
|||
let description: String?
|
||||
let amount: Int
|
||||
let expense: Bool
|
||||
let archived: Bool
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import Foundation
|
|||
import Combine
|
||||
|
||||
class CategoryDataStore: ObservableObject {
|
||||
private var currentRequest: AnyCancellable? = nil
|
||||
var categories: Result<[Category], NetworkError> = .failure(.loading) {
|
||||
didSet {
|
||||
self.objectWillChange.send()
|
||||
|
@ -22,14 +23,15 @@ class CategoryDataStore: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func getCategories(budgetId: String? = nil, count: Int? = nil, page: Int? = nil) {
|
||||
func getCategories(budgetId: String? = nil, archived: Bool? = false, count: Int? = nil, page: Int? = nil) {
|
||||
self.categories = .failure(.loading)
|
||||
|
||||
_ = categoryRepository.getCategories(budgetId: budgetId, count: count, page: page)
|
||||
self.currentRequest = categoryRepository.getCategories(budgetId: budgetId, archived: archived, count: count, page: page)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveCompletion: { (completion) in
|
||||
switch completion {
|
||||
case .finished:
|
||||
self.currentRequest = nil
|
||||
return
|
||||
case .failure(let error):
|
||||
self.categories = .failure(error)
|
||||
|
@ -43,11 +45,12 @@ class CategoryDataStore: ObservableObject {
|
|||
func getCategory(_ categoryId: String) {
|
||||
self.category = .failure(.loading)
|
||||
|
||||
_ = categoryRepository.getCategory(categoryId)
|
||||
self.currentRequest = categoryRepository.getCategory(categoryId)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveCompletion: { (completion) in
|
||||
switch completion {
|
||||
case .finished:
|
||||
self.currentRequest = nil
|
||||
return
|
||||
case .failure(let error):
|
||||
self.category = .failure(error)
|
||||
|
|
|
@ -10,7 +10,7 @@ import Foundation
|
|||
import Combine
|
||||
|
||||
protocol CategoryRepository {
|
||||
func getCategories(budgetId: String?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError>
|
||||
func getCategories(budgetId: String?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError>
|
||||
func getCategory(_ categoryId: String) -> AnyPublisher<Category, NetworkError>
|
||||
}
|
||||
|
||||
|
@ -23,14 +23,14 @@ class NetworkCategoryRepository: CategoryRepository {
|
|||
self.cacheService = cacheService
|
||||
}
|
||||
|
||||
func getCategories(budgetId: String?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
|
||||
if let categories = cacheService?.getCategories(budgetId: budgetId, count: count, page: page) {
|
||||
func getCategories(budgetId: String?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
|
||||
if let categories = cacheService?.getCategories(budgetId: budgetId, archived: archived, count: count, page: page) {
|
||||
print("Returning categories from cache")
|
||||
return categories
|
||||
}
|
||||
|
||||
print("No cached categories, fetching from network")
|
||||
return apiService.getCategories(budgetId: budgetId, count: count, page: page).map { (categories: [Category]) in
|
||||
return apiService.getCategories(budgetId: budgetId, archived: archived, count: count, page: page).map { (categories: [Category]) in
|
||||
self.cacheService?.addCategories(categories)
|
||||
return categories
|
||||
}.eraseToAnyPublisher()
|
||||
|
@ -58,10 +58,11 @@ class MockCategoryRepository: CategoryRepository {
|
|||
title: "Test Category",
|
||||
description: "This is a test category to help with testing",
|
||||
amount: 10000,
|
||||
expense: true
|
||||
expense: true,
|
||||
archived: false
|
||||
)
|
||||
|
||||
func getCategories(budgetId: String?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
|
||||
func getCategories(budgetId: String?, archived: Bool?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
|
||||
return Result.Publisher([MockCategoryRepository.category]).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
|
|
@ -61,10 +61,10 @@ class BudgetAppApiService {
|
|||
) -> AnyPublisher<[Transaction], NetworkError> {
|
||||
var queries = [String: Array<String>]()
|
||||
if budgetIds != nil {
|
||||
queries["budgetId"] = budgetIds!
|
||||
queries["budgetIds"] = budgetIds!
|
||||
}
|
||||
if categoryIds != nil {
|
||||
queries["categoryId"] = categoryIds!
|
||||
queries["categoryIds"] = categoryIds!
|
||||
}
|
||||
if from != nil {
|
||||
queries["from"] = [from!.toISO8601String()]
|
||||
|
@ -99,10 +99,13 @@ class BudgetAppApiService {
|
|||
|
||||
// MARK: Categories
|
||||
|
||||
func getCategories(budgetId: String? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError> {
|
||||
func getCategories(budgetId: String? = nil, archived: Bool? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError> {
|
||||
var queries = [String: Array<String>]()
|
||||
if budgetId != nil {
|
||||
queries["budgetId"] = [String(budgetId!)]
|
||||
queries["budgetIds"] = [String(budgetId!)]
|
||||
}
|
||||
if archived != nil {
|
||||
queries["archived"] = [String(archived!)]
|
||||
}
|
||||
if count != nil {
|
||||
queries["count"] = [String(count!)]
|
||||
|
@ -197,7 +200,7 @@ class RequestHelper {
|
|||
|
||||
init(_ baseUrl: String) {
|
||||
self.baseUrl = baseUrl
|
||||
self.decoder.dateDecodingStrategy = .iso8601
|
||||
self.decoder.dateDecodingStrategy = .formatted(Date.iso8601DateFormatter)
|
||||
}
|
||||
|
||||
func get<ResultType: Codable>(
|
||||
|
@ -373,26 +376,26 @@ extension Encodable {
|
|||
}
|
||||
|
||||
extension Date {
|
||||
var iso8601DateFormatter: DateFormatter {
|
||||
static let iso8601DateFormatter: DateFormatter = {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
|
||||
dateFormatter.timeZone = TimeZone(identifier: "UTC")
|
||||
return dateFormatter
|
||||
}
|
||||
}()
|
||||
|
||||
var localeDateFormatter: DateFormatter {
|
||||
static let localeDateFormatter: DateFormatter = {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale.current
|
||||
dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "yyyyMMdd", options: 0, locale: Locale.current)
|
||||
return dateFormatter
|
||||
}
|
||||
}()
|
||||
|
||||
func toISO8601String() -> String {
|
||||
return iso8601DateFormatter.string(from: self)
|
||||
return Date.iso8601DateFormatter.string(from: self)
|
||||
}
|
||||
|
||||
func toLocaleString() -> String {
|
||||
return localeDateFormatter.string(from: self)
|
||||
return Date.localeDateFormatter.string(from: self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,11 +61,14 @@ class BudgetAppInMemoryCacheService {
|
|||
}
|
||||
|
||||
// MARK: Categories
|
||||
func getCategories(budgetId: String? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError>? {
|
||||
func getCategories(budgetId: String? = nil, archived: Bool? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError>? {
|
||||
var results = categories
|
||||
if budgetId != nil {
|
||||
results = categories.filter { $0.budgetId == budgetId }
|
||||
}
|
||||
if archived != nil {
|
||||
results = results.filter { $0.archived == archived }
|
||||
}
|
||||
if results.isEmpty {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ struct ProfileView: View {
|
|||
let currentUser: User
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
VStack(spacing: 10) {
|
||||
Image(systemName: "person.circle.fill")
|
||||
.frame(width: 100, height: 100, alignment: .center)
|
||||
|
@ -32,8 +31,6 @@ struct ProfileView: View {
|
|||
.foregroundColor(.red)
|
||||
}
|
||||
}
|
||||
.navigationBarTitle("profile")
|
||||
}
|
||||
}
|
||||
|
||||
let dataStoreProvider: DataStoreProvider
|
||||
|
|
|
@ -28,7 +28,7 @@ struct TabbedBudgetView: View {
|
|||
selectedTab = 0
|
||||
}
|
||||
|
||||
BudgetListsView(dataStoreProvider).tabItem {
|
||||
CategoryListView(dataStoreProvider, budget: self.budget).tabItem {
|
||||
Image(systemName: "chart.pie.fill")
|
||||
Text("categories")
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class TransactionDataStore: ObservableObject {
|
|||
self.currentRequest = nil
|
||||
return
|
||||
case .failure(let error):
|
||||
print("Error loading transactions: \(error.name)")
|
||||
self.transactions = .failure(error)
|
||||
}
|
||||
}, receiveValue: { (transactions) in
|
||||
|
|
|
@ -16,7 +16,7 @@ struct TransactionListView: View {
|
|||
var body: some View {
|
||||
switch transactionDataStore.transactions {
|
||||
case .success(let transactions):
|
||||
Section{
|
||||
Section {
|
||||
List(transactions) { transaction in
|
||||
TransactionListItemView(self.dataStoreProvider, transaction: transaction)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue