changeset 19:94fd7ac93060

Redesign
author Dennis Concepción Martín <dennisconcepcionmartin@gmail.com>
date Sun, 18 Jul 2021 20:00:05 +0100
parents a3512b689bbe
children f8aabe5b7251
files Simoleon.xcodeproj/project.pbxproj Simoleon.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved Simoleon.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate Simoleon/Assets.xcassets/PlainButton.colorset/Contents.json Simoleon/ContentView.swift Simoleon/ContentViewPad.swift Simoleon/Conversion.swift Simoleon/Helpers/ConversionBox.swift Simoleon/Helpers/CurrencyButton.swift Simoleon/Helpers/CurrencyConversion.swift Simoleon/Helpers/CurrencyRow.swift Simoleon/Helpers/CurrencySelector.swift Simoleon/Helpers/SearchBar.swift Simoleon/Helpers/Sidebar.swift Simoleon/Preview Content/CurrencyQuoteData.json Simoleon/Resources/PopularCurrencyPairs.json Simoleon/SimoleonApp.swift
diffstat 17 files changed, 408 insertions(+), 292 deletions(-) [+]
line wrap: on
line diff
--- a/Simoleon.xcodeproj/project.pbxproj	Sun Jul 18 16:43:06 2021 +0100
+++ b/Simoleon.xcodeproj/project.pbxproj	Sun Jul 18 20:00:05 2021 +0100
@@ -7,16 +7,19 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		95559337269B0A7B000FD726 /* CurrencyQuoteData.json in Resources */ = {isa = PBXBuildFile; fileRef = 95559336269B0A7B000FD726 /* CurrencyQuoteData.json */; };
 		9555933A269B0AB8000FD726 /* ParseJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95559339269B0AB8000FD726 /* ParseJson.swift */; };
 		9555933D269B0E0A000FD726 /* CurrencyMetadata.json in Resources */ = {isa = PBXBuildFile; fileRef = 9555933C269B0E0A000FD726 /* CurrencyMetadata.json */; };
 		95AEBC9526A03ECB00613729 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9426A03ECB00613729 /* ContentView.swift */; };
-		95AEBC9726A043C100613729 /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9626A043C100613729 /* SearchBar.swift */; };
 		95AEBC9B26A04A4200613729 /* CurrencyMetadataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9A26A04A4200613729 /* CurrencyMetadataModel.swift */; };
 		95AEBC9D26A04D4600613729 /* CurrencyRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9C26A04D4600613729 /* CurrencyRow.swift */; };
-		95AEBC9F26A08A1C00613729 /* CurrencyConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9E26A08A1C00613729 /* CurrencyConversion.swift */; };
 		95AEBCA326A0900E00613729 /* CurrencyQuoteModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBCA226A0900E00613729 /* CurrencyQuoteModel.swift */; };
-		95AEBCA826A0AE2400613729 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBCA726A0AE2400613729 /* Sidebar.swift */; };
+		95B54F4426A4842C001DC0D8 /* Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F4326A4842C001DC0D8 /* Conversion.swift */; };
+		95B54F4626A48852001DC0D8 /* CurrencySelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F4526A48852001DC0D8 /* CurrencySelector.swift */; };
+		95B54F4826A4954B001DC0D8 /* CurrencyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F4726A4954B001DC0D8 /* CurrencyButton.swift */; };
+		95B54F4A26A4A450001DC0D8 /* ConversionBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F4926A4A450001DC0D8 /* ConversionBox.swift */; };
+		95B54F4D26A4A64F001DC0D8 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 95B54F4C26A4A64F001DC0D8 /* Introspect */; };
+		95B54F4F26A4AC52001DC0D8 /* ContentViewPad.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F4E26A4AC52001DC0D8 /* ContentViewPad.swift */; };
+		95B54F5126A4ACAC001DC0D8 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F5026A4ACAC001DC0D8 /* Sidebar.swift */; };
 		95C02C8B269B61680061DD6D /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 95C02C8A269B61680061DD6D /* Alamofire */; };
 		95C5B2282697752600941585 /* SimoleonApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C5B2272697752600941585 /* SimoleonApp.swift */; };
 		95C5B22C2697752700941585 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 95C5B22B2697752700941585 /* Assets.xcassets */; };
@@ -26,7 +29,6 @@
 		95C5B23F2697752700941585 /* SimoleonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C5B23E2697752700941585 /* SimoleonTests.swift */; };
 		95C5B24A2697752700941585 /* SimoleonUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C5B2492697752700941585 /* SimoleonUITests.swift */; };
 		95DD4ABB269B33810027CA1F /* CurrencyPairs.json in Resources */ = {isa = PBXBuildFile; fileRef = 95DD4ABA269B33810027CA1F /* CurrencyPairs.json */; };
