Browse Source

Added history page and color filter

Víctor Hernández 3 years ago
parent
commit
19863e9e89

+ 37
- 5
Flowerdex/Flowerdex.xcodeproj/project.pbxproj View File

13
 		A52FB5C42546C2EA000AD235 /* rawResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = A52FB5C32546C2EA000AD235 /* rawResponse.json */; };
13
 		A52FB5C42546C2EA000AD235 /* rawResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = A52FB5C32546C2EA000AD235 /* rawResponse.json */; };
14
 		A5711B8B255CE03000E727BB /* Flower.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5711B8A255CE03000E727BB /* Flower.swift */; };
14
 		A5711B8B255CE03000E727BB /* Flower.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5711B8A255CE03000E727BB /* Flower.swift */; };
15
 		A5711B8E255CE53900E727BB /* DummyData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5711B8D255CE53900E727BB /* DummyData.swift */; };
15
 		A5711B8E255CE53900E727BB /* DummyData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5711B8D255CE53900E727BB /* DummyData.swift */; };
16
+		A5799DB02591390D003E975D /* HistoryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5799DAF2591390D003E975D /* HistoryService.swift */; };
17
+		A5799DB4259157AC003E975D /* FlowerVerbose.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5799DB3259157AC003E975D /* FlowerVerbose.swift */; };
18
+		A5799DB72591594D003E975D /* HistoryResponseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5799DB62591594D003E975D /* HistoryResponseModel.swift */; };
19
+		A5799DBB25915C2B003E975D /* FlowerVerboseDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5799DBA25915C2B003E975D /* FlowerVerboseDetailView.swift */; };
16
 		A58640BA258F30AD00F626AB /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58640B9258F30AD00F626AB /* LoginView.swift */; };
20
 		A58640BA258F30AD00F626AB /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58640B9258F30AD00F626AB /* LoginView.swift */; };
17
 		A58640BE258F30F200F626AB /* RegisterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58640BD258F30F200F626AB /* RegisterView.swift */; };
21
 		A58640BE258F30F200F626AB /* RegisterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58640BD258F30F200F626AB /* RegisterView.swift */; };
18
 		A59A2741254556880052319F /* FlowerdexApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59A2740254556880052319F /* FlowerdexApp.swift */; };
22
 		A59A2741254556880052319F /* FlowerdexApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59A2740254556880052319F /* FlowerdexApp.swift */; };
24
 		A5EA2F28258FEC3D00699182 /* FlowerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EA2F27258FEC3D00699182 /* FlowerService.swift */; };
28
 		A5EA2F28258FEC3D00699182 /* FlowerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EA2F27258FEC3D00699182 /* FlowerService.swift */; };
25
 		A5EA2F2C258FF0BD00699182 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EA2F2B258FF0BD00699182 /* Constants.swift */; };
29
 		A5EA2F2C258FF0BD00699182 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EA2F2B258FF0BD00699182 /* Constants.swift */; };
26
 		A5EA2F32258FF58200699182 /* Responses.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EA2F31258FF58200699182 /* Responses.swift */; };
30
 		A5EA2F32258FF58200699182 /* Responses.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EA2F31258FF58200699182 /* Responses.swift */; };
31
+		A5EA2F3A2590A62D00699182 /* HistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EA2F392590A62D00699182 /* HistoryView.swift */; };
32
+		A5EA2F3F2590A65A00699182 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EA2F3E2590A65A00699182 /* MainView.swift */; };
27
 		A5EE388D2576362B0014D0BE /* FilterFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EE388C2576362B0014D0BE /* FilterFields.swift */; };
33
 		A5EE388D2576362B0014D0BE /* FilterFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EE388C2576362B0014D0BE /* FilterFields.swift */; };
28
 		A5EE389125763D3A0014D0BE /* AuthenticationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EE389025763D3A0014D0BE /* AuthenticationModel.swift */; };
34
 		A5EE389125763D3A0014D0BE /* AuthenticationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EE389025763D3A0014D0BE /* AuthenticationModel.swift */; };
29
 		A5EE3897257658400014D0BE /* Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EE3896257658400014D0BE /* Filters.swift */; };
35
 		A5EE3897257658400014D0BE /* Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EE3896257658400014D0BE /* Filters.swift */; };
