-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4e215d7
commit 56b6f8b
Showing
6 changed files
with
422 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// | ||
// AssetAddView.swift | ||
// MMEX | ||
// | ||
// Created by Lisheng Guan on 2024/9/25. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct AssetAddView: View { | ||
@Binding var newAsset: AssetData | ||
@Binding var isPresentingAssetAddView: Bool | ||
|
||
@State private var isShowingAlert = false | ||
@State private var alertMessage = "" | ||
|
||
var onSave: (inout AssetData) -> Void | ||
|
||
var body: some View { | ||
NavigationStack { | ||
AssetEditView(asset: $newAsset) | ||
.toolbar { | ||
ToolbarItem(placement: .cancellationAction) { | ||
Button("Dismiss") { | ||
isPresentingAssetAddView = false | ||
} | ||
} | ||
ToolbarItem(placement: .confirmationAction) { | ||
Button("Add") { | ||
if validateAsset() { | ||
isPresentingAssetAddView = false | ||
onSave(&newAsset) | ||
} else { | ||
isShowingAlert = true | ||
} | ||
} | ||
} | ||
} | ||
} | ||
.alert(isPresented: $isShowingAlert) { | ||
Alert(title: Text("Validation Error"), message: Text(alertMessage), dismissButton: .default(Text("OK"))) | ||
} | ||
} | ||
|
||
func validateAsset() -> Bool { | ||
if newAsset.name.isEmpty { | ||
alertMessage = "Asset name cannot be empty." | ||
return false | ||
} | ||
|
||
// Add more validation logic here if needed (e.g., category selection) | ||
return true | ||
} | ||
} | ||
|
||
#Preview { | ||
AssetAddView( | ||
newAsset: .constant(AssetData()), | ||
isPresentingAssetAddView: .constant(true) | ||
) { newAsset in | ||
// Handle saving in preview | ||
print("New asset: \(newAsset.name)") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// | ||
// AssetDetailView.swift | ||
// MMEX | ||
// | ||
// Created by Lisheng Guan on 2024/9/25. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct AssetDetailView: View { | ||
@Binding var asset: AssetData | ||
let databaseURL: URL | ||
|
||
@State private var editingAsset = AssetData() | ||
@State private var isPresentingEditView = false | ||
@Environment(\.presentationMode) var presentationMode // To dismiss the view | ||
|
||
@State private var isExporting = false | ||
@State private var exportURL: URL? | ||
|
||
@State private var isShowingAlert = false | ||
@State private var alertMessage = "" | ||
|
||
var body: some View { | ||
List { | ||
Section(header: Text("Asset Name")) { | ||
Text("\(asset.name)") | ||
} | ||
|
||
Section(header: Text("Type")) { | ||
Text(asset.type.rawValue) | ||
} | ||
|
||
Section(header: Text("Status")) { | ||
Text(asset.status.rawValue) | ||
} | ||
|
||
Section(header: Text("Value")) { | ||
Text("\(asset.value)") | ||
} | ||
|
||
Section(header: Text("Change")) { | ||
Text(asset.change.rawValue) | ||
} | ||
|
||
Section(header: Text("Change Mode")) { | ||
Text(asset.changeMode.rawValue) | ||
} | ||
|
||
Section(header: Text("Notes")) { | ||
Text(asset.notes) | ||
} | ||
|
||
Button("Delete Asset") { | ||
// Implement delete functionality | ||
} | ||
} | ||
.textSelection(.enabled) | ||
.toolbar { | ||
ToolbarItemGroup(placement: .navigationBarTrailing) { | ||
Button("Edit") { | ||
isPresentingEditView = true | ||
editingAsset = asset | ||
} | ||
// Export button for pasteboard and external storage | ||
Menu { | ||
Button("Copy to Clipboard") { | ||
asset.copyToPasteboard() | ||
} | ||
Button("Export as JSON File") { | ||
isExporting = true | ||
} | ||
} label: { | ||
Image(systemName: "square.and.arrow.up") | ||
} | ||
} | ||
} | ||
.sheet(isPresented: $isPresentingEditView) { | ||
NavigationStack { | ||
AssetEditView(asset: $editingAsset) | ||
.navigationTitle(asset.name) | ||
.toolbar { | ||
ToolbarItem(placement: .cancellationAction) { | ||
Button("Cancel") { | ||
isPresentingEditView = false | ||
} | ||
} | ||
ToolbarItem(placement: .confirmationAction) { | ||
Button("Done") { | ||
if validateAsset() { | ||
isPresentingEditView = false | ||
asset = editingAsset | ||
saveChanges() | ||
} else { | ||
isShowingAlert = true | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
.fileExporter( | ||
isPresented: $isExporting, | ||
document: ExportableEntityDocument(entity: asset), | ||
contentType: .json, | ||
defaultFilename: "\(asset.name)_Asset" | ||
) { result in | ||
switch result { | ||
case .success(let url): | ||
print("File saved to: \(url)") | ||
case .failure(let error): | ||
print("Error exporting file: \(error)") | ||
} | ||
} | ||
.alert(isPresented: $isShowingAlert) { | ||
Alert(title: Text("Validation Error"), message: Text(alertMessage), dismissButton: .default(Text("OK"))) | ||
} | ||
} | ||
|
||
func saveChanges() { | ||
let repository = DataManager(databaseURL: databaseURL).getAssetRepository() // pass URL here | ||
if repository.update(asset) { | ||
// TODO | ||
} else { | ||
// TODO update failure | ||
} | ||
} | ||
|
||
func deleteAsset(){ | ||
let repository = DataManager(databaseURL: databaseURL).getAssetRepository() // pass URL here | ||
if repository.delete(asset) { | ||
// Dismiss the AssetDetailView and go back to the previous view | ||
presentationMode.wrappedValue.dismiss() | ||
} else { | ||
// TODO | ||
// handle deletion failure | ||
} | ||
} | ||
|
||
func validateAsset() -> Bool { | ||
if editingAsset.name.isEmpty { | ||
alertMessage = "Asset name cannot be empty." | ||
return false | ||
} | ||
|
||
// Add more validation logic here if needed (e.g., category selection) | ||
return true | ||
} | ||
} | ||
|
||
#Preview { | ||
AssetDetailView(asset: .constant(AssetData.sampleData[0]), databaseURL: URL(string: "path/to/database")!) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// | ||
// AssetEditView.swift | ||
// MMEX | ||
// | ||
// Created by Lisheng Guan on 2024/9/25. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct AssetEditView: View { | ||
@Binding var asset: AssetData | ||
// @Binding var currencies: [CurrencyData] | ||
|
||
var body: some View { | ||
NavigationStack { | ||
Form { | ||
Section(header: Text("Asset Name")) { | ||
TextField("Enter asset name", text: $asset.name) | ||
} | ||
|
||
Section(header: Text("Type")) { | ||
Picker("Asset Type", selection: $asset.type) { | ||
ForEach(AssetType.allCases, id: \.self) { type in | ||
Text(type.rawValue).tag(type) | ||
} | ||
} | ||
} | ||
|
||
Section(header: Text("Status")) { | ||
Picker("Asset Status", selection: $asset.status) { | ||
ForEach(AssetStatus.allCases, id: \.self) { status in | ||
Text(status.rawValue).tag(status) | ||
} | ||
} | ||
} | ||
|
||
// Section(header: Text("Currency")) { | ||
// Picker("Currency", selection: $asset.currencyId) { | ||
// ForEach(currencyOptions) { currency in | ||
// Text(currency.name).tag(currency.id) | ||
// } | ||
// } | ||
// } | ||
|
||
Section(header: Text("Value")) { | ||
TextField("Enter asset value", value: $asset.value, format: .number) | ||
.keyboardType(.decimalPad) | ||
} | ||
|
||
Section(header: Text("Change")) { | ||
Picker("Change Type", selection: $asset.change) { | ||
ForEach(AssetChange.allCases, id: \.self) { change in | ||
Text(change.rawValue).tag(change) | ||
} | ||
} | ||
|
||
if asset.change != .none { | ||
Picker("Change Mode", selection: $asset.changeMode) { | ||
ForEach(AssetChangeMode.allCases, id: \.self) { mode in | ||
Text(mode.rawValue).tag(mode) | ||
} | ||
} | ||
|
||
TextField("Change Rate", value: $asset.changeRate, format: .number) | ||
.keyboardType(.decimalPad) | ||
} | ||
} | ||
|
||
Section(header: Text("Notes")) { | ||
TextField("Notes", text: $asset.notes) | ||
} | ||
} | ||
.navigationTitle("Edit Asset") | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
AssetEditView(asset: .constant(AssetData.sampleData[0])) | ||
} |
Oops, something went wrong.