-		95E76432269DF531008E9F31 /* PopularCurrencyPairs.json in Resources */ = {isa = PBXBuildFile; fileRef = 95E76431269DF531008E9F31 /* PopularCurrencyPairs.json */; };
 		95E76436269DFC1A008E9F31 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 95E76435269DFC1A008E9F31 /* LaunchScreen.storyboard */; };
 		95E7643A269E0037008E9F31 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95E76439269E0037008E9F31 /* CloudKit.framework */; };
 /* End PBXBuildFile section */
@@ -49,16 +51,18 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
-		95559336269B0A7B000FD726 /* CurrencyQuoteData.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = CurrencyQuoteData.json; sourceTree = "<group>"; };
 		95559339269B0AB8000FD726 /* ParseJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseJson.swift; sourceTree = "<group>"; };
 		9555933C269B0E0A000FD726 /* CurrencyMetadata.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = CurrencyMetadata.json; sourceTree = "<group>"; };
 		95AEBC9426A03ECB00613729 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
-		95AEBC9626A043C100613729 /* SearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = "<group>"; };
 		95AEBC9A26A04A4200613729 /* CurrencyMetadataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyMetadataModel.swift; sourceTree = "<group>"; };
 		95AEBC9C26A04D4600613729 /* CurrencyRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyRow.swift; sourceTree = "<group>"; };
-		95AEBC9E26A08A1C00613729 /* CurrencyConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyConversion.swift; sourceTree = "<group>"; };
 		95AEBCA226A0900E00613729 /* CurrencyQuoteModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyQuoteModel.swift; sourceTree = "<group>"; };
-		95AEBCA726A0AE2400613729 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; };
+		95B54F4326A4842C001DC0D8 /* Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conversion.swift; sourceTree = "<group>"; };
+		95B54F4526A48852001DC0D8 /* CurrencySelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencySelector.swift; sourceTree = "<group>"; };
+		95B54F4726A4954B001DC0D8 /* CurrencyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyButton.swift; sourceTree = "<group>"; };
+		95B54F4926A4A450001DC0D8 /* ConversionBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversionBox.swift; sourceTree = "<group>"; };
+		95B54F4E26A4AC52001DC0D8 /* ContentViewPad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewPad.swift; sourceTree = "<group>"; };
+		95B54F5026A4ACAC001DC0D8 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; };
 		95C5B2242697752600941585 /* Simoleon.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Simoleon.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		95C5B2272697752600941585 /* SimoleonApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimoleonApp.swift; sourceTree = "<group>"; };
 		95C5B22B2697752700941585 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -73,7 +77,6 @@
 		95C5B2492697752700941585 /* SimoleonUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimoleonUITests.swift; sourceTree = "<group>"; };
 		95C5B24B2697752700941585 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		95DD4ABA269B33810027CA1F /* CurrencyPairs.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = CurrencyPairs.json; sourceTree = "<group>"; };
-		95E76431269DF531008E9F31 /* PopularCurrencyPairs.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = PopularCurrencyPairs.json; sourceTree = "<group>"; };
 		95E76435269DFC1A008E9F31 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
 		95E76437269E0033008E9F31 /* Simoleon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Simoleon.entitlements; sourceTree = "<group>"; };
 		95E76439269E0037008E9F31 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
@@ -85,6 +88,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				95C02C8B269B61680061DD6D /* Alamofire in Frameworks */,
+				95B54F4D26A4A64F001DC0D8 /* Introspect in Frameworks */,
 				95E7643A269E0037008E9F31 /* CloudKit.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -128,7 +132,6 @@
 			children = (
 				9555933C269B0E0A000FD726 /* CurrencyMetadata.json */,
 				95DD4ABA269B33810027CA1F /* CurrencyPairs.json */,
-				95E76431269DF531008E9F31 /* PopularCurrencyPairs.json */,
 			);
 			path = Resources;
 			sourceTree = "<group>";
@@ -160,6 +163,8 @@
 				95E76437269E0033008E9F31 /* Simoleon.entitlements */,
 				95C5B2272697752600941585 /* SimoleonApp.swift */,
 				95AEBC9426A03ECB00613729 /* ContentView.swift */,
+				95B54F4E26A4AC52001DC0D8 /* ContentViewPad.swift */,
+				95B54F4326A4842C001DC0D8 /* Conversion.swift */,
 				95C5B22B2697752700941585 /* Assets.xcassets */,
 				95C5B2302697752700941585 /* Persistence.swift */,
 				95C5B2352697752700941585 /* Info.plist */,