42
 		A52FB5C32546C2EA000AD235 /* rawResponse.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = rawResponse.json; sourceTree = "<group>"; };
48
 		A52FB5C32546C2EA000AD235 /* rawResponse.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = rawResponse.json; sourceTree = "<group>"; };
43
 		A5711B8A255CE03000E727BB /* Flower.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Flower.swift; sourceTree = "<group>"; };
49
 		A5711B8A255CE03000E727BB /* Flower.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Flower.swift; sourceTree = "<group>"; };
44
 		A5711B8D255CE53900E727BB /* DummyData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DummyData.swift; sourceTree = "<group>"; };
50
 		A5711B8D255CE53900E727BB /* DummyData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DummyData.swift; sourceTree = "<group>"; };
51
+		A5799DAF2591390D003E975D /* HistoryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryService.swift; sourceTree = "<group>"; };
52
+		A5799DB3259157AC003E975D /* FlowerVerbose.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowerVerbose.swift; sourceTree = "<group>"; };
53
+		A5799DB62591594D003E975D /* HistoryResponseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryResponseModel.swift; sourceTree = "<group>"; };
54
+		A5799DBA25915C2B003E975D /* FlowerVerboseDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowerVerboseDetailView.swift; sourceTree = "<group>"; };
45
 		A58640B9258F30AD00F626AB /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
55
 		A58640B9258F30AD00F626AB /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
46
 		A58640BD258F30F200F626AB /* RegisterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterView.swift; sourceTree = "<group>"; };
56
 		A58640BD258F30F200F626AB /* RegisterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterView.swift; sourceTree = "<group>"; };
47
 		A59A273D254556880052319F /* Flowerdex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Flowerdex.app; sourceTree = BUILT_PRODUCTS_DIR; };
57
 		A59A273D254556880052319F /* Flowerdex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Flowerdex.app; sourceTree = BUILT_PRODUCTS_DIR; };
55
 		A5EA2F27258FEC3D00699182 /* FlowerService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowerService.swift; sourceTree = "<group>"; };
65
 		A5EA2F27258FEC3D00699182 /* FlowerService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowerService.swift; sourceTree = "<group>"; };
56
 		A5EA2F2B258FF0BD00699182 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
66
 		A5EA2F2B258FF0BD00699182 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
57
 		A5EA2F31258FF58200699182 /* Responses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Responses.swift; sourceTree = "<group>"; };
67
 		A5EA2F31258FF58200699182 /* Responses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Responses.swift; sourceTree = "<group>"; };
68
+		A5EA2F392590A62D00699182 /* HistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = "<group>"; };
69
+		A5EA2F3E2590A65A00699182 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
58
 		A5EE388C2576362B0014D0BE /* FilterFields.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterFields.swift; sourceTree = "<group>"; };
70
 		A5EE388C2576362B0014D0BE /* FilterFields.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterFields.swift; sourceTree = "<group>"; };
59
 		A5EE389025763D3A0014D0BE /* AuthenticationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationModel.swift; sourceTree = "<group>"; };
71
 		A5EE389025763D3A0014D0BE /* AuthenticationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationModel.swift; sourceTree = "<group>"; };
60
 		A5EE3896257658400014D0BE /* Filters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filters.swift; sourceTree = "<group>"; };
72
 		A5EE3896257658400014D0BE /* Filters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filters.swift; sourceTree = "<group>"; };
81
 			isa = PBXGroup;
93
 			isa = PBXGroup;
82
 			children = (
94
 			children = (
83
 				A51B4F762546674C002AFF05 /* FlowersResponseModel.swift */,
95
 				A51B4F762546674C002AFF05 /* FlowersResponseModel.swift */,
96
+				A5799DB62591594D003E975D /* HistoryResponseModel.swift */,
97
+				A5EE389025763D3A0014D0BE /* AuthenticationModel.swift */,
98
+				A5799DB3259157AC003E975D /* FlowerVerbose.swift */,
84
 				A5711B8A255CE03000E727BB /* Flower.swift */,
99
 				A5711B8A255CE03000E727BB /* Flower.swift */,
85
 				A5EE3896257658400014D0BE /* Filters.swift */,
100
 				A5EE3896257658400014D0BE /* Filters.swift */,
86
-				A5EE389025763D3A0014D0BE /* AuthenticationModel.swift */,
87
 				A5F0D2FB258F3D2200AF735C /* User.swift */,
101
 				A5F0D2FB258F3D2200AF735C /* User.swift */,
88
 			);
102
 			);
89
 			path = Model;
103
 			path = Model;
102
 		A5711B85255CCC1700E727BB /* View */ = {
116
 		A5711B85255CCC1700E727BB /* View */ = {
103
 			isa = PBXGroup;
117
 			isa = PBXGroup;
104
 			children = (
118
 			children = (
105
-				A58640AE258F213600F626AB /* Authentication */,
119
+				A58640AE258F213600F626AB /* Authentication Page */,
106
 				A5EE38B6257819AA0014D0BE /* Discover Page */,
120
 				A5EE38B6257819AA0014D0BE /* Discover Page */,
121
+				A5EA2F382590A61000699182 /* History Page */,
122
+				A5EA2F3E2590A65A00699182 /* MainView.swift */,
107
 				A5EE38B2257818BE0014D0BE /* StatusIcons.swift */,
123
 				A5EE38B2257818BE0014D0BE /* StatusIcons.swift */,
108
 			);
124
 			);
109
 			path = View;
125
 			path = View;
110
 			sourceTree = "<group>";
126
 			sourceTree = "<group>";
111
 		};
127
 		};
112
-		A58640AE258F213600F626AB /* Authentication */ = {
128
+		A58640AE258F213600F626AB /* Authentication Page */ = {
113
 			isa = PBXGroup;
129
 			isa = PBXGroup;
114
 			children = (
130
 			children = (
115
 				A58640B9258F30AD00F626AB /* LoginView.swift */,
131
 				A58640B9258F30AD00F626AB /* LoginView.swift */,
116
 				A58640BD258F30F200F626AB /* RegisterView.swift */,
132
 				A58640BD258F30F200F626AB /* RegisterView.swift */,
117
 			);
133
 			);
118
-			path = Authentication;
134
+			path = "Authentication Page";
119
 			sourceTree = "<group>";
135
 			sourceTree = "<group>";
120
 		};
136
 		};
121
 		A59A2734254556870052319F = {
137
 		A59A2734254556870052319F = {
162
 			isa = PBXGroup;
178
 			isa = PBXGroup;
163
 			children = (
179
 			children = (
164
 				A50EEFCC255D175400545CFE /* ContentDataSource.swift */,
180
 				A50EEFCC255D175400545CFE /* ContentDataSource.swift */,
181
+				A5EE38A3257700230014D0BE /* ImageManager.swift */,
165
 				A5EA2F23258FEC2300699182 /* AuthenticationService.swift */,
182
 				A5EA2F23258FEC2300699182 /* AuthenticationService.swift */,
166
 				A5EA2F27258FEC3D00699182 /* FlowerService.swift */,
183
 				A5EA2F27258FEC3D00699182 /* FlowerService.swift */,
167
-				A5EE38A3257700230014D0BE /* ImageManager.swift */,
184
+				A5799DAF2591390D003E975D /* HistoryService.swift */,
168
 			);
185
 			);
169
 			path = Services;
186
 			path = Services;
170
 			sourceTree = "<group>";
187
 			sourceTree = "<group>";
178
 			path = Supporting;
195
 			path = Supporting;
179
 			sourceTree = "<group>";
196
 			sourceTree = "<group>";
180
 		};
197
 		};
