diff --git a/iphone/Maps/Classes/MapsAppDelegate.mm b/iphone/Maps/Classes/MapsAppDelegate.mm index ec3c456a86..655096d9d4 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.mm +++ b/iphone/Maps/Classes/MapsAppDelegate.mm @@ -209,7 +209,7 @@ using namespace osm_auth_ios; - (void)applicationDidBecomeActive:(UIApplication *)application { LOG(LINFO, ("applicationDidBecomeActive - begin")); - [[MapViewController sharedController]performSegueWithIdentifier:@"Map2TourismMain" sender:nil]; + [[MapViewController sharedController]performSegueWithIdentifier:@"Map2Auth" sender:nil]; auto & f = GetFramework(); f.EnterForeground(); diff --git a/iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings index 2263147597..e929259743 100644 --- a/iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings @@ -3963,7 +3963,11 @@ "country" = "Country"; -"confirm_password" = "Repeat the password"; +"tourism_email" = "Email"; + +"tourism_password" = "Repeat the password"; + +"tourism_forgot_password" = "Forgot password?"; "home" = "Home"; diff --git a/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings index 2b46f6eebb..9850f20630 100644 --- a/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings @@ -3965,6 +3965,12 @@ "confirm_password" = "Repeat the password"; +"tourism_email" = "Email"; + +"tourism_password" = "Repeat the password"; + +"tourism_forgot_password" = "Forgot password?"; + "home" = "Home"; "favorites" = "Favorites"; diff --git a/iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings index e940a03c95..b97417c7b0 100644 --- a/iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings @@ -3963,6 +3963,12 @@ "country" = "Страна"; +"tourism_email" = "Email"; + +"tourism_password" = "Пароль"; + +"tourism_forgot_password" = "Забыли пароль?"; + "confirm_password" = "Повторите пароль"; "home" = "Главная"; diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 5896bb61f6..e872613ffe 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -263,7 +263,19 @@ 4B4153B52BF9695500EE4B02 /* MWMTextToSpeechTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B4153B42BF9695500EE4B02 /* MWMTextToSpeechTests.mm */; }; 524634C62C53BC3100FDCABA /* Auth.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 524634C22C53BB3A00FDCABA /* Auth.storyboard */; }; 524634CD2C57232400FDCABA /* TourismMain.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 524634CC2C57232400FDCABA /* TourismMain.storyboard */; }; + 527D5E752C60A1F800736A85 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 527D5E742C60A1F800736A85 /* Images.xcassets */; }; + 527D5E782C60D94B00736A85 /* AppButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527D5E772C60D94B00736A85 /* AppButton.swift */; }; + 527D5E7B2C60E05D00736A85 /* LanguageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527D5E7A2C60E05D00736A85 /* LanguageUtils.swift */; }; + 527D5E7F2C60E69C00736A85 /* Layouting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527D5E7E2C60E69C00736A85 /* Layouting.swift */; }; + 527D5E822C60EFEE00736A85 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527D5E812C60EFEE00736A85 /* UIViewExtensions.swift */; }; 528D72A12C5BBBF700D53210 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 528D72A02C5BBBF700D53210 /* Colors.xcassets */; }; + 52B573EC2C61E1C10047FAC9 /* SignInViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B573EB2C61E1C10047FAC9 /* SignInViewController.swift */; }; + 52B573F02C61E4110047FAC9 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B573EF2C61E4110047FAC9 /* Constants.swift */; }; + 52B573F22C61E8980047FAC9 /* SignUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B573F12C61E8980047FAC9 /* SignUpViewController.swift */; }; + 52B573F52C61F11E0047FAC9 /* AuhtTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B573F42C61F11E0047FAC9 /* AuhtTextField.swift */; }; + 52B573F72C61F4D00047FAC9 /* PasswordTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B573F62C61F4D00047FAC9 /* PasswordTextField.swift */; }; + 52B573F92C6223CE0047FAC9 /* AuthBackButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B573F82C6223CE0047FAC9 /* AuthBackButton.swift */; }; + 52B573FC2C623ECF0047FAC9 /* CountryPickerView in Frameworks */ = {isa = PBXBuildFile; productRef = 52B573FB2C623ECF0047FAC9 /* CountryPickerView */; }; 52D588A92C5CD56200AB96B3 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D588A82C5CD56200AB96B3 /* Color.swift */; }; 52D588BA2C5CE2E800AB96B3 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D588B92C5CE2E800AB96B3 /* Font.swift */; }; 52D588C52C5CEAF900AB96B3 /* Gilroy-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 52D588BB2C5CEAF800AB96B3 /* Gilroy-Thin.ttf */; }; @@ -1200,7 +1212,18 @@ 4B4153B42BF9695500EE4B02 /* MWMTextToSpeechTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTextToSpeechTests.mm; sourceTree = ""; }; 524634C22C53BB3A00FDCABA /* Auth.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Auth.storyboard; sourceTree = ""; }; 524634CC2C57232400FDCABA /* TourismMain.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TourismMain.storyboard; sourceTree = ""; }; + 527D5E742C60A1F800736A85 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 527D5E772C60D94B00736A85 /* AppButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppButton.swift; sourceTree = ""; }; + 527D5E7A2C60E05D00736A85 /* LanguageUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageUtils.swift; sourceTree = ""; }; + 527D5E7E2C60E69C00736A85 /* Layouting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Layouting.swift; sourceTree = ""; }; + 527D5E812C60EFEE00736A85 /* UIViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewExtensions.swift; sourceTree = ""; }; 528D72A02C5BBBF700D53210 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; }; + 52B573EB2C61E1C10047FAC9 /* SignInViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInViewController.swift; sourceTree = ""; }; + 52B573EF2C61E4110047FAC9 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + 52B573F12C61E8980047FAC9 /* SignUpViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpViewController.swift; sourceTree = ""; }; + 52B573F42C61F11E0047FAC9 /* AuhtTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuhtTextField.swift; sourceTree = ""; }; + 52B573F62C61F4D00047FAC9 /* PasswordTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordTextField.swift; sourceTree = ""; }; + 52B573F82C6223CE0047FAC9 /* AuthBackButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthBackButton.swift; sourceTree = ""; }; 52D588A82C5CD56200AB96B3 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; 52D588B92C5CE2E800AB96B3 /* Font.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Font.swift; sourceTree = ""; }; 52D588BB2C5CEAF800AB96B3 /* Gilroy-Thin.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Gilroy-Thin.ttf"; sourceTree = ""; }; @@ -1760,6 +1783,7 @@ FA853BEF26BC5BA40026D455 /* libdescriptions.a in Frameworks */, FA853BEB26BC5B9E0026D455 /* libbsdiff.a in Frameworks */, FA853BED26BC5B9E0026D455 /* libmwm_diff.a in Frameworks */, + 52B573FC2C623ECF0047FAC9 /* CountryPickerView in Frameworks */, FA853BE926BC5B8B0026D455 /* libopen_location_code.a in Frameworks */, FA853BE726BC5B820026D455 /* libstb_image.a in Frameworks */, FA853BE526BC5B660026D455 /* libvulkan_wrapper.a in Frameworks */, @@ -2715,8 +2739,11 @@ 5236A3692C52588000E3A7AD /* Tourism */ = { isa = PBXGroup; children = ( + 527D5E792C60E04900736A85 /* Utils */, 52D588B62C5CE10200AB96B3 /* Fonts */, 5236A36C2C5258AC00E3A7AD /* Presentation */, + 527D5E742C60A1F800736A85 /* Images.xcassets */, + 52B573EF2C61E4110047FAC9 /* Constants.swift */, ); path = Tourism; sourceTree = ""; @@ -2724,6 +2751,8 @@ 5236A36C2C5258AC00E3A7AD /* Presentation */ = { isa = PBXGroup; children = ( + 527D5E7D2C60E68200736A85 /* Utils */, + 527D5E762C60D92900736A85 /* Components */, 528D729F2C5BB7D100D53210 /* Theme */, 52B189982C53B9FD00B5B6F9 /* Auth */, 52B189972C53B9E900B5B6F9 /* Home */, @@ -2731,6 +2760,33 @@ path = Presentation; sourceTree = ""; }; + 527D5E762C60D92900736A85 /* Components */ = { + isa = PBXGroup; + children = ( + 52B573F32C61F10B0047FAC9 /* TextFields */, + 527D5E772C60D94B00736A85 /* AppButton.swift */, + 52B573F82C6223CE0047FAC9 /* AuthBackButton.swift */, + ); + path = Components; + sourceTree = ""; + }; + 527D5E792C60E04900736A85 /* Utils */ = { + isa = PBXGroup; + children = ( + 527D5E7A2C60E05D00736A85 /* LanguageUtils.swift */, + ); + path = Utils; + sourceTree = ""; + }; + 527D5E7D2C60E68200736A85 /* Utils */ = { + isa = PBXGroup; + children = ( + 527D5E7E2C60E69C00736A85 /* Layouting.swift */, + 527D5E812C60EFEE00736A85 /* UIViewExtensions.swift */, + ); + path = Utils; + sourceTree = ""; + }; 528D729F2C5BB7D100D53210 /* Theme */ = { isa = PBXGroup; children = ( @@ -2759,6 +2815,15 @@ path = Auth; sourceTree = ""; }; + 52B573F32C61F10B0047FAC9 /* TextFields */ = { + isa = PBXGroup; + children = ( + 52B573F42C61F11E0047FAC9 /* AuhtTextField.swift */, + 52B573F62C61F4D00047FAC9 /* PasswordTextField.swift */, + ); + path = TextFields; + sourceTree = ""; + }; 52D588B62C5CE10200AB96B3 /* Fonts */ = { isa = PBXGroup; children = ( @@ -2788,6 +2853,8 @@ isa = PBXGroup; children = ( 52E2D3A32C59F9CE00A8843A /* WelcomeViewController.swift */, + 52B573EB2C61E1C10047FAC9 /* SignInViewController.swift */, + 52B573F12C61E8980047FAC9 /* SignUpViewController.swift */, ); path = Screens; sourceTree = ""; @@ -3944,6 +4011,9 @@ FA456C4D26BDCC9400B83C20 /* PBXTargetDependency */, ); name = OMaps; + packageProductDependencies = ( + 52B573FB2C623ECF0047FAC9 /* CountryPickerView */, + ); productName = Maps; productReference = 6741AA5D1BF340DE002C974C /* Organic Maps (Debug).app */; productType = "com.apple.product-type.application"; @@ -4040,6 +4110,9 @@ hi, ); mainGroup = 29B97314FDCFA39411CA2CEA /* Maps */; + packageReferences = ( + 52B573FA2C623ECF0047FAC9 /* XCRemoteSwiftPackageReference "CountryPickerView" */, + ); productRefGroup = 19C28FACFE9D520D11CA2CBB /* Products */; projectDirPath = ""; projectReferences = ( @@ -4232,6 +4305,7 @@ 6741A9741BF340DE002C974C /* resources-6plus_dark in Resources */, 677A2DE21C0DD50900635A00 /* resources-default in Resources */, F607C1881C032A8800B53A87 /* resources-hdpi_light in Resources */, + 527D5E752C60A1F800736A85 /* Images.xcassets in Resources */, F607C18A1C032A8800B53A87 /* resources-hdpi_dark in Resources */, FA637ED229A500BE00D8921A /* drules_proto_outdoors_light.bin in Resources */, 6741A97F1BF340DE002C974C /* resources-mdpi_light in Resources */, @@ -4351,6 +4425,7 @@ 3D15ACEE2155117000F725D5 /* MWMObjectsCategorySelectorDataSource.mm in Sources */, 9977E6A32480F9BF0073780C /* BottomMenuLayerButtonRenderer.swift in Sources */, 3454D7D11E07F045004AF2AD /* UIImage+RGBAData.m in Sources */, + 52B573EC2C61E1C10047FAC9 /* SignInViewController.swift in Sources */, 6741A9B71BF340DE002C974C /* EAGLView.mm in Sources */, 6741A9B81BF340DE002C974C /* MapViewController.mm in Sources */, 34AB662C1FC5AA330078E451 /* RouteManagerViewModel.swift in Sources */, @@ -4373,6 +4448,7 @@ CDCA278E2248F34C00167D87 /* MWMRoutingManager.mm in Sources */, 34D3AFF21E37945B004100F9 /* UITableView+Cells.swift in Sources */, 34D3B0301E389D05004100F9 /* MWMEditorCategoryCell.m in Sources */, + 52B573F72C61F4D00047FAC9 /* PasswordTextField.swift in Sources */, F653CE191C71F62700A453F1 /* MWMAddPlaceNavigationBar.mm in Sources */, 340475621E081A4600C92850 /* MWMNetworkPolicy+UI.m in Sources */, F6E2FEE51E097BA00083EBEC /* MWMSearchNoResults.m in Sources */, @@ -4393,6 +4469,7 @@ 44360A0D2A7D34990016F412 /* TransportRuler.swift in Sources */, CD6E8677226774C700D1EDF7 /* CPConstants.swift in Sources */, 99A906DE23F6F7030005872B /* PlacePageBookmarkViewController.swift in Sources */, + 52B573F92C6223CE0047FAC9 /* AuthBackButton.swift in Sources */, F6791B141C43DF0B007A8A6E /* MWMStartButton.m in Sources */, 9977E6A12480E1EE0073780C /* BottomMenuLayerButton.swift in Sources */, 471527372491C20500E91BBA /* SelectBookmarkGroupViewController.swift in Sources */, @@ -4423,6 +4500,7 @@ 470F0B7D238842EA006AEC94 /* ExpandableLabel.swift in Sources */, B33D21AF20DAF9F000BAD749 /* Toast.swift in Sources */, 6741A9D41BF340DE002C974C /* MWMAlertViewController.mm in Sources */, + 52B573F52C61F11E0047FAC9 /* AuhtTextField.swift in Sources */, 34D3B0181E389D05004100F9 /* EditorAdditionalNamePlaceholderTableViewCell.swift in Sources */, 993DF12223F6BDB100AC231A /* UINavigationItemRenderer.swift in Sources */, 993DF12B23F6BDB100AC231A /* StyleManager.swift in Sources */, @@ -4443,6 +4521,7 @@ F6E2FF481E097BA00083EBEC /* SettingsTableViewSelectableCell.swift in Sources */, ED63CEB92BDF8F9D006155C4 /* SettingsTableViewiCloudSwitchCell.swift in Sources */, 47CA68D4250043C000671019 /* BookmarksListPresenter.swift in Sources */, + 527D5E7F2C60E69C00736A85 /* Layouting.swift in Sources */, F6E2FF451E097BA00083EBEC /* SettingsTableViewLinkCell.swift in Sources */, 34C9BD0A1C6DBCDA000DC38D /* MWMNavigationController.m in Sources */, ED1080A72B791CFE0023F27E /* SocialMediaCollectionViewHeader.swift in Sources */, @@ -4463,12 +4542,14 @@ 34AB66741FC5AA330078E451 /* BaseRoutePreviewStatus.swift in Sources */, 8C4FB9C72BEFEFF400D44877 /* CarPlayWindowScaleAdjuster.swift in Sources */, 349D1CE41E3F836900A878FD /* UIViewController+Hierarchy.swift in Sources */, + 52B573F02C61E4110047FAC9 /* Constants.swift in Sources */, 8CB13C3B2BF1276A004288F2 /* CarplayPlaceholderView.swift in Sources */, CDB4D4E1222D70DF00104869 /* CarPlayMapViewController.swift in Sources */, 471AB98923AA8A3500F56D49 /* IDownloaderDataSource.swift in Sources */, EDE243E72B6D55610057369B /* InfoView.swift in Sources */, F692F3831EA0FAF5001E82EB /* MWMAutoupdateController.mm in Sources */, 34BF0CC71C31304A00D097EB /* MWMAuthorizationCommon.mm in Sources */, + 527D5E822C60EFEE00736A85 /* UIViewExtensions.swift in Sources */, 34AB664D1FC5AA330078E451 /* RouteManagerFooterView.swift in Sources */, 6741A9E01BF340DE002C974C /* MWMDownloaderDialogHeader.mm in Sources */, CDCA2748223FD24600167D87 /* MWMCarPlaySearchResultObject.mm in Sources */, @@ -4567,6 +4648,7 @@ F6E2FD6B1E097BA00083EBEC /* MWMMapDownloaderSubplaceTableViewCell.m in Sources */, CDCA27842245090900167D87 /* ListenerContainer.swift in Sources */, 47E3C7252111E41B008B3B27 /* DimmedModalPresentationController.swift in Sources */, + 52B573F22C61E8980047FAC9 /* SignUpViewController.swift in Sources */, 3472B5CB200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift in Sources */, 34FE5A6F1F18F30F00BCA729 /* TrafficButtonArea.swift in Sources */, 993DF10D23F6BDB100AC231A /* UIPageControlRenderer.swift in Sources */, @@ -4607,6 +4689,7 @@ 347040301EA6470700038379 /* BorderedButton.swift in Sources */, F6E2FF4B1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */, 993DF12623F6BDB100AC231A /* SwizzleStyle.m in Sources */, + 527D5E782C60D94B00736A85 /* AppButton.swift in Sources */, 993DF10E23F6BDB100AC231A /* UIButtonRenderer.swift in Sources */, 99514BBB23E82B450085D3A7 /* ElevationProfileBuilder.swift in Sources */, 34AB66381FC5AA330078E451 /* RouteManagerCell.swift in Sources */, @@ -4692,6 +4775,7 @@ 34B924431DC8A29C0008D971 /* MWMMailViewController.m in Sources */, 340475651E081A4600C92850 /* MWMRouter.mm in Sources */, 47E3C72F2111F472008B3B27 /* CoverVerticalModalTransitioning.swift in Sources */, + 527D5E7B2C60E05D00736A85 /* LanguageUtils.swift in Sources */, 34E776101F14B165003040B3 /* VisibleArea.swift in Sources */, 995F1613244F0AA50060631D /* BottomMenuLayersCell.swift in Sources */, 993DF10723F6BDB100AC231A /* UIColor+image.swift in Sources */, @@ -5106,6 +5190,25 @@ defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 52B573FA2C623ECF0047FAC9 /* XCRemoteSwiftPackageReference "CountryPickerView" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/kizitonwose/CountryPickerView.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 3.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 52B573FB2C623ECF0047FAC9 /* CountryPickerView */ = { + isa = XCSwiftPackageProductDependency; + package = 52B573FA2C623ECF0047FAC9 /* XCRemoteSwiftPackageReference "CountryPickerView" */; + productName = CountryPickerView; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; } diff --git a/iphone/Maps/Tourism/Constants.swift b/iphone/Maps/Tourism/Constants.swift new file mode 100644 index 0000000000..3ab43ddb29 --- /dev/null +++ b/iphone/Maps/Tourism/Constants.swift @@ -0,0 +1,15 @@ +struct Constants { + // MARK: - Image Loading URLs + static let imageUrlExample = "https://img.freepik.com/free-photo/young-woman-hiker-taking-photo-with-smartphone-on-mountains-peak-in-winter_335224-427.jpg?w=2000" + static let thumbnailUrlExample = "https://render.fineartamerica.com/images/images-profile-flow/400/images-medium-large-5/awesome-solitude-bess-hamiti.jpg" + static let logoUrlExample = "https://brandeps.com/logo-download/O/OSCE-logo-vector-01.svg" + + // MARK: - Data + static let categories: [String: String] = [ + "sights": NSLocalizedString("sights", comment: ""), + "restaurants": NSLocalizedString("restaurants", comment: ""), + "hotels_tourism": NSLocalizedString("hotels_tourism", comment: "") + ] +} + +let BASE_URL = "https://product.rebus.tj" diff --git a/iphone/Maps/Tourism/Images.xcassets/Contents.json b/iphone/Maps/Tourism/Images.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/Image.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/Image.imageset/Contents.json new file mode 100644 index 0000000000..c55afb67e3 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/Image.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/add.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/add.imageset/Contents.json new file mode 100644 index 0000000000..9f185bd9db --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/add.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "add.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/add.imageset/add.svg b/iphone/Maps/Tourism/Images.xcassets/add.imageset/add.svg new file mode 100644 index 0000000000..f568b59ea4 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/add.imageset/add.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/back.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/back.imageset/Contents.json new file mode 100644 index 0000000000..391020dcb8 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/back.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "back.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/back.imageset/back.svg b/iphone/Maps/Tourism/Images.xcassets/back.imageset/back.svg new file mode 100644 index 0000000000..6585371749 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/back.imageset/back.svg @@ -0,0 +1,3 @@ + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/categories.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/categories.imageset/Contents.json new file mode 100644 index 0000000000..3774f0e708 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/categories.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "categories.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/categories.imageset/categories.svg b/iphone/Maps/Tourism/Images.xcassets/categories.imageset/categories.svg new file mode 100644 index 0000000000..83e333ba0f --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/categories.imageset/categories.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/categories_selected.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/categories_selected.imageset/Contents.json new file mode 100644 index 0000000000..36cf033e79 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/categories_selected.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "categories_selected.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/categories_selected.imageset/categories_selected.svg b/iphone/Maps/Tourism/Images.xcassets/categories_selected.imageset/categories_selected.svg new file mode 100644 index 0000000000..47eae3b77e --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/categories_selected.imageset/categories_selected.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/check_circle_fill.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/check_circle_fill.imageset/Contents.json new file mode 100644 index 0000000000..3b74c5e49f --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/check_circle_fill.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "check_circle_fill.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/check_circle_fill.imageset/check_circle_fill.svg b/iphone/Maps/Tourism/Images.xcassets/check_circle_fill.imageset/check_circle_fill.svg new file mode 100644 index 0000000000..f9a168753c --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/check_circle_fill.imageset/check_circle_fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/iphone/Maps/Tourism/Images.xcassets/chevron_down.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/chevron_down.imageset/Contents.json new file mode 100644 index 0000000000..8f4c57ff85 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/chevron_down.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "chevron_down.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/chevron_down.imageset/chevron_down.svg b/iphone/Maps/Tourism/Images.xcassets/chevron_down.imageset/chevron_down.svg new file mode 100644 index 0000000000..f87d1768a3 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/chevron_down.imageset/chevron_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/close.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/close.imageset/Contents.json new file mode 100644 index 0000000000..ce4276fe0a --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/close.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "close.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/close.imageset/close.svg b/iphone/Maps/Tourism/Images.xcassets/close.imageset/close.svg new file mode 100644 index 0000000000..0b8c2442d7 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/close.imageset/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/eye.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/eye.imageset/Contents.json new file mode 100644 index 0000000000..8965be5fcd --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/eye.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "eye.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/eye.imageset/eye.svg b/iphone/Maps/Tourism/Images.xcassets/eye.imageset/eye.svg new file mode 100644 index 0000000000..36ed4da108 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/eye.imageset/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/iphone/Maps/Tourism/Images.xcassets/eye_slash.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/eye_slash.imageset/Contents.json new file mode 100644 index 0000000000..0dd4eb3aea --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/eye_slash.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "eye-slash.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/eye_slash.imageset/eye-slash.svg b/iphone/Maps/Tourism/Images.xcassets/eye_slash.imageset/eye-slash.svg new file mode 100644 index 0000000000..6dc0e47a41 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/eye_slash.imageset/eye-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/iphone/Maps/Tourism/Images.xcassets/globe.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/globe.imageset/Contents.json new file mode 100644 index 0000000000..82c869261f --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/globe.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "globe.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/globe.imageset/globe.svg b/iphone/Maps/Tourism/Images.xcassets/globe.imageset/globe.svg new file mode 100644 index 0000000000..74de75fdff --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/globe.imageset/globe.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/heart.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/heart.imageset/Contents.json new file mode 100644 index 0000000000..bea90a2c9f --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/heart.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "heart.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/heart.imageset/heart.svg b/iphone/Maps/Tourism/Images.xcassets/heart.imageset/heart.svg new file mode 100644 index 0000000000..56cbad653c --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/heart.imageset/heart.svg @@ -0,0 +1,3 @@ + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/heart_selected.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/heart_selected.imageset/Contents.json new file mode 100644 index 0000000000..dee9c6a1f5 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/heart_selected.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "heart_selected.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/heart_selected.imageset/heart_selected.svg b/iphone/Maps/Tourism/Images.xcassets/heart_selected.imageset/heart_selected.svg new file mode 100644 index 0000000000..1fa489f053 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/heart_selected.imageset/heart_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/home.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/home.imageset/Contents.json new file mode 100644 index 0000000000..365f6c410f --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/home.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "home.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/home.imageset/home.svg b/iphone/Maps/Tourism/Images.xcassets/home.imageset/home.svg new file mode 100644 index 0000000000..94fe5e9229 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/home.imageset/home.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/home_selected.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/home_selected.imageset/Contents.json new file mode 100644 index 0000000000..1030913ac2 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/home_selected.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "home_selected.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/home_selected.imageset/home_selected.svg b/iphone/Maps/Tourism/Images.xcassets/home_selected.imageset/home_selected.svg new file mode 100644 index 0000000000..6e9b515745 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/home_selected.imageset/home_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/image_down.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/image_down.imageset/Contents.json new file mode 100644 index 0000000000..ee448c5037 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/image_down.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "image_down.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/image_down.imageset/image_down.svg b/iphone/Maps/Tourism/Images.xcassets/image_down.imageset/image_down.svg new file mode 100644 index 0000000000..e29e16a84b --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/image_down.imageset/image_down.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/map.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/map.imageset/Contents.json new file mode 100644 index 0000000000..e051c50407 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/map.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "map.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/map.imageset/map.svg b/iphone/Maps/Tourism/Images.xcassets/map.imageset/map.svg new file mode 100644 index 0000000000..8414c1f56c --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/map.imageset/map.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/profile.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/profile.imageset/Contents.json new file mode 100644 index 0000000000..305cb38066 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/profile.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "profile.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/profile.imageset/profile.svg b/iphone/Maps/Tourism/Images.xcassets/profile.imageset/profile.svg new file mode 100644 index 0000000000..900a02e77a --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/profile.imageset/profile.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/profile_selected.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/profile_selected.imageset/Contents.json new file mode 100644 index 0000000000..8d5fecd6eb --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/profile_selected.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "profile_selected.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/profile_selected.imageset/profile_selected.svg b/iphone/Maps/Tourism/Images.xcassets/profile_selected.imageset/profile_selected.svg new file mode 100644 index 0000000000..11ae4f707d --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/profile_selected.imageset/profile_selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/search.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/search.imageset/Contents.json new file mode 100644 index 0000000000..c258d38ab3 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/search.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "search.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/search.imageset/search.svg b/iphone/Maps/Tourism/Images.xcassets/search.imageset/search.svg new file mode 100644 index 0000000000..87a7e4afc3 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/search.imageset/search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/sign_out.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/sign_out.imageset/Contents.json new file mode 100644 index 0000000000..2e7664fc46 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/sign_out.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "sign_out.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/sign_out.imageset/sign_out.svg b/iphone/Maps/Tourism/Images.xcassets/sign_out.imageset/sign_out.svg new file mode 100644 index 0000000000..329e4ab86d --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/sign_out.imageset/sign_out.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/splash_background.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/splash_background.imageset/Contents.json new file mode 100644 index 0000000000..2ce999338e --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/splash_background.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "splash_background.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/splash_background.imageset/splash_background.png b/iphone/Maps/Tourism/Images.xcassets/splash_background.imageset/splash_background.png new file mode 100644 index 0000000000..bab37574db Binary files /dev/null and b/iphone/Maps/Tourism/Images.xcassets/splash_background.imageset/splash_background.png differ diff --git a/iphone/Maps/Tourism/Images.xcassets/star.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/star.imageset/Contents.json new file mode 100644 index 0000000000..3119f94e3f --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/star.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "star.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/star.imageset/star.svg b/iphone/Maps/Tourism/Images.xcassets/star.imageset/star.svg new file mode 100644 index 0000000000..1cabdae9b1 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/star.imageset/star.svg @@ -0,0 +1,3 @@ + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/star_border.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/star_border.imageset/Contents.json new file mode 100644 index 0000000000..ae1555db5f --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/star_border.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "star_border.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/star_border.imageset/star_border.svg b/iphone/Maps/Tourism/Images.xcassets/star_border.imageset/star_border.svg new file mode 100644 index 0000000000..95c5eac6c3 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/star_border.imageset/star_border.svg @@ -0,0 +1,3 @@ + + + diff --git a/iphone/Maps/Tourism/Images.xcassets/unchecked.imageset/Contents.json b/iphone/Maps/Tourism/Images.xcassets/unchecked.imageset/Contents.json new file mode 100644 index 0000000000..d033f0e167 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/unchecked.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "unchecked.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Tourism/Images.xcassets/unchecked.imageset/unchecked.svg b/iphone/Maps/Tourism/Images.xcassets/unchecked.imageset/unchecked.svg new file mode 100644 index 0000000000..1cc94529b4 --- /dev/null +++ b/iphone/Maps/Tourism/Images.xcassets/unchecked.imageset/unchecked.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/iphone/Maps/Tourism/Presentation/Auth/Auth.storyboard b/iphone/Maps/Tourism/Presentation/Auth/Auth.storyboard index 3538207c1d..9da9886d06 100644 --- a/iphone/Maps/Tourism/Presentation/Auth/Auth.storyboard +++ b/iphone/Maps/Tourism/Presentation/Auth/Auth.storyboard @@ -33,15 +33,6 @@ - - - diff --git a/iphone/Maps/Tourism/Presentation/Auth/Screens/SignInViewController.swift b/iphone/Maps/Tourism/Presentation/Auth/Screens/SignInViewController.swift new file mode 100644 index 0000000000..8d6fc371d5 --- /dev/null +++ b/iphone/Maps/Tourism/Presentation/Auth/Screens/SignInViewController.swift @@ -0,0 +1,158 @@ +import UIKit + +class SignInViewController: UIViewController { + + private let backButton: BackButton = { + let backButton = BackButton() + backButton.translatesAutoresizingMaskIntoConstraints = false + return backButton + }() + + private let backgroundImageView: UIImageView = { + let imageView = UIImageView() + imageView.image = UIImage(named: "splash_background") + imageView.contentMode = .scaleAspectFill + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + }() + + private let containerView: UIView = { + let view = UIView() + view.backgroundColor = .clear + view.translatesAutoresizingMaskIntoConstraints = false + view.layer.cornerRadius = 16 + return view + }() + + private let blurView: UIVisualEffectView = { + let blurEffect = UIBlurEffect(style: .light) + let blurView = UIVisualEffectView(effect: blurEffect) + blurView.translatesAutoresizingMaskIntoConstraints = false + blurView.layer.cornerRadius = 16 + blurView.clipsToBounds = true + return blurView + }() + + private let titleLabel: UILabel = { + let label = UILabel() + label.text = L("sign_in_title") + label.font = UIFont.systemFont(ofSize: 24, weight: .bold) + label.textColor = .white + label.textAlignment = .center + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let emailTextField: AuthTextField = { + let textField = AuthTextField() + textField.placeholder = L("tourism_email") + textField.keyboardType = .emailAddress + textField.autocapitalizationType = .none + textField.translatesAutoresizingMaskIntoConstraints = false + return textField + }() + + private let passwordTextField: PasswordTextField = { + let textField = PasswordTextField() + textField.placeholder = L("tourism_password") + textField.translatesAutoresizingMaskIntoConstraints = false + return textField + }() + + private let signInButton: AppButton = { + let button = AppButton(label: L("sign_in"), isPrimary: true, target: self, action: #selector(signInClicked)) + return button + }() + + private let forgotPasswordButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle(L("tourism_forgot_password"), for: .normal) + button.setTitleColor(.white, for: .normal) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + override func viewDidLoad() { + super.viewDidLoad() + setupViews() + } + + private func setupViews() { + view.addSubview(backgroundImageView) + view.addSubview(backButton) + view.addSubview(containerView) + + containerView.addSubview(blurView) + containerView.addSubview(titleLabel) + containerView.addSubview(emailTextField) + containerView.addSubview(passwordTextField) + containerView.addSubview(signInButton) + containerView.addSubview(forgotPasswordButton) + + NSLayoutConstraint.activate([ + // Background Image + backgroundImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + backgroundImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + backgroundImageView.topAnchor.constraint(equalTo: view.topAnchor), + backgroundImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + + // Back Button + backButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16), + backButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), + + // Container View + containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), + containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16), + containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -120), + + // Blur View + blurView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), + blurView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), + blurView.topAnchor.constraint(equalTo: containerView.topAnchor), + blurView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor), + + // Title Label + titleLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 32), + titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Email Text Field + emailTextField.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 32), + emailTextField.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + emailTextField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Password Text Field + passwordTextField.topAnchor.constraint(equalTo: emailTextField.bottomAnchor, constant: 40), + passwordTextField.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + passwordTextField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Sign In Button + signInButton.topAnchor.constraint(equalTo: passwordTextField.bottomAnchor, constant: 48), + signInButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + signInButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Forgot Password Button + forgotPasswordButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20), + forgotPasswordButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + forgotPasswordButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -32) + ]) + + backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) + signInButton.addTarget(self, action: #selector(signInClicked), for: .touchUpInside) + forgotPasswordButton.addTarget(self, action: #selector(forgotPasswordTapped), for: .touchUpInside) + } + + @objc private func signInClicked() { + // Implement sign-in logic + } + + @objc private func forgotPasswordTapped() { + if let url = URL(string: "\(BASE_URL)/forgot-password") { + UIApplication.shared.open(url) + } + } + + @objc private func backButtonTapped() { + self.navigationController?.popViewController(animated: false) + } +} diff --git a/iphone/Maps/Tourism/Presentation/Auth/Screens/SignUpViewController.swift b/iphone/Maps/Tourism/Presentation/Auth/Screens/SignUpViewController.swift new file mode 100644 index 0000000000..9b4037d89d --- /dev/null +++ b/iphone/Maps/Tourism/Presentation/Auth/Screens/SignUpViewController.swift @@ -0,0 +1,218 @@ +import UIKit +import CountryPickerView + +class SignUpViewController: UIViewController { + + private let backButton: BackButton = { + let backButton = BackButton() + backButton.translatesAutoresizingMaskIntoConstraints = false + return backButton + }() + + private let backgroundImageView: UIImageView = { + let imageView = UIImageView() + imageView.image = UIImage(named: "splash_background") + imageView.contentMode = .scaleAspectFill + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + }() + + private let containerView: UIView = { + let view = UIView() + view.backgroundColor = .clear + view.translatesAutoresizingMaskIntoConstraints = false + view.layer.cornerRadius = 16 + return view + }() + + private let blurView: UIVisualEffectView = { + let blurEffect = UIBlurEffect(style: .light) + let blurView = UIVisualEffectView(effect: blurEffect) + blurView.translatesAutoresizingMaskIntoConstraints = false + blurView.layer.cornerRadius = 16 + blurView.clipsToBounds = true + return blurView + }() + + private let titleLabel: UILabel = { + let label = UILabel() + label.text = L("sign_up_title") + label.font = UIFont.systemFont(ofSize: 24, weight: .bold) + label.textColor = .white + label.textAlignment = .center + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let nameTextField: AuthTextField = { + let textField = AuthTextField() + textField.placeholder = L("full_name") + textField.keyboardType = .emailAddress + textField.autocapitalizationType = .none + textField.translatesAutoresizingMaskIntoConstraints = false + return textField + }() + + private let cpv: CountryPickerView = { + let cpv = CountryPickerView() + cpv.textColor = .white + cpv.translatesAutoresizingMaskIntoConstraints = false + cpv.showCountryNameInView = true + cpv.showPhoneCodeInView = false + cpv.showCountryCodeInView = false + return cpv + }() + + private let underline: UIView = { + let underline = UIView() + underline.translatesAutoresizingMaskIntoConstraints = false + underline.backgroundColor = .white + return underline + }() + + private let emailTextField: AuthTextField = { + let textField = AuthTextField() + textField.placeholder = L("tourism_email") + textField.keyboardType = .emailAddress + textField.autocapitalizationType = .none + textField.translatesAutoresizingMaskIntoConstraints = false + return textField + }() + + private let passwordTextField: PasswordTextField = { + let textField = PasswordTextField() + textField.placeholder = L("tourism_password") + textField.translatesAutoresizingMaskIntoConstraints = false + return textField + }() + + private let confirmPasswordTextField: PasswordTextField = { + let confirmTextField = PasswordTextField() + confirmTextField.placeholder = L("confirm_password") + confirmTextField.translatesAutoresizingMaskIntoConstraints = false + return confirmTextField + }() + + private let signUpButton: AppButton = { + let button = AppButton(label: L("sign_up"), isPrimary: true, target: self, action: #selector(signUpClicked)) + return button + }() + + private let forgotPasswordButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle(L("tourism_forgot_password"), for: .normal) + button.setTitleColor(.white, for: .normal) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + override func viewDidLoad() { + super.viewDidLoad() + setupViews() + } + + private func setupViews() { + view.addSubview(backgroundImageView) + view.addSubview(backButton) + view.addSubview(containerView) + + containerView.addSubview(blurView) + containerView.addSubview(titleLabel) + containerView.addSubview(nameTextField) + containerView.addSubview(cpv) + containerView.addSubview(underline) + containerView.addSubview(emailTextField) + containerView.addSubview(passwordTextField) + containerView.addSubview(confirmPasswordTextField) + containerView.addSubview(signUpButton) + containerView.addSubview(forgotPasswordButton) + + NSLayoutConstraint.activate([ + // Background Image + backgroundImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + backgroundImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + backgroundImageView.topAnchor.constraint(equalTo: view.topAnchor), + backgroundImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + + // Back Button + backButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16), + backButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), + + // Container View + containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), + containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16), + containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -60), + + // Blur View + blurView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), + blurView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), + blurView.topAnchor.constraint(equalTo: containerView.topAnchor), + blurView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor), + + // Title Label + titleLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 32), + titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Name Text Field + nameTextField.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 32), + nameTextField.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + nameTextField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Country Picker + cpv.topAnchor.constraint(equalTo: nameTextField.bottomAnchor, constant: 32), + cpv.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + cpv.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + cpv.heightAnchor.constraint(equalToConstant: 20), + + // Underline for Country Picker + underline.topAnchor.constraint(equalTo: cpv.bottomAnchor, constant: 8), + underline.leadingAnchor.constraint(equalTo: containerView.leadingAnchor,constant: 32), + underline.trailingAnchor.constraint(equalTo: containerView.trailingAnchor,constant: -32), + underline.heightAnchor.constraint(equalToConstant: 1), + + // Email Text Field + emailTextField.topAnchor.constraint(equalTo: cpv.bottomAnchor, constant: 32), + emailTextField.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + emailTextField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Password Text Field + passwordTextField.topAnchor.constraint(equalTo: emailTextField.bottomAnchor, constant: 40), + passwordTextField.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + passwordTextField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Confirm Password Text Field + confirmPasswordTextField.topAnchor.constraint(equalTo: passwordTextField.bottomAnchor, constant: 40), + confirmPasswordTextField.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + confirmPasswordTextField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Sign In Button + signUpButton.topAnchor.constraint(equalTo: confirmPasswordTextField.bottomAnchor, constant: 48), + signUpButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + signUpButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -32), + + // Forgot Password Button + forgotPasswordButton.topAnchor.constraint(equalTo: signUpButton.bottomAnchor, constant: 20), + forgotPasswordButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 32), + forgotPasswordButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -32) + ]) + + backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) + signUpButton.addTarget(self, action: #selector(signUpClicked), for: .touchUpInside) + forgotPasswordButton.addTarget(self, action: #selector(forgotPasswordTapped), for: .touchUpInside) + } + + @objc private func signUpClicked() { + // TODO: signUpClicked + } + + @objc private func forgotPasswordTapped() { + if let url = URL(string: "\(BASE_URL)/forgot-password") { + UIApplication.shared.open(url) + } + } + + @objc private func backButtonTapped() { + self.navigationController?.popViewController(animated: false) + } +} diff --git a/iphone/Maps/Tourism/Presentation/Auth/Screens/WelcomeViewController.swift b/iphone/Maps/Tourism/Presentation/Auth/Screens/WelcomeViewController.swift index 74b41644e9..e7af52e205 100644 --- a/iphone/Maps/Tourism/Presentation/Auth/Screens/WelcomeViewController.swift +++ b/iphone/Maps/Tourism/Presentation/Auth/Screens/WelcomeViewController.swift @@ -2,8 +2,163 @@ import UIKit class WelcomeViewController: UIViewController { + // MARK: - UI Components + + private let backgroundImageView: UIImageView = { + let imageView = UIImageView() + imageView.image = UIImage(named: "splash_background") + imageView.contentMode = .scaleAspectFill + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + }() + + private let languageLabel: UILabel = { + let label = UILabel() + label.text = L("current_language") + label.textColor = .white + Font.applyStyle(to: label, style: Font.h4) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let globeIcon: UIImageView = { + let imageView = UIImageView() + imageView.image = UIImage(named: "globe") + imageView.tintColor = .white + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + }() + + private let welcomeLabel: UILabel = { + let label = UILabel() + label.text = L("welcome_to_tjk") + label.textColor = .white + Font.applyStyle(to: label, style: Font.h1) + applyWrapContent(label: label) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let signInButton: AppButton = { + let button = AppButton( + label: L("sign_in"), + isPrimary: true, + target: self, + action: #selector(signInClicked) + ) + return button + }() + + private let signUpButton: AppButton = { + let button = AppButton( + label: L("sign_up"), + isPrimary: true, + target: self, + action: #selector(signUpClicked) + ) + return button + }() + + private let copyrightLabel: UILabel = { + let label = UILabel() + label.text = "©" + label.textColor = .white + Font.applyStyle(to: label, style: Font.h1) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let organizationNameLabel: UILabel = { + let label = UILabel() + label.text = L("organization_name") + label.textColor = .white + Font.applyStyle(to: label, style: Font.h4) + applyWrapContent(label: label) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + // MARK: - Lifecycle + override func viewDidLoad() { super.viewDidLoad() + setupUI() } + // MARK: - Setup + + private func setupUI() { + + let gradientView = UIView(frame: CGRect(x: 0, y: view.height - 100, width: view.width, height: 100)) + let gradient = CAGradientLayer() + gradient.frame = gradientView.bounds + gradient.colors = [UIColor.clear.cgColor, UIColor.black.cgColor] + gradientView.layer.insertSublayer(gradient, at: 0) + + view.addSubview(backgroundImageView) + view.addSubview(languageLabel) + view.addSubview(globeIcon) + view.addSubview(welcomeLabel) + view.addSubview(signInButton) + view.addSubview(signUpButton) + view.addSubview(gradientView) + view.addSubview(copyrightLabel) + view.addSubview(organizationNameLabel) + + let languageTapGesture = UITapGestureRecognizer(target: self, action: #selector(languageClicked)) + languageLabel.isUserInteractionEnabled = true + languageLabel.addGestureRecognizer(languageTapGesture) + + NSLayoutConstraint.activate([ + // Background Image + backgroundImageView.topAnchor.constraint(equalTo: view.topAnchor), + backgroundImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + backgroundImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + backgroundImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + + // Language Selection Row + languageLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), + languageLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), + + globeIcon.centerYAnchor.constraint(equalTo: languageLabel.centerYAnchor), + globeIcon.leadingAnchor.constraint(equalTo: languageLabel.trailingAnchor, constant: 8), + + // Welcome Text + welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -24), + welcomeLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), + welcomeLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16), + + // Sign In and Sign Up Buttons + signInButton.bottomAnchor.constraint(equalTo: copyrightLabel.topAnchor, constant: -24), + signInButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), + signInButton.trailingAnchor.constraint(equalTo: view.centerXAnchor, constant: -8), + signInButton.heightAnchor.constraint(equalToConstant: 44), + + signUpButton.bottomAnchor.constraint(equalTo: copyrightLabel.topAnchor, constant: -24), + signUpButton.leadingAnchor.constraint(equalTo: view.centerXAnchor, constant: 8), + signUpButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16), + signUpButton.heightAnchor.constraint(equalToConstant: 44), + + // Copyright and Organization Name + copyrightLabel.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20), + copyrightLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), + + organizationNameLabel.centerYAnchor.constraint(equalTo: copyrightLabel.centerYAnchor), + organizationNameLabel.leadingAnchor.constraint(equalTo: copyrightLabel.trailingAnchor, constant: 8), + organizationNameLabel.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -16), + ]) + } + + // MARK: - Actions + @objc private func languageClicked() { + navigateToLanguageSettings() + } + + @objc private func signInClicked() { + navigationController?.pushViewController(SignInViewController(), animated: false) + } + + @objc private func signUpClicked() { + navigationController?.pushViewController(SignUpViewController(), animated: false) + } } diff --git a/iphone/Maps/Tourism/Presentation/Components/AppButton.swift b/iphone/Maps/Tourism/Presentation/Components/AppButton.swift new file mode 100644 index 0000000000..7f421f9a8e --- /dev/null +++ b/iphone/Maps/Tourism/Presentation/Components/AppButton.swift @@ -0,0 +1,103 @@ +import UIKit + +class AppButton: UIButton { + + private var originalButtonText: String? + private var activityIndicator: UIActivityIndicatorView! + + var isLoading: Bool = false { + didSet { + updateLoadingState() + } + } + + private let highlightScale: CGFloat = 0.95 + + init(label: String, isPrimary: Bool, icon: UIImage? = nil, target: Any?, action: Selector) { + super.init(frame: .zero) + + setTitle(label, for: .normal) + + isPrimary ? setPrimaryAppearance() : setSecondaryAppearance() + heightAnchor.constraint(equalToConstant: 56).isActive = true + + translatesAutoresizingMaskIntoConstraints = false + + addTarget(target, action: action, for: .touchUpInside) + addTarget(self, action: #selector(handleTouchDown), for: .touchDown) + addTarget(self, action: #selector(handleTouchUp), for: .touchUpInside) + addTarget(self, action: #selector(handleTouchUp), for: .touchCancel) + + setupActivityIndicator() + + if let icon = icon { + setImage(icon, for: .normal) + imageEdgeInsets = UIEdgeInsets(top: 0, left: -8, bottom: 0, right: 8) + } + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Styles + private func setPrimaryAppearance() { + setTitleColor(.white, for: .normal) + self.backgroundColor = Color.primary + if let lab = self.titleLabel { + Font.applyStyle(to: lab, style: Font.h4) + } + layer.cornerRadius = 16 + } + + private func setSecondaryAppearance() { + setTitleColor(.systemBlue, for: .normal) + backgroundColor = .clear + layer.cornerRadius = 16 + layer.borderWidth = 1 + layer.borderColor = UIColor.systemBlue.cgColor + } + + // MARK: click animation + @objc private func handleTouchDown() { + animate(scale: highlightScale) + } + + @objc private func handleTouchUp() { + animate(scale: 1.0) + } + + private func animate(scale: CGFloat) { + UIView.animate(withDuration: 0.2, animations: { + self.transform = CGAffineTransform(scaleX: scale, y: scale) + }) + } + + // MARK: loading + private func setupActivityIndicator() { + activityIndicator = UIActivityIndicatorView(style: .white) + activityIndicator.color = .white + activityIndicator.hidesWhenStopped = true + activityIndicator.translatesAutoresizingMaskIntoConstraints = false + addSubview(activityIndicator) + + // Center the activity indicator in the button + NSLayoutConstraint.activate([ + activityIndicator.centerXAnchor.constraint(equalTo: centerXAnchor), + activityIndicator.centerYAnchor.constraint(equalTo: centerYAnchor) + ]) + } + + private func updateLoadingState() { + if isLoading { + originalButtonText = title(for: .normal) + setTitle("", for: .normal) + activityIndicator.startAnimating() + isUserInteractionEnabled = false + } else { + setTitle(originalButtonText, for: .normal) + activityIndicator.stopAnimating() + isUserInteractionEnabled = true + } + } +} diff --git a/iphone/Maps/Tourism/Presentation/Components/AuthBackButton.swift b/iphone/Maps/Tourism/Presentation/Components/AuthBackButton.swift new file mode 100644 index 0000000000..860eafc993 --- /dev/null +++ b/iphone/Maps/Tourism/Presentation/Components/AuthBackButton.swift @@ -0,0 +1,22 @@ +import UIKit + +class BackButton: UIButton { + + override init(frame: CGRect) { + super.init(frame: frame) + setupButton() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setupButton() + } + + private func setupButton() { + self.setTitle("←", for: .normal) + self.setTitleColor(.white, for: .normal) + self.titleLabel?.font = UIFont.systemFont(ofSize: 32) + self.layer.borderColor = UIColor.clear.cgColor + self.backgroundColor = .clear + } +} diff --git a/iphone/Maps/Tourism/Presentation/Components/TextFields/AuhtTextField.swift b/iphone/Maps/Tourism/Presentation/Components/TextFields/AuhtTextField.swift new file mode 100644 index 0000000000..f99f3ea34e --- /dev/null +++ b/iphone/Maps/Tourism/Presentation/Components/TextFields/AuhtTextField.swift @@ -0,0 +1,46 @@ +import UIKit + +class AuthTextField: UITextField { + private let underline: UIView = UIView() + + override init(frame: CGRect) { + super.init(frame: frame) + setupTextField() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setupTextField() + } + + private func setupTextField() { + self.backgroundColor = .clear + self.borderStyle = .none + self.attributedPlaceholder = NSAttributedString( + string: "Enter text here", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.white] + ) + self.textColor = .white + self.leftViewMode = .always + self.font = UIFont.systemFont(ofSize: 16) + self.keyboardType = .default + self.returnKeyType = .done + + self.heightAnchor.constraint(equalToConstant: 50) + + addUnderline() + } + + private func addUnderline() { + underline.translatesAutoresizingMaskIntoConstraints = false + underline.backgroundColor = .white + self.addSubview(underline) + + NSLayoutConstraint.activate([ + underline.leadingAnchor.constraint(equalTo: self.leadingAnchor), + underline.trailingAnchor.constraint(equalTo: self.trailingAnchor), + underline.topAnchor.constraint(equalTo: self.bottomAnchor, constant: 8), + underline.heightAnchor.constraint(equalToConstant: 1) + ]) + } +} diff --git a/iphone/Maps/Tourism/Presentation/Components/TextFields/PasswordTextField.swift b/iphone/Maps/Tourism/Presentation/Components/TextFields/PasswordTextField.swift new file mode 100644 index 0000000000..c79271d70c --- /dev/null +++ b/iphone/Maps/Tourism/Presentation/Components/TextFields/PasswordTextField.swift @@ -0,0 +1,59 @@ +import UIKit + +class PasswordTextField: AuthTextField { + + private let toggleVisibilityButton: UIButton = { + let button = UIButton(type: .custom) + let eyeSlashImg = UIImage(named: "eye_slash") + let eyeImage = UIImage(named: "eye") + button.setImage(eyeSlashImg, for: .normal) + button.setImage(eyeImage, for: .selected) + button.tintColor = .white + button.addTarget(self, action: #selector(togglePasswordVisibility), for: .touchUpInside) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setupPasswordTextField() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setupPasswordTextField() + } + + private func setupPasswordTextField() { + self.isSecureTextEntry = true + self.rightView = toggleVisibilityButton + self.rightViewMode = .always + + // Ensure the button is laid out correctly + self.addSubview(toggleVisibilityButton) + NSLayoutConstraint.activate([ + toggleVisibilityButton.widthAnchor.constraint(equalToConstant: 24), + toggleVisibilityButton.heightAnchor.constraint(equalToConstant: 24), + toggleVisibilityButton.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -8), + toggleVisibilityButton.centerYAnchor.constraint(equalTo: self.centerYAnchor) + ]) + } + + @objc private func togglePasswordVisibility() { + self.isSecureTextEntry.toggle() + toggleVisibilityButton.isSelected = !self.isSecureTextEntry + } + + override func layoutSubviews() { + super.layoutSubviews() + // Adjust the frame of the right view if needed + let buttonWidth: CGFloat = 24 + let padding: CGFloat = 8 + self.rightView?.frame = CGRect( + x: self.bounds.width - buttonWidth - padding, + y: (self.bounds.height - buttonWidth) / 2, + width: buttonWidth, + height: buttonWidth + ) + } +} diff --git a/iphone/Maps/Tourism/Presentation/Utils/Layouting.swift b/iphone/Maps/Tourism/Presentation/Utils/Layouting.swift new file mode 100644 index 0000000000..e3f451af88 --- /dev/null +++ b/iphone/Maps/Tourism/Presentation/Utils/Layouting.swift @@ -0,0 +1,6 @@ +func applyWrapContent(label: UILabel) { + label.numberOfLines = 0 + label.lineBreakMode = .byWordWrapping + label.setContentCompressionResistancePriority(.required, for: .vertical) + label.setContentHuggingPriority(.defaultLow, for: .vertical) +} diff --git a/iphone/Maps/Tourism/Presentation/Utils/UIViewExtensions.swift b/iphone/Maps/Tourism/Presentation/Utils/UIViewExtensions.swift new file mode 100644 index 0000000000..b3d58add21 --- /dev/null +++ b/iphone/Maps/Tourism/Presentation/Utils/UIViewExtensions.swift @@ -0,0 +1,69 @@ +extension UIView { + + func applyGradient(isVertical: Bool, colorArray: [UIColor]) { + layer.sublayers?.filter({ $0 is CAGradientLayer }).forEach({ $0.removeFromSuperlayer() }) + + let gradientLayer = CAGradientLayer() + gradientLayer.colors = colorArray.map({ $0.cgColor }) + if isVertical { + //top to bottom + gradientLayer.locations = [0.0, 1.0] + } else { + //left to right + gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5) + gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) + } + + backgroundColor = .clear + gradientLayer.frame = bounds + layer.insertSublayer(gradientLayer, at: 0) + } + + +} + +func gradientColor(yourView:UIView, startColor: UIColor, endColor: UIColor, colorAngle: CGFloat){ + + let gradientLayer = CAGradientLayer() + gradientLayer.colors = [startColor.cgColor, endColor.cgColor] + gradientLayer.locations = [0.0, 1.0] + let (start, end) = gradientPointsForAngle(colorAngle) + gradientLayer.startPoint = start + gradientLayer.endPoint = end + gradientLayer.frame = yourView.bounds + + yourView.layer.insertSublayer(gradientLayer, at: 0) + yourView.layer.masksToBounds = true +} + +func gradientPointsForAngle(_ angle: CGFloat) -> (CGPoint, CGPoint) { + + let end = pointForAngle(angle) + let start = oppositePoint(end) + let p0 = transformToGradientSpace(start) + let p1 = transformToGradientSpace(end) + return (p0, p1) +} + +func pointForAngle(_ angle: CGFloat) -> CGPoint { + let radians = angle * .pi / 180.0 + var x = cos(radians) + var y = sin(radians) + + if (abs(x) > abs(y)) { + x = x > 0 ? 1 : -1 + y = x * tan(radians) + } else { + y = y > 0 ? 1 : -1 + x = y / tan(radians) + } + return CGPoint(x: x, y: y) +} + +func oppositePoint(_ point: CGPoint) -> CGPoint { + return CGPoint(x: -point.x, y: -point.y) +} + +private func transformToGradientSpace(_ point: CGPoint) -> CGPoint { + return CGPoint(x: (point.x + 1) * 0.5, y: 1.0 - (point.y + 1) * 0.5) +} diff --git a/iphone/Maps/Tourism/Utils/LanguageUtils.swift b/iphone/Maps/Tourism/Utils/LanguageUtils.swift new file mode 100644 index 0000000000..aa2d0e6480 --- /dev/null +++ b/iphone/Maps/Tourism/Utils/LanguageUtils.swift @@ -0,0 +1,4 @@ +func navigateToLanguageSettings() { + guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else {return} + UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil) +}