@@ -178,7 +183,6 @@
 			isa = PBXGroup;
 			children = (
 				95C5B22E2697752700941585 /* Preview Assets.xcassets */,
-				95559336269B0A7B000FD726 /* CurrencyQuoteData.json */,
 			);
 			path = "Preview Content";
 			sourceTree = "<group>";
@@ -212,10 +216,11 @@
 		95FE659A269AFB44008745DE /* Helpers */ = {
 			isa = PBXGroup;
 			children = (
-				95AEBC9626A043C100613729 /* SearchBar.swift */,
+				95B54F4726A4954B001DC0D8 /* CurrencyButton.swift */,
+				95B54F4526A48852001DC0D8 /* CurrencySelector.swift */,
 				95AEBC9C26A04D4600613729 /* CurrencyRow.swift */,
-				95AEBC9E26A08A1C00613729 /* CurrencyConversion.swift */,
-				95AEBCA726A0AE2400613729 /* Sidebar.swift */,
+				95B54F4926A4A450001DC0D8 /* ConversionBox.swift */,
+				95B54F5026A4ACAC001DC0D8 /* Sidebar.swift */,
 			);
 			path = Helpers;
 			sourceTree = "<group>";
@@ -238,6 +243,7 @@
 			name = Simoleon;
 			packageProductDependencies = (
 				95C02C8A269B61680061DD6D /* Alamofire */,
+				95B54F4C26A4A64F001DC0D8 /* Introspect */,
 			);
 			productName = Simoleon;
 			productReference = 95C5B2242697752600941585 /* Simoleon.app */;
@@ -312,6 +318,7 @@
 			mainGroup = 95C5B21B2697752600941585;
 			packageReferences = (
 				95C02C89269B61680061DD6D /* XCRemoteSwiftPackageReference "Alamofire" */,
+				95B54F4B26A4A64F001DC0D8 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */,
 			);
 			productRefGroup = 95C5B2252697752600941585 /* Products */;
 			projectDirPath = "";
@@ -329,9 +336,7 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				95559337269B0A7B000FD726 /* CurrencyQuoteData.json in Resources */,
 				95DD4ABB269B33810027CA1F /* CurrencyPairs.json in Resources */,
-				95E76432269DF531008E9F31 /* PopularCurrencyPairs.json in Resources */,
 				95C5B22F2697752700941585 /* Preview Assets.xcassets in Resources */,
 				95E76436269DFC1A008E9F31 /* LaunchScreen.storyboard in Resources */,
 				9555933D269B0E0A000FD726 /* CurrencyMetadata.json in Resources */,
@@ -361,16 +366,19 @@
 			buildActionMask = 2147483647;
 			files = (
 				95C5B2312697752700941585 /* Persistence.swift in Sources */,
-				95AEBC9F26A08A1C00613729 /* CurrencyConversion.swift in Sources */,
 				95AEBC9526A03ECB00613729 /* ContentView.swift in Sources */,
 				95AEBC9B26A04A4200613729 /* CurrencyMetadataModel.swift in Sources */,
 				9555933A269B0AB8000FD726 /* ParseJson.swift in Sources */,
 				95C5B2282697752600941585 /* SimoleonApp.swift in Sources */,
+				95B54F4A26A4A450001DC0D8 /* ConversionBox.swift in Sources */,
 				95AEBC9D26A04D4600613729 /* CurrencyRow.swift in Sources */,
 				95AEBCA326A0900E00613729 /* CurrencyQuoteModel.swift in Sources */,
-				95AEBCA826A0AE2400613729 /* Sidebar.swift in Sources */,
+				95B54F4826A4954B001DC0D8 /* CurrencyButton.swift in Sources */,
+				95B54F4F26A4AC52001DC0D8 /* ContentViewPad.swift in Sources */,
+				95B54F4426A4842C001DC0D8 /* Conversion.swift in Sources */,
 				95C5B2342697752700941585 /* Simoleon.xcdatamodeld in Sources */,
-				95AEBC9726A043C100613729 /* SearchBar.swift in Sources */,
+				95B54F5126A4ACAC001DC0D8 /* Sidebar.swift in Sources */,
+				95B54F4626A48852001DC0D8 /* CurrencySelector.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -696,6 +704,14 @@
 /* End XCConfigurationList section */
 
 /* Begin XCRemoteSwiftPackageReference section */
+		95B54F4B26A4A64F001DC0D8 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/siteline/SwiftUI-Introspect.git";
+			requirement = {
+				kind = upToNextMajorVersion;
+				minimumVersion = 0.1.3;
+			};
+		};
 		95C02C89269B61680061DD6D /* XCRemoteSwiftPackageReference "Alamofire" */ = {
 			isa = XCRemoteSwiftPackageReference;
 			repositoryURL = "https://github.com/Alamofire/Alamofire.git";
@@ -707,6 +723,11 @@
 /* End XCRemoteSwiftPackageReference section */
 
 /* Begin XCSwiftPackageProductDependency section */
+		95B54F4C26A4A64F001DC0D8 /* Introspect */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = 95B54F4B26A4A64F001DC0D8 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */;
+			productName = Introspect;
+		};
 		95C02C8A269B61680061DD6D /* Alamofire */ = {
 			isa = XCSwiftPackageProductDependency;
 			package = 95C02C89269B61680061DD6D /* XCRemoteSwiftPackageReference "Alamofire" */;
--- a/Simoleon.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved	Sun Jul 18 16:43:06 2021 +0100
+++ b/Simoleon.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved	Sun Jul 18 20:00:05 2021 +0100
@@ -9,6 +9,15 @@
           "revision": "f96b619bcb2383b43d898402283924b80e2c4bae",
           "version": "5.4.3"
         }
+      },
+      {
+        "package": "Introspect",
+        "repositoryURL": "https://github.com/siteline/SwiftUI-Introspect.git",
+        "state": {
+          "branch": null,
+          "revision": "2e09be8af614401bc9f87d40093ec19ce56ccaf2",
+          "version": "0.1.3"
+        }
       }
     ]
   },