198
+		A5EA2F382590A61000699182 /* History Page */ = {
199
+			isa = PBXGroup;
200
+			children = (
201
+				A5EA2F392590A62D00699182 /* HistoryView.swift */,
202
+				A5799DBA25915C2B003E975D /* FlowerVerboseDetailView.swift */,
203
+			);
204
+			path = "History Page";
205
+			sourceTree = "<group>";
206
+		};
181
 		A5EE38B6257819AA0014D0BE /* Discover Page */ = {
207
 		A5EE38B6257819AA0014D0BE /* Discover Page */ = {
182
 			isa = PBXGroup;
208
 			isa = PBXGroup;
183
 			children = (
209
 			children = (
263
 			buildActionMask = 2147483647;
289
 			buildActionMask = 2147483647;
264
 			files = (
290
 			files = (
265
 				A50EEFCD255D175400545CFE /* ContentDataSource.swift in Sources */,
291
 				A50EEFCD255D175400545CFE /* ContentDataSource.swift in Sources */,
292
+				A5EA2F3F2590A65A00699182 /* MainView.swift in Sources */,
266
 				A5EA2F2C258FF0BD00699182 /* Constants.swift in Sources */,
293
 				A5EA2F2C258FF0BD00699182 /* Constants.swift in Sources */,
267
 				A59A2743254556880052319F /* DiscoverView.swift in Sources */,
294
 				A59A2743254556880052319F /* DiscoverView.swift in Sources */,
268
 				A5EE389125763D3A0014D0BE /* AuthenticationModel.swift in Sources */,
295
 				A5EE389125763D3A0014D0BE /* AuthenticationModel.swift in Sources */,
269
 				A5EE38A4257700230014D0BE /* ImageManager.swift in Sources */,
296
 				A5EE38A4257700230014D0BE /* ImageManager.swift in Sources */,
270
 				A5EE38B0257818520014D0BE /* FlowersList.swift in Sources */,
297
 				A5EE38B0257818520014D0BE /* FlowersList.swift in Sources */,
298
+				A5799DB02591390D003E975D /* HistoryService.swift in Sources */,
299
+				A5EA2F3A2590A62D00699182 /* HistoryView.swift in Sources */,
271
 				A51B4F772546674C002AFF05 /* FlowersResponseModel.swift in Sources */,
300
 				A51B4F772546674C002AFF05 /* FlowersResponseModel.swift in Sources */,
272
 				A5EE3897257658400014D0BE /* Filters.swift in Sources */,
301
 				A5EE3897257658400014D0BE /* Filters.swift in Sources */,
273
 				A5711B8B255CE03000E727BB /* Flower.swift in Sources */,
302
 				A5711B8B255CE03000E727BB /* Flower.swift in Sources */,
274
 				A59A2741254556880052319F /* FlowerdexApp.swift in Sources */,
303
 				A59A2741254556880052319F /* FlowerdexApp.swift in Sources */,
304
+				A5799DB72591594D003E975D /* HistoryResponseModel.swift in Sources */,
275
 				A5EA2F32258FF58200699182 /* Responses.swift in Sources */,
305
 				A5EA2F32258FF58200699182 /* Responses.swift in Sources */,
306
+				A5799DBB25915C2B003E975D /* FlowerVerboseDetailView.swift in Sources */,
276
 				A58640BE258F30F200F626AB /* RegisterView.swift in Sources */,
307
 				A58640BE258F30F200F626AB /* RegisterView.swift in Sources */,
277
 				A5EE388D2576362B0014D0BE /* FilterFields.swift in Sources */,
308
 				A5EE388D2576362B0014D0BE /* FilterFields.swift in Sources */,
278
 				A5F3271A25460C0B003BCE0F /* FlowerDetailView.swift in Sources */,
309
 				A5F3271A25460C0B003BCE0F /* FlowerDetailView.swift in Sources */,
284
 				A5F0D2FC258F3D2200AF735C /* User.swift in Sources */,
315
 				A5F0D2FC258F3D2200AF735C /* User.swift in Sources */,
285
 				A5EE38AC257772200014D0BE /* FiltersSheet.swift in Sources */,
316
 				A5EE38AC257772200014D0BE /* FiltersSheet.swift in Sources */,
286
 				A5EA2F28258FEC3D00699182 /* FlowerService.swift in Sources */,
317
 				A5EA2F28258FEC3D00699182 /* FlowerService.swift in Sources */,
318
+				A5799DB4259157AC003E975D /* FlowerVerbose.swift in Sources */,
287
 			);
319
 			);
288
 			runOnlyForDeploymentPostprocessing = 0;
320
 			runOnlyForDeploymentPostprocessing = 0;
289
 		};
321
 		};

BIN
Flowerdex/Flowerdex.xcodeproj/project.xcworkspace/xcuserdata/victor.hernandez.xcuserdatad/UserInterfaceState.xcuserstate View File


+ 3
- 1
Flowerdex/Flowerdex/FlowerdexApp.swift View File

12
     @StateObject var lm = LoginModel()
12
     @StateObject var lm = LoginModel()
13
     @StateObject var rm = RegistrationModel()
13
     @StateObject var rm = RegistrationModel()
14
     @StateObject var fm = FlowerService()
14
     @StateObject var fm = FlowerService()
15
+    @StateObject var hm = HistoryService()
15
     var body: some Scene {
16
     var body: some Scene {
16
         WindowGroup {
17
         WindowGroup {
17
             if User.exists() {
18
             if User.exists() {
18
-                DiscoverView()
19
+                MainView()
19
                     .environmentObject(fm)
20
                     .environmentObject(fm)
21
+                    .environmentObject(hm)
20
             } else {
22
             } else {
21
                 LoginView()
23
                 LoginView()
22
                     .environmentObject(lm)
24
                     .environmentObject(lm)

+ 3
- 1
Flowerdex/Flowerdex/Model/Filters.swift View File

16
     var bloomMonths: Int
16
     var bloomMonths: Int
17
     var scientificName: String
17
     var scientificName: String
18
     var commonName: String
18
     var commonName: String
19
+    var flowerColor: String
19
     
20
     
20
-    init(edible: Bool, vegetable: Bool, petalCount: Int, growthMonths: Int, bloomMonths: Int, scientificName: String, commonName: String) {
21
+    init(edible: Bool, vegetable: Bool, petalCount: Int, growthMonths: Int, bloomMonths: Int, scientificName: String, commonName: String, flowerColor: String) {
21
         self.edible = edible
22
         self.edible = edible
22
         self.vegetable = vegetable
23
         self.vegetable = vegetable
23
         self.petalCount = petalCount
24
         self.petalCount = petalCount
25
         self.bloomMonths = bloomMonths
26
         self.bloomMonths = bloomMonths
26
         self.scientificName = scientificName
27
         self.scientificName = scientificName
27
         self.commonName = commonName
28
         self.commonName = commonName
29
+        self.flowerColor = flowerColor
28
     }
30
     }
29
     
31
     
30
 }
32
 }

+ 21
- 15
Flowerdex/Flowerdex/Model/Flower.swift View File

9
 
9
 
10
 struct Flower: Hashable, Codable, Identifiable {
10
 struct Flower: Hashable, Codable, Identifiable {
11
     let id: Int
11
     let id: Int
12
+    
12
     let common_name: String?
13
     let common_name: String?
13
     var commonName: String {
14
     var commonName: String {
14
         if let cm = common_name {
15
         if let cm = common_name {
17
             return scientificName
18
             return scientificName
18
         }
19
         }
19
     }
20
     }
21
+    
20
     let slug: String // *
22
     let slug: String // *
23
+    
21
     let scientific_name: String
24
     let scientific_name: String
22
     var scientificName: String { scientific_name }
25
     var scientificName: String { scientific_name }
26
+    
27
+    let image_url: String?
28
+    var imageURL: String {
29
+        if let iu = image_url {
30
+            return iu
31
+        } else {
32
+            return "[Image URL]"
33
+        }
34
+    }
35
+    
23
     let year: Int?
36
     let year: Int?
24
     let bibliography: String?
37
     let bibliography: String?
25
     let author: String? // *
38
     let author: String? // *
26
-    let status: String // *
27
-    let rank: String // *
39
+    
28
     let family_common_name: String?
40
     let family_common_name: String?
29
     var familyCommonName: String {
41
     var familyCommonName: String {
30
         if let fcn = family_common_name {
42
         if let fcn = family_common_name {
33
             return "[Family Common Name]"
45
             return "[Family Common Name]"
34
         }
46
         }
35
     }
47
     }
48
+    
36
     let genus_id: Int // *
49
     let genus_id: Int // *
37
     var genusID: Int { genus_id }
50
     var genusID: Int { genus_id }
38
-    let image_url: String?
39
-    var imageURL: String {
40
-        if let iu = image_url {
41
-            return iu
42
-        } else {
43
-            return "[Image URL]"
44
-        }
45
-    }
51
+    
52
+    let status: String // *
53
+    let rank: String // *
46
     let synonyms: [String]
54
     let synonyms: [String]
47
     let genus: String
55
     let genus: String
48
     let family: String
56
     let family: String
49
-    let links: Dictionary<String, String> // FlowerLinks
57
+    let links: FlowerLinks
50
     
58
     
51
     // Properties added by us
59
     // Properties added by us
52
     let isFavorite: Bool
60
     let isFavorite: Bool
53
     let hasBeenFound: Bool
61
     let hasBeenFound: Bool
54
 }
62
 }
55
 
63
 
56
-/*
57
-struct FlowerLinks: Codable {
58
-    // let self: String
64
+struct FlowerLinks: Codable, Hashable {
65
+     let `self`: String
59
     let plant: String
66
     let plant: String
60
     let genus: String
67
     let genus: String
61
 }
68
 }
62
-*/

+ 111
- 0
Flowerdex/Flowerdex/Model/FlowerVerbose.swift View File

1
+//
2
+//  FlowerVerbose.swift
3
+//  Flowerdex
4
+//
5
+//  Created by Víctor A. Hernández on 12/21/20.
6
+//
7
+
8
+import Foundation
9
+
10
+struct FlowerVerbose: Hashable, Identifiable, Codable {
11
+    let id: Int
12
+    
13
+    let common_name: String?
14
+    var commonName: String {
15
+        if let cm = common_name {
16
+            return cm
17
+        } else {
18
+            return scientificName
19
+        }
20
+    }
21
+    
22
+    let slug: String // *
23
+    
24
+    let scientific_name: String
25
+    var scientificName: String { scientific_name }
26
+    
27
+    let image_url: String?
28
+    var imageURL: String {
29
+        if let iu = image_url {
30
+            return iu
31
+        } else {
32
+            return "[Image URL]"
33
+        }
34
+    }
35
+    
36
+    let year: Int?
37
+    let bibliography: String?
38
+    let author: String? // *
39
+    
40
+    let family_common_name: String?
41
+    var familyCommonName: String {
42
+        if let fcn = family_common_name {
43
+            return fcn
44
+        } else {
45
+            return "[Family Common Name]"
46
+        }
47
+    }
48
+    
49
+    let genus_id: Int // *
50
+    var genusID: Int { genus_id }
51
+    
52
+    let observations: String? // new
53
+    let vegetable: Bool? // new
54
+    let links: FlowerLinks
55
+    let genus: GenusVerbose? // changed
56
+    let family: FamilyVerbose? // changed
57
+    let species: [Flower]? // new
58
+    
59
+//    let subspecies: []
60
+//    let varieties: []
61
+//    let hybrids: []
62
+//    let forms : []
63
+//    let subvarieties: []
64
+//    let sources: []
65
+    
66
+    // Properties added by us
67
+    let isFavorite: Bool
68
+    let hasBeenFound: Bool
69
+}
70
+
71
+struct GenusVerbose: Codable, Hashable, Identifiable {
72
+    let id: Int
73
+    let name: String
74
+    let slug: String
75
+    let links: FlowerLinks
76
+}
77
+
78
+struct FamilyVerbose: Codable, Hashable, Identifiable {
79
+    let id: Int
80
+    let name: String
81
+    let common_name: String
82
+    let slug: String
83
+    let links: FlowerLinks
84
+}
85
+
86
+/*
87
+ "id": 238331,
88
+ "common_name": null,
89
+ "slug": "senecio-gamolepis",
90
+ "scientific_name": "Senecio gamolepis",
91
+ "main_species_id": 273225,
92
+ "image_url": null,
93
+ "year": 1955,
94
+ "bibliography": "Notas Mus. La Plata, Bot. 18(89): 222 (1955)",
95
+ "author": "Cabrera",
96
+ "family_common_name": "Aster family",
97
+ "genus_id": 669,
98
+ "observations": "Peru",
99
+ "vegetable": false,
100
+ "links": {},
101
+ "main_species": {},
102
+ "genus": {},
103
+ "family": {},
104
+ "species": [],
105
+ "subspecies": [ ],
106
+ "varieties": [ ],
107
+ "hybrids": [ ],
108
+ "forms": [ ],
109
+ "subvarieties": [ ],
110
+ "sources": []
111
+ */

+ 13
- 0
Flowerdex/Flowerdex/Model/HistoryResponseModel.swift View File

1
+//
2
+//  HistoryResponseModel.swift
3
+//  Flowerdex
4
+//
5
+//  Created by Víctor A. Hernández on 12/21/20.
6
+//
7
+
8
+import Foundation
9
+
10
+struct HistoryResponseModel: Hashable, Codable {
11
+    let data: [FlowerVerbose]?
12
+    let error: String?
13
+}

+ 7
- 3
Flowerdex/Flowerdex/Services/FlowerService.swift View File

20
         list.append(URLQueryItem(name: "vegetable", value: "\(filters.vegetable)"))
20
         list.append(URLQueryItem(name: "vegetable", value: "\(filters.vegetable)"))
21
         
21
         
22
         if filters.commonName != "" {
22
         if filters.commonName != "" {
23
-            list.append(URLQueryItem(name: "q", value: filters.commonName))
23
+            list.append(URLQueryItem(name: "q", value: filters.commonName.lowercased()))
24
         }
24
         }
25
-//        list.append(URLQueryItem(name: "common_name", value: filters.commonName)) // if common_name was empty, which didn't make sense
25
+//        list.append(URLQueryItem(name: "common_name", value: filters.commonName.lowercased())) // if common_name was empty, which didn't make sense
26
         
26
         
27
 
27
 
28
         if filters.scientificName != "" {
28
         if filters.scientificName != "" {
29
-            list.append(URLQueryItem(name: "scientific_name", value: filters.scientificName))
29
+            list.append(URLQueryItem(name: "scientific_name", value: filters.scientificName.lowercased()))
30
         }
30
         }
31
         
31
         
32
         if filters.growthMonths > 0 {
32
         if filters.growthMonths > 0 {
37
             list.append(URLQueryItem(name: "bloom_months", value: "\(filters.bloomMonths)"))
37
             list.append(URLQueryItem(name: "bloom_months", value: "\(filters.bloomMonths)"))
38
         }
38
         }
39
         
39
         
40
+        if filters.flowerColor != "" {
41
+            list.append(URLQueryItem(name: "flower_color", value: filters.flowerColor.lowercased()))
42
+        }
43
+        
40
         return list
44
         return list
41
         
45
         
42
     }
46
     }

+ 100
- 0
Flowerdex/Flowerdex/Services/HistoryService.swift View File

1
+//
2
+//  HistoryService.swift
3
+//  Flowerdex
4
+//
5
+//  Created by Víctor A. Hernández on 12/21/20.
6
+//
7
+
8
+import Foundation
9
+
10
+class HistoryService: ObservableObject {
11
+    
12
+    @Published var response: Response = .unfetched
13
+    @Published var items = [FlowerVerbose]()
14
+    
15
+    
16
+    private func getBaseURLComponent(_ apiPath: String) -> URLComponents {
17
+        var components = URLComponents()
18
+        components.scheme = Constants.Services.apiScheme
19
+        components.host = Constants.Services.apiHost
20
+        components.path = apiPath
21
+        if apiPath == Constants.Services.apiGetHistoryPath {
22
+            components.queryItems = [
23
+                URLQueryItem(name: "user_id", value: "\(User.current.id!)"),
24
+            ]
25
+        }
26
+        return components
27
+    }
28
+    
29
+    
30
+    private func fetchFlowers(_ request: URLRequest) {
31
+        URLSession.shared.dataTask(with: request) { data, response, error in
32
+            guard let data = data else {
33
+                print("No data in response: \(error?.localizedDescription ?? "Unknown error")")
34
+                DispatchQueue.main.async {
35
+                    self.response = .failure
36
+                }
37
+                return
38
+            }
39
+            print(response ?? "No response")
40
+//            print("Recieved data:", String(decoding: data, as: UTF8.self))
41
+            
42
+            guard let apiResponse = try? JSONDecoder().decode(HistoryResponseModel.self, from: data) else {
43
+                print("Failed to decode History response")
44
+                DispatchQueue.main.async {
45
+                    self.response = .failure
46
+                }
47
+                return
48
+            }
49
+            
50
+            if let httpResponse = response as? HTTPURLResponse {
51
+                DispatchQueue.main.async {
52
+                    if httpResponse.statusCode == 200 && apiResponse.error == nil {
53
+                        print("No error")
54
+                        self.response = .success
55
+                        self.items = apiResponse.data!
56
+                    } else {
57
+                        print("Error: \(apiResponse.error ?? "Unknown error")")
58
+                        self.response = .failure
59
+//                        self.items = [FlowerVerbose]()
60
+                    }
61
+                }
62
+            }
63
+        }.resume()
64
+    }
65
+    
66
+    
67
+    func getHistory() {
68
+        
69
+        // Start loading state
70
+        self.response = .loading
71
+        
72
+        // Construct URL
73
+        let components = getBaseURLComponent(Constants.Services.apiGetHistoryPath)
74
+        
75
+        // Prepare and carry out request
76
+        var request = URLRequest(url: components.url!)
77
+        request.httpMethod = "GET"
78
+        self.fetchFlowers(request)
79
+        
80
+    }
81
+    
82
+    
83
+    func getWishlist() {
84
+        
85
+        // Start loading state
86
+        self.response = .loading
87
+        
88
+        // Construct URL
89
+        let components = getBaseURLComponent(Constants.Services.apiGetWishlistPath)
90
+        
91
+        // Prepare and carry out request
92
+        var request = URLRequest(url: components.url!)
93
+        request.httpMethod = "GET"
94
+        self.fetchFlowers(request)
95
+        
96
+    }
97
+    
98
+    
99
+    
100
+}

+ 0
- 45
Flowerdex/Flowerdex/Services/ImageManager.swift View File

45
     }
45
     }
46
     
46
     
47
 }
47
 }
