diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..959cd66
Binary files /dev/null and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
index 9bdca8e..5708445 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,8 @@ node_modules
.env
dist
migrations
-.DS_Store
+Rethread/Rethread.xcodeproj/project.xcworkspace/xcuserdata/mortezafaraji.xcuserdatad/UserInterfaceState.xcuserstate
.vscode
-coverage
\ No newline at end of file
+**/GoogleService-Info.plist
+.DS_Store
+coverage
diff --git a/Rethread/.DS_Store b/Rethread/.DS_Store
index 6d556de..ec8e23f 100644
Binary files a/Rethread/.DS_Store and b/Rethread/.DS_Store differ
diff --git a/Rethread/.gitignore b/Rethread/.gitignore
new file mode 100644
index 0000000..1d62266
--- /dev/null
+++ b/Rethread/.gitignore
@@ -0,0 +1,91 @@
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+
+## Obj-C/Swift specific
+*.hmap
+
+## App packaging
+*.ipa
+*.dSYM.zip
+*.dSYM
+
+## Playgrounds
+timeline.xctimeline
+playground.xcworkspace
+
+# Swift Package Manager
+#
+# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
+Packages/
+Package.pins
+Package.resolved
+# *.xcodeproj
+#
+# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
+# hence it is not needed unless you have added a package configuration file to your project
+# .swiftpm
+
+.build/
+
+# CocoaPods
+#
+# We recommend against adding the Pods directory to your .gitignore. However
+# you should judge for yourself, the pros and cons are mentioned at:
+# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
+#
+# Pods/
+#
+# Add this line if you want to avoid checking in source code from the Xcode workspace
+# *.xcworkspace
+
+# Carthage
+#
+# Add this line if you want to avoid checking in source code from Carthage dependencies.
+# Carthage/Checkouts
+
+Carthage/Build/
+
+# Accio dependency management
+Dependencies/
+.accio/
+
+# fastlane
+#
+# It is recommended to not store the screenshots in the git repo.
+# Instead, use fastlane to re-generate the screenshots whenever they are needed.
+# For more information about the recommended setup visit:
+# https://docs.fastlane.tools/best-practices/source-control/#source-control
+
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots/**/*.png
+fastlane/test_output
+
+# Code Injection
+#
+# After new code Injection tools there's a generated folder /iOSInjectionProject
+# https://github.com/johnno1962/injectionforxcode
+
+iOSInjectionProject/
+GoogleService-Info.plist
\ No newline at end of file
diff --git a/Rethread/GoogleService-Info.plist b/Rethread/GoogleService-Info.plist
new file mode 100644
index 0000000..34f2b70
--- /dev/null
+++ b/Rethread/GoogleService-Info.plist
@@ -0,0 +1,34 @@
+
+
+
+
+ CLIENT_ID
+ 69711373157-smt51cs82nik0nceo6slguta9vmaip00.apps.googleusercontent.com
+ REVERSED_CLIENT_ID
+ com.googleusercontent.apps.69711373157-smt51cs82nik0nceo6slguta9vmaip00
+ API_KEY
+ AIzaSyCt95kuSORiMMuxgV7BXBI0LqhQ78E3CS0
+ GCM_SENDER_ID
+ 69711373157
+ PLIST_VERSION
+ 1
+ BUNDLE_ID
+ techstart.Rethread
+ PROJECT_ID
+ rethread-6c539
+ STORAGE_BUCKET
+ rethread-6c539.appspot.com
+ IS_ADS_ENABLED
+
+ IS_ANALYTICS_ENABLED
+
+ IS_APPINVITE_ENABLED
+
+ IS_GCM_ENABLED
+
+ IS_SIGNIN_ENABLED
+
+ GOOGLE_APP_ID
+ 1:69711373157:ios:31a3f912661197e84ef78c
+
+
\ No newline at end of file
diff --git a/Rethread/Rethread.xcodeproj/project.pbxproj b/Rethread/Rethread.xcodeproj/project.pbxproj
index f23537c..bcda19b 100644
--- a/Rethread/Rethread.xcodeproj/project.pbxproj
+++ b/Rethread/Rethread.xcodeproj/project.pbxproj
@@ -7,27 +7,45 @@
objects = {
/* Begin PBXBuildFile section */
- 7C3A04B82B0AD9DF00E36883 /* OnboardingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C3A04B42B0AD9DF00E36883 /* OnboardingApp.swift */; };
+ 7C8446E52B58CE8F00911C00 /* MapViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C8446E42B58CE8F00911C00 /* MapViewModel.swift */; };
983014C22B451A3E004A6A07 /* NavigationTransitions in Frameworks */ = {isa = PBXBuildFile; productRef = 983014C12B451A3E004A6A07 /* NavigationTransitions */; };
983286B92B05698F00851B19 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 983286B82B05698F00851B19 /* Assets.xcassets */; };
983286BC2B05698F00851B19 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 983286BB2B05698F00851B19 /* Preview Assets.xcassets */; };
983286C62B05698F00851B19 /* RethreadTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 983286C52B05698F00851B19 /* RethreadTests.swift */; };
983286D02B05698F00851B19 /* RethreadUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 983286CF2B05698F00851B19 /* RethreadUITests.swift */; };
983286D22B05698F00851B19 /* RethreadUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 983286D12B05698F00851B19 /* RethreadUITestsLaunchTests.swift */; };
- 9868A7D82B1FAD280063D9BA /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9868A7D72B1FAD280063D9BA /* WelcomeView.swift */; };
- 9868A7DA2B1FADA70063D9BA /* QuestionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9868A7D92B1FADA70063D9BA /* QuestionView.swift */; };
+ 98434A5D2B63342700F81127 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98434A5C2B63342700F81127 /* ContentView.swift */; };
+ 984674952B747FD200AFB77A /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 984674942B747FD200AFB77A /* GoogleService-Info.plist */; };
+ 985674F12B663E0D003FA5A0 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 985674F02B663E0D003FA5A0 /* FirebaseAuth */; };
+ 985674F32B663E0D003FA5A0 /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = 985674F22B663E0D003FA5A0 /* FirebaseFirestore */; };
+ 985674F52B663E0D003FA5A0 /* FirebaseFirestoreSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 985674F42B663E0D003FA5A0 /* FirebaseFirestoreSwift */; };
+ 985674F72B663E0D003FA5A0 /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 985674F62B663E0D003FA5A0 /* FirebaseStorage */; };
9868A7DE2B1FAE780063D9BA /* ButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9868A7DD2B1FAE780063D9BA /* ButtonStyles.swift */; };
- 988A0F952B3BFB4C00ACDC90 /* SignUpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988A0F942B3BFB4C00ACDC90 /* SignUpView.swift */; };
988A0F992B3C112300ACDC90 /* DatePickerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988A0F982B3C112300ACDC90 /* DatePickerModel.swift */; };
9897C7732B3E6C4000EDE9D9 /* CustomDropdownMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9897C7722B3E6C4000EDE9D9 /* CustomDropdownMenu.swift */; };
- 98A183862B38273B001E324A /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A183852B38273B001E324A /* MainView.swift */; };
- 98A183882B383C0B001E324A /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A183872B383C0B001E324A /* SignInView.swift */; };
- 98A1838A2B383C47001E324A /* VerificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A183892B383C47001E324A /* VerificationView.swift */; };
98A1838C2B38D32A001E324A /* ColorPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A1838B2B38D32A001E324A /* ColorPalette.swift */; };
- 98AE7AB92B1FAADB0029C2F7 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AE7AB82B1FAADB0029C2F7 /* OnboardingView.swift */; };
+ 98BBA11D2B68A6A100003AC2 /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA10F2B68A6A100003AC2 /* ProfileView.swift */; };
+ 98BBA11E2B68A6A100003AC2 /* VerificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1102B68A6A100003AC2 /* VerificationView.swift */; };
+ 98BBA11F2B68A6A100003AC2 /* ProductView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1112B68A6A100003AC2 /* ProductView.swift */; };
+ 98BBA1202B68A6A100003AC2 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1122B68A6A100003AC2 /* MapView.swift */; };
+ 98BBA1212B68A6A100003AC2 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1132B68A6A100003AC2 /* HomeView.swift */; };
+ 98BBA1222B68A6A100003AC2 /* testest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1142B68A6A100003AC2 /* testest.swift */; };
+ 98BBA1232B68A6A100003AC2 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1152B68A6A100003AC2 /* WelcomeView.swift */; };
+ 98BBA1242B68A6A100003AC2 /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1162B68A6A100003AC2 /* SignInView.swift */; };
+ 98BBA1252B68A6A100003AC2 /* SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1172B68A6A100003AC2 /* SwiftUIView.swift */; };
+ 98BBA1262B68A6A100003AC2 /* ClothingItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1182B68A6A100003AC2 /* ClothingItemView.swift */; };
+ 98BBA1272B68A6A100003AC2 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA1192B68A6A100003AC2 /* MainView.swift */; };
+ 98BBA1282B68A6A100003AC2 /* SignUpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA11A2B68A6A100003AC2 /* SignUpView.swift */; };
+ 98BBA1292B68A6A100003AC2 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA11B2B68A6A100003AC2 /* OnboardingView.swift */; };
+ 98BBA12B2B68A75200003AC2 /* OnboardingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA12A2B68A75200003AC2 /* OnboardingApp.swift */; };
+ 98BBA12D2B68ACBF00003AC2 /* Verification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BBA12C2B68ACBF00003AC2 /* Verification.swift */; };
+ 98D04FFD2B7871F200889156 /* CustomTextField in Frameworks */ = {isa = PBXBuildFile; productRef = 98D04FFC2B7871F200889156 /* CustomTextField */; };
+ 98D04FFF2B78763C00889156 /* CustomField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98D04FFE2B78763C00889156 /* CustomField.swift */; };
+ 98EA47352B6065C600AA2E8F /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98EA47342B6065C600AA2E8F /* User.swift */; };
98F525C92B469BBD00CCAD78 /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98F525C82B469BBD00CCAD78 /* PlayerView.swift */; };
98F525CB2B469BEB00CCAD78 /* UIPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98F525CA2B469BEB00CCAD78 /* UIPlayerView.swift */; };
98F525CE2B46A96F00CCAD78 /* TermsAndConditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98F525CD2B46A96F00CCAD78 /* TermsAndConditions.swift */; };
+ 98F541222B60A2CC00B6AA04 /* AuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98F541212B60A2CC00B6AA04 /* AuthViewModel.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -48,7 +66,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- 7C3A04B42B0AD9DF00E36883 /* OnboardingApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingApp.swift; sourceTree = ""; };
+ 7C8446E42B58CE8F00911C00 /* MapViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewModel.swift; sourceTree = ""; };
983286B12B05698E00851B19 /* Rethread.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Rethread.app; sourceTree = BUILT_PRODUCTS_DIR; };
983286B82B05698F00851B19 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
983286BB2B05698F00851B19 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
@@ -57,20 +75,34 @@
983286CB2B05698F00851B19 /* RethreadUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RethreadUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
983286CF2B05698F00851B19 /* RethreadUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RethreadUITests.swift; sourceTree = ""; };
983286D12B05698F00851B19 /* RethreadUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RethreadUITestsLaunchTests.swift; sourceTree = ""; };
- 9868A7D72B1FAD280063D9BA /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; };
- 9868A7D92B1FADA70063D9BA /* QuestionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestionView.swift; sourceTree = ""; };
+ 983D40FA2B68D13E00905D4E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
+ 98434A5C2B63342700F81127 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
+ 984674942B747FD200AFB77A /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; };
9868A7DD2B1FAE780063D9BA /* ButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonStyles.swift; sourceTree = ""; };
- 988A0F942B3BFB4C00ACDC90 /* SignUpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpView.swift; sourceTree = ""; };
988A0F982B3C112300ACDC90 /* DatePickerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerModel.swift; sourceTree = ""; };
9897C7722B3E6C4000EDE9D9 /* CustomDropdownMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDropdownMenu.swift; sourceTree = ""; };
- 98A183852B38273B001E324A /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; };
- 98A183872B383C0B001E324A /* SignInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInView.swift; sourceTree = ""; };
- 98A183892B383C47001E324A /* VerificationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerificationView.swift; sourceTree = ""; };
98A1838B2B38D32A001E324A /* ColorPalette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPalette.swift; sourceTree = ""; };
- 98AE7AB82B1FAADB0029C2F7 /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; };
+ 98BBA10F2B68A6A100003AC2 /* ProfileView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = ""; };
+ 98BBA1102B68A6A100003AC2 /* VerificationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerificationView.swift; sourceTree = ""; };
+ 98BBA1112B68A6A100003AC2 /* ProductView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProductView.swift; sourceTree = ""; };
+ 98BBA1122B68A6A100003AC2 /* MapView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; };
+ 98BBA1132B68A6A100003AC2 /* HomeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; };
+ 98BBA1142B68A6A100003AC2 /* testest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = testest.swift; sourceTree = ""; };
+ 98BBA1152B68A6A100003AC2 /* WelcomeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; };
+ 98BBA1162B68A6A100003AC2 /* SignInView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignInView.swift; sourceTree = ""; };
+ 98BBA1172B68A6A100003AC2 /* SwiftUIView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftUIView.swift; sourceTree = ""; };
+ 98BBA1182B68A6A100003AC2 /* ClothingItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClothingItemView.swift; sourceTree = ""; };
+ 98BBA1192B68A6A100003AC2 /* MainView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; };
+ 98BBA11A2B68A6A100003AC2 /* SignUpView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignUpView.swift; sourceTree = ""; };
+ 98BBA11B2B68A6A100003AC2 /* OnboardingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; };
+ 98BBA12A2B68A75200003AC2 /* OnboardingApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingApp.swift; sourceTree = ""; };
+ 98BBA12C2B68ACBF00003AC2 /* Verification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Verification.swift; sourceTree = ""; };
+ 98D04FFE2B78763C00889156 /* CustomField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomField.swift; sourceTree = ""; };
+ 98EA47342B6065C600AA2E8F /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; };
98F525C82B469BBD00CCAD78 /* PlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerView.swift; sourceTree = ""; };
98F525CA2B469BEB00CCAD78 /* UIPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIPlayerView.swift; sourceTree = ""; };
98F525CD2B46A96F00CCAD78 /* TermsAndConditions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TermsAndConditions.swift; sourceTree = ""; };
+ 98F541212B60A2CC00B6AA04 /* AuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthViewModel.swift; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -79,6 +111,11 @@
buildActionMask = 2147483647;
files = (
983014C22B451A3E004A6A07 /* NavigationTransitions in Frameworks */,
+ 98D04FFD2B7871F200889156 /* CustomTextField in Frameworks */,
+ 985674F12B663E0D003FA5A0 /* FirebaseAuth in Frameworks */,
+ 985674F32B663E0D003FA5A0 /* FirebaseFirestore in Frameworks */,
+ 985674F72B663E0D003FA5A0 /* FirebaseStorage in Frameworks */,
+ 985674F52B663E0D003FA5A0 /* FirebaseFirestoreSwift in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -104,33 +141,36 @@
children = (
988A0F982B3C112300ACDC90 /* DatePickerModel.swift */,
98F525CD2B46A96F00CCAD78 /* TermsAndConditions.swift */,
+ 7C8446E42B58CE8F00911C00 /* MapViewModel.swift */,
);
path = Models;
sourceTree = "";
};
- 7C9AA2D12B0EC3BC00EF6F36 /* Extensions */ = {
+ 7C9AA2D42B0ECADF00EF6F36 /* Styles */ = {
isa = PBXGroup;
children = (
+ 9868A7DD2B1FAE780063D9BA /* ButtonStyles.swift */,
+ 98A1838B2B38D32A001E324A /* ColorPalette.swift */,
);
- path = Extensions;
+ path = Styles;
sourceTree = "";
};
- 7C9AA2D42B0ECADF00EF6F36 /* Styles */ = {
+ 980DACBB2B71E7110008B88A /* Extensions */ = {
isa = PBXGroup;
children = (
- 9868A7DD2B1FAE780063D9BA /* ButtonStyles.swift */,
- 98A1838B2B38D32A001E324A /* ColorPalette.swift */,
);
- path = Styles;
+ path = Extensions;
sourceTree = "";
};
983286A82B05698E00851B19 = {
isa = PBXGroup;
children = (
983286B32B05698E00851B19 /* Rethread */,
+ 984674942B747FD200AFB77A /* GoogleService-Info.plist */,
983286C42B05698F00851B19 /* RethreadTests */,
983286CE2B05698F00851B19 /* RethreadUITests */,
983286B22B05698E00851B19 /* Products */,
+ 98BBA10C2B68A51A00003AC2 /* Recovered References */,
);
sourceTree = "";
};
@@ -147,19 +187,15 @@
983286B32B05698E00851B19 /* Rethread */ = {
isa = PBXGroup;
children = (
- 7C9AA2D12B0EC3BC00EF6F36 /* Extensions */,
+ 983D40FA2B68D13E00905D4E /* Info.plist */,
7C9AA2D42B0ECADF00EF6F36 /* Styles */,
+ 980DACBB2B71E7110008B88A /* Extensions */,
9897C7712B3E6BF600EDE9D9 /* Components */,
98F525CC2B46A8E900CCAD78 /* VideoPlayer */,
7C9AA2CC2B0EC02600EF6F36 /* Models */,
+ 98EA47332B6065A500AA2E8F /* UserAuthentication */,
+ 98BBA10D2B68A6A100003AC2 /* Views */,
98EA47322B605E5200AA2E8F /* Core */,
- 98AE7AB82B1FAADB0029C2F7 /* OnboardingView.swift */,
- 98A183852B38273B001E324A /* MainView.swift */,
- 98A183872B383C0B001E324A /* SignInView.swift */,
- 988A0F942B3BFB4C00ACDC90 /* SignUpView.swift */,
- 98A183892B383C47001E324A /* VerificationView.swift */,
- 9868A7D92B1FADA70063D9BA /* QuestionView.swift */,
- 9868A7D72B1FAD280063D9BA /* WelcomeView.swift */,
983286B82B05698F00851B19 /* Assets.xcassets */,
983286BA2B05698F00851B19 /* Preview Content */,
);
@@ -194,19 +230,58 @@
9897C7712B3E6BF600EDE9D9 /* Components */ = {
isa = PBXGroup;
children = (
+ 98BBA12C2B68ACBF00003AC2 /* Verification.swift */,
9897C7722B3E6C4000EDE9D9 /* CustomDropdownMenu.swift */,
+ 98D04FFE2B78763C00889156 /* CustomField.swift */,
);
path = Components;
sourceTree = "";
};
+ 98BBA10C2B68A51A00003AC2 /* Recovered References */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = "Recovered References";
+ sourceTree = "";
+ };
+ 98BBA10D2B68A6A100003AC2 /* Views */ = {
+ isa = PBXGroup;
+ children = (
+ 98BBA10F2B68A6A100003AC2 /* ProfileView.swift */,
+ 98BBA1102B68A6A100003AC2 /* VerificationView.swift */,
+ 98BBA1112B68A6A100003AC2 /* ProductView.swift */,
+ 98BBA1122B68A6A100003AC2 /* MapView.swift */,
+ 98BBA1132B68A6A100003AC2 /* HomeView.swift */,
+ 98BBA1142B68A6A100003AC2 /* testest.swift */,
+ 98BBA1152B68A6A100003AC2 /* WelcomeView.swift */,
+ 98BBA1162B68A6A100003AC2 /* SignInView.swift */,
+ 98BBA1172B68A6A100003AC2 /* SwiftUIView.swift */,
+ 98BBA1182B68A6A100003AC2 /* ClothingItemView.swift */,
+ 98BBA1192B68A6A100003AC2 /* MainView.swift */,
+ 98BBA11A2B68A6A100003AC2 /* SignUpView.swift */,
+ 98BBA11B2B68A6A100003AC2 /* OnboardingView.swift */,
+ );
+ path = Views;
+ sourceTree = "";
+ };
98EA47322B605E5200AA2E8F /* Core */ = {
isa = PBXGroup;
children = (
- 7C3A04B42B0AD9DF00E36883 /* OnboardingApp.swift */,
+ 98BBA12A2B68A75200003AC2 /* OnboardingApp.swift */,
+ 98434A5C2B63342700F81127 /* ContentView.swift */,
);
path = Core;
sourceTree = "";
};
+ 98EA47332B6065A500AA2E8F /* UserAuthentication */ = {
+ isa = PBXGroup;
+ children = (
+ 98F541212B60A2CC00B6AA04 /* AuthViewModel.swift */,
+ 98EA47342B6065C600AA2E8F /* User.swift */,
+ );
+ path = UserAuthentication;
+ sourceTree = "";
+ };
98F525CC2B46A8E900CCAD78 /* VideoPlayer */ = {
isa = PBXGroup;
children = (
@@ -234,6 +309,11 @@
name = Rethread;
packageProductDependencies = (
983014C12B451A3E004A6A07 /* NavigationTransitions */,
+ 985674F02B663E0D003FA5A0 /* FirebaseAuth */,
+ 985674F22B663E0D003FA5A0 /* FirebaseFirestore */,
+ 985674F42B663E0D003FA5A0 /* FirebaseFirestoreSwift */,
+ 985674F62B663E0D003FA5A0 /* FirebaseStorage */,
+ 98D04FFC2B7871F200889156 /* CustomTextField */,
);
productName = Rethread;
productReference = 983286B12B05698E00851B19 /* Rethread.app */;
@@ -310,6 +390,8 @@
mainGroup = 983286A82B05698E00851B19;
packageReferences = (
983014C02B451A3E004A6A07 /* XCRemoteSwiftPackageReference "swiftui-navigation-transitions" */,
+ 985674EF2B663E0D003FA5A0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
+ 98D04FFB2B7871F200889156 /* XCRemoteSwiftPackageReference "SwiftUI-Custom-TextField" */,
);
productRefGroup = 983286B22B05698E00851B19 /* Products */;
projectDirPath = "";
@@ -328,6 +410,7 @@
buildActionMask = 2147483647;
files = (
983286BC2B05698F00851B19 /* Preview Assets.xcassets in Resources */,
+ 984674952B747FD200AFB77A /* GoogleService-Info.plist in Resources */,
983286B92B05698F00851B19 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -353,21 +436,33 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 9868A7DA2B1FADA70063D9BA /* QuestionView.swift in Sources */,
- 7C3A04B82B0AD9DF00E36883 /* OnboardingApp.swift in Sources */,
+ 98BBA1292B68A6A100003AC2 /* OnboardingView.swift in Sources */,
+ 98BBA1222B68A6A100003AC2 /* testest.swift in Sources */,
+ 98BBA1262B68A6A100003AC2 /* ClothingItemView.swift in Sources */,
9868A7DE2B1FAE780063D9BA /* ButtonStyles.swift in Sources */,
- 98AE7AB92B1FAADB0029C2F7 /* OnboardingView.swift in Sources */,
- 988A0F952B3BFB4C00ACDC90 /* SignUpView.swift in Sources */,
+ 98EA47352B6065C600AA2E8F /* User.swift in Sources */,
+ 98BBA12D2B68ACBF00003AC2 /* Verification.swift in Sources */,
98A1838C2B38D32A001E324A /* ColorPalette.swift in Sources */,
+ 98BBA12B2B68A75200003AC2 /* OnboardingApp.swift in Sources */,
+ 98BBA1242B68A6A100003AC2 /* SignInView.swift in Sources */,
+ 98F541222B60A2CC00B6AA04 /* AuthViewModel.swift in Sources */,
98F525CE2B46A96F00CCAD78 /* TermsAndConditions.swift in Sources */,
- 98A183862B38273B001E324A /* MainView.swift in Sources */,
98F525C92B469BBD00CCAD78 /* PlayerView.swift in Sources */,
- 98A1838A2B383C47001E324A /* VerificationView.swift in Sources */,
98F525CB2B469BEB00CCAD78 /* UIPlayerView.swift in Sources */,
- 98A183882B383C0B001E324A /* SignInView.swift in Sources */,
+ 98BBA1232B68A6A100003AC2 /* WelcomeView.swift in Sources */,
+ 98BBA11D2B68A6A100003AC2 /* ProfileView.swift in Sources */,
+ 98434A5D2B63342700F81127 /* ContentView.swift in Sources */,
988A0F992B3C112300ACDC90 /* DatePickerModel.swift in Sources */,
9897C7732B3E6C4000EDE9D9 /* CustomDropdownMenu.swift in Sources */,
- 9868A7D82B1FAD280063D9BA /* WelcomeView.swift in Sources */,
+ 98BBA1272B68A6A100003AC2 /* MainView.swift in Sources */,
+ 98BBA1212B68A6A100003AC2 /* HomeView.swift in Sources */,
+ 98BBA1252B68A6A100003AC2 /* SwiftUIView.swift in Sources */,
+ 98BBA11E2B68A6A100003AC2 /* VerificationView.swift in Sources */,
+ 98D04FFF2B78763C00889156 /* CustomField.swift in Sources */,
+ 98BBA11F2B68A6A100003AC2 /* ProductView.swift in Sources */,
+ 98BBA1282B68A6A100003AC2 /* SignUpView.swift in Sources */,
+ 98BBA1202B68A6A100003AC2 /* MapView.swift in Sources */,
+ 7C8446E52B58CE8F00911C00 /* MapViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -535,18 +630,20 @@
DEVELOPMENT_TEAM = 4GW9NWA7H9;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = Rethread/Info.plist;
+ INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Rethread needs your location";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
- IPHONEOS_DEPLOYMENT_TARGET = 16.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = techstart.Rethread;
+ PRODUCT_BUNDLE_IDENTIFIER = techstart.Rethread2;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -567,18 +664,20 @@
DEVELOPMENT_TEAM = 4GW9NWA7H9;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = Rethread/Info.plist;
+ INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Rethread needs your location";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
- IPHONEOS_DEPLOYMENT_TARGET = 16.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = techstart.Rethread;
+ PRODUCT_BUNDLE_IDENTIFIER = techstart.Rethread2;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
@@ -708,6 +807,22 @@
minimumVersion = 0.13.3;
};
};
+ 985674EF2B663E0D003FA5A0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 10.20.0;
+ };
+ };
+ 98D04FFB2B7871F200889156 /* XCRemoteSwiftPackageReference "SwiftUI-Custom-TextField" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/esatgozcu/SwiftUI-Custom-TextField";
+ requirement = {
+ branch = main;
+ kind = branch;
+ };
+ };
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@@ -716,6 +831,31 @@
package = 983014C02B451A3E004A6A07 /* XCRemoteSwiftPackageReference "swiftui-navigation-transitions" */;
productName = NavigationTransitions;
};
+ 985674F02B663E0D003FA5A0 /* FirebaseAuth */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 985674EF2B663E0D003FA5A0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
+ productName = FirebaseAuth;
+ };
+ 985674F22B663E0D003FA5A0 /* FirebaseFirestore */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 985674EF2B663E0D003FA5A0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
+ productName = FirebaseFirestore;
+ };
+ 985674F42B663E0D003FA5A0 /* FirebaseFirestoreSwift */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 985674EF2B663E0D003FA5A0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
+ productName = FirebaseFirestoreSwift;
+ };
+ 985674F62B663E0D003FA5A0 /* FirebaseStorage */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 985674EF2B663E0D003FA5A0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
+ productName = FirebaseStorage;
+ };
+ 98D04FFC2B7871F200889156 /* CustomTextField */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 98D04FFB2B7871F200889156 /* XCRemoteSwiftPackageReference "SwiftUI-Custom-TextField" */;
+ productName = CustomTextField;
+ };
/* End XCSwiftPackageProductDependency section */
};
rootObject = 983286A92B05698E00851B19 /* Project object */;
diff --git a/Rethread/Rethread.xcodeproj/xcuserdata/parsakargari.xcuserdatad/xcschemes/xcschememanagement.plist b/Rethread/Rethread.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
similarity index 50%
rename from Rethread/Rethread.xcodeproj/xcuserdata/parsakargari.xcuserdatad/xcschemes/xcschememanagement.plist
rename to Rethread/Rethread.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
index c636354..0c67376 100644
--- a/Rethread/Rethread.xcodeproj/xcuserdata/parsakargari.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/Rethread/Rethread.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -1,14 +1,5 @@
-
- SchemeUserState
-
- Rethread.xcscheme_^#shared#^_
-
- orderHint
- 0
-
-
-
+
diff --git a/Rethread/Rethread.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Rethread/Rethread.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
deleted file mode 100644
index 81d08fe..0000000
--- a/Rethread/Rethread.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "pins" : [
- {
- "identity" : "swiftui-introspect",
- "kind" : "remoteSourceControl",
- "location" : "https://github.com/siteline/swiftui-introspect",
- "state" : {
- "revision" : "9e1cc02a65b22e09a8251261cccbccce02731fc5",
- "version" : "1.1.1"
- }
- },
- {
- "identity" : "swiftui-navigation-transitions",
- "kind" : "remoteSourceControl",
- "location" : "https://github.com/davdroman/swiftui-navigation-transitions.git",
- "state" : {
- "revision" : "a6a3c70ad5d771bd1e927fb55897231cd9592024",
- "version" : "0.13.3"
- }
- }
- ],
- "version" : 2
-}
diff --git a/Rethread/Rethread.xcodeproj/project.xcworkspace/xcuserdata/mortezafaraji.xcuserdatad/UserInterfaceState.xcuserstate b/Rethread/Rethread.xcodeproj/project.xcworkspace/xcuserdata/mortezafaraji.xcuserdatad/UserInterfaceState.xcuserstate
deleted file mode 100644
index b5e369f..0000000
Binary files a/Rethread/Rethread.xcodeproj/project.xcworkspace/xcuserdata/mortezafaraji.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ
diff --git a/Rethread/Rethread.xcodeproj/project.xcworkspace/xcuserdata/parsakargari.xcuserdatad/UserInterfaceState.xcuserstate b/Rethread/Rethread.xcodeproj/project.xcworkspace/xcuserdata/parsakargari.xcuserdatad/UserInterfaceState.xcuserstate
deleted file mode 100644
index d7ee170..0000000
Binary files a/Rethread/Rethread.xcodeproj/project.xcworkspace/xcuserdata/parsakargari.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ
diff --git a/Rethread/Rethread.xcodeproj/xcuserdata/mortezafaraji.xcuserdatad/xcschemes/xcschememanagement.plist b/Rethread/Rethread.xcodeproj/xcuserdata/mortezafaraji.xcuserdatad/xcschemes/xcschememanagement.plist
deleted file mode 100644
index c636354..0000000
--- a/Rethread/Rethread.xcodeproj/xcuserdata/mortezafaraji.xcuserdatad/xcschemes/xcschememanagement.plist
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
- SchemeUserState
-
- Rethread.xcscheme_^#shared#^_
-
- orderHint
- 0
-
-
-
-
diff --git a/Rethread/Rethread.xcodeproj/xcuserdata/parsakargari.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Rethread/Rethread.xcodeproj/xcuserdata/parsakargari.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
deleted file mode 100644
index a9d4ab5..0000000
--- a/Rethread/Rethread.xcodeproj/xcuserdata/parsakargari.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
diff --git a/Rethread/Rethread/.DS_Store b/Rethread/Rethread/.DS_Store
index 71e5808..eb14a59 100644
Binary files a/Rethread/Rethread/.DS_Store and b/Rethread/Rethread/.DS_Store differ
diff --git a/Rethread/Rethread/Assets.xcassets/.DS_Store b/Rethread/Rethread/Assets.xcassets/.DS_Store
new file mode 100644
index 0000000..6ddd850
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/.DS_Store differ
diff --git a/Rethread/Rethread/Assets.xcassets/appleLogo.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/appleLogo.imageset/Contents.json
new file mode 100644
index 0000000..a33044f
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/appleLogo.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "appleLogo.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Rethread/Rethread/Assets.xcassets/appleLogo.imageset/appleLogo.png b/Rethread/Rethread/Assets.xcassets/appleLogo.imageset/appleLogo.png
new file mode 100644
index 0000000..263562e
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/appleLogo.imageset/appleLogo.png differ
diff --git a/Rethread/Rethread/Assets.xcassets/brandCard_1.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/brandCard_1.imageset/Contents.json
new file mode 100644
index 0000000..07bc69b
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/brandCard_1.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "patagonia.jpeg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Rethread/Rethread/Assets.xcassets/brandCard_1.imageset/patagonia.jpeg b/Rethread/Rethread/Assets.xcassets/brandCard_1.imageset/patagonia.jpeg
new file mode 100644
index 0000000..a202c7a
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/brandCard_1.imageset/patagonia.jpeg differ
diff --git a/Rethread/Rethread/Assets.xcassets/brandCard_2.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/brandCard_2.imageset/Contents.json
new file mode 100644
index 0000000..848f235
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/brandCard_2.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "tentree_Logo.jpg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Rethread/Rethread/Assets.xcassets/brandCard_2.imageset/tentree_Logo.jpg b/Rethread/Rethread/Assets.xcassets/brandCard_2.imageset/tentree_Logo.jpg
new file mode 100644
index 0000000..019c071
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/brandCard_2.imageset/tentree_Logo.jpg differ
diff --git a/Rethread/Rethread/Assets.xcassets/brandCard_3.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/brandCard_3.imageset/Contents.json
new file mode 100644
index 0000000..979e884
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/brandCard_3.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "Pact_Logo_Grey_ID_Logo.jpg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Rethread/Rethread/Assets.xcassets/brandCard_3.imageset/Pact_Logo_Grey_ID_Logo.jpg b/Rethread/Rethread/Assets.xcassets/brandCard_3.imageset/Pact_Logo_Grey_ID_Logo.jpg
new file mode 100644
index 0000000..d9a08cf
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/brandCard_3.imageset/Pact_Logo_Grey_ID_Logo.jpg differ
diff --git a/Rethread/Rethread/Assets.xcassets/clothingCard_1.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/clothingCard_1.imageset/Contents.json
new file mode 100644
index 0000000..3444f35
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/clothingCard_1.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "download.jpg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Rethread/Rethread/Assets.xcassets/clothingCard_1.imageset/download.jpg b/Rethread/Rethread/Assets.xcassets/clothingCard_1.imageset/download.jpg
new file mode 100644
index 0000000..d9bf8c3
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/clothingCard_1.imageset/download.jpg differ
diff --git a/Rethread/Rethread/Assets.xcassets/flowerMainPage.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/flowerMainPage.imageset/Contents.json
new file mode 100644
index 0000000..031c178
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/flowerMainPage.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "Screenshot 2024-02-10 at 7.44.59 PM.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git "a/Rethread/Rethread/Assets.xcassets/flowerMainPage.imageset/Screenshot 2024-02-10 at 7.44.59\342\200\257PM.png" "b/Rethread/Rethread/Assets.xcassets/flowerMainPage.imageset/Screenshot 2024-02-10 at 7.44.59\342\200\257PM.png"
new file mode 100644
index 0000000..907f632
Binary files /dev/null and "b/Rethread/Rethread/Assets.xcassets/flowerMainPage.imageset/Screenshot 2024-02-10 at 7.44.59\342\200\257PM.png" differ
diff --git a/Rethread/Rethread/Assets.xcassets/googleLogo.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/googleLogo.imageset/Contents.json
new file mode 100644
index 0000000..4fe01b3
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/googleLogo.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "googleLogo.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Rethread/Rethread/Assets.xcassets/googleLogo.imageset/googleLogo.png b/Rethread/Rethread/Assets.xcassets/googleLogo.imageset/googleLogo.png
new file mode 100644
index 0000000..bf4722a
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/googleLogo.imageset/googleLogo.png differ
diff --git a/Rethread/Rethread/Assets.xcassets/starSky.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/king.imageset/Contents.json
similarity index 88%
rename from Rethread/Rethread/Assets.xcassets/starSky.imageset/Contents.json
rename to Rethread/Rethread/Assets.xcassets/king.imageset/Contents.json
index 4aa7228..09b8b72 100644
--- a/Rethread/Rethread/Assets.xcassets/starSky.imageset/Contents.json
+++ b/Rethread/Rethread/Assets.xcassets/king.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "starSky.jpg",
+ "filename" : "king.jpeg",
"idiom" : "universal",
"scale" : "1x"
},
diff --git a/Rethread/Rethread/Assets.xcassets/king.imageset/king.jpeg b/Rethread/Rethread/Assets.xcassets/king.imageset/king.jpeg
new file mode 100644
index 0000000..4f6bef7
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/king.imageset/king.jpeg differ
diff --git a/Rethread/Rethread/Assets.xcassets/metaLogo.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/metaLogo.imageset/Contents.json
new file mode 100644
index 0000000..c749717
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/metaLogo.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "metaLogo.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Rethread/Rethread/Assets.xcassets/metaLogo.imageset/metaLogo.png b/Rethread/Rethread/Assets.xcassets/metaLogo.imageset/metaLogo.png
new file mode 100644
index 0000000..84a24cc
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/metaLogo.imageset/metaLogo.png differ
diff --git a/Rethread/Rethread/Assets.xcassets/starSky.imageset/starSky.jpg b/Rethread/Rethread/Assets.xcassets/starSky.imageset/starSky.jpg
deleted file mode 100644
index 9a64bd5..0000000
Binary files a/Rethread/Rethread/Assets.xcassets/starSky.imageset/starSky.jpg and /dev/null differ
diff --git a/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/.DS_Store b/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/.DS_Store differ
diff --git a/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/Contents.json b/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/Contents.json
new file mode 100644
index 0000000..594d773
--- /dev/null
+++ b/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "sweatshirt.jpeg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/sweatshirt.jpeg b/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/sweatshirt.jpeg
new file mode 100644
index 0000000..befdd4f
Binary files /dev/null and b/Rethread/Rethread/Assets.xcassets/sweatshirt.imageset/sweatshirt.jpeg differ
diff --git a/Rethread/Rethread/Components/CustomDropdownMenu.swift b/Rethread/Rethread/Components/CustomDropdownMenu.swift
index 6020c5f..d90a3ec 100644
--- a/Rethread/Rethread/Components/CustomDropdownMenu.swift
+++ b/Rethread/Rethread/Components/CustomDropdownMenu.swift
@@ -23,7 +23,7 @@ struct CustomDropdownMenu: View {
}
.padding(.horizontal)
.padding(.vertical, 1.5)
- .foregroundColor(Color.primaryTextColor)
+ .foregroundColor(Color.primaryDark)
if isSelecting {
Divider()
@@ -40,7 +40,7 @@ struct CustomDropdownMenu: View {
.padding(.vertical)
.background(
RoundedRectangle(cornerRadius: 10)
- .strokeBorder(Color.gray, lineWidth: 1)
+ .strokeBorder(Color.primaryDark, lineWidth: 1)
.background(Color.white)
.cornerRadius(10)
)
@@ -54,6 +54,7 @@ struct CustomDropdownMenu: View {
}
.animation(.easeInOut(duration: 0.3))
}
+
}
private func dropDownItemsList() -> some View {
diff --git a/Rethread/Rethread/Components/CustomField.swift b/Rethread/Rethread/Components/CustomField.swift
new file mode 100644
index 0000000..7da1400
--- /dev/null
+++ b/Rethread/Rethread/Components/CustomField.swift
@@ -0,0 +1,25 @@
+import SwiftUI
+import CustomTextField
+
+struct CustomField: View {
+ @Binding var text: String
+ var titleText: String
+ var placeHolderText: String
+ var secureText: Bool = false
+
+ var body: some View {
+ EGTextField(text: $text)
+ .setTitleText(titleText)
+ .setTitleColor(Color.primaryDark)
+ .setPlaceHolderText(placeHolderText)
+ .setPlaceHolderTextColor(Color.PrimaryLight)
+ .setTruncateMode(.tail)
+ .setBorderColor(.primaryDark)
+ .setTextColor(Color.primaryDark)
+ .setDisableAutoCorrection(true)
+ .setTextFieldHeight(48)
+ .setFocusedBorderColorEnable(true)
+ .setSecureText(secureText)
+ .setTrailingImageForegroundColor(Color.primaryDark)
+ }
+}
diff --git a/Rethread/Rethread/Components/Verification.swift b/Rethread/Rethread/Components/Verification.swift
new file mode 100644
index 0000000..634ed37
--- /dev/null
+++ b/Rethread/Rethread/Components/Verification.swift
@@ -0,0 +1,99 @@
+import SwiftUI
+
+
+struct Verification: View {
+ @Binding var otpFields: [String]
+ @State var otpText: String
+
+ // Text Field Focus State
+ @FocusState var activeField: OTPField?
+
+ var body: some View {
+ VStack {
+ OTPField()
+ }
+ .padding()
+ .frame(maxHeight: .infinity, alignment: .top)
+ .onChange(of: otpFields) { newValue in
+ OTPCondition(value: newValue)
+ }
+ }
+
+ func checkStates()->Bool {
+ for index in 0..<6 {
+ if otpFields[index].isEmpty { return true }
+ }
+
+ return false
+ }
+
+ // MARK: Only one character per input & Moving
+ func OTPCondition(value: [String]) {
+
+ // Move Front
+ for index in 0..<5 {
+ if value[index].count == 1 && activeStateForIndex(index: index) == activeField {
+ activeField = activeStateForIndex(index: index + 1)
+ }
+ }
+
+ //Move back if current is empty and back is not
+ for index in 1...5 {
+ if value[index].isEmpty && !value[index - 1].isEmpty {
+ activeField = activeStateForIndex(index: index - 1)
+ }
+ }
+
+ for index in 0..<6 {
+ if value[index].count > 1 {
+ otpFields[index] = String(value[index].last!)
+ }
+ }
+ }
+
+ @ViewBuilder
+ func OTPField()->some View {
+ HStack(spacing: 14) {
+ ForEach(0..<6, id: \.self) { index in
+ VStack (spacing: 8) {
+ TextField("", text: $otpFields[index])
+ .keyboardType(.numberPad)
+ .textContentType(.oneTimeCode)
+ .multilineTextAlignment(.center)
+ .frame(width: 45, height: 45)
+ .overlay(RoundedRectangle(cornerRadius: 8).stroke(
+ activeField == activeStateForIndex(index: index) ? Color.primaryDark.opacity(0.4) : Color.primaryDark,
+ lineWidth: 1))
+ .focused($activeField, equals: activeStateForIndex(index: index))
+
+
+ }
+ .frame(width: 40)
+ }
+ }
+ }
+
+ func activeStateForIndex (index: Int) -> OTPField {
+ switch index {
+ case 0: return .field1
+ case 1: return .field2
+ case 2: return .field3
+ case 3: return .field4
+ case 4: return .field5
+ default: return .field6
+ }
+ }
+}
+
+enum OTPField {
+ case field1
+ case field2
+ case field3
+ case field4
+ case field5
+ case field6
+}
+
+#Preview {
+ Verification(otpFields: .constant(["","","","","",""]), otpText: "")
+}
diff --git a/Rethread/Rethread/Core/ContentView.swift b/Rethread/Rethread/Core/ContentView.swift
new file mode 100644
index 0000000..f15249f
--- /dev/null
+++ b/Rethread/Rethread/Core/ContentView.swift
@@ -0,0 +1,22 @@
+import SwiftUI
+
+struct ContentView: View {
+ @EnvironmentObject var viewModel: AuthViewModel
+
+
+ var body: some View {
+ Group {
+ if viewModel.isLoading {
+ ProgressView("Loading...")
+ } else {
+ if viewModel.currentUser?.onboardingComplete == false {
+ WelcomeView()
+ } else if viewModel.userSession != nil {
+ HomeView()
+ } else {
+ MainView()
+ }
+ }
+ }
+ }
+}
diff --git a/Rethread/Rethread/Core/OnboardingApp.swift b/Rethread/Rethread/Core/OnboardingApp.swift
index 05a2d43..366e95a 100644
--- a/Rethread/Rethread/Core/OnboardingApp.swift
+++ b/Rethread/Rethread/Core/OnboardingApp.swift
@@ -1,12 +1,20 @@
// OnboardingApp.swift
import SwiftUI
+import Firebase
@main
struct OnboardingApp: App {
+ @StateObject var viewModel = AuthViewModel()
+
+ init() {
+ FirebaseApp.configure()
+ }
+
var body: some Scene {
WindowGroup {
- MainView()
+ ContentView()
+ .environmentObject(viewModel)
}
}
}
diff --git a/Rethread/Rethread/Info.plist b/Rethread/Rethread/Info.plist
new file mode 100644
index 0000000..83fb1ab
--- /dev/null
+++ b/Rethread/Rethread/Info.plist
@@ -0,0 +1,17 @@
+
+
+
+
+ CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLSchemes
+
+ com.googleusercontent.apps.69711373157-smt51cs82nik0nceo6slguta9vmaip00
+
+
+
+
+
diff --git a/Rethread/Rethread/MainView.swift b/Rethread/Rethread/MainView.swift
deleted file mode 100644
index 9e58835..0000000
--- a/Rethread/Rethread/MainView.swift
+++ /dev/null
@@ -1,128 +0,0 @@
-import SwiftUI
-import NavigationTransitions
-
-#if canImport(UIKit)
-extension View {
- func hideKeyboard() {
- UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
- }
-}
-#endif
-
-struct MainView: View {
- @AppStorage("isLoggedIn") var isLoggedIn = false
- @State private var path: [String] = []
-
- var body: some View {
- NavigationStack (path: $path) {
- ZStack (alignment: .bottom) {
- // Add Image
- Image("starSky")
- .resizable()
- .overlay(Color.black.opacity(0.01))
- .clipped()
- .edgesIgnoringSafeArea(.all)
- .padding(.bottom, 210)
-
- // Description text
- VStack {
- Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit purus sit amet luctus venenatis, lectus magna fringilla urna.")
- .font(.body)
- .foregroundColor(.gray)
- .multilineTextAlignment(.center)
- .padding(.horizontal, 25)
- .padding(.bottom, 55)
- .padding(.top, 35)
-
-
-
- HStack(spacing: 30) {
- // Log In Button
- Button(action: {
- path.append("SignInView")
- }) {
- HStack {
- Text("Log In")
- Image(systemName: "arrow.right.circle")
- }
- .frame(maxWidth: .infinity)
- }
- .buttonStyle(PrimaryButtonStyle())
-
- // Sign Up Button
- Button(action: {
- path.append("SignUpView")
- }) {
- HStack {
- Text("Join Us")
- Image(systemName: "person.crop.circle.badge.plus")
- }
- .frame(maxWidth: .infinity)
- }
- .buttonStyle(SecondaryButtonStyle())
- }
- .padding(.horizontal)
- .padding(.bottom, 15)
- .navigationDestination(for: String.self) { view in
- if view == "SignInView" {
- SignInView(path: $path)
- } else if view == "SignUpView" {
- SignUpView(path: $path)
- } else if view == "WelcomeView" {
- WelcomeView(path: $path)
- }
- }
- }
- .frame(maxWidth: .infinity)
- .background(Color.white) // Background for text readability
- .cornerRadius(20)
- .edgesIgnoringSafeArea(.bottom)
- }
- .frame(maxHeight: .infinity)
- .onAppear() {
- if isLoggedIn {
-
- // Get user data from database and store in userDefaults
- // We want to check if the user has onboarding completed or not
- // If not, we want to show the onboarding view
-
- // If logged in, and onboarding is not completed, show onboarding
- }
- }
- }
- .navigationTransition(.slide(axis: .vertical))
- // Safe area for iPhone X and above
- .edgesIgnoringSafeArea(.all) // This will extend the content to the edges
- .background(Color(UIColor.systemGray6))
- .overlay(
- GeometryReader { geometry in
- Color.white.opacity(0.65) // Adjust the opacity here for semi-transparency
- .frame(width: geometry.size.width, height: geometry.safeAreaInsets.top)
- .edgesIgnoringSafeArea(.top)
- }, alignment: .top
- )
- }
-}
-
-struct CustomTextField: View {
- var placeholder: String
- @Binding var text: String
-
- var body: some View {
- TextField(placeholder, text: $text)
- .foregroundColor(Color.primaryTextColor)
- .padding()
- .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray, lineWidth: 1))
- .zIndex(-1)
- }
-
-}
-
-#if DEBUG
-struct MainView_Previews: PreviewProvider {
- static var previews: some View {
- MainView()
- }
-}
-#endif
-
diff --git a/Rethread/Rethread/Models/MapViewModel.swift b/Rethread/Rethread/Models/MapViewModel.swift
new file mode 100644
index 0000000..7526762
--- /dev/null
+++ b/Rethread/Rethread/Models/MapViewModel.swift
@@ -0,0 +1,47 @@
+// MapViewModel.swift
+
+import MapKit
+
+
+final class MapViewModel: NSObject, ObservableObject, CLLocationManagerDelegate {
+
+ @Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.331516, longitude: -121.891054), span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05))
+
+
+ var locationManager: CLLocationManager?
+
+ func isUserLocationOn() {
+ if CLLocationManager.locationServicesEnabled() {
+ locationManager = CLLocationManager()
+ locationManager!.delegate = self
+ }
+ else {
+ print("Show an alert showing user that they need to turn on location")
+ }
+ }
+
+ private func checkLocationAuthorization () {
+ guard let locationManager = locationManager else { return }
+
+
+ switch locationManager.authorizationStatus {
+
+ case .notDetermined:
+ locationManager.requestWhenInUseAuthorization()
+ case .restricted:
+ print("Sorry! Your location is restricted.")
+ case .denied:
+ print("You have denied ReThread the use of your location. Go into settings to allow premissions.")
+ case .authorizedAlways, .authorizedWhenInUse:
+ region = MKCoordinateRegion(center: locationManager.location!.coordinate,
+ span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05))
+ @unknown default:
+ break
+ }
+ }
+
+ func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
+ checkLocationAuthorization()
+ }
+
+}
diff --git a/Rethread/Rethread/QuestionView.swift b/Rethread/Rethread/QuestionView.swift
deleted file mode 100644
index 0c60716..0000000
--- a/Rethread/Rethread/QuestionView.swift
+++ /dev/null
@@ -1,84 +0,0 @@
-import SwiftUI
-
-struct QuestionView: View {
- var question: String
- var options: [String]
- var isLastPage: Bool
- var action: () -> Void
- var previousAction: () -> Void
-
- @Binding var selectedAnswers: [String] // Directly using the binding to manage state
-
- private func currentButtonStyle() -> AnyButtonStyle {
- if isLastPage {
- return AnyButtonStyle(LetStartButtonStyle(isEnabled: !selectedAnswers.isEmpty))
- } else {
- return AnyButtonStyle(NextButtonStyle(isEnabled: !selectedAnswers.isEmpty))
- }
- }
-
- var body: some View {
- VStack {
- Text(question)
- .font(.body)
- .foregroundColor(.gray)
- .padding(.top, 100)
- .padding(.bottom, 40)
- .frame(maxWidth: .infinity, alignment: .leading)
- .padding(.horizontal, 20.0)
-
- ForEach(options, id: \.self) { option in
- OptionRow(option: option, isSelected: selectedAnswers.contains(option)) {
- if let index = selectedAnswers.firstIndex(of: option) {
- selectedAnswers.remove(at: index) // Deselect the option
- } else {
- selectedAnswers.append(option) // Select the option
- }
- }
- }
- .padding([.leading, .trailing], 35)
-
- Spacer()
-
- // Navigation buttons
- HStack {
- Button(action: previousAction) {
- Image(systemName: "chevron.left")
- .font(.title)
- }
- .buttonStyle(PreviousButtonStyle())
-
- Spacer()
-
- Button(action: action) {
- if isLastPage {
- Text("Let's Start!")
- .font(.body)
- .foregroundColor(.white)
- } else {
- Image(systemName: "chevron.right")
- .font(.title)
- }
- }
- .buttonStyle(currentButtonStyle())
- .disabled(selectedAnswers.isEmpty)
- }
- .padding(.bottom, 70)
-
- }
- .background(Color(UIColor.systemGray6)) // Use the system background color
- .edgesIgnoringSafeArea(.all)
- }
-}
-
-struct AnyButtonStyle: ButtonStyle {
- private let _makeBody: (Configuration) -> AnyView
-
- init(_ style: Style) {
- self._makeBody = { configuration in AnyView(style.makeBody(configuration: configuration)) }
- }
-
- func makeBody(configuration: Configuration) -> some View {
- self._makeBody(configuration)
- }
-}
diff --git a/Rethread/Rethread/SignInView.swift b/Rethread/Rethread/SignInView.swift
deleted file mode 100644
index 90d88ec..0000000
--- a/Rethread/Rethread/SignInView.swift
+++ /dev/null
@@ -1,144 +0,0 @@
-import SwiftUI
-
-
-
-struct SignInView: View {
- @Binding var path: [String]
- @State private var email: String = ""
- @State private var password: String = ""
- @State private var isShowingVerification: Bool = false
- @State private var isPasswordVisible: Bool = false
- @FocusState var isFieldFocus: FieldToFocus?
- @Environment(\.dismiss) private var dismiss
-
- enum FieldToFocus {
- case secureField, textField
- }
-
- var body: some View {
- VStack {
- // Top content, including the back button and text fields
- VStack(alignment: .leading) {
- HStack {
- Button(action: {
- dismiss()
- }) {
- Image(systemName: "chevron.left")
- }
- .buttonStyle(SecondaryButtonStyle(width: 15, height: 15))
- .clipShape(Circle())
- Spacer()
- }
- .padding(.horizontal)
- .padding(.top, 40)
- .padding(.bottom, 20)
-
- Text("Welcome back!")
- .font(.largeTitle)
- .fontWeight(.bold)
- .padding(.horizontal, 25)
- .padding(.bottom, 1)
- .foregroundColor(Color.primaryColor)
-
- HStack (spacing: 0) {
- Text("Login below or ")
- .fontWeight(.medium)
- .foregroundColor(Color.primaryColor)
- Button(action: {
- path.removeLast()
- path.append("SignUpView")
- }) {
- Text("create an account")
- .foregroundColor(Color.primaryColor)
- .fontWeight(.bold)
- .underline() // Underlined text
- }
- Spacer()
- }
- .padding(.horizontal, 25)
-
-
- VStack(alignment: .leading, spacing: 0) {
- Text("Email")
- .foregroundColor(Color.primaryColor)
- .padding(.horizontal, 25)
- .padding(.top, 25)
-
- CustomTextField(placeholder: "Email", text: $email)
- .padding(.horizontal, 25)
- .padding(.top, 9)
-
- Text("Password")
- .foregroundColor(Color.primaryColor)
- .padding(.horizontal, 25)
- .padding(.top, 20)
- .padding(.bottom, 9)
-
- HStack {
- if isPasswordVisible {
- TextField("Password", text: $password)
- .disableAutocorrection(true)
- .autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
- .focused($isFieldFocus, equals: .textField)
- } else {
- SecureField("Password", text: $password)
- .disableAutocorrection(true)
- .autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
- .focused($isFieldFocus, equals: .secureField)
- }
-
- Button(action: {
- self.isPasswordVisible.toggle()
- }) {
- Image(systemName: self.isPasswordVisible ? "eye.slash.fill" : "eye.fill")
- .foregroundColor(Color.gray)
- }
- }
- .padding()
- .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray, lineWidth: 1))
- .padding(.horizontal, 25)
- .onChange(of: isPasswordVisible) { newValue in
- isFieldFocus = isPasswordVisible ? .textField : .secureField
- }
- }
-
- Spacer()
- }
-
- // Bottom content, including the sign-in button
- VStack (spacing: 16) {
- Button("Sign In") {
- // Handle sign in action
- self.isShowingVerification = true
- }
- .buttonStyle(PrimaryButtonStyle(width: 300))
-
-
-
- Button(action: {
- // Handle forgot password action
- }) {
- Text("Forgot Password")
- .foregroundColor(Color.primaryColor)
- .fontWeight(.semibold)
- .underline() // Underlined text
- }
- }
- .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) // Aligns buttons to the bottom
- }
- .fullScreenCover(isPresented: $isShowingVerification) {
- VerificationView(isSignIn: true, path: $path)
- }
- .gesture(TapGesture().onEnded{
- self.hideKeyboard()
- })
- .ignoresSafeArea(.keyboard)
- .navigationBarBackButtonHidden(true)
- }
-}
-
-struct MainView2_Previews: PreviewProvider {
- static var previews: some View {
- MainView()
- }
-}
diff --git a/Rethread/Rethread/SignUpView.swift b/Rethread/Rethread/SignUpView.swift
deleted file mode 100644
index 8a18f0d..0000000
--- a/Rethread/Rethread/SignUpView.swift
+++ /dev/null
@@ -1,264 +0,0 @@
-import SwiftUI
-
-struct SignUpView: View {
- @Binding var path: [String]
- @State private var isShowingVerification: Bool = false
- struct SignUpFormData {
- var firstName: String = "" // First name text field
- var lastName: String = "" // Last name text field
- var email: String = "" // Email text field
- var password: String = "" // Password text field
- var confirmPassword: String = "" // Confirm password text field
- var phoneNumber: String = "" // Phone number text field
- var postalCode: String = "" // Zip code text field
- var dateOfBirth: String = "" // Date of birth text field
- var gender: String = "Male" // Gender text field
- }
- @State private var formData = SignUpFormData()
- @State private var isPasswordVisible = false
- @State private var showingDatePicker = false
- @State private var showingTermsAndConditions = false
- @State private var showingGenderPicker = false
- @State private var genderOptions = ["Male", "Female", "Other"]
- @State private var areTermsAccepted = false
- @Environment(\.dismiss) private var dismiss
-
- func toggleDatePicker() {
- showingDatePicker.toggle()
- }
-
-
- var body: some View {
- ZStack {
- VStack {
- // Top content, including the back button and text fields
- ScrollView {
- VStack(alignment: .leading) {
- HStack {
- Button(action: {
- dismiss()
- }) {
- Image(systemName: "chevron.left")
- }
- .buttonStyle(SecondaryButtonStyle(width: 15, height: 15))
- .clipShape(Circle())
- Spacer()
- }
- .padding(.horizontal)
- .padding(.top, 40)
- .padding(.bottom, 20)
-
- Text("Create an account")
- .font(.largeTitle)
- .fontWeight(.bold)
- .padding(.horizontal, 25)
- .padding(.bottom, 1)
- .foregroundColor(Color.primaryColor)
-
- HStack (spacing: 0) {
- Text("Enter your account details below or ")
- .fontWeight(.medium)
- .foregroundColor(Color.primaryColor)
- Button(action: {
- path.removeLast()
- path.append("SignInView")
- }) {
- Text("log in")
- .foregroundColor(Color.primaryColor)
- .fontWeight(.bold)
- .underline() // Underlined text
- }
- Spacer()
- }
- .padding(.horizontal, 25)
- .padding(.bottom, 10)
- }
-
- VStack(alignment: .leading) {
- VStack(alignment: .leading, spacing: 0) {
- HStack {
- VStack(alignment: .leading, spacing: 0) {
- Text("First Name")
- .foregroundColor(Color.primaryColor)
- .padding(.leading, 25)
- .padding(.top, 20)
-
- CustomTextField(placeholder: "First Name", text: $formData.firstName)
- .padding(.leading, 25)
- .padding(.top, 9)
- }
-
- VStack(alignment: .leading, spacing: 0) {
- Text("Last Name")
- .foregroundColor(Color.primaryColor)
- .padding(.trailing, 25)
- .padding(.top, 20)
-
- CustomTextField(placeholder: "Last Name", text: $formData.lastName)
- .padding(.trailing, 25)
- .padding(.top, 9)
- }
- }
-
- Text("Email")
- .foregroundColor(Color.primaryColor)
- .padding(.horizontal, 25)
- .padding(.top, 20)
-
- CustomTextField(placeholder: "Email", text: $formData.email)
- .padding(.horizontal, 25)
- .padding(.top, 9)
- HStack {
- VStack (alignment: .leading, spacing: 0){
- Text("Date of Birth")
- .foregroundColor(Color.primaryColor)
- .padding(.top, 20)
-
- HStack {
- TextField("MM / DD / YYYY", text: $formData.dateOfBirth )
- .foregroundColor(Color.primaryTextColor)
- .keyboardType(.numberPad)
- .onChange(of: formData.dateOfBirth) { newValue in
- formData.dateOfBirth = formatDate(newValue)
- }
-
-
- Button(action: {
- // Actions to present a date picker
- toggleDatePicker()
- }) {
- Image(systemName: "calendar")
- .foregroundColor(.gray)
- }
- }
- .padding()
- .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray, lineWidth: 1))
- .padding(.top, 9)
- }
-
-
- VStack (alignment: .leading, spacing: 0) {
- Text("Gender")
- .foregroundColor(Color.primaryColor)
- .padding(.trailing, 25)
- .padding(.top, 20)
-
- CustomDropdownMenu(items: [
- DropdownItem(id: 1, title: "Male", onSelect: {formData.gender = "Male"}),
- DropdownItem(id: 2, title: "Female", onSelect: {formData.gender = "Female"}),
- DropdownItem(id: 3, title: "Other", onSelect: {formData.gender = "Other"})
- ])
- .frame(width:130)
- .padding(.top, 9)
-
- }
- }
- .padding(.horizontal, 25)
-
- Text("Phone Number")
- .foregroundColor(Color.primaryColor)
- .padding(.horizontal, 25)
- .padding(.top, 20)
-
- CustomTextField(placeholder: "Phone Number", text: $formData.phoneNumber)
- .padding(.horizontal, 25)
- .padding(.top, 9)
-
- Text("Password")
- .foregroundColor(Color.primaryColor)
- .padding(.horizontal, 25)
- .padding(.top, 20)
- .padding(.bottom, 9)
-
- SecureField("Password", text: $formData.password)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .padding()
- .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray, lineWidth: 1))
- .padding(.horizontal, 25)
-
- Text("Confirm Password")
- .foregroundColor(Color.primaryColor)
- .padding(.horizontal, 25)
- .padding(.top, 20)
- .padding(.bottom, 9)
-
- SecureField("Confirm Password", text: $formData.confirmPassword)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .padding()
- .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray, lineWidth: 1))
- .padding(.horizontal, 25)
-
- Text("Postal Code")
- .foregroundColor(Color.primaryColor)
- .padding(.horizontal, 25)
- .padding(.top, 20)
-
- CustomTextField(placeholder: "Postal Code", text: $formData.postalCode)
- .padding(.horizontal, 25)
- .padding(.top, 9)
-
- }
- }
-
- Spacer()
-
-
- // Bottom content, including the sign-in button
- VStack (spacing: 16) {
- Button("Join Us") {
- // Handle sign up
- print(formData)
- self.isShowingVerification = true
- }
- .buttonStyle(PrimaryButtonStyle(width: 300, isDisabled: !areTermsAccepted))
- .disabled(!areTermsAccepted)
-
- HStack {
- Image(systemName: areTermsAccepted ? "checkmark.square.fill" : "square")
- .foregroundColor(Color.primaryColor)
- .onTapGesture {
- areTermsAccepted.toggle()
- }
- .offset(y: 2)
- .font(.system(size: 20))
-
-
- Button(action: {
- showingTermsAndConditions.toggle()
- }) {
- Text("Terms and Conditions")
- .foregroundColor(Color.primaryColor)
- .fontWeight(.semibold)
- .underline() // Underlined text
- }
- }
- }
- .frame(maxWidth: .infinity) // Aligns buttons to the bottom
- .padding(.vertical, 10)
- }
- }
- .fullScreenCover(isPresented: $isShowingVerification) {
- VerificationView(isSignIn: false, path: $path)
- }
- .gesture(TapGesture().onEnded{
- self.hideKeyboard()
- })
- }
- // Date picker modal
- .sheet(isPresented: $showingDatePicker) {
- DatePickerModalView(showModal: $showingDatePicker, chosenDate: $formData.dateOfBirth)
- .presentationDetents([.fraction(0.7)])
- .presentationDragIndicator(.visible)
-
- }
- .sheet(isPresented: $showingTermsAndConditions){
- TermsAndConditions()
- .presentationDetents([.medium, .large])
- .padding(.horizontal, 15)
- .padding(.top, 15)
- }
- .navigationBarBackButtonHidden(true)
- }
-}
diff --git a/Rethread/Rethread/Styles/ButtonStyles.swift b/Rethread/Rethread/Styles/ButtonStyles.swift
index a2050bb..7d0acac 100644
--- a/Rethread/Rethread/Styles/ButtonStyles.swift
+++ b/Rethread/Rethread/Styles/ButtonStyles.swift
@@ -34,8 +34,7 @@ struct PrimaryButtonStyle: ButtonStyle {
configuration.label
.frame(width: width, height: height) // Use optional binding in case width and height are not provided
.padding()
- .background(configuration.isPressed || isDisabled ? Color(red: 170/255, green: 177/255, blue: 187/255)
- : Color.primaryColor)
+ .background(configuration.isPressed || isDisabled ? Color.GrayDisabled : Color.primaryDark)
.cornerRadius(9)
.foregroundColor(.white)
.scaleEffect(configuration.isPressed ? 0.95 : 1)
@@ -53,10 +52,9 @@ struct SecondaryButtonStyle: ButtonStyle {
configuration.label
.frame(width: width, height: height) // Use optional binding in case width and height are not provided
.padding()
- .background(configuration.isPressed ? Color(red: 214/255, green: 216/255, blue: 219/255)
- : Color(red: 238/255, green: 241/255, blue: 244/255))
+ .background(configuration.isPressed ? Color.GrayDisabled : Color.Secondary)
.cornerRadius(9)
- .foregroundColor(Color(red: 84/255, green: 95/255, blue: 113/255))
+ .foregroundColor(.white)
.scaleEffect(configuration.isPressed ? 0.95 : 1)
}
}
@@ -66,14 +64,15 @@ struct PreviousButtonStyle: ButtonStyle {
configuration.label
.foregroundColor(.white)
.frame(width: 70, height: 60)
- .background(UnevenRoundedRectangle(cornerRadii: .init(
- topLeading: 0.0,
- bottomLeading: 0.0,
- bottomTrailing: 25.0,
- topTrailing: 6.0),
- style: .continuous)
- .fill(configuration.isPressed ? Color(red: 170/255, green: 177/255, blue: 187/255)
- : Color.primaryColor))
+ .background(
+ RoundedCorners(
+ color: !configuration.isPressed ? Color.primaryDark : Color.primaryDark.opacity(0.5),
+ tl: 0,
+ tr: 7,
+ bl: 0,
+ br: 7
+ )
+ )
}
}
@@ -84,14 +83,15 @@ struct NextButtonStyle: ButtonStyle {
configuration.label
.foregroundColor(.white)
.frame(width: 70, height: 60)
- .background(UnevenRoundedRectangle(cornerRadii: .init(
- topLeading: 6.0,
- bottomLeading: 25.0,
- bottomTrailing: 0.0,
- topTrailing: 0.0),
- style: .continuous)
- .fill(isEnabled && !configuration.isPressed ? Color.primaryColor
- : Color(red: 170/255, green: 177/255, blue: 187/255))) // Disabled color
+ .background(
+ RoundedCorners(
+ color: isEnabled && !configuration.isPressed ? Color.Secondary : Color.Secondary.opacity(0.5),
+ tl: 7,
+ tr: 0,
+ bl: 7,
+ br: 0
+ )
+ )
}
}
@@ -102,14 +102,15 @@ struct LetStartButtonStyle: ButtonStyle {
configuration.label
.foregroundColor(.white)
.frame(width: 140, height: 60)
- .background(UnevenRoundedRectangle(cornerRadii: .init(
- topLeading: 6.0,
- bottomLeading: 25.0,
- bottomTrailing: 0.0,
- topTrailing: 0.0),
- style: .continuous)
- .fill(isEnabled && !configuration.isPressed ? Color.primaryColor
- : Color(red: 170/255, green: 177/255, blue: 187/255))) // Disabled color
+ .background(
+ RoundedCorners(
+ color: isEnabled && !configuration.isPressed ? Color.Secondary : Color.Secondary.opacity(0.5),
+ tl: 7,
+ tr: 0,
+ bl: 7,
+ br: 0
+ )
+ )
}
}
diff --git a/Rethread/Rethread/Styles/ColorPalette.swift b/Rethread/Rethread/Styles/ColorPalette.swift
index 4cc4bca..dcb7646 100644
--- a/Rethread/Rethread/Styles/ColorPalette.swift
+++ b/Rethread/Rethread/Styles/ColorPalette.swift
@@ -3,4 +3,11 @@ import SwiftUI
extension Color {
static let primaryColor = Color(red: 102/255, green: 112/255, blue: 128/255)
static let primaryTextColor = Color(red: 84/255, green: 95/255, blue: 113/255)
+
+ // New Colors
+ static let primaryDark = Color(red: 25/255, green: 75/255, blue: 82/255, opacity: 1)
+ static let Secondary = Color(red: 249/255, green: 95/255, blue: 95/255, opacity: 1)
+ static let GrayDisabled = Color(red: 217/255, green: 217/255, blue: 218/255, opacity: 1)
+ static let PrimaryLight = Color(red: 93/255, green: 148/255, blue: 167/255, opacity: 1)
+
}
diff --git a/Rethread/Rethread/UserAuthentication/AuthViewModel.swift b/Rethread/Rethread/UserAuthentication/AuthViewModel.swift
new file mode 100644
index 0000000..ebe927c
--- /dev/null
+++ b/Rethread/Rethread/UserAuthentication/AuthViewModel.swift
@@ -0,0 +1,110 @@
+import Foundation
+import FirebaseCore
+import FirebaseAuth
+import FirebaseFirestore
+import FirebaseFirestoreSwift
+
+@MainActor
+class AuthViewModel: ObservableObject {
+ @Published var userSession: FirebaseAuth.User?
+ @Published var currentUser: User?
+ @Published var CLIENT_CODE: String = ""
+ private var verificationId: String?
+ @Published var isLoading: Bool = true
+
+ init(){
+ self.userSession = Auth.auth().currentUser
+ self.isLoading = true
+ Task {
+ await fetchUser()
+ self.isLoading = false
+ }
+ }
+
+ // Sign In function
+ func signIn(withEmail email: String, password: String) async throws {
+ do {
+ let result = try await Auth.auth().signIn(withEmail: email, password: password)
+ self.userSession = result.user
+ await fetchUser()
+ } catch {
+ print("DEBUG: Failed to log in with error .\(error.localizedDescription)")
+ }
+ }
+
+ // Sign Up a user
+ func createUser(formData: SignUpFormData) async throws {
+ do {
+ let result = try await Auth.auth().createUser(withEmail: formData.email, password: formData.password)
+ self.userSession = result.user
+
+ let user = User(id: result.user.uid, firstname: formData.firstName, lastname: formData.lastName,
+ email: formData.email, dateOfBirth: formData.dateOfBirth, gender: formData.gender,
+ phoneNumber: formData.phoneNumber,postalCode: formData.postalCode, onboardingComplete: false)
+
+ let encodedUser = try Firestore.Encoder().encode(user)
+ try await Firestore.firestore().collection("users").document(user.id).setData(encodedUser)
+ await fetchUser()
+ } catch {
+ print("DEBUG: Error creating user: \(error.localizedDescription)")
+ }
+ }
+
+ func updateOnboardingComplete() async throws {
+ do {
+ let userRef = Firestore.firestore().collection("users").document(userSession!.uid)
+ try await userRef.updateData(["onboardingComplete": true])
+ await fetchUser()
+ } catch {
+ print("DEBUG: Error updating user onboard status: \(error.localizedDescription)")
+ }
+ }
+
+ // Signout
+ func signOut() {
+ do {
+ try Auth.auth().signOut()
+ self.userSession = nil
+ self.currentUser = nil
+ } catch {
+ print("DEBUG: Failed to sign out with error \(error.localizedDescription)")
+ }
+ }
+
+ // Delete Account
+ func deleteAccount() {
+ //TODO: Implement user deleting account.
+ }
+
+ // Fetch User
+ func fetchUser() async {
+ guard let uid = Auth.auth().currentUser?.uid else {return}
+ guard let snapshot = try? await Firestore.firestore().collection("users").document(uid).getDocument() else {return}
+ self.currentUser = try? snapshot.data(as: User.self)
+ }
+
+
+
+// func sendPhoneAuth() async {
+// PhoneAuthProvider.provider().verifyPhoneNumber("+16505551111", uiDelegate: nil) { [weak self] verificationID, error in
+// guard let verificationID = verificationID, error == nil else {
+// print("DEBUG: Error sending phone auth: \(error!.localizedDescription)")
+// return
+// }
+// self?.verificationId = verificationID
+// }
+// }
+// func verifyPhoneAuth(otp: String) async {
+// guard let verificationId = self.verificationId else {return}
+// let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationId, verificationCode: otp)
+//
+// Auth.auth().signIn(with: credential) { (result, error) in
+// if let error = error {
+// print("DEBUG: Error verifying phone auth: \(error.localizedDescription)")
+// return
+// }
+// self.userSession = result?.user
+// }
+// }
+
+}
diff --git a/Rethread/Rethread/UserAuthentication/User.swift b/Rethread/Rethread/UserAuthentication/User.swift
new file mode 100644
index 0000000..58f328b
--- /dev/null
+++ b/Rethread/Rethread/UserAuthentication/User.swift
@@ -0,0 +1,14 @@
+import Foundation
+
+
+struct User: Identifiable, Codable {
+ let id: String
+ let firstname: String
+ let lastname: String
+ let email: String
+ let dateOfBirth: String
+ let gender: String
+ let phoneNumber: String
+ let postalCode: String
+ let onboardingComplete: Bool
+}
diff --git a/Rethread/Rethread/VerificationView.swift b/Rethread/Rethread/VerificationView.swift
deleted file mode 100644
index 015b28a..0000000
--- a/Rethread/Rethread/VerificationView.swift
+++ /dev/null
@@ -1,125 +0,0 @@
-import SwiftUI
-
-struct VerificationView: View {
- // Sign in or Sign up verification?
- @State var isSignIn: Bool
- @Binding var path: [String]
- @Environment(\.dismiss) private var dismiss
- @State private var code: [String] = ["", "", "", ""]
- @FocusState private var focusedField: Field?
-
- enum Field: Int, Hashable {
- case field1 = 0, field2, field3, field4
-
- var next: Field? {
- return Field(rawValue: self.rawValue + 1)
- }
- }
-
-
- var body: some View {
- VStack {
- VStack(alignment: .leading) {
- HStack {
- Button(action: {
- dismiss()
- }) {
- Image(systemName: "chevron.left")
- }
- .buttonStyle(SecondaryButtonStyle(width: 15, height: 15))
- .clipShape(Circle())
- Spacer()
- }
- .padding(.horizontal)
- .padding(.top, 40)
- .padding(.bottom, 20)
-
- Text("Verify your account")
- .font(.largeTitle)
- .fontWeight(.bold)
- .padding(.horizontal, 25)
- .padding(.bottom, 1)
- .foregroundColor(Color.primaryColor)
-
- HStack (spacing: 0) {
- Text("Enter the 4-digit PIN code sent to your email address xxx@example.com.")
- .fontWeight(.medium)
- .foregroundColor(Color.primaryColor)
- Spacer()
- }
- .padding(.horizontal, 25)
-
- VStack(alignment: .leading, spacing: 0) {
- HStack(spacing: 10) {
- ForEach(0..<4, id: \.self) { index in
- TextField("", text: $code[index])
- .frame(width: 45, height: 45)
- .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.primary, lineWidth: 1))
- .multilineTextAlignment(.center)
- .keyboardType(.numberPad)
- .focused($focusedField, equals: Field(rawValue: index))
- .onChange(of: code[index]) { newValue in
- if newValue.count == 1 {
- // A character is entered in the current field
- if index < code.count - 1 {
- // Move to the next field only if it's not the last one
- focusedField = Field(rawValue: index + 1)
- } else {
- // Last field - perhaps perform some action or unfocus
- focusedField = nil
- }
- } else if newValue.isEmpty && index > 0 {
- // Backspace is pressed, and it's not the first field
- // Move to the previous field
- focusedField = Field(rawValue: index - 1)
- }
- }
-
-
-
- }
- }
- .padding(.horizontal, 25)
- .padding(.top, 30)
-
- }
- Spacer()
- }
-
- // Bottom content, including the sign-in button
- VStack (spacing: 16) {
- Button("Verify") {
- // Handle sign in
- if isSignIn {
- // Sign in
- print("Sign in")
- } else {
- withAnimation {
- dismiss()
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
- path.append("WelcomeView")
- }
- }
- }
- }
- .buttonStyle(PrimaryButtonStyle(width: 300))
-
- Button(action: {
- // Handle request new code
- }) {
- Text("Request new code")
- .foregroundColor(Color.primaryColor)
- .fontWeight(.semibold)
- .underline() // Underlined text
- }
- }
- .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) // Aligns buttons to the bottom
- }
- .onTapGesture {
- self.hideKeyboard()
- }
-
- }
-}
-
-
diff --git a/Rethread/Rethread/VideoPlayer/UIPlayerView.swift b/Rethread/Rethread/VideoPlayer/UIPlayerView.swift
index 10ddba6..5dc64f3 100644
--- a/Rethread/Rethread/VideoPlayer/UIPlayerView.swift
+++ b/Rethread/Rethread/VideoPlayer/UIPlayerView.swift
@@ -1,6 +1,5 @@
-import Foundation
-import SwiftUI
-import AVKit
+import UIKit
+import AVFoundation
class UIVideoPlayer: UIView {
@@ -9,7 +8,15 @@ class UIVideoPlayer: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
-
+ setupVideoPlayer()
+ addAppLifecycleObservers()
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ private func setupVideoPlayer() {
guard let url = URL(string: "https://github.com/bbmvicomte/videoOnboardingScreen/blob/master/bounce.mp4?raw=true") else { return }
player = AVPlayer(url: url)
@@ -17,10 +24,8 @@ class UIVideoPlayer: UIView {
playerLayer.player = player
playerLayer.videoGravity = .resizeAspectFill
-
layer.addSublayer(playerLayer)
-
- // Add observer
+
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: .AVPlayerItemDidPlayToEndTime,
@@ -34,18 +39,25 @@ class UIVideoPlayer: UIView {
playerLayer.frame = bounds
}
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
+ @objc private func playerItemDidReachEnd(notification: Notification) {
+ player?.seek(to: CMTime.zero)
+ player?.play()
}
- @objc func playerItemDidReachEnd(notification: Notification) {
- // Restart video from the beginning
- player?.seek(to: CMTime.zero)
+ private func addAppLifecycleObservers() {
+ NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(appWillResignActive), name: UIApplication.willResignActiveNotification, object: nil)
+ }
+
+ @objc private func appDidBecomeActive() {
player?.play()
}
+ @objc private func appWillResignActive() {
+ player?.pause()
+ }
+
deinit {
- // Remove observer
NotificationCenter.default.removeObserver(self)
}
}
diff --git a/Rethread/Rethread/Views/.DS_Store b/Rethread/Rethread/Views/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/Rethread/Rethread/Views/.DS_Store differ
diff --git a/Rethread/Rethread/Views/ClothingItemView.swift b/Rethread/Rethread/Views/ClothingItemView.swift
new file mode 100644
index 0000000..4e885d4
--- /dev/null
+++ b/Rethread/Rethread/Views/ClothingItemView.swift
@@ -0,0 +1,122 @@
+// ClothingItemView.swift
+
+import SwiftUI
+
+struct ClothingItemView: View {
+ let columns: [GridItem] = [
+ GridItem(.flexible()),
+ GridItem(.flexible()),
+ ]
+
+ @State private var isHidden = false
+
+
+ var body: some View {
+
+ VStack {
+ VStack {
+ HomeBarView()
+ MainSearchBar()
+
+ ScrollView(.horizontal, showsIndicators: false) {
+ HStack {
+ Button(action: {
+ withAnimation {
+ isHidden.toggle()
+ }
+ }, label: {
+ Text("Category")
+ Image(systemName: "chevron.down")
+ })
+ .buttonStyle(.borderedProminent)
+ .tint(.white)
+ .foregroundStyle(Color(hex: "#2C4C52"))
+ .overlay(
+ RoundedRectangle(cornerSize: CGSize(width: 5, height: 5))
+ .stroke(Color(hex: "#2C4C52"))
+ )
+
+
+
+ Button(action: {
+ }, label: {
+ Text("Color")
+ Image(systemName: "chevron.down")
+ })
+ .buttonStyle(.borderedProminent)
+ .tint(.white)
+ .foregroundStyle(Color(hex: "#2C4C52"))
+ .overlay(
+ RoundedRectangle(cornerSize: CGSize(width: 5, height: 5))
+ .stroke(Color(hex: "#2C4C52"))
+ )
+
+
+ Button(action: {}, label: {
+ Text("Gender")
+ Image(systemName: "chevron.down")
+
+ })
+ .buttonStyle(.borderedProminent)
+ .tint(.white)
+ .foregroundStyle(Color(hex: "#2C4C52"))
+ .overlay(
+ RoundedRectangle(cornerSize: CGSize(width: 5, height: 5))
+ .stroke(Color(hex: "#2C4C52"))
+ )
+
+ }
+ }
+ .padding(.horizontal)
+ }
+
+ ZStack(alignment: .leading) {
+ VStack {
+ VStack() {
+ Text("PLACEHOLDER")
+ .padding()
+ Spacer()
+
+ }
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
+ .background(.white)
+ VStack {
+ Text("")
+
+ }
+ .frame(maxWidth: .infinity, maxHeight: 300)
+ }
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
+ .zIndex(5)
+ .opacity(isHidden ? 0 : 1)
+ .transition(.slide)
+
+
+
+
+ VStack {
+ HStack {
+ Text("Shirts")
+ .font(.title)
+ .fontWeight(.bold)
+ Spacer()
+ }
+ .padding(.horizontal)
+
+
+ LazyVGrid(columns: columns) {
+ ForEach(0..<3) {index in
+ ClothCard(width: 160, height: 150, clothingItem: Image("sweatshirt"))
+ }
+ }
+ .zIndex(-1)
+ Spacer()
+ }
+ }
+ }
+ }
+}
+
+#Preview {
+ ClothingItemView()
+}
diff --git a/Rethread/Rethread/Views/HomeView.swift b/Rethread/Rethread/Views/HomeView.swift
new file mode 100644
index 0000000..f1d32c6
--- /dev/null
+++ b/Rethread/Rethread/Views/HomeView.swift
@@ -0,0 +1,317 @@
+// HomeView.swift
+
+import SwiftUI
+import MapKit
+
+struct HomeView: View {
+ var body: some View {
+ TabView {
+ Group {
+ ZStack {
+ ScrollView(.vertical, showsIndicators: false) {
+ VStack {
+ HomeBarView()
+
+ MainSearchBar()
+
+ ScrollText() // This is just the"sustainable brands text"
+ BrandCardScrollView()
+
+ ShopByClothingText()
+
+ ClothingCardView()
+
+ SaveWithUsText()
+
+ ScrollView(.horizontal, showsIndicators: false) {
+ HStack {
+ ForEach (0 ..< 3) { index in
+ ClothCard(width: 150, height: 150, clothingItem: Image("sweatshirt") // This isnt the "shop by clothing card" its the real clothing
+ )}
+ }
+ }
+ .padding(.horizontal)
+
+
+ }
+ }
+
+ }
+ .padding(.bottom)
+ .tabItem {
+ Image(systemName: "house")
+ }
+ MapView()
+ .tabItem {
+ Spacer()
+ Image(systemName: "qrcode")
+
+ }
+
+ MapView()
+ .tabItem {
+ Image(systemName: "mappin.circle.fill")
+ }
+ MapView()
+ .tabItem {
+ Image(systemName: "person")
+ .padding(.vertical)
+ }
+ .foregroundStyle(.green)
+ }
+ .accentColor(.purple)
+ .toolbarBackground(.white, for: .tabBar)
+
+
+
+ }
+ }
+}
+
+#Preview {
+ HomeView()
+}
+
+struct HomeBarView: View {
+ @State var isShowingSheet = false
+ var body: some View {
+ HStack {
+ Text("Hey Morteza!")
+ .font(.title2)
+ .titleText()
+ Spacer()
+ Button {
+ isShowingSheet.toggle()
+ } label: {
+ Image(systemName: "slider.horizontal.3")
+ .foregroundStyle(Color(hex: "#2C4C52"))
+ }
+ .sheet(isPresented: $isShowingSheet, content: {
+ FilterView()
+ .presentationDetents([.medium])
+ })
+
+
+ }
+ .padding(.horizontal)
+ }
+}
+
+
+
+extension Color {
+ init(hex: String) {
+ var cleanHexCode = hex.trimmingCharacters(in: .whitespacesAndNewlines)
+ cleanHexCode = cleanHexCode.replacingOccurrences(of: "#", with: "")
+ print(cleanHexCode)
+ var rgb: UInt64 = 0
+
+ Scanner(string: cleanHexCode).scanHexInt64(&rgb)
+
+ let redValue = Double((rgb >> 16) & 0xFF) / 255.0
+ let greenValue = Double((rgb >> 8) & 0xFF) / 255.0
+ let blueValue = Double(rgb & 0xFF) / 255.0
+ self.init(red: redValue, green: greenValue, blue: blueValue)
+ }
+}
+
+struct MainSearchBar: View {
+ @State private var search: String = ""
+ var body: some View {
+ HStack {
+ HStack {
+ TextField("Search Clothes", text: $search)
+ Image(systemName: "magnifyingglass")
+ .foregroundStyle(Color(hex: "#2C4C52"))
+
+ }
+ .padding(.vertical, 10)
+ .padding(.horizontal, 10)
+ .background(.white)
+ .cornerRadius(5)
+ .overlay(
+ RoundedRectangle(cornerSize: CGSize(width: 5, height: 5))
+ .stroke(Color(hex: "#2C4C52"))
+ )
+ }
+ .padding()
+
+
+ }
+}
+
+struct ScrollText: View {
+ var body: some View {
+ HStack {
+ Text("Sustainable Brands")
+ .titleText()
+
+ }
+ .frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, alignment: .leading)
+ .padding(.horizontal)
+ }
+}
+
+struct SaveWithUsText: View {
+ var body: some View {
+ HStack {
+ Text("Save With Us!")
+ .titleText()
+ Spacer()
+ NavigationStack {
+ NavigationLink(destination: ProductView()) {
+ Text("View All")
+ .foregroundStyle(Color(hex: "#2C4C52"))
+ .fontWeight(.semibold)
+ .underline()
+ }
+ }
+
+ }
+ .padding(.horizontal)
+ }
+}
+
+struct FilterView: View {
+ var body: some View {
+ VStack {
+ CustomDropdownMenu(items: [
+ DropdownItem(id: 1, title: "Category", onSelect: {}),
+ DropdownItem(id: 2, title: "Medium", onSelect: {}),
+ DropdownItem(id: 3, title: "Large", onSelect: {}),
+ DropdownItem(id: 4, title: "X-Large", onSelect: {}),
+ ])
+ .frame(maxHeight: .maximum(100, 100))
+
+
+ CustomDropdownMenu(items: [
+ DropdownItem(id: 1, title: "Category", onSelect: {}),
+ DropdownItem(id: 2, title: "Medium", onSelect: {}),
+ DropdownItem(id: 3, title: "Large", onSelect: {}),
+ DropdownItem(id: 4, title: "X-Large", onSelect: {}),
+ ])
+ .frame(maxHeight: .maximum(100, 100))
+
+
+ }
+ .padding()
+ }
+}
+
+struct BrandImageCardView: View {
+ let brandCard: Image
+ var body: some View {
+ HStack {
+ brandCard
+ .brandCard()
+ }
+ }
+}
+
+struct ClothingImageCardView: View {
+ let clothingCard: Image
+ var body: some View {
+ HStack {
+ clothingCard
+ .clothingCard()
+ }
+ }
+}
+
+
+struct BrandCardScrollView: View {
+ var body: some View {
+ ScrollView (.horizontal, showsIndicators: false) {
+ HStack{
+ ForEach(0 ..< 3) { index in
+ BrandImageCardView(brandCard: Image("brandCard_\(index + 1)"))
+ }
+ }
+ }
+ .padding(.horizontal)
+ .padding(.bottom)
+ }
+}
+
+// MARK: EXTENSIONS
+extension Image {
+ func brandCard() -> some View {
+ self
+ .resizable()
+ .frame(width: 200, height: 110)
+ .clipShape(RoundedRectangle(cornerRadius: 5))
+ }
+}
+
+extension Image {
+ func clothingCard() -> some View {
+ self
+ .resizable()
+ .frame(width: 100, height: 250)
+ .clipShape(RoundedRectangle(cornerRadius: 5))
+ }
+
+}
+
+extension Text {
+ func titleText() -> some View {
+ self
+ .foregroundStyle(Color(hex: "#2C4C52"))
+ .fontWeight(.semibold)
+ .font(.title3)
+ }
+}
+
+struct ShopByClothingText: View {
+ var body: some View {
+ Text("Shop By Clothing")
+ .titleText()
+ .frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, alignment: .leading)
+ .padding(.horizontal)
+ }
+}
+
+struct ClothingCardView: View {
+ var body: some View {
+ ScrollView(.horizontal, showsIndicators: false) {
+ HStack {
+ ForEach (0 ..< 4) { index in
+ ClothingImageCardView(clothingCard: Image ("clothingCard_1"))
+ }
+ }
+ }
+ .padding(.horizontal)
+ .padding(.bottom)
+ }
+}
+
+struct ClothCard: View {
+ let width: CGFloat
+ let height: CGFloat
+ let clothingItem: Image
+ var body: some View {
+ VStack (alignment: .leading) {
+ clothingItem
+ .resizable()
+ .frame(width: width, height: height)
+ .clipShape(RoundedRectangle(cornerRadius: 8))
+ Text("Sweat Shirt")
+ .font(.subheadline)
+ Text("$55")
+ .font(.subheadline)
+ }
+ }
+}
+
+struct BottomNavBarItem: View {
+ let image: Image
+ let action: ()-> Void
+ var body: some View {
+ Button(action: action, label: {
+ image
+ .frame(maxWidth: .infinity)
+ .foregroundStyle(Color(hex: "#2C4C52"))
+ .fontWeight(.semibold)
+ })
+ }
+}
diff --git a/Rethread/Rethread/Views/MainView.swift b/Rethread/Rethread/Views/MainView.swift
new file mode 100644
index 0000000..768983d
--- /dev/null
+++ b/Rethread/Rethread/Views/MainView.swift
@@ -0,0 +1,109 @@
+import SwiftUI
+import NavigationTransitions
+
+#if canImport(UIKit)
+extension View {
+ func hideKeyboard() {
+ UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
+ }
+}
+#endif
+
+struct MainView: View {
+ @State private var path: [String] = []
+
+ var body: some View {
+ NavigationStack (path: $path) {
+ ZStack (alignment: .bottom) {
+ // Add Image
+ Image("flowerMainPage")
+ .resizable()
+ .overlay(Color.black.opacity(0.1))
+ .clipped()
+ .edgesIgnoringSafeArea(.all)
+ .padding(.bottom, 220)
+
+ // Botom Part
+ VStack (spacing: 50) {
+
+ HStack {
+ Text("Get involved with" + "\n" + "sustainable fashion")
+ .font(.system(size: 20))
+ .fontWeight(.semibold)
+ .foregroundColor(Color.primaryDark)
+ .opacity(0.5)
+ .multilineTextAlignment(.leading)
+ .lineSpacing(6)
+ Spacer()
+ }
+ .padding(.horizontal, 35)
+ .padding(.top, 25)
+
+
+
+ VStack (spacing: 17) {
+ Button(action: {
+ path.append("SignInView")
+ }) {
+ HStack {
+ Text("Log In")
+ }
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
+ }
+ .buttonStyle(PrimaryButtonStyle(width: 300))
+
+ HStack {
+ Spacer()
+
+ Button(action: {
+ path.append("SignUpView")
+ }) {
+ Text("Create Account")
+ .foregroundColor(Color.primaryDark)
+ .fontWeight(.semibold)
+ .underline()
+ }
+ }
+ .padding(.horizontal, 35)
+ }
+ .navigationDestination(for: String.self) { view in
+ if view == "SignInView" {
+ SignInView(path: $path)
+ } else if view == "SignUpView" {
+ SignUpView(path: $path)
+ } else if view == "WelcomeView" {
+ WelcomeView()
+ }
+ }
+ }
+ .background(RoundedCorners(
+ color: .white,
+ tl: 20,
+ tr: 20
+ ))
+ .frame(height: 270)
+ }
+ .frame(maxHeight: .infinity)
+ }
+ .navigationTransition(.slide(axis: .vertical))
+ // Safe area for iPhone X and above
+ .edgesIgnoringSafeArea(.all) // This will extend the content to the edges
+ .background(Color(UIColor.systemGray6))
+ .overlay(
+ GeometryReader { geometry in
+ Color.white.opacity(0.3) // Adjust the opacity here for semi-transparency
+ .frame(width: geometry.size.width, height: geometry.safeAreaInsets.top)
+ .edgesIgnoringSafeArea(.top)
+ }, alignment: .top
+ )
+ }
+}
+
+#if DEBUG
+struct MainView_Previews: PreviewProvider {
+ static var previews: some View {
+ MainView()
+ }
+}
+#endif
+
diff --git a/Rethread/Rethread/Views/MapView.swift b/Rethread/Rethread/Views/MapView.swift
new file mode 100644
index 0000000..998084f
--- /dev/null
+++ b/Rethread/Rethread/Views/MapView.swift
@@ -0,0 +1,90 @@
+// MapView.swift
+
+import SwiftUI
+import MapKit
+import CoreLocation
+
+struct MapView: View {
+ @StateObject private var viewModel = MapViewModel() // MapViewModel can be fouund in Models/MapViewModels in the directory
+ @State private var cameraPos: MapCameraPosition = .userLocation(fallback: .automatic)
+ var body: some View {
+
+ VStack {
+ Text("Use your current postal code or enter a new one to see locations near you!")
+ .padding()
+ .foregroundStyle(Color(hex: "#2C4C52"))
+
+ LocationSearchBar()
+
+ Text("Locations Around you")
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .padding(.horizontal)
+ .foregroundStyle(Color(hex: "#2C4C52"))
+
+ CustomDropdownMenu(items: [
+ DropdownItem(id: 1, title: "24 Ave. NW", onSelect: {}),
+ DropdownItem(id: 2, title: "32 Deer foot trail NE", onSelect: {}),
+ DropdownItem(id: 3, title: "18 Blvd. Road W", onSelect: {})
+ ])
+ .zIndex(1000)
+ .frame(maxHeight: .maximum(100, 100))
+ .padding(.horizontal)
+
+
+ Map(position: $cameraPos) {
+
+ }
+ .mapControls {
+ MapCompass()
+ MapUserLocationButton()
+ MapPitchToggle()
+ }
+ .accentColor(Color(hex: "#2C4C52"))
+ .onAppear {
+ viewModel.isUserLocationOn()
+ }
+ }
+
+
+ }
+}
+
+struct LocationSearchBar: View {
+ @State private var search: String = ""
+ var body: some View {
+ HStack {
+ HStack {
+ TextField("Enter New Postal Code", text: $search)
+ Image(systemName: "mappin.circle")
+ .foregroundStyle(Color(hex: "#2C4C52"))
+
+ }
+ .padding(.vertical, 10)
+ .padding(.horizontal, 10)
+ .background(.white)
+ .cornerRadius(5)
+ .overlay(
+ RoundedRectangle(cornerSize: CGSize(width: 8, height: 8))
+ .stroke(Color(hex: "#2C4C52"))
+ )
+ }
+ .padding()
+
+
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+#Preview {
+ MapView()
+}
diff --git a/Rethread/Rethread/OnboardingView.swift b/Rethread/Rethread/Views/OnboardingView.swift
similarity index 76%
rename from Rethread/Rethread/OnboardingView.swift
rename to Rethread/Rethread/Views/OnboardingView.swift
index 303e0a4..e141975 100644
--- a/Rethread/Rethread/OnboardingView.swift
+++ b/Rethread/Rethread/Views/OnboardingView.swift
@@ -6,18 +6,19 @@ struct OnboardingStep {
let maxSelections: Int
}
+// MARK: Onboarding Questions
let onboardingSteps = [
- OnboardingStep(question: "What is your favorite color?",
- options: ["Red", "Green", "Blue", "Purple"],
+ OnboardingStep(question: "Which description best matches your style preference?",
+ options: ["Activewear", "Classic", "Minimalist", "Others"],
maxSelections: 1),
- OnboardingStep(question: "What is your favorite animal?",
- options: ["Dog", "Cat", "Bird"],
- maxSelections: 2),
+ OnboardingStep(question: "What are your main goals for sustainable consumption?",
+ options: ["Reduce carbon footprint", "Support ethical labour practices", "Reduce waste"],
+ maxSelections: 3),
- OnboardingStep(question: "What is your favorite food?",
- options: ["Pizza", "Pasta", "Burgers"],
- maxSelections: 1)
+ OnboardingStep(question: "Who's the best?",
+ options: ["Parsa", "Parsa!", "Parsa!!"],
+ maxSelections: 2)
]
struct OnboardingView: View {
@@ -25,6 +26,7 @@ struct OnboardingView: View {
@State private var selectedOptions = [[String]](repeating: [], count: onboardingSteps.count)
let onboardingStepsCount = onboardingSteps.count
@Environment(\.presentationMode) var presentationMode
+ @EnvironmentObject var viewModel: AuthViewModel
var body: some View {
@@ -33,9 +35,10 @@ struct OnboardingView: View {
ForEach(0..Bool {
+ for index in 0..<6 {
+ if otpFields[index].isEmpty { return true }
+ }
+
+ return false
+ }
+}
+
+#if DEBUG
+struct VerificationView_Previews: PreviewProvider {
+ static var previews: some View {
+ VerificationView(isSignIn: false, path: .constant([""]), formData: nil)
+ }
+}
+#endif
diff --git a/Rethread/Rethread/WelcomeView.swift b/Rethread/Rethread/Views/WelcomeView.swift
similarity index 53%
rename from Rethread/Rethread/WelcomeView.swift
rename to Rethread/Rethread/Views/WelcomeView.swift
index 6692b20..22d7363 100644
--- a/Rethread/Rethread/WelcomeView.swift
+++ b/Rethread/Rethread/Views/WelcomeView.swift
@@ -2,47 +2,47 @@ import SwiftUI
import AVKit
struct WelcomeView: View {
- @Binding var path: [String]
@State private var showOnboarding = false
@State private var player = AVPlayer()
-
+ @EnvironmentObject var viewModel: AuthViewModel
+
var body: some View {
ZStack(alignment: .bottom) {
PlayerView()
- .edgesIgnoringSafeArea(.all)
- .padding(.bottom, 290)
+ .ignoresSafeArea()
+ .padding(.bottom, 255)
Spacer()
- VStack(alignment: .center, spacing: 40.0) {
-
- Text("Hi, Parsa!")
- .font(.title)
- .fontWeight(.bold)
- .foregroundColor(.gray)
- .padding(.top, 20)
-
- Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit purus sit amet luctus venenatis, lectus magna fringilla urna, porttitor.")
- .font(.body)
- .foregroundColor(.gray)
- .multilineTextAlignment(.center)
- .padding(.horizontal)
-
+ VStack(alignment: .center, spacing: 40) {
+ VStack (alignment: .leading, spacing: 20) {
+ Text("Hi, " + (viewModel.currentUser?.firstname ?? "there") + "!")
+ .font(.system(size: 32))
+ .fontWeight(.bold)
+ .foregroundColor(Color.primaryDark.opacity(0.5))
+
+ Text("We connect you to sustainability brands and help you save money!")
+ .font(.body)
+ .foregroundColor(Color.primaryDark.opacity(0.5))
+ .multilineTextAlignment(.leading)
+ }
+ .padding(.top, 25)
+ .padding(.horizontal, 30)
Button("Get Started", action: {
withAnimation {
showOnboarding.toggle()
}
})
- .buttonStyle(PrimaryButtonStyle(width: 200, height: 20))
- .padding(.bottom, 40.0)
+ .buttonStyle(PrimaryButtonStyle(width: 300))
+ .padding(.bottom, 45)
.padding(.top)
}
.frame(maxWidth: .infinity)
- .background(Color.white) // Apply background and corner radius
- .cornerRadius(15) // Adjust the corner radius as needed
+ .background(Color.white)
+ .cornerRadius(15)
}
.fullScreenCover(isPresented: $showOnboarding) {
@@ -62,9 +62,9 @@ struct WelcomeView: View {
}
#if DEBUG
-struct MainView23_Previews: PreviewProvider {
+struct WelcomeView_Previews: PreviewProvider {
static var previews: some View {
- WelcomeView(path: .constant(["WelcomeView"]))
+ WelcomeView()
}
}
#endif
diff --git a/Rethread/Rethread/Views/testest.swift b/Rethread/Rethread/Views/testest.swift
new file mode 100644
index 0000000..2302cfd
--- /dev/null
+++ b/Rethread/Rethread/Views/testest.swift
@@ -0,0 +1,13 @@
+// testest.swift
+
+import SwiftUI
+
+struct testest: View {
+ var body: some View {
+ Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
+ }
+}
+
+#Preview {
+ testest()
+}