Binary file Simoleon.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Assets.xcassets/PlainButton.colorset/Contents.json	Sun Jul 18 20:00:05 2021 +0100
@@ -0,0 +1,38 @@
+{
+  "colors" : [
+    {
+      "color" : {
+        "color-space" : "srgb",
+        "components" : {
+          "alpha" : "1.000",
+          "blue" : "0.000",
+          "green" : "0.000",
+          "red" : "0.000"
+        }
+      },
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "color" : {
+        "color-space" : "srgb",
+        "components" : {
+          "alpha" : "1.000",
+          "blue" : "1.000",
+          "green" : "1.000",
+          "red" : "1.000"
+        }
+      },
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}
--- a/Simoleon/ContentView.swift	Sun Jul 18 16:43:06 2021 +0100
+++ b/Simoleon/ContentView.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -8,53 +8,12 @@
 import SwiftUI
 
 struct ContentView: View {
-    @State var searchText = ""
-    @State var searching = false
-    @State private var refreshView = 0
-    let currencyPairs: [String] = parseJson("CurrencyPairs.json")
-    
     var body: some View {
-        VStack {
-            SearchBar(searchText: $searchText, searching: $searching)
-            List(filterCurrencies(), id: \.self) { currency in
-                NavigationLink(destination: CurrencyConversion(currency: currency)) {
-                    CurrencyRow(currency: currency)
-                }
-            }
-            .id(UUID())
-            .listStyle(InsetListStyle())
-            .gesture(DragGesture()
-                .onChanged({ _ in
-                     UIApplication.shared.dismissKeyboard()
-                 })
-            )
-        }
-        .navigationTitle(searching ? "Search" : "Popular currencies")
-        .toolbar {
-             if searching {
-                 Button("Cancel") { searchText = ""
-                     withAnimation {
-                        searching = false
-                        UIApplication.shared.dismissKeyboard()
-                     }
-                 }
-             }
-        }
-    }
-    
-    private func filterCurrencies() -> [String] {
-        if searchText.isEmpty {
-            return currencyPairs
-        } else {
-            return currencyPairs.filter { $0.contains(searchText.uppercased()) }
+        NavigationView {
+            Conversion()
         }
     }
 }
-extension UIApplication {
-      func dismissKeyboard() {
-          sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
-      }
-  }
 
 struct ContentView_Previews: PreviewProvider {
     static var previews: some View {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/ContentViewPad.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -0,0 +1,23 @@
+//
+//  ContentViewPad.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 18/07/2021.
+//
+
+import SwiftUI
+
+struct ContentViewPad: View {
+    var body: some View {
+        NavigationView {
+            Sidebar()
+            Conversion()
+        }
+    }
+}
+
+struct ContentViewPad_Previews: PreviewProvider {
+    static var previews: some View {
+        ContentViewPad()
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Conversion.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -0,0 +1,93 @@
+//
+//  Conversion.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 18/07/2021.
+//
+
+import SwiftUI
+import Alamofire
+
+struct Conversion: View {
+    @State private var mainCurrency = "USD"
+    @State private var secondaryCurrency = "GBP"
+    @State private var amountToConvert = "1000"
+    @State private var price: Double = 1.00
+    @State private var showingConversion = false
+    @State private var showingCurrencySelector = false
+    @State private var selectingMainCurrency = false
+    @State private var currencyPairNotFound = false
+    
+    let currencyMetadata: [String: CurrencyMetadataModel] = parseJson("CurrencyMetadata.json")
+    
+    var body: some View {
+        ScrollView(showsIndicators: false) {
+            VStack(alignment: .leading) {
+                HStack {
+                    Button(action: { selectingMainCurrency = true; showingCurrencySelector = true }) {
+                        CurrencyButton(currency: $mainCurrency)
+                    }
+                    
+                    Button(action: { selectingMainCurrency = false; showingCurrencySelector = true }) {
+                        CurrencyButton(currency: $secondaryCurrency)
+                    }
+                }
+                
+                ConversionBox(
+                    mainCurrency: $mainCurrency,
+                    secondaryCurrency: $secondaryCurrency,
+                    amountToConvert: $amountToConvert,
+                    price: $price,
+                    showingConversion: $showingConversion,
+                    showingCurrencySelector: $showingCurrencySelector,
+                    currencyPairNotFound: $currencyPairNotFound
+                )
+            }
+            .padding()
+            .onAppear { requestApi(mainCurrency, secondaryCurrency) }
+            .onChange(of: showingCurrencySelector, perform: { showingCurrencySelector in
+                if !showingCurrencySelector {
+                    requestApi(mainCurrency, secondaryCurrency)
+                }
+            })
+            .sheet(isPresented: $showingCurrencySelector) {
+                CurrencySelector(
+                    mainCurrencySelected: $mainCurrency,
+                    secondaryCurrencySelected: $secondaryCurrency,
+                    showingCurrencySelector: $showingCurrencySelector,
+                    selectingMainCurrency: $selectingMainCurrency
+                )
+            }
+        }
+        .navigationBarHidden(true)
+    }
+    
+    private func requestApi(_ mainCurrency: String, _ secondaryCurrency: String) {
+        let url = "https://api.1forge.com/quotes?pairs=\(mainCurrency)/\(secondaryCurrency)&api_key=BFWeJQ3jJtqqpDv5ArNis59pAlFcQ4KF"
+        
+        AF.request(url).responseDecodable(of: [CurrencyQuoteModel].self) { response in
+            self.showingConversion = false
+            self.currencyPairNotFound = false
+            
+            if let currencyQuotes = response.value {
+                if let price = currencyQuotes.first?.price {
+                    self.price = price
+                    self.showingConversion =  true
+                } else {
+                    self.currencyPairNotFound = true
+                }
+            } else {
+//               Handle error
+            }
+        }
+    }
+}
+
+
+struct Conversion_Previews: PreviewProvider {
+    static var previews: some View {
+        NavigationView {
+            Conversion()
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Helpers/ConversionBox.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -0,0 +1,85 @@
+//
+//  ConversionBox.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 18/07/2021.
+//
+
+import SwiftUI
+import Introspect
+
+struct ConversionBox: View {
+    @Binding var mainCurrency: String
+    @Binding var secondaryCurrency: String
+    @Binding var amountToConvert: String
+    @Binding var price: Double
+    @Binding var showingConversion: Bool
+    @Binding var showingCurrencySelector: Bool
+    @Binding var currencyPairNotFound: Bool
+    
+    @State private var showingCancelationButton = false
+    
+    let currencyMetadata: [String: CurrencyMetadataModel] = parseJson("CurrencyMetadata.json")
+    
+    var body: some View {
+        VStack(alignment: .leading) {
+            Text("\(currencyMetadata[mainCurrency]!.name) (\(mainCurrency))")
+                .font(.callout)
+                .fontWeight(.semibold)
+                .padding(.top, 40)
+            
+            ZStack(alignment: .trailing) {
+                TextField("Enter amount", text: $amountToConvert)
+                    .keyboardType(.decimalPad)
+                    .font(Font.title.weight(.semibold))
+                    .lineLimit(1)
+                    .padding(.bottom, 10)
+                    .introspectTextField { textField in
+                        if !showingCurrencySelector {
+                            textField.becomeFirstResponder()
+                        }
+                    }
+            }
+            
+            Divider()
+            
+            Text("\(currencyMetadata[secondaryCurrency]!.name) (\(secondaryCurrency))")
+                .font(.callout)
+                .fontWeight(.semibold)
+                .padding(.top, 10)
+            
+            if showingConversion {
+                Text("\(makeConversion(), specifier: "%.2f")")
+                    .font(Font.title.weight(.semibold))
+                    .lineLimit(1)
+                    .padding(.top, 5)
+            } else {
+                if currencyPairNotFound {
+                    Text("The currency pair selected is not supported yet 😢")
+                        .padding(.top, 5)
+                } else {
+                    ProgressView()
+                        .padding(.top, 5)
+                }
+            }
+        }
+    }
+    
+    
+    private func makeConversion() -> Double {
+        if amountToConvert.isEmpty {  /// Avoid nil error when string is empty
+            return 0
+        } else {
+            let conversion = Double(amountToConvert)!  * price
+
+            return conversion
+        }
+    }
+}
+
+
+struct ConversionBox_Previews: PreviewProvider {
+    static var previews: some View {
+        ConversionBox(mainCurrency: .constant("USD"), secondaryCurrency: .constant("GBP"), amountToConvert: .constant("1000"), price: .constant(1), showingConversion: .constant(true), showingCurrencySelector: .constant(false), currencyPairNotFound: .constant(false))
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Helpers/CurrencyButton.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -0,0 +1,39 @@
+//
+//  CurrencyButton.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 18/07/2021.
+//
+
+import SwiftUI
+
+struct CurrencyButton: View {
+    @Binding var currency: String
+    let currencyMetadata: [String: CurrencyMetadataModel] = parseJson("CurrencyMetadata.json")
+    
+    var body: some View {
+        RoundedRectangle(cornerRadius: 25)
+            .foregroundColor(Color(.secondarySystemBackground))
+            .frame(height: 75)
+            .overlay(
+                HStack {
+                    Image(currencyMetadata[currency]!.flag)
+                        .resizable()
+                        .aspectRatio(contentMode: .fill)
+                        .frame(width: 30, height: 30)
+                        .clipShape(Circle())
+                        .overlay(Circle().stroke(Color(.systemGray), lineWidth: 1))
+                    
+                    Text("\(currency)")
+                        .fontWeight(.semibold)
+                        .foregroundColor(Color("PlainButton"))
+                }
+            )
+    }
+}
+
+struct CurrencyButton_Previews: PreviewProvider {
+    static var previews: some View {
+        CurrencyButton(currency: .constant("USD"))
+    }
+}
--- a/Simoleon/Helpers/CurrencyConversion.swift	Sun Jul 18 16:43:06 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-//
-//  CurrencyConversion.swift
-//  Simoleon
-//
-//  Created by Dennis Concepción Martín on 15/07/2021.
-//
-
-import SwiftUI
-import Alamofire
-
-struct CurrencyConversion: View {
-    var currency: String
-    @State private var price: Double = 1.00
-    @State private var amountToConvert = "100"
-    @State private var isEditing = false
-    @State private var showConversion = false
-    let currencyMetadata: [String: CurrencyMetadataModel] = parseJson("CurrencyMetadata.json")
-    
-    var body: some View {
-        let currencies = currency.components(separatedBy: "/")
-        let mainCurrency = String(currencies[0])
-        let secondaryCurrency = String(currencies[1])
-        
-        ScrollView(showsIndicators: false) {
-            VStack(spacing: 20) {
-                ZStack {
-                    Rectangle()
-                       .foregroundColor(Color(.secondarySystemBackground))
-                    
-                    HStack {
-                        Image(currencyMetadata[mainCurrency]!.flag)
-                            .resizable()
-                            .aspectRatio(contentMode: .fill)
-                            .frame(width: 30, height: 30)
-                            .clipShape(Circle())
-                            .overlay(Circle().stroke(Color(.systemGray), lineWidth: 1))
-                        
-                        TextField("Amount", text: $amountToConvert) { startedEditing in
-                            if startedEditing {
-                                withAnimation {
-                                    isEditing = true
-                                }
-                            }
-                        }
-                        onCommit: {
-                             withAnimation {
-                                isEditing = false
-                             }
-                         }
-                        .keyboardType(.decimalPad)
-                        .lineLimit(1)
-                        .padding(.horizontal)
-                        
-                        Text("\(mainCurrency)")
-                            .fontWeight(.semibold)
-                    }
-                    .padding(.horizontal)
-                }
-                .frame(height: 50)
-                .cornerRadius(13)
-                
-                ZStack {
-                    Rectangle()
-                       .foregroundColor(Color(.secondarySystemBackground))
-                    
-                    HStack {
-                        Image(currencyMetadata[secondaryCurrency]!.flag)
-                            .resizable()
-                            .aspectRatio(contentMode: .fill)
-                            .frame(width: 30, height: 30)
-                            .clipShape(Circle())
-                            .overlay(Circle().stroke(Color(.systemGray), lineWidth: 1))
-                        
-                        if showConversion {
-                            Text("\(makeConversion(), specifier: "%.4f")")
-                                .lineLimit(1)
-                                .padding(.horizontal)
-                        } else {
-                            ProgressView()
-                                .padding(.horizontal)
-                        }
-                        
-                        Spacer()
-                        Text("\(secondaryCurrency)")
-                            .fontWeight(.semibold)
-                    }
-                    .padding(.horizontal)
-                }
-                .frame(height: 50)
-                .cornerRadius(13)
-                
-                if showConversion {
-                    Text("From \(currencyMetadata[mainCurrency]!.name) to \(currencyMetadata[secondaryCurrency]!.name) at \(price, specifier: "%.4f") exchange rate.")
-                        .multilineTextAlignment(.center)
-                }
-                
-            }
-            .padding()
-        }
-        .onAppear { requestApi(mainCurrency, secondaryCurrency) }
-        .navigationTitle("Conversion")
-    }
-    
-    private func makeConversion() -> Double {
-        if amountToConvert.isEmpty {  /// Avoid nil error when string is empty
-            return 0
-        } else {
-            let conversion = Double(amountToConvert)!  * price
-
-            return conversion
-        }
-    }
-    
-    private func requestApi(_ mainCurrency: String, _ secondaryCurrency: String) {
-        let url = "https://api.simoleon.app/quotes=\(mainCurrency)-\(secondaryCurrency)"
-        AF.request(url).responseDecodable(of: [CurrencyQuoteModel].self) { response in
-            if let currencyQuotes = response.value {
-                if let price = currencyQuotes[0].price {
-                    self.price = price
-                }
-                self.showConversion = true
-            } else {
-//               Handle error
-            }
-        }
-    }
-}
-
-struct CurrencyConversion_Previews: PreviewProvider {
-    static var previews: some View {
-        NavigationView {
-            CurrencyConversion(currency: "USD/GBP")
-        }
-    }
-}
--- a/Simoleon/Helpers/CurrencyRow.swift	Sun Jul 18 16:43:06 2021 +0100
+++ b/Simoleon/Helpers/CurrencyRow.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -8,48 +8,37 @@
 import SwiftUI
 
 struct CurrencyRow: View {
+    var currency: String
     let currencyMetadata: [String: CurrencyMetadataModel] = parseJson("CurrencyMetadata.json")
-    var currency: String
     
     var body: some View {
-        let currencies = currency.components(separatedBy: "/")
-        let mainCurrency = String(currencies[0])
-        let secondaryCurrency = String(currencies[1])
         HStack {
-            Image(currencyMetadata[mainCurrency]!.flag)
+            Image(currencyMetadata[currency]!.flag)
                 .resizable()
                 .aspectRatio(contentMode: .fill)
                 .frame(width: 30, height: 30)
                 .clipShape(Circle())
                 .overlay(Circle().stroke(Color(.systemGray), lineWidth: 1))
             
-            Image(currencyMetadata[secondaryCurrency]!.flag)
-                .resizable()
-                .aspectRatio(contentMode: .fill)
-                .frame(width: 30, height: 30)
-                .clipShape(Circle())
-                .overlay(Circle().stroke(Color(.systemGray), lineWidth: 1))
-                .offset(x: -20)
-                .padding(.trailing, -20)
-            
             VStack(alignment: .leading) {
                 Text("\(currency)")
                     .fontWeight(.semibold)
+                    .foregroundColor(Color("PlainButton"))
                 
-                Text("\(currencyMetadata[mainCurrency]!.name)/\(currencyMetadata[secondaryCurrency]!.name)")
+                Text("\(currencyMetadata[currency]!.name)")
                     .font(.footnote)
                     .fontWeight(.semibold)
+                    .foregroundColor(Color("PlainButton"))
                     .opacity(0.5)
                     .lineLimit(1)
             }
             .padding(.horizontal)
         }
-        .padding(.vertical, 7)
     }
 }
 
 struct CurrencyRow_Previews: PreviewProvider {
     static var previews: some View {
-        CurrencyRow(currency: "USD/GBP")
+        CurrencyRow(currency: "USD")
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Helpers/CurrencySelector.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -0,0 +1,65 @@
+//
+//  CurrencySelector.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 18/07/2021.
+//
+
+import SwiftUI
+
+struct CurrencySelector: View {
+    @Binding var mainCurrencySelected: String
+    @Binding var secondaryCurrencySelected: String
+    @Binding var showingCurrencySelector: Bool
+    @Binding var selectingMainCurrency: Bool
+    
+    var body: some View {
+        NavigationView {
+            Form {
+                ForEach(generateCurrencyList(), id: \.self) { currency in
+                    Button(action: { select(currency) }) {
+                        CurrencyRow(currency: currency)
+                    }
+                }
+            }
+            .navigationTitle("Currencies")
+            .navigationBarTitleDisplayMode(.inline)
+            .toolbar {
+                ToolbarItem(placement: .confirmationAction) {
+                    Button("OK", action: { showingCurrencySelector = false })
+                }
+            }
+        }
+    }
+    
+    private func generateCurrencyList() -> [String] {
+        let currencyPairs: [String] = parseJson("CurrencyPairs.json")
+        var currencies: [String] = []
+        
+        for currencyPair in currencyPairs {
+            let splittedCurrencies = currencyPair.split(separator: "/")
+            let mainCurrency = String(splittedCurrencies[0])
+            if !currencies.contains(mainCurrency) {
+                currencies.append(mainCurrency)
+            }
+        }
+        
+        return currencies
+    }
+    
+    private func select(_ currency: String) {
+        if selectingMainCurrency {
+            self.mainCurrencySelected = currency
+        } else {
+            self.secondaryCurrencySelected = currency
+        }
+        
+        showingCurrencySelector = false
+    }
+}
+
+struct CurrencySelector_Previews: PreviewProvider {
+    static var previews: some View {
+        CurrencySelector(mainCurrencySelected: .constant(""), secondaryCurrencySelected: .constant(""), showingCurrencySelector: .constant(false), selectingMainCurrency: .constant(true))
+    }
+}
--- a/Simoleon/Helpers/SearchBar.swift	Sun Jul 18 16:43:06 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-//
-//  SearchBar.swift
-//  Simoleon
-//
-//  Created by Dennis Concepción Martín on 15/07/2021.
-//
-
-import SwiftUI
-
-struct SearchBar: View {
-    @Binding var searchText: String
-    @Binding var searching: Bool
-    
-    var body: some View {
-        ZStack {
-            Rectangle()
-               .foregroundColor(Color(.secondarySystemBackground))
-            
-             HStack {
-                Image(systemName: "magnifyingglass")
-                TextField("Search ..", text: $searchText) { startedEditing in
-                    if startedEditing {
-                        withAnimation {
-                            searching = true
-                        }
-                    }
-                }
-                onCommit: {
-                     withAnimation {
-                         searching = false
-                     }
-                 }
-             }
-             .padding(.leading, 13)
-            
-         }
-        .frame(height: 40)
-        .cornerRadius(13)
-        .padding()
-    }
-}
-
-struct SearchBar_Previews: PreviewProvider {
-    static var previews: some View {
-        SearchBar(searchText: .constant(""), searching: .constant(false))
-    }
-}
--- a/Simoleon/Helpers/Sidebar.swift	Sun Jul 18 16:43:06 2021 +0100
+++ b/Simoleon/Helpers/Sidebar.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -2,7 +2,7 @@
 //  Sidebar.swift
 //  Simoleon
 //
-//  Created by Dennis Concepción Martín on 15/07/2021.
+//  Created by Dennis Concepción Martín on 18/07/2021.
 //
 
 import SwiftUI
@@ -10,12 +10,11 @@
 struct Sidebar: View {
     var body: some View {
         List {
-            NavigationLink(destination: ContentView()) {
-                Text("Popular currencies")
+            NavigationLink(destination: Conversion()) {
+                Label("Convert", systemImage: "glass")
             }
         }
         .listStyle(SidebarListStyle())
-        .navigationBarTitle("Categories")
     }
 }
 
--- a/Simoleon/Preview Content/CurrencyQuoteData.json	Sun Jul 18 16:43:06 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-{
-    "p": 1.39011,
-    "a": 1.39016,
-    "b": 1.39006,
-    "s": "GBP/USD",
-    "t": 1625864399283
-}
-
--- a/Simoleon/Resources/PopularCurrencyPairs.json	Sun Jul 18 16:43:06 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-[
-    "EUR/USD",
-    "USD/JPY",
-    "USD/GBP",
-    "USD/CHF",
-    "USD/CAD",
-    "AUD/USD",
-    "NZD/USD"
-]
--- a/Simoleon/SimoleonApp.swift	Sun Jul 18 16:43:06 2021 +0100
+++ b/Simoleon/SimoleonApp.swift	Sun Jul 18 20:00:05 2021 +0100
@@ -14,16 +14,11 @@
     var body: some Scene {
         WindowGroup {
             if UIDevice.current.userInterfaceIdiom == .pad {
-                NavigationView {
-                    Sidebar()
-                    ContentView()
-                    CurrencyConversion(currency: "EUR/USD")
-                }
+                ContentViewPad()
+                    .environment(\.managedObjectContext, persistenceController.container.viewContext)
             } else {
-                NavigationView {
-                    ContentView()
-                        .environment(\.managedObjectContext, persistenceController.container.viewContext)
-                }
+                ContentView()
+                    .environment(\.managedObjectContext, persistenceController.container.viewContext)
             }
         }
     }