48
-
49
-//
50
-//class HistoryManager: ObservableObject {
51
-//    
52
-//    @Published var response: Response = .unfetched
53
-//    @Published var hasBeenFound = false
54
-//    let baseURL = "https://ada.uprrp.edu/~victor.hernandez17/"
55
-//    let foundEndpoint = "flowerdex/isFoundFlower.php"
56
-//    let putFoundEndpoint = "flowerdex/putFoundFlower.php"
57
-//    let removeFoundEndpoint = "flowerdex/removeFoundFlower.php"
58
-//    
59
-//    func fetch() {
60
-//        
61
-//        // Start loading state
62
-//        self.response = .loading
63
-//        
64
-//        let urlString = baseURL + foundEndpoint
65
-//        
66
-//        if let url = URL(string: urlString) {
67
-//            URLSession(configuration: .default).dataTask(with: url) { data, response, error in
68
-//                
69
-//                if error != nil {
70
-//                    print("Error occurred: \(error?.localizedDescription ?? "Unknown error")")
71
-//                    return
72
-//                }
73
-//                
74
-//                guard let data = data else {
75
-//                    print("No data in response: \(error?.localizedDescription ?? "Unknown error")")
76
-//                    return
77
-//                }
78
-//                
79
-//                DispatchQueue.main.async {
80
-//                    if let img = UIImage(data: data) {
81
-//                        self.image = img
82
-//                        self.response = .success
83
-//                    } else {
84
-//                        self.response = .failure
85
-//                    }
86
-//                }
87
-//                
88
-//            }.resume()
89
-//        }
90
-//    }URLSession.shared.dataTask(with: request) { data, response, error in
91
-//    
92
-//}

+ 2
- 0
Flowerdex/Flowerdex/Supporting/Constants.swift View File

24
         static let apiRemoveFavoritePath = "/~victor.hernandez17/flowerdex/removeFavoriteFlower.php"
24
         static let apiRemoveFavoritePath = "/~victor.hernandez17/flowerdex/removeFavoriteFlower.php"
25
         static let apiPutFoundPath = "/~victor.hernandez17/flowerdex/putFoundFlower.php"
25
         static let apiPutFoundPath = "/~victor.hernandez17/flowerdex/putFoundFlower.php"
26
         static let apiRemoveFoundPath = "/~victor.hernandez17/flowerdex/removeFoundFlower.php"
26
         static let apiRemoveFoundPath = "/~victor.hernandez17/flowerdex/removeFoundFlower.php"
27
+        static let apiGetHistoryPath = "/~victor.hernandez17/flowerdex/listHistory.php"
28
+        static let apiGetWishlistPath = "/~victor.hernandez17/flowerdex/getWishlist.php"
27
     }
29
     }
28
     
30
     
29
     struct Colors {
31
     struct Colors {

Flowerdex/Flowerdex/View/Authentication/LoginView.swift → Flowerdex/Flowerdex/View/Authentication Page/LoginView.swift View File


Flowerdex/Flowerdex/View/Authentication/RegisterView.swift → Flowerdex/Flowerdex/View/Authentication Page/RegisterView.swift View File


+ 6
- 2
Flowerdex/Flowerdex/View/Discover Page/DiscoverView.swift View File

21
     @State var bloomMonths: Int = 0
21
     @State var bloomMonths: Int = 0
22
     @State var scientificName: String = ""
22
     @State var scientificName: String = ""
23
     @State var commonName: String = ""
23
     @State var commonName: String = ""
24
+    @State var flowerColor: String = ""
24
     
25
     
25
     init() {
26
     init() {
26
         // FROM: https://sarunw.com/posts/uinavigationbar-changes-in-ios13/
27
         // FROM: https://sarunw.com/posts/uinavigationbar-changes-in-ios13/
42
                     FilterButtonIcon()
43
                     FilterButtonIcon()
43
                 }
44
                 }
44
                 .sheet(isPresented: $showingFilterPane, content: {
45
                 .sheet(isPresented: $showingFilterPane, content: {
45
-                    FiltersSheet(showingFilterPane: $showingFilterPane, page: $page, edible: $edible, vegetable: $vegetable, petalCount: $petalCount, growthMonths: $growthMonths, bloomMonths: $bloomMonths, scientificName: $scientificName, commonName: $commonName)
46
+                    FiltersSheet(showingFilterPane: $showingFilterPane, page: $page, edible: $edible, vegetable: $vegetable, petalCount: $petalCount, growthMonths: $growthMonths, bloomMonths: $bloomMonths, scientificName: $scientificName, commonName: $commonName, flowerColor: $flowerColor)
46
                 })
47
                 })
47
             )
48
             )
48
         }
49
         }
49
         .onAppear {
50
         .onAppear {
50
-            self.fModel.getFlowers(p: page, f: nil)
51
+            // Refresh only if there's no items loaded yet
52
+            if self.fModel.items.count == 0 {
53
+                self.fModel.getFlowers(p: page, f: nil)
54
+            }
51
         }
55
         }
52
     }
56
     }
53
     
57
     

+ 16
- 0
Flowerdex/Flowerdex/View/Discover Page/FilterFields.swift View File

16
     @Binding var bloomMonths: Int
16
     @Binding var bloomMonths: Int
17
     @Binding var scientificName: String
17
     @Binding var scientificName: String
18
     @Binding var commonName: String
18
     @Binding var commonName: String
19
+    @Binding var flowerColor: String
19
     
20
     
20
     var body: some View {
21
     var body: some View {
21
         VStack {
22
         VStack {
27
             BloomMonthsField(bloomMonths: $bloomMonths)
28
             BloomMonthsField(bloomMonths: $bloomMonths)
28
             CommonNameField(commonName: $commonName)
29
             CommonNameField(commonName: $commonName)
29
             ScientificNameField(scientificName: $scientificName)
30
             ScientificNameField(scientificName: $scientificName)
31
+            FlowerColorField(flowerColor: $flowerColor)
30
         }
32
         }
31
         .padding()
33
         .padding()
32
     }
34
     }
41
     }
43
     }
42
 }
44
 }
43
 
45
 
46
+struct FlowerColorField: View {
47
+    @Binding var flowerColor: String
48
+    @Environment(\.colorScheme) var colorScheme
49
+    var body: some View {
50
+        TextField("FlowerColor", text: $flowerColor)
51
+            .disableAutocorrection(true)
52
+            .autocapitalization(.none)
53
+            .padding()
54
+            .background(colorScheme == .dark ? Constants.Colors.darkGrayColor : Constants.Colors.lightGrayColor)
55
+            .cornerRadius(5.0)
56
+            .padding(.bottom, 5)
57
+    }
58
+}
59
+
44
 struct CommonNameField: View {
60
 struct CommonNameField: View {
45
     @Binding var commonName: String
61
     @Binding var commonName: String
46
     @Environment(\.colorScheme) var colorScheme
62
     @Environment(\.colorScheme) var colorScheme

+ 3
- 2
Flowerdex/Flowerdex/View/Discover Page/FiltersSheet.swift View File

21
     @Binding var bloomMonths: Int
21
     @Binding var bloomMonths: Int
22
     @Binding var scientificName: String
22
     @Binding var scientificName: String
23
     @Binding var commonName: String
23
     @Binding var commonName: String
24
+    @Binding var flowerColor: String
24
 
25
 
25
     var body: some View {
26
     var body: some View {
26
-        FilterFields(edible: $edible, vegetable: $vegetable, petalCount: $petalCount, growthMonths: $growthMonths, bloomMonths: $bloomMonths, scientificName: $scientificName, commonName: $commonName)
27
+        FilterFields(edible: $edible, vegetable: $vegetable, petalCount: $petalCount, growthMonths: $growthMonths, bloomMonths: $bloomMonths, scientificName: $scientificName, commonName: $commonName, flowerColor: $flowerColor)
27
         
28
         
28
         Spacer()
29
         Spacer()
29
         
30
         
30
         Button(action: {
31
         Button(action: {
31
-            let filters = Filters(edible: edible, vegetable: vegetable, petalCount: petalCount, growthMonths: growthMonths, bloomMonths: bloomMonths, scientificName: scientificName, commonName: commonName)
32
+            let filters = Filters(edible: edible, vegetable: vegetable, petalCount: petalCount, growthMonths: growthMonths, bloomMonths: bloomMonths, scientificName: scientificName, commonName: commonName, flowerColor: flowerColor)
32
             
33
             
33
             self.fModel.getFlowers(p: page, f: filters)
34
             self.fModel.getFlowers(p: page, f: filters)
34
             
35
             

+ 112
- 0
Flowerdex/Flowerdex/View/History Page/FlowerVerboseDetailView.swift View File

1
+//
2
+//  FlowerVerboseDetailView.swift
3
+//  Flowerdex
4
+//
5
+//  Created by Víctor A. Hernández on 12/21/20.
6
+//
7
+
8
+import SwiftUI
9
+
10
+struct FlowerVerboseDetailView: View {
11
+    
12
+    var flower: FlowerVerbose
13
+    @State var hasBeenFoundLocal: Bool
14
+    @ObservedObject var imageManager = ImageManager()
15
+    @EnvironmentObject var fModel: FlowerService
16
+    var size: CGFloat = 300
17
+    
18
+    var body: some View {
19
+        VStack(alignment: .leading, spacing: 0) {
20
+            HStack {
21
+                Text(self.flower.commonName.capitalized)
22
+                    .font(.title)
23
+                    .fontWeight(/*@START_MENU_TOKEN@*/.semibold/*@END_MENU_TOKEN@*/)
24
+                    .foregroundColor(Constants.Colors.blueGray)
25
+                //                .frame(width: .infinity, alignment: .center)
26
+                Spacer()
27
+                Button(action: {
28
+                    
29
+                    // Depending on past value
30
+                    if self.hasBeenFoundLocal {
31
+                        fModel.removeFound(self.flower.id)
32
+                    } else {
33
+                        fModel.putFound(self.flower.id)
34
+                    }
35
+                    
36
+                    // Change value after request
37
+                    self.hasBeenFoundLocal.toggle()
38
+                    
39
+                }) {
40
+                    if self.hasBeenFoundLocal {
41
+                        Image(systemName: "eye")
42
+                            .font(.title)
43
+                            .foregroundColor(Constants.Colors.rausch)
44
+                    } else {
45
+                        Image(systemName: "eye.slash")
46
+                            .font(.title)
47
+                            .foregroundColor(Constants.Colors.blueGray)
48
+                    }
49
+                    
50
+                }
51
+            }
52
+            
53
+            .padding()
54
+            
55
+
56
+            
57
+//            URLImage(url: self.flower.imageURL)
58
+//            Image("amapola")
59
+            // TODO: make placeholder and actual image look equally good
60
+            Image(uiImage: self.imageManager.image!)
61
+                .resizable()
62
+                .frame(width: self.size, height: self.size)
63
+            FlowerVerboseInformationPane(flower: flower)
64
+            Spacer()
65
+        }
66
+        .onAppear {
67
+            self.imageManager.fetchImage(self.flower.imageURL)
68
+        }
69
+    }
70
+}
71
+
72
+// TODO: account for text overflow
73
+struct FlowerVerboseInformationPane: View {
74
+    var flower: FlowerVerbose
75
+    var body: some View {
76
+        HStack {
77
+            VStack(alignment: .leading, spacing: nil) {
78
+                Text("Scientific Name:")
79
+                    .bold()
80
+                Text("\(self.flower.scientificName)")
81
+                    .foregroundColor(Constants.Colors.blueGray)
82
+                    .padding(.bottom)
83
+                Text("Year Discovered:")
84
+                    .bold()
85
+                Text("\(self.flower.year ?? -999)")
86
+                    .foregroundColor(Constants.Colors.blueGray)
87
+            }
88
+            .foregroundColor(Constants.Colors.rausch)
89
+            .padding()
90
+            VStack(alignment: .leading, spacing: nil) {
91
+                Text("Bibliography:")
92
+                    .bold()
93
+                Text("\(self.flower.bibliography ?? "n/a")")
94
+                    .foregroundColor(Constants.Colors.blueGray)
95
+                    .padding(.bottom)
96
+                Text("Author:")
97
+                    .bold()
98
+                Text("\(self.flower.author ?? "n/a")")
99
+                    .foregroundColor(Constants.Colors.blueGray)
100
+            }
101
+            .foregroundColor(Constants.Colors.rausch)
102
+            .padding()
103
+        }
104
+        .padding(.vertical)
105
+    }
106
+}
107
+
108
+struct FlowerVerboseDetailView_Previews: PreviewProvider {
109
+    static var previews: some View {
110
+        FlowerDetailView(flower: dummyFlowers[0], hasBeenFoundLocal: true)
111
+    }
112
+}

+ 50
- 0
Flowerdex/Flowerdex/View/History Page/HistoryView.swift View File

1
+//
2
+//  HistoryView.swift
3
+//  Flowerdex
4
+//
5
+//  Created by Víctor A. Hernández on 12/21/20.
6
+//
7
+
8
+import SwiftUI
9
+
10
+struct HistoryView: View {
11
+    @EnvironmentObject var hModel: HistoryService
12
+    var body: some View {
13
+        NavigationView {
14
+            ScrollableHistoryContent()
15
+        }
16
+        .onAppear {
17
+            self.hModel.getHistory()
18
+        }
19
+    }
20
+}
21
+
22
+struct ScrollableHistoryContent: View {
23
+    @EnvironmentObject var hModel: HistoryService
24
+    var body: some View {
25
+        if hModel.response == .success {
26
+            List {
27
+                HistoryList(flowerList: hModel.items)
28
+            }
29
+            .navigationBarTitle("Discover")
30
+        } else if hModel.response == .loading || hModel.response == .unfetched {
31
+            // TODO: make this centered vertically within parent ScrollView
32
+            ProgressView("Loading...")
33
+        } else if hModel.response == .failure {
34
+            // TODO: make this centered vertically within parent ScrollView
35
+            FailureIcon()
36
+        }
37
+    }
38
+}
39
+
40
+struct HistoryList: View {
41
+    var flowerList: [FlowerVerbose]
42
+    var body: some View {
43
+        ForEach(flowerList) { flower in
44
+            NavigationLink(destination: FlowerVerboseDetailView(flower: flower, hasBeenFoundLocal: flower.hasBeenFound)) {
45
+                Text(flower.commonName.capitalized)
46
+            }
47
+//                    .foregroundColor(Constants.Colors.blueGray)
48
+        }
49
+    }
50
+}

+ 27
- 0
Flowerdex/Flowerdex/View/MainView.swift View File

1
+//
2
+//  MainView.swift
3
+//  Flowerdex
4
+//
5
+//  Created by Víctor A. Hernández on 12/21/20.
6
+//
7
+
8
+import SwiftUI
9
+
10
+struct MainView: View {
11
+    var body: some View {
12
+        TabView {
13
+            DiscoverView()
14
+                .tabItem {
15
+                    Image(systemName: "magnifyingglass")
16
+                    Text("Discover")
17
+                }
18
+            
19
+            HistoryView()
20
+                .tabItem {
21
+                    Image(systemName: "square.and.pencil")
22
+                    Text("History")
23
+                }
24
+        }
25
+        .accentColor(Constants.Colors.rausch)
26
+    }
27
+}