git.iko.soy/dashared/hookah-tau
on develop help sign in
Я забыла что я делала, тут ВСЕ
commit7e9dd454a677722d8942fe4306d63341321a4a5f authorDarya Rednikina <rednikina.com@yandex.ru> dateSun 17 Nov 2019, 13:15 (7 years ago) parent3a43f0e
48 files changed+1652−39
DataStorage.swift+8−1 Hookah Tau.xcodeproj/project.pbxproj+112 Hookah Tau/API/APIClient.swift+4 Hookah Tau/API/ApiRequest.swift+1−1 Hookah Tau/API/ApiResolver.swift+7−1 Hookah Tau/API/Authorization api/AuthorizationService.swift+1−1 Hookah Tau/API/Authorization api/Resolvers/AuthResolver.swift+1−1 Hookah Tau/API/Authorization api/Resolvers/PhoneCodeResolver.swift+1−1 Hookah Tau/API/Authorization api/Resolvers/RegistrationResolver.swift+1−1 Hookah Tau/API/MyCodable.swift+12−2 Hookah Tau/API/Reservations api/ReservationsService.swift+78 Hookah Tau/API/Reservations api/Resolvers/ReservationsResolver.swift+46 Hookah Tau/API/ServerError.swift+1 Hookah Tau/AppDelegate.swift+4−1 Hookah Tau/Controllers/ApplicationCoordinator.swift+15−5 Hookah Tau/Controllers/Authentication/Code from sms/CodeSmsViewController.swift+1 Hookah Tau/Controllers/Authentication/Phone/PhoneCoordinator.swift+7−2 Hookah Tau/Controllers/BaseViewController.swift+13−3 Hookah Tau/Controllers/Client/Profile/ProfileClientViewController.swift+12−2 Hookah Tau/Controllers/Client/Profile/ProfileCoordinator.swift+2−1 Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsViewController.swift+42−12 Hookah Tau/Controllers/Client/Reservations/Adress of reservation/AddresViewController.swift+9 Hookah Tau/Controllers/Client/Reservations/Adress of reservation/AddressCoordinator.swift+8−2 Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationCell.swift+2−2 Hookah Tau/Controllers/Client/Reservations/Maps/MapView.swift+25 Hookah Tau/Controllers/Client/Reservations/Maps/MapView1.swift+128 Hookah Tau/Controllers/Client/Reservations/Maps/MapView1.xib+151 Hookah Tau/Controllers/Client/Reservations/Reservation.storyboard+44 Hookah Tau/Controllers/Client/Reservations/ReservationCoordinator.swift+34 Hookah Tau/Controllers/Client/Reservations/ReservationViewController.swift+133 Hookah Tau/Controllers/Client/Reservations/Steps/First/DateView.swift+18 Hookah Tau/Controllers/Client/Reservations/Steps/First/DateView.xib+42 Hookah Tau/Controllers/Client/Reservations/Steps/First/FirstStepView.swift+168 Hookah Tau/Controllers/Client/Reservations/Steps/First/FirstStepView.xib+191 Hookah Tau/Controllers/Client/Reservations/Steps/First/TimePointView.swift+50 Hookah Tau/Controllers/Client/Reservations/Steps/First/TimePointView.xib+83 Hookah Tau/Controllers/Client/Tab bar/ClientTabbarCoordinator.swift+4 Hookah Tau/Extensions+Date.swift+76 Hookah Tau/Extensions+UIView.swift+16 Hookah Tau/Extenstions+IBDesignable.swift+25 Hookah Tau/Models/AllReservations.swift+19 Hookah Tau/Models/Reservation.swift+21 Hookah Tau/Supporting Files/Assets.xcassets/TriangleDown.imageset/Contents.json+12 Hookah Tau/Supporting Files/Assets.xcassets/TriangleDown.imageset/Triangle.pdf Hookah Tau/Supporting Files/Assets.xcassets/TriangleUp.imageset/Contents.json+12 Hookah Tau/Supporting Files/Assets.xcassets/TriangleUp.imageset/TriangleUp.pdf Hookah Tau/Supporting Files/Assets.xcassets/map_1.imageset/Contents.json+12 Hookah Tau/Supporting Files/Assets.xcassets/map_1.imageset/map_1.pdf
DataStorage.swift+8−1
@@ -6,7 +6,7 @@
66// Copyright © 2019 Daria Rednikina. All rights reserved.
77//
88
9−import Foundation
9+import UIKit
1010
1111/// Класс для хранения промежуточного состояния регистрации,
1212/// данных пользователя, ...
@@ -52,4 +52,11 @@ class DataStorage {
5252 return User(name: name, phoneNumber: phone, isAdmin: isAdmin)
5353 }
5454
55+ func isLoggedIn() -> Bool {
56+ return UserDefaults.standard.bool(forKey: Keys.loggedIn.rawValue)
57+ }
58+
59+ func setLoggedInState(_ value: Bool) {
60+ UserDefaults.standard.set(value, forKey: Keys.loggedIn.rawValue)
61+ }
5562}
Hookah Tau.xcodeproj/project.pbxproj+112
@@ -7,6 +7,8 @@
77 objects = {
88
99/* Begin PBXBuildFile section */
10+ 12050569238048CE00801618 /* Extensions+Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12050568238048CE00801618 /* Extensions+Date.swift */; };
11+ 1205056B2380588C00801618 /* Extenstions+IBDesignable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1205056A2380588C00801618 /* Extenstions+IBDesignable.swift */; };
1012 12118B9C23682022006BAEE3 /* RegistrationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12118B9B23682022006BAEE3 /* RegistrationResolver.swift */; };
1113 12118B9E23682049006BAEE3 /* PhoneCodeResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12118B9D23682049006BAEE3 /* PhoneCodeResolver.swift */; };
1214 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12219CEE2353A63E0057DDEE /* ReservationsCoordinator.swift */; };
@@ -18,6 +20,9 @@
1820 1246B71C235CDF3A004CBFA1 /* ReservationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1246B71B235CDF3A004CBFA1 /* ReservationCell.swift */; };
1921 1246B71E235CDF8A004CBFA1 /* ReservationView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1246B71D235CDF8A004CBFA1 /* ReservationView.xib */; };
2022 1246B720235CDF9E004CBFA1 /* ReservationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1246B71F235CDF9E004CBFA1 /* ReservationView.swift */; };
23+ 124D007C23721FD400AE76B9 /* Reservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007B23721FD400AE76B9 /* Reservation.swift */; };
24+ 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007E237222B200AE76B9 /* ReservationsResolver.swift */; };
25+ 124D0081237222C900AE76B9 /* ReservationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D0080237222C900AE76B9 /* ReservationsService.swift */; };
2126 12838EA9236764A600CEF108 /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EA8236764A600CEF108 /* APIClient.swift */; };
2227 12838EAC2367689600CEF108 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 12838EAB2367689600CEF108 /* Alamofire */; };
2328 12838EAE2367701300CEF108 /* AuthorizationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EAD2367701300CEF108 /* AuthorizationService.swift */; };
@@ -26,14 +31,27 @@
2631 12838EB4236779C700CEF108 /* ApiResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB3236779C700CEF108 /* ApiResolver.swift */; };
2732 12838EB623677FB900CEF108 /* ApiRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB523677FB900CEF108 /* ApiRequest.swift */; };
2833 12838EB82367834900CEF108 /* MyCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB72367834900CEF108 /* MyCodable.swift */; };
34+ 12A075F72373535C00D749BB /* ReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A075F62373535C00D749BB /* ReservationViewController.swift */; };
35+ 12A075F9237353F500D749BB /* MapView1.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12A075F8237353F500D749BB /* MapView1.xib */; };
36+ 12A075FB2373561A00D749BB /* Reservation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12A075FA2373561A00D749BB /* Reservation.storyboard */; };
37+ 12A075FD237357E900D749BB /* ReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A075FC237357E900D749BB /* ReservationCoordinator.swift */; };
38+ 12A075FF237358F200D749BB /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A075FE237358F200D749BB /* MapView.swift */; };
39+ 12A07601237359BB00D749BB /* MapView1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A07600237359BB00D749BB /* MapView1.swift */; };
2940 12B6A60F235B857A00898B31 /* ProfileChangeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B6A60E235B857A00898B31 /* ProfileChangeCoordinator.swift */; };
3041 12B6A611235B8EC500898B31 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B6A610235B8EC500898B31 /* User.swift */; };
3142 12B6A613235B9B4300898B31 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B6A612235B9B4300898B31 /* BaseViewController.swift */; };
3243 12B6A615235BB36C00898B31 /* ChangeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12B6A614235BB36C00898B31 /* ChangeView.xib */; };
3344 12B6A617235BB37D00898B31 /* ChangeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B6A616235BB37D00898B31 /* ChangeView.swift */; };
45+ 12BD95B0237EBEDF009614D8 /* FirstStepView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12BD95AF237EBEDE009614D8 /* FirstStepView.xib */; };
46+ 12BD95B2237EC22B009614D8 /* FirstStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BD95B1237EC22B009614D8 /* FirstStepView.swift */; };
47+ 12BD95B6237ED8AC009614D8 /* TimePointView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12BD95B5237ED8AB009614D8 /* TimePointView.xib */; };
48+ 12BD95B8237EDB01009614D8 /* TimePointView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BD95B7237EDB01009614D8 /* TimePointView.swift */; };
3449 12C72EDF23537D1B00AD7004 /* ProfileCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C72EDE23537D1B00AD7004 /* ProfileCoordinator.swift */; };
3550 12C72EE1235380D400AD7004 /* ProfileClientViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C72EE0235380D400AD7004 /* ProfileClientViewController.swift */; };
3651 12C72EE3235380EB00AD7004 /* ReservationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C72EE2235380EB00AD7004 /* ReservationsViewController.swift */; };
52+ 12D8FA2D237F003800305F57 /* DateView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12D8FA2C237F003800305F57 /* DateView.xib */; };
53+ 12D8FA2F237F00E200305F57 /* DateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D8FA2E237F00E200305F57 /* DateView.swift */; };
54+ 12D8FA31237F08C700305F57 /* AllReservations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D8FA30237F08C700305F57 /* AllReservations.swift */; };
3755 12DBEEB223539F2100AF1BB6 /* Client.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12DBEEB123539F2100AF1BB6 /* Client.storyboard */; };
3856 12EA99462362B674005D9FE9 /* AddressCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EA99452362B674005D9FE9 /* AddressCoordinator.swift */; };
3957 12EA99482362B684005D9FE9 /* AddresViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EA99472362B684005D9FE9 /* AddresViewController.swift */; };
@@ -91,6 +109,8 @@
91109/* End PBXContainerItemProxy section */
92110
93111/* Begin PBXFileReference section */
112+ 12050568238048CE00801618 /* Extensions+Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extensions+Date.swift"; sourceTree = "<group>"; };
113+ 1205056A2380588C00801618 /* Extenstions+IBDesignable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extenstions+IBDesignable.swift"; sourceTree = "<group>"; };
94114 12118B9B23682022006BAEE3 /* RegistrationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationResolver.swift; sourceTree = "<group>"; };
95115 12118B9D23682049006BAEE3 /* PhoneCodeResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneCodeResolver.swift; sourceTree = "<group>"; };
96116 12219CEE2353A63E0057DDEE /* ReservationsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReservationsCoordinator.swift; sourceTree = "<group>"; };
@@ -102,6 +122,9 @@
102122 1246B71B235CDF3A004CBFA1 /* ReservationCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationCell.swift; sourceTree = "<group>"; };
103123 1246B71D235CDF8A004CBFA1 /* ReservationView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ReservationView.xib; sourceTree = "<group>"; };
104124 1246B71F235CDF9E004CBFA1 /* ReservationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationView.swift; sourceTree = "<group>"; };
125+ 124D007B23721FD400AE76B9 /* Reservation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reservation.swift; sourceTree = "<group>"; };
126+ 124D007E237222B200AE76B9 /* ReservationsResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsResolver.swift; sourceTree = "<group>"; };
127+ 124D0080237222C900AE76B9 /* ReservationsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsService.swift; sourceTree = "<group>"; };
105128 12838EA8236764A600CEF108 /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = "<group>"; };
106129 12838EAD2367701300CEF108 /* AuthorizationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorizationService.swift; sourceTree = "<group>"; };
107130 12838EAF236777D400CEF108 /* ServerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerError.swift; sourceTree = "<group>"; };
@@ -109,14 +132,27 @@
109132 12838EB3236779C700CEF108 /* ApiResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiResolver.swift; sourceTree = "<group>"; };
110133 12838EB523677FB900CEF108 /* ApiRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiRequest.swift; sourceTree = "<group>"; };
111134 12838EB72367834900CEF108 /* MyCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCodable.swift; sourceTree = "<group>"; };
135+ 12A075F62373535C00D749BB /* ReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationViewController.swift; sourceTree = "<group>"; };
136+ 12A075F8237353F500D749BB /* MapView1.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapView1.xib; sourceTree = "<group>"; };
137+ 12A075FA2373561A00D749BB /* Reservation.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Reservation.storyboard; sourceTree = "<group>"; };
138+ 12A075FC237357E900D749BB /* ReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationCoordinator.swift; sourceTree = "<group>"; };
139+ 12A075FE237358F200D749BB /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = "<group>"; };
140+ 12A07600237359BB00D749BB /* MapView1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView1.swift; sourceTree = "<group>"; };
112141 12B6A60E235B857A00898B31 /* ProfileChangeCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileChangeCoordinator.swift; sourceTree = "<group>"; };
113142 12B6A610235B8EC500898B31 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
114143 12B6A612235B9B4300898B31 /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = "<group>"; };
115144 12B6A614235BB36C00898B31 /* ChangeView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ChangeView.xib; sourceTree = "<group>"; };
116145 12B6A616235BB37D00898B31 /* ChangeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeView.swift; sourceTree = "<group>"; };
146+ 12BD95AF237EBEDE009614D8 /* FirstStepView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FirstStepView.xib; sourceTree = "<group>"; };
147+ 12BD95B1237EC22B009614D8 /* FirstStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstStepView.swift; sourceTree = "<group>"; };
148+ 12BD95B5237ED8AB009614D8 /* TimePointView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TimePointView.xib; sourceTree = "<group>"; };
149+ 12BD95B7237EDB01009614D8 /* TimePointView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimePointView.swift; sourceTree = "<group>"; };
117150 12C72EDE23537D1B00AD7004 /* ProfileCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileCoordinator.swift; sourceTree = "<group>"; };
118151 12C72EE0235380D400AD7004 /* ProfileClientViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileClientViewController.swift; sourceTree = "<group>"; };
119152 12C72EE2235380EB00AD7004 /* ReservationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsViewController.swift; sourceTree = "<group>"; };
153+ 12D8FA2C237F003800305F57 /* DateView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DateView.xib; sourceTree = "<group>"; };
154+ 12D8FA2E237F00E200305F57 /* DateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateView.swift; sourceTree = "<group>"; };
155+ 12D8FA30237F08C700305F57 /* AllReservations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllReservations.swift; sourceTree = "<group>"; };
120156 12DBEEB123539F2100AF1BB6 /* Client.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Client.storyboard; sourceTree = "<group>"; };
121157 12EA99452362B674005D9FE9 /* AddressCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressCoordinator.swift; sourceTree = "<group>"; };
122158 12EA99472362B684005D9FE9 /* AddresViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddresViewController.swift; sourceTree = "<group>"; };
@@ -222,6 +258,11 @@
222258 1212F1322353A603005BEF8A /* Reservations */ = {
223259 isa = PBXGroup;
224260 children = (
261+ 12BD95AE237EBE52009614D8 /* Maps */,
262+ 12BD95B3237EC231009614D8 /* Steps */,
263+ 12A075FC237357E900D749BB /* ReservationCoordinator.swift */,
264+ 12A075F62373535C00D749BB /* ReservationViewController.swift */,
265+ 12A075FA2373561A00D749BB /* Reservation.storyboard */,
225266 1246B721235CDFC2004CBFA1 /* Cells */,
226267 1246B71A235CD4C5004CBFA1 /* Views */,
227268 12EA994A2362BA11005D9FE9 /* Active Reservations */,
@@ -259,6 +300,23 @@
259300 path = Cells;
260301 sourceTree = "<group>";
261302 };
303+ 124D007D2372229500AE76B9 /* Reservations api */ = {
304+ isa = PBXGroup;
305+ children = (
306+ 124D0080237222C900AE76B9 /* ReservationsService.swift */,
307+ 124D00822372233000AE76B9 /* Resolvers */,
308+ );
309+ path = "Reservations api";
310+ sourceTree = "<group>";
311+ };
312+ 124D00822372233000AE76B9 /* Resolvers */ = {
313+ isa = PBXGroup;
314+ children = (
315+ 124D007E237222B200AE76B9 /* ReservationsResolver.swift */,
316+ );
317+ path = Resolvers;
318+ sourceTree = "<group>";
319+ };
262320 12838EB923679AEB00CEF108 /* API */ = {
263321 isa = PBXGroup;
264322 children = (
@@ -267,11 +325,43 @@
267325 12838EAF236777D400CEF108 /* ServerError.swift */,
268326 12838EB523677FB900CEF108 /* ApiRequest.swift */,
269327 12838EB72367834900CEF108 /* MyCodable.swift */,
328+ 124D007D2372229500AE76B9 /* Reservations api */,
270329 12118B9A2368187B006BAEE3 /* Authorization api */,
271330 );
272331 path = API;
273332 sourceTree = "<group>";
274333 };
334+ 12BD95AE237EBE52009614D8 /* Maps */ = {
335+ isa = PBXGroup;
336+ children = (
337+ 12A075FE237358F200D749BB /* MapView.swift */,
338+ 12A07600237359BB00D749BB /* MapView1.swift */,
339+ 12A075F8237353F500D749BB /* MapView1.xib */,
340+ );
341+ path = Maps;
342+ sourceTree = "<group>";
343+ };
344+ 12BD95B3237EC231009614D8 /* Steps */ = {
345+ isa = PBXGroup;
346+ children = (
347+ 12BD95B4237EC23A009614D8 /* First */,
348+ );
349+ path = Steps;
350+ sourceTree = "<group>";
351+ };
352+ 12BD95B4237EC23A009614D8 /* First */ = {
353+ isa = PBXGroup;
354+ children = (
355+ 12BD95AF237EBEDE009614D8 /* FirstStepView.xib */,
356+ 12D8FA2C237F003800305F57 /* DateView.xib */,
357+ 12D8FA2E237F00E200305F57 /* DateView.swift */,
358+ 12BD95B5237ED8AB009614D8 /* TimePointView.xib */,
359+ 12BD95B7237EDB01009614D8 /* TimePointView.swift */,
360+ 12BD95B1237EC22B009614D8 /* FirstStepView.swift */,
361+ );
362+ path = First;
363+ sourceTree = "<group>";
364+ };
275365 12C72EDB235367CF00AD7004 /* Tab bar */ = {
276366 isa = PBXGroup;
277367 children = (
@@ -394,6 +484,8 @@
394484 children = (
395485 F3851B2F2340A513009EE0B6 /* RegistationViewModel.swift */,
396486 12B6A610235B8EC500898B31 /* User.swift */,
487+ 124D007B23721FD400AE76B9 /* Reservation.swift */,
488+ 12D8FA30237F08C700305F57 /* AllReservations.swift */,
397489 );
398490 path = Models;
399491 sourceTree = "<group>";
@@ -490,6 +582,8 @@
490582 F3FC7DCC2315BE610080D851 /* AppDelegate.swift */,
491583 F3DC59FE233E893400B5E751 /* Extensions+UIFont.swift */,
492584 F31E20C62348DDB900BEA215 /* Extensions+UIView.swift */,
585+ 12050568238048CE00801618 /* Extensions+Date.swift */,
586+ 1205056A2380588C00801618 /* Extenstions+IBDesignable.swift */,
493587 12838EB923679AEB00CEF108 /* API */,
494588 F30369BC2336861100A8EA84 /* Models */,
495589 F3199E59233FD7F700F3C17A /* Views */,
@@ -631,10 +725,15 @@
631725 files = (
632726 F3199E5B233FE08200F3C17A /* PhoneView.xib in Resources */,
633727 12DBEEB223539F2100AF1BB6 /* Client.storyboard in Resources */,
728+ 12D8FA2D237F003800305F57 /* DateView.xib in Resources */,
634729 12387337234BB98700D1F1AB /* CodeView.xib in Resources */,
635730 12B6A615235BB36C00898B31 /* ChangeView.xib in Resources */,
636731 F3851B2C2340A280009EE0B6 /* TitleTextView.xib in Resources */,
637732 1246B71E235CDF8A004CBFA1 /* ReservationView.xib in Resources */,
733+ 12BD95B6237ED8AC009614D8 /* TimePointView.xib in Resources */,
734+ 12A075F9237353F500D749BB /* MapView1.xib in Resources */,
735+ 12A075FB2373561A00D749BB /* Reservation.storyboard in Resources */,
736+ 12BD95B0237EBEDF009614D8 /* FirstStepView.xib in Resources */,
638737 F30369B5233679EA00A8EA84 /* LaunchScreen.storyboard in Resources */,
639738 1246B717235CD186004CBFA1 /* NoReservationsView.xib in Resources */,
640739 F3FC7DD42315BE630080D851 /* Assets.xcassets in Resources */,
@@ -666,6 +765,7 @@
666765 buildActionMask = 2147483647;
667766 files = (
668767 12EA99482362B684005D9FE9 /* AddresViewController.swift in Sources */,
768+ 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */,
669769 1246B719235CD3AD004CBFA1 /* NoReservationsView.swift in Sources */,
670770 F3895F4A233D323700FA6A37 /* CodeCoordinator.swift in Sources */,
671771 12838EB4236779C700CEF108 /* ApiResolver.swift in Sources */,
@@ -683,10 +783,18 @@
683783 12EB698123661CB300E4D1CE /* AddressCell.swift in Sources */,
684784 F3895F48233D2EEA00FA6A37 /* CodeSmsViewController.swift in Sources */,
685785 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */,
786+ 12A07601237359BB00D749BB /* MapView1.swift in Sources */,
787+ 12BD95B8237EDB01009614D8 /* TimePointView.swift in Sources */,
686788 12838EB2236779A000CEF108 /* AuthResolver.swift in Sources */,
687789 12FE4042236B8B050012391E /* DataStorage.swift in Sources */,
790+ 12A075F72373535C00D749BB /* ReservationViewController.swift in Sources */,
688791 1246B71C235CDF3A004CBFA1 /* ReservationCell.swift in Sources */,
792+ 12A075FD237357E900D749BB /* ReservationCoordinator.swift in Sources */,
793+ 124D0081237222C900AE76B9 /* ReservationsService.swift in Sources */,
689794 1246B720235CDF9E004CBFA1 /* ReservationView.swift in Sources */,
795+ 12050569238048CE00801618 /* Extensions+Date.swift in Sources */,
796+ 124D007C23721FD400AE76B9 /* Reservation.swift in Sources */,
797+ 12D8FA2F237F00E200305F57 /* DateView.swift in Sources */,
690798 F3895F4E233D348B00FA6A37 /* PhoneCoordinator.swift in Sources */,
691799 12B6A617235BB37D00898B31 /* ChangeView.swift in Sources */,
692800 F3FC7DCD2315BE610080D851 /* AppDelegate.swift in Sources */,
@@ -705,14 +813,18 @@
705813 12EA994E2362FCE8005D9FE9 /* AddressView.swift in Sources */,
706814 F3895F4C233D347E00FA6A37 /* PhoneNumberViewController.swift in Sources */,
707815 12EE4A76234BB8FE005B4D1A /* CodeView.swift in Sources */,
816+ 12BD95B2237EC22B009614D8 /* FirstStepView.swift in Sources */,
708817 F3EBE2472340FE87000FEE1A /* NameTextView.swift in Sources */,
709818 F3DC5A01233E896300B5E751 /* ButtonStyle.swift in Sources */,
819+ 12A075FF237358F200D749BB /* MapView.swift in Sources */,
820+ 1205056B2380588C00801618 /* Extenstions+IBDesignable.swift in Sources */,
710821 12C72EE1235380D400AD7004 /* ProfileClientViewController.swift in Sources */,
711822 F31E20C92348E0F300BEA215 /* AuthorizationViewController.swift in Sources */,
712823 F3851B2923409F8A009EE0B6 /* PhoneView.swift in Sources */,
713824 12C72EE3235380EB00AD7004 /* ReservationsViewController.swift in Sources */,
714825 12B6A611235B8EC500898B31 /* User.swift in Sources */,
715826 12B6A60F235B857A00898B31 /* ProfileChangeCoordinator.swift in Sources */,
827+ 12D8FA31237F08C700305F57 /* AllReservations.swift in Sources */,
716828 12838EB0236777D400CEF108 /* ServerError.swift in Sources */,
717829 );
718830 runOnlyForDeploymentPostprocessing = 0;
Hookah Tau/API/APIClient.swift+4
@@ -59,6 +59,10 @@ class APIClient {
5959 }
6060 }
6161
62+ if let _ = response.error {
63+ return GeneralError.alamofireError
64+ }
65+
6266 return GeneralError.somethingWentCompletelyWrong
6367 }
6468}
Hookah Tau/API/ApiRequest.swift+1−1
@@ -34,7 +34,7 @@ class ApiRequest {
3434 let url = URL(string: APIClient.BaseUrls.staging + (resolver.groupName ?? "") + resolver.name)!
3535 self.request = URLRequest(url: url)
3636
37− self.request.httpBody = resolver.parameters().toJSONData()
37+ self.request.httpBody = resolver.parameters()?.toJSONData()
3838 self.request.setValue("application/json;charset=utf-8",
3939 forHTTPHeaderField: "Content-Type")
4040 self.request.httpMethod = httpMethod.rawValue
Hookah Tau/API/ApiResolver.swift+7−1
@@ -15,5 +15,11 @@ protocol ApiResolver: class {
1515 var groupName: String? { get }
1616
1717 /// Parameter for request
18− func parameters() -> MyCodable
18+ func parameters() -> MyCodable?
19+}
20+
21+extension ApiResolver {
22+ var groupName: String? { return nil }
23+
24+ func parameters() -> MyCodable? { return nil }
1925}
Hookah Tau/API/Authorization api/AuthorizationService.swift+1−1
@@ -100,7 +100,7 @@ class AuthorizationService {
100100
101101 private func setCookies(response: AFDataResponse<Data?>) {
102102 let fields = response.response?.allHeaderFields as? [String :String]
103− guard let fieldss = fields, let url = response.response?.url else {
103+ guard let fieldss = fields, let url = URL(string: APIClient.BaseUrls.staging) else {
104104 return
105105 }
106106 let cookies = HTTPCookie.cookies(withResponseHeaderFields: fieldss, for: url)
Hookah Tau/API/Authorization api/Resolvers/AuthResolver.swift+1−1
@@ -38,7 +38,7 @@ class AuthResolver<Response: MyCodable>: ApiResolver {
3838 self.phoneNumber = phoneNumber
3939 }
4040
41− func parameters() -> MyCodable {
41+ func parameters() -> MyCodable? {
4242 return Request(phoneNumber: phoneNumber)
4343 }
4444
Hookah Tau/API/Authorization api/Resolvers/PhoneCodeResolver.swift+1−1
@@ -37,7 +37,7 @@ class PhoneCodeResolver<Response: MyCodable>: ApiResolver {
3737 self.code = code
3838 }
3939
40− func parameters() -> MyCodable {
40+ func parameters() -> MyCodable? {
4141 return Request(phoneNumber: phoneNumber,
4242 code: code)
4343 }
Hookah Tau/API/Authorization api/Resolvers/RegistrationResolver.swift+1−1
@@ -40,7 +40,7 @@ class RegistrationResolver<Response: MyCodable>: ApiResolver {
4040 self.phoneNumber = phoneNumber
4141 }
4242
43− func parameters() -> MyCodable {
43+ func parameters() -> MyCodable? {
4444 return Request(name: uname,
4545 phoneNumber: phoneNumber,
4646 code: code)
Hookah Tau/API/MyCodable.swift+12−2
@@ -16,10 +16,20 @@ protocol MyCodable: Codable {
1616
1717extension MyCodable {
1818 func toJSONData() -> Data? {
19− return try? JSONEncoder().encode(self)
19+ let encoder = JSONEncoder()
20+ encoder.dateEncodingStrategy = .formatted(DateFormatter.iso8601Full)
21+ return try? encoder.encode(self)
2022 }
2123
2224 static func fromJSONToSelf(data: Data) -> Self? {
23− return try? JSONDecoder().decode(self, from: data)
25+ let decoder = JSONDecoder()
26+ decoder.dateDecodingStrategy = .formatted(DateFormatter.iso8601Full)
27+ return try? decoder.decode(self, from: data)
28+ }
29+
30+ static func fromJSONToSelfArray<T: MyCodable>(data : Data) -> [T]? {
31+ let decoder = JSONDecoder()
32+ decoder.dateDecodingStrategy = .formatted(DateFormatter.iso8601Full)
33+ return try? decoder.decode([T].self, from: data)
2434 }
2535}
Hookah Tau/API/Reservations api/ReservationsService.swiftnew file+78
@@ -0,0 +1,78 @@
1+//
2+// ReservationsService.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 06/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import Foundation
10+import Alamofire
11+
12+/// Слой методов для авторизации пользователя в приложении
13+class ReservationsService {
14+ private var apiClient: APIClient
15+
16+ init(apiClient: APIClient) {
17+ self.apiClient = apiClient
18+ }
19+
20+ /// Gets all reservations made by the current user.
21+ func loadUsersReservations(completion: @escaping (Result<[Reservation], GeneralError>) -> Void) {
22+ let resolver = ReservationsResolver<ReservationsResponce>()
23+
24+ let request = ApiRequest(resolver: resolver, httpMethod: .get)
25+ apiClient.load(request: request.request) { (result) in
26+ switch result {
27+ case .failure(let err):
28+ completion(.failure(err))
29+ case .success(let response):
30+ guard
31+ let d = response.data,
32+ let decodedData = resolver.targetClass().fromJSONToSelf(data: d)
33+ else {
34+ completion(.failure(GeneralError.decodeError))
35+ return
36+ }
37+
38+ completion(.success(decodedData.reservations))
39+ }
40+ }
41+ }
42+
43+ func deleteReservation() {
44+
45+ }
46+
47+ func updateReservation() {
48+
49+ }
50+
51+ func createReservation() {
52+
53+ }
54+
55+ func getAllReservations(establishmentID: Int,
56+ completion: @escaping ((Result<AllReservations, GeneralError>) -> Void)) {
57+ let resolver = AllReservationsResolver<AllReservations>(establishmentID: establishmentID)
58+
59+ let request = ApiRequest(resolver: resolver, httpMethod: .get)
60+
61+ apiClient.load(request: request.request) { result in
62+ switch result {
63+ case .failure(let err):
64+ completion(.failure(err))
65+ case .success(let response):
66+ guard
67+ let d = response.data,
68+ let decodedData = resolver.targetClass().fromJSONToSelf(data: d)
69+ else {
70+ completion(.failure(GeneralError.decodeError))
71+ return
72+ }
73+
74+ completion(.success(decodedData))
75+ }
76+ }
77+ }
78+}
Hookah Tau/API/Reservations api/Resolvers/ReservationsResolver.swiftnew file+46
@@ -0,0 +1,46 @@
1+//
2+// ReservationsResolver.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 06/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+struct ReservationsResponce: MyCodable {
10+ var reservations: [Reservation]
11+}
12+
13+class ReservationsResolver<Response: MyCodable>: ApiResolver {
14+ var name: String {
15+ return "/reservations"
16+ }
17+
18+ func targetClass() -> Response.Type {
19+ return Response.self
20+ }
21+}
22+
23+class AllReservationsResolver<Response: Codable>: ApiResolver {
24+
25+ struct Request: MyCodable {
26+ var establishmentUUID: Int
27+ }
28+
29+ var name: String {
30+ return "/all/\(self.establishmentID)"
31+ }
32+
33+ var groupName: String? {
34+ return "/reservations"
35+ }
36+
37+ var establishmentID: Int
38+
39+ init(establishmentID: Int) {
40+ self.establishmentID = establishmentID
41+ }
42+
43+ func targetClass() -> Response.Type {
44+ return Response.self
45+ }
46+}
Hookah Tau/API/ServerError.swift+1
@@ -18,4 +18,5 @@ enum GeneralError: Error {
1818 case noData
1919 case Error400
2020 case somethingWentCompletelyWrong
21+ case alamofireError
2122}
Hookah Tau/AppDelegate.swift+4−1
@@ -21,13 +21,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2121 window?.makeKeyAndVisible()
2222
2323 let navController = UINavigationController()
24− window?.rootViewController = navController
2524
2625 applicationCoordinator = ApplicationCoordinator(navigationController: navController)
2726 applicationCoordinator?.start()
2827
2928 return true
3029 }
30+
31+ func relaunch(){
32+ applicationCoordinator?.start()
33+ }
3134
3235 func applicationWillResignActive(_ application: UIApplication) {
3336 // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Hookah Tau/Controllers/ApplicationCoordinator.swift+15−5
@@ -10,7 +10,9 @@ import UIKit
1010
1111class ApplicationCoordinator: BaseCoordinator {
1212
13− var launch: LaunchOptions?
13+ var launch: LaunchOptions? {
14+ return LaunchOptions.configure()
15+ }
1416
1517 override func start() {
1618 guard let launch = launch else { return }
@@ -27,13 +29,11 @@ class ApplicationCoordinator: BaseCoordinator {
2729
2830 required init(navigationController: UINavigationController?) {
2931 super.init(navigationController: navigationController)
30− self.launch = LaunchOptions.configure()
3132 }
3233
3334 private func runAuthFlow() {
3435 let phoneCoordinator = PhoneCoordinator(navigationController: navigationController)
3536 phoneCoordinator.didEndFlow = { [weak self] in
36− self?.launch = LaunchOptions.main // TESTING
3737 self?.start()
3838 self?.removeDependency(phoneCoordinator)
3939 }
@@ -62,8 +62,18 @@ extension ApplicationCoordinator {
6262 case auth, admin, main
6363
6464 static func configure() -> LaunchOptions {
65− print("configuring...")
66− return .auth
65+ let isAuthorized = DataStorage.standard.isLoggedIn()
66+ let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
67+
68+ if !isAuthorized {
69+ return .auth
70+ }
71+
72+ if isAdmin {
73+ return .admin
74+ }
75+
76+ return .main
6777 }
6878 }
6979}
Hookah Tau/Controllers/Authentication/Code from sms/CodeSmsViewController.swift+1
@@ -91,6 +91,7 @@ final class CodeSmsViewController: AuthorizationViewController {
9191 self?.displayAlert(forError: err)
9292 case .success(let user):
9393 DataStorage.standard.saveUserModel(user)
94+ DataStorage.standard.setLoggedInState(true)
9495 self?.coordinator?.goToNextStep()
9596 }
9697 }
Hookah Tau/Controllers/Authentication/Phone/PhoneCoordinator.swift+7−2
@@ -6,7 +6,7 @@
66// Copyright © 2019 Daria Rednikina. All rights reserved.
77//
88
9−import Foundation
9+import UIKit
1010
1111class PhoneCoordinator: BaseCoordinator {
1212
@@ -15,7 +15,12 @@ class PhoneCoordinator: BaseCoordinator {
1515 override func start() {
1616 let phoneVC = PhoneNumberViewController()
1717 phoneVC.coordinator = self
18− navigationController?.viewControllers = [ phoneVC ]
18+
19+ let appDelegate = UIApplication.shared.delegate as? AppDelegate
20+ guard let appD = appDelegate else { return }
21+ appD.window?.rootViewController = navigationController
22+
23+ navigationController?.pushViewController(phoneVC, animated: false)
1924 }
2025
2126 /// Method chooses next step. Depends on weather user was previously registered
Hookah Tau/Controllers/BaseViewController.swift+13−3
@@ -16,7 +16,10 @@ class BaseViewController: UIViewController {
1616
1717 // MARK: - Buttons
1818
19− func addStackViewWithButtons(leftBtn: Button? = nil, rightBtn: Button? = nil) {
19+ func addStackViewWithButtons(leftBtn: Button? = nil,
20+ rightBtn: Button? = nil,
21+ constant: CGFloat = -20) {
22+
2023 let stackView = UIStackView()
2124 stackView.translatesAutoresizingMaskIntoConstraints = false
2225 stackView.backgroundColor = .red
@@ -25,7 +28,14 @@ class BaseViewController: UIViewController {
2528 leftBtn?.translatesAutoresizingMaskIntoConstraints = false
2629 rightBtn?.translatesAutoresizingMaskIntoConstraints = false
2730
28− bottomConstraint = NSLayoutConstraint(item: stackView, attribute: .bottom, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .bottom, multiplier: 1, constant: -20)
31+ bottomConstraint = NSLayoutConstraint(item: stackView,
32+ attribute: .bottom,
33+ relatedBy: .equal,
34+ toItem: view.safeAreaLayoutGuide,
35+ attribute: .bottom,
36+ multiplier: 1,
37+ constant: constant)
38+
2939 guard let bottomContraint = bottomConstraint else { return }
3040 view.addConstraint(bottomContraint)
3141
@@ -101,7 +111,7 @@ class BaseViewController: UIViewController {
101111 // MARK: - Alert
102112
103113 func displayAlert(forError error: GeneralError) {
104− var title: String? = "MEOW"
114+ var title: String? = error.localizedDescription
105115 switch error {
106116 case .serverError(let se):
107117 title = se.error
Hookah Tau/Controllers/Client/Profile/ProfileClientViewController.swift+12−2
@@ -14,8 +14,9 @@ class ProfileClientViewController: UIViewController {
1414
1515 weak var coordinator: ProfileCoordinator?
1616
17− var model: User = User(name: "Стасик", phoneNumber: "+ 8 901 733 01 79", isAdmin: false) {
17+ var model: User? {
1818 didSet {
19+ guard let model = model else { return }
1920 profileContentView?.bind(withModel: model)
2021 }
2122 }
@@ -33,7 +34,9 @@ class ProfileClientViewController: UIViewController {
3334 navigationController?.navigationBar.prefersLargeTitles = true
3435
3536 profileContentView = ProfileView.loadFromNib()
36− profileContentView?.bind(withModel: model)
37+ profileContentView?.logOutButton?.addTarget(self, action: #selector(logout), for: .touchUpInside)
38+
39+ model = DataStorage.standard.getUserModel()
3740
3841 view.addSubviewThatFills(profileContentView)
3942
@@ -41,19 +44,26 @@ class ProfileClientViewController: UIViewController {
4144 }
4245
4346 @objc func presentChangeViewPhone() {
47+ guard let model = model else { return }
4448 let changeModel = ChangeModel(userModel: model, editingOption: .phone)
4549 coordinator?.presentEditMode(withModel: changeModel)
4650 }
4751
4852 @objc func presentChangeViewInvite() {
53+ guard let model = model else { return }
4954 let changeModel = ChangeModel(userModel: model, editingOption: .invite)
5055 coordinator?.presentEditMode(withModel: changeModel)
5156 }
5257
5358 @objc func presentChangeViewName() {
59+ guard let model = model else { return }
5460 let changeModel = ChangeModel(userModel: model, editingOption: .name)
5561 coordinator?.presentEditMode(withModel: changeModel)
5662 }
63+
64+ @objc func logout() {
65+ coordinator?.logout()
66+ }
5767}
5868
5969// MARK: - UserUpdate ext
Hookah Tau/Controllers/Client/Profile/ProfileCoordinator.swift+2−1
@@ -33,6 +33,7 @@ class ProfileCoordinator: BaseCoordinator {
3333 }
3434
3535 func logout() {
36−
36+ DataStorage.standard.setLoggedInState(false)
37+ didEndFlow?()
3738 }
3839}
Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsViewController.swift+42−12
@@ -10,11 +10,17 @@ import UIKit
1010
1111let reservationCell = "ReservationCell"
1212
13−class ReservationsViewController: UIViewController {
13+class ReservationsViewController: BaseViewController {
1414
1515 // MARK: - Properties
1616
17− var activeReservations = [1]
17+ var activeReservations: [Reservation] = [] {
18+ didSet {
19+ setUpContentView()
20+ }
21+ }
22+
23+ var reservationsService: ReservationsService?
1824
1925 weak var coordinator: ReservationsCoordinator?
2026
@@ -33,18 +39,11 @@ class ReservationsViewController: UIViewController {
3339 override func viewDidLoad() {
3440 super.viewDidLoad()
3541
36− setUpContentView()
42+ setUpNavigationBar()
3743
38− tableView?.delegate = self
39− tableView?.dataSource = self
44+ reservationsService = ReservationsService(apiClient: APIClient.shared)
4045
41− tableView?.register(ReservationCell.self, forCellReuseIdentifier: reservationCell)
42−
43− view.backgroundColor = .white
44− navigationItem.title = "Брони"
45−
46− navigationItem.rightBarButtonItem =
47− UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(tapToMakeReservation))
46+ performUpdate()
4847 }
4948
5049 // MARK: - Setup
@@ -59,7 +58,25 @@ class ReservationsViewController: UIViewController {
5958 } else {
6059 tableView = UITableView()
6160 contentView.addSubviewThatFills(tableView)
61+ tableView?.reloadData()
6262 }
63+
64+ setUpTableView()
65+ }
66+
67+ func setUpTableView() {
68+ tableView?.delegate = self
69+ tableView?.dataSource = self
70+
71+ tableView?.register(ReservationCell.self, forCellReuseIdentifier: reservationCell)
72+ }
73+
74+ func setUpNavigationBar() {
75+ view.backgroundColor = .white
76+ navigationItem.title = "Брони"
77+
78+ navigationItem.rightBarButtonItem =
79+ UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(tapToMakeReservation))
6380 }
6481
6582 // MARK: - handlers
@@ -68,6 +85,19 @@ class ReservationsViewController: UIViewController {
6885 coordinator?.makeReservation()
6986 }
7087
88+ // MARK: - Update
89+
90+ func performUpdate() {
91+ reservationsService?.loadUsersReservations(completion: { [weak self] (result) in
92+ switch result {
93+ case .success(let reservations):
94+ self?.activeReservations = reservations
95+ case .failure(let err):
96+ self?.displayAlert(forError: err)
97+ }
98+ })
99+ }
100+
71101}
72102
73103extension ReservationsViewController: UITableViewDelegate, UITableViewDataSource {
Hookah Tau/Controllers/Client/Reservations/Adress of reservation/AddresViewController.swift+9
@@ -60,4 +60,13 @@ extension AddresViewController: UITableViewDelegate, UITableViewDataSource {
6060 return 168.0
6161 }
6262
63+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
64+ let establishment = dataSource?[indexPath.row]
65+ guard let id = establishment else { return }
66+
67+ coordinator?.chooseTableAndTime(inEstablishment: id)
68+ }
69+
70+
71+
6372}
Hookah Tau/Controllers/Client/Reservations/Adress of reservation/AddressCoordinator.swift+8−2
@@ -29,7 +29,13 @@ class AddressCoordinator: BaseCoordinator {
2929
3030 /// continue with reservation
3131 /// TODO: pass some data
32− func chooseTableAndTime() {
33−
32+ func chooseTableAndTime(inEstablishment id: Int) {
33+ let reservationCoordinator = ReservationCoordinator(navigationController: navigationController)
34+ addDependency(reservationCoordinator)
35+ reservationCoordinator.didFinish = { [weak self] in
36+ self?.removeDependency(reservationCoordinator)
37+ self?.navigationController?.popViewController(animated: true)
38+ }
39+ reservationCoordinator.start()
3440 }
3541}
Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationCell.swift+2−2
@@ -33,8 +33,8 @@ class ReservationCell: UITableViewCell {
3333
3434 // MARK: - Data
3535
36− func bind(withModel model: Int) {
37−
36+ func bind(withModel model: Reservation) {
37+ self.reservationCellView?.maxPeopleLabel?.text = "\(model.numberOfGuests)"
3838 }
3939
4040}
Hookah Tau/Controllers/Client/Reservations/Maps/MapView.swiftnew file+25
@@ -0,0 +1,25 @@
1+//
2+// MapView.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 06/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+
12+class MapImageScroll: UIView {
13+ var scrollViewParent: UIScrollView!
14+ var tables: [Int: UIButton] = [:]
15+}
16+
17+extension MapImageScroll {
18+
19+ func performUpdate(inactive: [Int]) {
20+
21+ let active = Set(tables.keys).subtracting(inactive)
22+ active.forEach { ind in tables[ind]?.backgroundColor = #colorLiteral(red: 0, green: 1, blue: 1, alpha: 0.3711205051) }
23+ inactive.forEach { ind in tables[ind]?.backgroundColor = #colorLiteral(red: 1, green: 0, blue: 0.7170844332, alpha: 0.3711205051) }
24+ }
25+}
Hookah Tau/Controllers/Client/Reservations/Maps/MapView1.swiftnew file+128
@@ -0,0 +1,128 @@
1+//
2+// MapView1.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 06/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+protocol MapHandler {
12+ func handleTap(withId id: Int)
13+}
14+
15+class MapView1: MapImageScroll, UIScrollViewDelegate {
16+
17+ // MARK: - Properties
18+
19+ var handler: MapHandler?
20+
21+ @IBOutlet weak var scrollView: UIScrollView! {
22+ didSet {
23+ super.scrollViewParent = scrollView
24+ }
25+ }
26+
27+ @IBOutlet weak var image: UIImageView!
28+
29+ @IBOutlet weak var firstTable: UIButton! {
30+ didSet {
31+ firstTable.transform = CGAffineTransform(rotationAngle: CGFloat(-Double.pi / 4));
32+ }
33+ }
34+
35+ @IBOutlet weak var secondTable: UIButton!
36+
37+ @IBOutlet weak var trirdTable: UIButton!
38+
39+ @IBOutlet weak var forthTable: UIButton!
40+
41+ @IBOutlet weak var fifthTable: UIButton!
42+
43+ @IBOutlet weak var sixthTable: UIButton!
44+
45+ @IBOutlet weak var seventhTable: UIButton!
46+
47+ @IBOutlet weak var eighthTable: UIButton!
48+
49+ // MARK: - Lifecycle
50+
51+ override func awakeFromNib() {
52+ super.awakeFromNib()
53+
54+ self.scrollView.delegate = self
55+
56+ image.addSubview(firstTable)
57+ image.addSubview(secondTable)
58+ image.addSubview(trirdTable)
59+ image.addSubview(forthTable)
60+ image.addSubview(fifthTable)
61+ image.addSubview(sixthTable)
62+ image.addSubview(seventhTable)
63+ image.addSubview(eighthTable)
64+
65+ tables[1] = firstTable
66+ tables[2] = secondTable
67+ tables[3] = trirdTable
68+ tables[4] = forthTable
69+ tables[5] = fifthTable
70+ tables[6] = sixthTable
71+ tables[7] = seventhTable
72+ tables[8] = eighthTable
73+
74+ configureFor(image.frame.size)
75+ }
76+
77+ @IBAction func chooseSecondTable(_ sender: UIButton) {
78+ handler?.handleTap(withId: 2)
79+ }
80+
81+ // MARK: - Scroll view
82+
83+ func configureFor(_ imageSize: CGSize) {
84+ self.scrollView.contentSize = imageSize
85+ setMaxMinZoomScaleForCurrentBounds()
86+ }
87+
88+ func viewForZooming(in scrollView: UIScrollView) -> UIView? {
89+ self.image
90+ }
91+
92+ func setMaxMinZoomScaleForCurrentBounds() {
93+ let boundsSize = self.scrollView.bounds.size
94+ let imageSize = image.bounds.size
95+
96+ //1. calculate minimumZoomscale
97+ let xScale = boundsSize.width / imageSize.width
98+ let yScale = boundsSize.height / imageSize.height
99+ var minScale = min(xScale, yScale)
100+
101+ //2. calculate maximumZoomscale
102+ var maxScale: CGFloat = 1.0
103+ if minScale < 0.1 {
104+ maxScale = 0.3
105+ }
106+ if minScale >= 0.1 && minScale < 0.5 {
107+ maxScale = 0.7
108+ }
109+ if minScale >= 0.5 {
110+ maxScale = max(1.0, minScale)
111+ }
112+
113+ if image.frame.width < frame.width {
114+ let scaleW = frame.width / image.frame.width
115+ minScale = scaleW
116+ }
117+
118+ if image.frame.height < frame.height {
119+ let scaleH = frame.height / image.frame.height
120+ maxScale = scaleH
121+ }
122+
123+ image.transform = CGAffineTransform(scaleX: minScale, y: minScale)
124+
125+ self.scrollView.maximumZoomScale = maxScale
126+ self.scrollView.minimumZoomScale = minScale
127+ }
128+}
Hookah Tau/Controllers/Client/Reservations/Maps/MapView1.xibnew file+151
@@ -0,0 +1,151 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
3+ <device id="retina4_7" orientation="portrait" appearance="light"/>
4+ <dependencies>
5+ <deployment identifier="iOS"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
7+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
9+ </dependencies>
10+ <objects>
11+ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
12+ <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
13+ <view clipsSubviews="YES" contentMode="scaleToFill" id="iN0-l3-epB" customClass="MapView1" customModule="Hookah_Tau" customModuleProvider="target">
14+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
15+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16+ <subviews>
17+ <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FuE-LV-NBR">
18+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
19+ <subviews>
20+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="map_1" translatesAutoresizingMaskIntoConstraints="NO" id="btD-Wl-3P6">
21+ <rect key="frame" x="0.0" y="0.0" width="536" height="639"/>
22+ </imageView>
23+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xsw-fJ-8cN">
24+ <rect key="frame" x="209" y="116" width="131" height="119"/>
25+ <color key="backgroundColor" red="0.8027878853" green="0.39771511129999998" blue="0.73183326199999998" alpha="0.19301155819999999" colorSpace="calibratedRGB"/>
26+ <constraints>
27+ <constraint firstAttribute="width" constant="131" id="2xi-Oz-ceC"/>
28+ <constraint firstAttribute="height" constant="119" id="xPD-fh-9Zg"/>
29+ </constraints>
30+ <state key="normal" title="Button"/>
31+ </button>
32+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="onR-hl-Q2x">
33+ <rect key="frame" x="60" y="213" width="102" height="119"/>
34+ <color key="backgroundColor" red="0.8027878853" green="0.39771511129999998" blue="0.73183326199999998" alpha="0.19301155819999999" colorSpace="calibratedRGB"/>
35+ <constraints>
36+ <constraint firstAttribute="height" constant="119" id="JWf-x8-7CB"/>
37+ <constraint firstAttribute="width" constant="102" id="LZN-1O-mIP"/>
38+ </constraints>
39+ <state key="normal" title="Button"/>
40+ </button>
41+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fw9-l6-N8a">
42+ <rect key="frame" x="60" y="353" width="102" height="118"/>
43+ <color key="backgroundColor" red="0.8027878853" green="0.39771511129999998" blue="0.73183326199999998" alpha="0.19301155819999999" colorSpace="calibratedRGB"/>
44+ <constraints>
45+ <constraint firstAttribute="height" constant="118" id="2Vp-Ip-7cO"/>
46+ <constraint firstAttribute="width" constant="102" id="2hI-75-UCM"/>
47+ </constraints>
48+ <state key="normal" title="Button"/>
49+ </button>
50+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KJZ-Nl-7hH">
51+ <rect key="frame" x="222" y="275" width="104" height="119"/>
52+ <color key="backgroundColor" red="0.8027878853" green="0.39771511129999998" blue="0.73183326199999998" alpha="0.19301155819999999" colorSpace="calibratedRGB"/>
53+ <constraints>
54+ <constraint firstAttribute="height" constant="119" id="Ifu-kd-YHH"/>
55+ <constraint firstAttribute="width" constant="104" id="phm-aP-6dx"/>
56+ </constraints>
57+ <state key="normal" title="Button"/>
58+ </button>
59+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mUw-im-1BC">
60+ <rect key="frame" x="222" y="434" width="92" height="67"/>
61+ <color key="backgroundColor" red="0.8027878853" green="0.39771511129999998" blue="0.73183326199999998" alpha="0.19301155819999999" colorSpace="calibratedRGB"/>
62+ <constraints>
63+ <constraint firstAttribute="width" constant="92" id="AJ6-ku-4R3"/>
64+ <constraint firstAttribute="height" constant="67" id="jVI-uI-YDT"/>
65+ </constraints>
66+ <state key="normal" title="Button"/>
67+ </button>
68+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Bns-fd-Wv4">
69+ <rect key="frame" x="44" y="43" width="102" height="125"/>
70+ <color key="backgroundColor" red="0.8027878853" green="0.39771511129999998" blue="0.73183326199999998" alpha="0.19301155819999999" colorSpace="calibratedRGB"/>
71+ <constraints>
72+ <constraint firstAttribute="width" constant="102" id="l7h-tW-FfX"/>
73+ <constraint firstAttribute="height" constant="125" id="nDu-wc-Ll7"/>
74+ </constraints>
75+ <state key="normal" title="Button"/>
76+ </button>
77+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aIM-Qn-Uhl">
78+ <rect key="frame" x="386" y="116" width="130" height="119"/>
79+ <color key="backgroundColor" red="0.8027878853" green="0.39771511129999998" blue="0.73183326199999998" alpha="0.19301155819999999" colorSpace="calibratedRGB"/>
80+ <constraints>
81+ <constraint firstAttribute="width" constant="130" id="Lhq-jM-PQ0"/>
82+ <constraint firstAttribute="height" constant="119" id="vsx-u8-L6o"/>
83+ </constraints>
84+ <state key="normal" title="Button"/>
85+ </button>
86+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wpi-6E-c5p">
87+ <rect key="frame" x="399" y="275" width="104" height="119"/>
88+ <color key="backgroundColor" red="0.8027878853" green="0.39771511129999998" blue="0.73183326199999998" alpha="0.19301155819999999" colorSpace="calibratedRGB"/>
89+ <constraints>
90+ <constraint firstAttribute="height" constant="119" id="Lib-3b-h8b"/>
91+ <constraint firstAttribute="width" constant="104" id="nch-5L-cRo"/>
92+ </constraints>
93+ <state key="normal" title="Button"/>
94+ </button>
95+ </subviews>
96+ <constraints>
97+ <constraint firstItem="btD-Wl-3P6" firstAttribute="leading" secondItem="Fw9-l6-N8a" secondAttribute="trailing" constant="-162" id="1lP-Gg-qgW"/>
98+ <constraint firstItem="btD-Wl-3P6" firstAttribute="leading" secondItem="onR-hl-Q2x" secondAttribute="trailing" constant="-162" id="1vg-zK-zAf"/>
99+ <constraint firstItem="btD-Wl-3P6" firstAttribute="leading" secondItem="FuE-LV-NBR" secondAttribute="leading" id="ALg-fi-eby"/>
100+ <constraint firstItem="btD-Wl-3P6" firstAttribute="leading" secondItem="Bns-fd-Wv4" secondAttribute="trailing" constant="-146" id="Dd1-Ql-NS9"/>
101+ <constraint firstItem="Fw9-l6-N8a" firstAttribute="top" secondItem="btD-Wl-3P6" secondAttribute="bottom" constant="-286" id="DyF-KK-1VM"/>
102+ <constraint firstItem="btD-Wl-3P6" firstAttribute="top" secondItem="FuE-LV-NBR" secondAttribute="top" id="EKh-3k-EL9"/>
103+ <constraint firstItem="mUw-im-1BC" firstAttribute="top" secondItem="KJZ-Nl-7hH" secondAttribute="bottom" constant="40" id="GaI-BE-NZy"/>
104+ <constraint firstItem="btD-Wl-3P6" firstAttribute="width" secondItem="FuE-LV-NBR" secondAttribute="width" priority="250" id="MDs-kk-aza"/>
105+ <constraint firstItem="btD-Wl-3P6" firstAttribute="top" secondItem="aIM-Qn-Uhl" secondAttribute="bottom" constant="-235" id="NwR-U0-V6F"/>
106+ <constraint firstAttribute="bottom" secondItem="Bns-fd-Wv4" secondAttribute="bottom" constant="471" id="TL4-ma-hIl"/>
107+ <constraint firstItem="mUw-im-1BC" firstAttribute="top" secondItem="btD-Wl-3P6" secondAttribute="bottom" constant="-205" id="UXz-DD-dPH"/>
108+ <constraint firstItem="mUw-im-1BC" firstAttribute="leading" secondItem="Fw9-l6-N8a" secondAttribute="trailing" constant="60" id="V4u-ko-iFV"/>
109+ <constraint firstItem="KJZ-Nl-7hH" firstAttribute="top" secondItem="xsw-fJ-8cN" secondAttribute="bottom" constant="40" id="XFV-l2-chC"/>
110+ <constraint firstItem="btD-Wl-3P6" firstAttribute="top" secondItem="onR-hl-Q2x" secondAttribute="bottom" constant="-332" id="XNT-i4-1l8"/>
111+ <constraint firstItem="aIM-Qn-Uhl" firstAttribute="leading" secondItem="xsw-fJ-8cN" secondAttribute="trailing" constant="46" id="XVo-Ke-EGt"/>
112+ <constraint firstAttribute="trailing" secondItem="btD-Wl-3P6" secondAttribute="trailing" id="Ybd-7M-6Ft"/>
113+ <constraint firstItem="wpi-6E-c5p" firstAttribute="leading" secondItem="KJZ-Nl-7hH" secondAttribute="trailing" constant="73" id="cy7-0f-qGh"/>
114+ <constraint firstItem="wpi-6E-c5p" firstAttribute="top" secondItem="aIM-Qn-Uhl" secondAttribute="bottom" constant="40" id="dek-gp-H4X"/>
115+ <constraint firstItem="btD-Wl-3P6" firstAttribute="height" secondItem="FuE-LV-NBR" secondAttribute="height" priority="250" id="fSd-Le-0Bc"/>
116+ <constraint firstItem="btD-Wl-3P6" firstAttribute="top" secondItem="Bns-fd-Wv4" secondAttribute="bottom" constant="-168" id="gCy-q0-NO1"/>
117+ <constraint firstAttribute="bottom" secondItem="btD-Wl-3P6" secondAttribute="bottom" id="neR-bl-aSU"/>
118+ <constraint firstItem="KJZ-Nl-7hH" firstAttribute="leading" secondItem="onR-hl-Q2x" secondAttribute="trailing" constant="60" id="pka-Xh-e1c"/>
119+ <constraint firstItem="xsw-fJ-8cN" firstAttribute="leading" secondItem="onR-hl-Q2x" secondAttribute="trailing" constant="47" id="r9E-ps-zBG"/>
120+ </constraints>
121+ <viewLayoutGuide key="contentLayoutGuide" id="BDw-f7-kaJ"/>
122+ <viewLayoutGuide key="frameLayoutGuide" id="KRK-7M-mdV"/>
123+ </scrollView>
124+ </subviews>
125+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
126+ <constraints>
127+ <constraint firstItem="FuE-LV-NBR" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="0zj-Rn-Ogr"/>
128+ <constraint firstItem="FuE-LV-NBR" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="87c-vf-vMB"/>
129+ <constraint firstItem="FuE-LV-NBR" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="bhi-Ox-g2b"/>
130+ <constraint firstItem="FuE-LV-NBR" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="jLf-Pz-gy1"/>
131+ </constraints>
132+ <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
133+ <connections>
134+ <outlet property="eighthTable" destination="mUw-im-1BC" id="x44-wS-xJg"/>
135+ <outlet property="fifthTable" destination="KJZ-Nl-7hH" id="KXs-8a-Fo8"/>
136+ <outlet property="firstTable" destination="Bns-fd-Wv4" id="r5r-DX-4AD"/>
137+ <outlet property="forthTable" destination="wpi-6E-c5p" id="26b-bH-kEA"/>
138+ <outlet property="image" destination="btD-Wl-3P6" id="Ou2-hT-jap"/>
139+ <outlet property="scrollView" destination="FuE-LV-NBR" id="pWc-cI-eXE"/>
140+ <outlet property="secondTable" destination="xsw-fJ-8cN" id="2vH-LX-qF0"/>
141+ <outlet property="seventhTable" destination="Fw9-l6-N8a" id="Jwb-yY-Opx"/>
142+ <outlet property="sixthTable" destination="onR-hl-Q2x" id="Zi7-hJ-KLq"/>
143+ <outlet property="trirdTable" destination="aIM-Qn-Uhl" id="aFd-cB-neE"/>
144+ </connections>
145+ <point key="canvasLocation" x="-194.40000000000001" y="97.601199400299862"/>
146+ </view>
147+ </objects>
148+ <resources>
149+ <image name="map_1" width="536" height="636"/>
150+ </resources>
151+</document>
Hookah Tau/Controllers/Client/Reservations/Reservation.storyboardnew file+44
@@ -0,0 +1,44 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
3+ <device id="retina6_1" orientation="portrait" appearance="light"/>
4+ <dependencies>
5+ <deployment identifier="iOS"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
7+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
9+ </dependencies>
10+ <scenes>
11+ <!--Reservation View Controller-->
12+ <scene sceneID="EKz-nU-dQ1">
13+ <objects>
14+ <viewController storyboardIdentifier="ReservationViewController" id="Fha-pE-okd" customClass="ReservationViewController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
15+ <view key="view" contentMode="scaleToFill" id="cwG-Fa-gXD">
16+ <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
17+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18+ <subviews>
19+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RRF-jh-Xme">
20+ <rect key="frame" x="0.0" y="671" width="414" height="225"/>
21+ <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
22+ <constraints>
23+ <constraint firstAttribute="height" constant="225" id="43Q-xl-4hv"/>
24+ </constraints>
25+ </view>
26+ </subviews>
27+ <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
28+ <constraints>
29+ <constraint firstItem="RRF-jh-Xme" firstAttribute="leading" secondItem="MXi-ad-tf6" secondAttribute="leading" id="Bs8-yy-Zht"/>
30+ <constraint firstAttribute="bottom" secondItem="RRF-jh-Xme" secondAttribute="bottom" id="KZv-en-hrr"/>
31+ <constraint firstItem="RRF-jh-Xme" firstAttribute="trailing" secondItem="MXi-ad-tf6" secondAttribute="trailing" id="ehP-xe-Opz"/>
32+ </constraints>
33+ <viewLayoutGuide key="safeArea" id="MXi-ad-tf6"/>
34+ </view>
35+ <connections>
36+ <outlet property="childContentView" destination="RRF-jh-Xme" id="blV-8a-srQ"/>
37+ </connections>
38+ </viewController>
39+ <placeholder placeholderIdentifier="IBFirstResponder" id="TB1-Hv-wQ6" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
40+ </objects>
41+ <point key="canvasLocation" x="-140.57971014492756" y="-38.169642857142854"/>
42+ </scene>
43+ </scenes>
44+</document>
Hookah Tau/Controllers/Client/Reservations/ReservationCoordinator.swiftnew file+34
@@ -0,0 +1,34 @@
1+//
2+// ReservationCoordinator.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 06/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class ReservationCoordinator: BaseCoordinator {
12+
13+ // MARK: - Properties
14+
15+ var didFinish: (() -> Void)?
16+
17+ // MARK: - Lifecycle
18+
19+ override func start() {
20+ let storyboard = UIStoryboard(name: "Reservation", bundle: nil)
21+ let reservationVC = storyboard.instantiateViewController(withIdentifier: "ReservationViewController") as! ReservationViewController
22+
23+ navigationController?.pushViewController(reservationVC, animated: true)
24+ }
25+
26+ func callAdmin() {
27+
28+ }
29+
30+ // TODO: with parameters
31+ func makeReservation() {
32+
33+ }
34+}
Hookah Tau/Controllers/Client/Reservations/ReservationViewController.swiftnew file+133
@@ -0,0 +1,133 @@
1+//
2+// ReservationViewController.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 06/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+
12+class ReservationViewController: BaseViewController {
13+
14+ // MARK: - Properties
15+
16+ @IBOutlet weak var childContentView: UIView!
17+
18+ var firstStepView: FirstStepView?
19+
20+ var reservationsService: ReservationsService?
21+
22+ var mapView: MapImageScroll?
23+
24+ var allReservations: AllReservations? {
25+ didSet {
26+ guard let reservations = allReservations else {
27+ return
28+ }
29+
30+ self.firstStepView?.setUp(reservations)
31+ }
32+ }
33+
34+ let continueButton: Button = {
35+ let button = Button()
36+ let style = BlackButtonStyle()
37+ style.apply(to: button, withTitle: "ЗАБРОНИРОВАТЬ")
38+ //button.addTarget(self, action: #selector(doneChanging), for: .touchUpInside)
39+ return button
40+ }()
41+
42+ let callButton: Button = {
43+ let button = Button()
44+ let style = BlackButtonStyle()
45+ style.apply(to: button, withTitle: "ПОЗВОНИТЬ")
46+ //button.addTarget(self, action: #selector(cancelChange), for: .touchUpInside)
47+ return button
48+ }()
49+
50+ var establishmentId: Int = 1
51+ var step: Int = 1
52+
53+ // MARK: - Lifecycle
54+
55+ override func viewDidLoad() {
56+ super.viewDidLoad()
57+
58+ configureMap()
59+ configureStep()
60+
61+ addStackViewWithButtons(leftBtn: callButton, rightBtn: continueButton, constant: -childContentView.frame.height - 20)
62+ reservationsService = ReservationsService(apiClient: APIClient.shared)
63+
64+ performUpdate()
65+ }
66+
67+ func performUpdate() {
68+ reservationsService?.getAllReservations(establishmentID: establishmentId, completion: { [weak self] result in
69+ switch result {
70+ case .failure(let err):
71+ self?.displayAlert(forError: err)
72+ case .success(let allReservations):
73+ self?.allReservations = allReservations
74+ }
75+ })
76+ }
77+
78+ override func viewDidAppear(_ animated: Bool) {
79+ super.viewDidAppear(animated)
80+
81+ firstStepView?.setContent()
82+ }
83+
84+ override func viewWillAppear(_ animated: Bool) {
85+ super.viewWillAppear(animated)
86+
87+ tabBarController?.tabBar.isHidden = true
88+ }
89+
90+ override func viewWillDisappear(_ animated: Bool) {
91+ super.viewWillDisappear(animated)
92+
93+ tabBarController?.tabBar.isHidden = false
94+ }
95+
96+ func configureMap() {
97+ if establishmentId == 1 {
98+ mapView = MapView1.loadFromNib()
99+ view.addSubviewThatFills(mapView)
100+ } else {
101+ // mapView = MapView2.loadFromNib()
102+ }
103+
104+ guard let map = mapView else { return }
105+ map.scrollViewParent.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: childContentView.frame.height, right: 0)
106+ view.sendSubviewToBack(map)
107+ }
108+
109+ func configureStep() {
110+ if step == 1 {
111+ firstStepView = FirstStepView.loadFromNib()
112+ firstStepView?.mapUpdater = self
113+ childContentView.addSubviewThatFills(firstStepView)
114+ }
115+ }
116+
117+ func updateChildViewControllerWithChosenId(_ id: Int) {
118+ print("Chosen \(id) table")
119+ }
120+}
121+
122+extension ReservationViewController: MapHandler {
123+ func handleTap(withId id: Int) {
124+ updateChildViewControllerWithChosenId(id)
125+ }
126+}
127+
128+extension ReservationViewController: MapUpdater {
129+ func update(_ date: IntervalDate) {
130+ //let areBooked = allReservations?.intervals[date.getDateString()]?[date.getFullString()] ?? []
131+ //mapView?.performUpdate(inactive: areBooked)
132+ }
133+}
Hookah Tau/Controllers/Client/Reservations/Steps/First/DateView.swiftnew file+18
@@ -0,0 +1,18 @@
1+//
2+// DateView.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 15/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class DateView: UIView {
12+
13+ @IBOutlet weak var dateLabel: UILabel!
14+
15+ func setUp(with date: IntervalDate) {
16+ dateLabel.text = "\(date.day)"
17+ }
18+}
Hookah Tau/Controllers/Client/Reservations/Steps/First/DateView.xibnew file+42
@@ -0,0 +1,42 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
3+ <device id="retina4_7" orientation="portrait" appearance="light"/>
4+ <dependencies>
5+ <deployment identifier="iOS"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
7+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
9+ </dependencies>
10+ <objects>
11+ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
12+ <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
13+ <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="DateView" customModule="Hookah_Tau" customModuleProvider="target">
14+ <rect key="frame" x="0.0" y="0.0" width="31" height="59"/>
15+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16+ <subviews>
17+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="69" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hzu-lu-5Cc">
18+ <rect key="frame" x="5" y="19.5" width="21" height="20"/>
19+ <constraints>
20+ <constraint firstAttribute="width" constant="21" id="gdn-d6-auU"/>
21+ </constraints>
22+ <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
23+ <color key="textColor" red="0.60784313725490191" green="0.60784313725490191" blue="0.60784313725490191" alpha="1" colorSpace="calibratedRGB"/>
24+ <nil key="highlightedColor"/>
25+ </label>
26+ </subviews>
27+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
28+ <constraints>
29+ <constraint firstItem="hzu-lu-5Cc" firstAttribute="centerY" secondItem="vUN-kp-3ea" secondAttribute="centerY" id="Vwr-KU-m3O"/>
30+ <constraint firstItem="hzu-lu-5Cc" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="fhT-nh-ejJ"/>
31+ <constraint firstItem="hzu-lu-5Cc" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="5" id="mLo-I1-FSM"/>
32+ <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="hzu-lu-5Cc" secondAttribute="trailing" constant="5" id="qSb-Ok-1MH"/>
33+ </constraints>
34+ <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
35+ <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
36+ <connections>
37+ <outlet property="dateLabel" destination="hzu-lu-5Cc" id="n0M-OL-lME"/>
38+ </connections>
39+ <point key="canvasLocation" x="101.59999999999999" y="456.52173913043481"/>
40+ </view>
41+ </objects>
42+</document>
Hookah Tau/Controllers/Client/Reservations/Steps/First/FirstStepView.swiftnew file+168
@@ -0,0 +1,168 @@
1+//
2+// FirstStepView.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 15/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+protocol MapUpdater: class {
12+ func update(_ date: IntervalDate)
13+}
14+
15+class FirstStepView: UIView {
16+
17+ weak var mapUpdater: MapUpdater?
18+
19+ var chosenPoint: Int? = 0 {
20+ didSet {
21+ guard let point = chosenPoint, let date = chosenDate else { return }
22+ let newIntervalDate = IntervalDate(day: date.day,
23+ month: date.month,
24+ year: date.year,
25+ minutes: point)
26+ mapUpdater?.update(newIntervalDate)
27+ }
28+ }
29+
30+ var chosenDate: IntervalDate? = Date.getDateFromCurrent() {
31+ didSet {
32+ guard let date = chosenDate, let _ = chosenPoint else { return }
33+ mapUpdater?.update(date)
34+ }
35+ }
36+
37+ @IBOutlet weak var scrollViewIntervals: UIScrollView!
38+
39+ @IBOutlet weak var stackViewIntervals: UIStackView!
40+
41+ @IBOutlet weak var datesStackView: UIStackView!
42+
43+ @IBOutlet weak var datesScrollView: UIScrollView!
44+
45+
46+ override func awakeFromNib() {
47+ super.awakeFromNib()
48+
49+ self.scrollViewIntervals.delegate = self
50+ self.datesScrollView.delegate = self
51+
52+ scrollViewIntervals.showsHorizontalScrollIndicator = false
53+ datesScrollView.showsHorizontalScrollIndicator = false
54+
55+ setUpDateStackView()
56+ setUpIntervalStackView()
57+ }
58+
59+ func setUpIntervalStackView() {
60+
61+ for period in 0...Constants.day10MinPeriods {
62+ let timePointView = TimePointView.loadFromNib()
63+ timePointView?.setUp(withTimePoint: period)
64+ let view = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 92))
65+ view.addSubviewThatFills(timePointView)
66+ stackViewIntervals.addArrangedSubview(view)
67+ }
68+ }
69+
70+ func addBusyPeriods() {
71+
72+ }
73+
74+ func setContent() {
75+ scrollViewIntervals.contentSize = stackViewIntervals.frame.size
76+ datesScrollView.contentSize = datesStackView.frame.size
77+
78+ let edges = UIEdgeInsets(top: 0, left: self.frame.size.width / 2, bottom: 0, right: self.frame.size.width / 2)
79+ scrollViewIntervals.contentInset = edges
80+ datesScrollView.contentInset = edges
81+
82+ datesScrollView.setContentOffset(CGPoint(x: abs(Constants.widthDate * Constants.daysCount / 2 - Int(edges.left)), y: 0), animated: true)
83+ scrollViewIntervals.setContentOffset(CGPoint(x: abs(Constants.widthTimePoint * Constants.day10MinPeriods / 2 - Int(edges.left)), y: 0), animated: true)
84+ }
85+
86+ func setUp(_ data: AllReservations) {
87+ //let sortedDates = data.intervals.keys.sorted()
88+
89+ // setUpDateStackView()
90+ }
91+
92+ func setUpDateStackView() {
93+ let dates = Date.getNext(days: Constants.daysCount)
94+
95+ for date in dates {
96+ let dateView = DateView.loadFromNib()
97+ dateView?.setUp(with: date)
98+ let view = UIView(frame: CGRect(x: 0, y: 0, width: 21, height: 59))
99+ view.addSubviewThatFills(dateView)
100+ datesStackView.addArrangedSubview(view)
101+ }
102+ }
103+}
104+
105+extension FirstStepView: UIScrollViewDelegate {
106+
107+
108+ func scrollViewDidScroll(_ scrollView: UIScrollView) {
109+
110+ if scrollView == scrollViewIntervals {
111+ intervalsDidScroll()
112+ } else {
113+ datesDidScroll()
114+ }
115+ }
116+
117+ func intervalsDidScroll() {
118+ for (index, stack) in stackViewIntervals.subviews.enumerated() {
119+ if let intervalStack = stack.subviews[0] as? TimePointView {
120+ let positionToSelf = intervalStack.convert(intervalStack.frame, to: self)
121+
122+// var isBusy = false
123+// let positionToScrollView = intervalStack.convert(intervalStack.frame, to: self.scrollViewIntervals)
124+
125+// for busyView in busyViews {
126+// if busyView.frame.contains(positionToScrollView) {
127+// isBusy = true
128+// }
129+// }
130+
131+ if abs((positionToSelf.minX + positionToSelf.maxX) / 2 - frame.size.width / 2) < 5.5
132+ //,!isBusy
133+ {
134+ intervalStack.timePoint.backgroundColor = .darkGray
135+ chosenPoint = index
136+ } else {
137+ intervalStack.timePoint.backgroundColor = .lightGray
138+ }
139+ }
140+ }
141+ }
142+
143+ func datesDidScroll() {
144+ for (_, stack) in datesStackView.subviews.enumerated() {
145+ if let dateView = stack.subviews[0] as? DateView {
146+ let positionToSelf = dateView.convert(dateView.frame, to: self)
147+
148+ if abs((positionToSelf.minX + positionToSelf.maxX) / 2 - frame.size.width / 2) < 15.5 {
149+ dateView.dateLabel.textColor = .black
150+ chosenDate = Date.getDateFromCurrent(days: Int((datesScrollView.contentInset.left + datesScrollView.contentOffset.x) / 31), period: chosenPoint)
151+ } else {
152+ dateView.dateLabel.textColor = .lightGray
153+ }
154+ }
155+ }
156+ }
157+}
158+
159+// MARK: - Nested types
160+
161+extension FirstStepView {
162+ enum Constants {
163+ static let day10MinPeriods = 90
164+ static let daysCount = 14
165+ static let widthTimePoint = 11
166+ static let widthDate = 31
167+ }
168+}
Hookah Tau/Controllers/Client/Reservations/Steps/First/FirstStepView.xibnew file+191
@@ -0,0 +1,191 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
3+ <device id="retina4_7" orientation="portrait" appearance="light"/>
4+ <dependencies>
5+ <deployment identifier="iOS"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
7+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
9+ </dependencies>
10+ <objects>
11+ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
12+ <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
13+ <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="FirstStepView" customModule="Hookah_Tau" customModuleProvider="target">
14+ <rect key="frame" x="0.0" y="0.0" width="414" height="225"/>
15+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16+ <subviews>
17+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pgz-8G-Kx4" userLabel="Under scroll dates">
18+ <rect key="frame" x="0.0" y="29" width="414" height="59"/>
19+ <subviews>
20+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ocm-Ba-WCp">
21+ <rect key="frame" x="0.0" y="0.0" width="414" height="1"/>
22+ <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
23+ <constraints>
24+ <constraint firstAttribute="height" constant="1" id="Gst-4x-W6O"/>
25+ </constraints>
26+ </view>
27+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Eb3-64-oGl">
28+ <rect key="frame" x="0.0" y="58" width="414" height="1"/>
29+ <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
30+ <constraints>
31+ <constraint firstAttribute="height" constant="1" id="Llo-E4-www"/>
32+ </constraints>
33+ </view>
34+ </subviews>
35+ <color key="backgroundColor" red="0.8901960784313725" green="0.8901960784313725" blue="0.8901960784313725" alpha="0.14999999999999999" colorSpace="custom" customColorSpace="calibratedRGB"/>
36+ <constraints>
37+ <constraint firstItem="Ocm-Ba-WCp" firstAttribute="leading" secondItem="pgz-8G-Kx4" secondAttribute="leading" id="AyK-U9-Htr"/>
38+ <constraint firstAttribute="trailing" secondItem="Eb3-64-oGl" secondAttribute="trailing" id="UWJ-H4-iVD"/>
39+ <constraint firstItem="Eb3-64-oGl" firstAttribute="leading" secondItem="pgz-8G-Kx4" secondAttribute="leading" id="UqX-3l-90O"/>
40+ <constraint firstAttribute="trailing" secondItem="Ocm-Ba-WCp" secondAttribute="trailing" id="drj-rX-UvL"/>
41+ <constraint firstAttribute="bottom" secondItem="Eb3-64-oGl" secondAttribute="bottom" id="ebx-vE-0aF"/>
42+ <constraint firstItem="Ocm-Ba-WCp" firstAttribute="top" secondItem="pgz-8G-Kx4" secondAttribute="top" id="nEC-cm-sIz"/>
43+ </constraints>
44+ </view>
45+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="954-g3-FZD" userLabel="Under scroll view">
46+ <rect key="frame" x="0.0" y="97" width="414" height="91"/>
47+ <subviews>
48+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dh5-kt-LFH">
49+ <rect key="frame" x="0.0" y="20" width="414" height="71"/>
50+ <subviews>
51+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nqq-Xp-Lig">
52+ <rect key="frame" x="0.0" y="0.0" width="414" height="1"/>
53+ <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
54+ <constraints>
55+ <constraint firstAttribute="height" constant="1" id="me1-hs-aWn"/>
56+ </constraints>
57+ </view>
58+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zqK-OT-P26">
59+ <rect key="frame" x="0.0" y="70" width="414" height="1"/>
60+ <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
61+ <constraints>
62+ <constraint firstAttribute="height" constant="1" id="iUR-sJ-1M1"/>
63+ <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="1" id="xeo-B1-TLL"/>
64+ </constraints>
65+ </view>
66+ </subviews>
67+ <color key="backgroundColor" red="0.8901960784313725" green="0.8901960784313725" blue="0.8901960784313725" alpha="0.70716502568493156" colorSpace="custom" customColorSpace="calibratedRGB"/>
68+ <constraints>
69+ <constraint firstItem="nqq-Xp-Lig" firstAttribute="top" secondItem="dh5-kt-LFH" secondAttribute="top" id="6xZ-TR-tvC"/>
70+ <constraint firstAttribute="trailing" secondItem="zqK-OT-P26" secondAttribute="trailing" id="SeY-dj-8cT"/>
71+ <constraint firstAttribute="trailing" secondItem="nqq-Xp-Lig" secondAttribute="trailing" id="XtL-jd-AZH"/>
72+ <constraint firstAttribute="bottom" secondItem="zqK-OT-P26" secondAttribute="bottom" id="m0O-4r-wfZ"/>
73+ <constraint firstItem="nqq-Xp-Lig" firstAttribute="leading" secondItem="dh5-kt-LFH" secondAttribute="leading" id="qr9-52-TNC"/>
74+ <constraint firstAttribute="height" constant="71" id="tcS-2U-ecA"/>
75+ <constraint firstItem="zqK-OT-P26" firstAttribute="leading" secondItem="dh5-kt-LFH" secondAttribute="leading" id="yUf-Cj-HmN"/>
76+ </constraints>
77+ </view>
78+ </subviews>
79+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
80+ <constraints>
81+ <constraint firstAttribute="trailing" secondItem="dh5-kt-LFH" secondAttribute="trailing" id="Ogq-Ny-UtZ"/>
82+ <constraint firstItem="dh5-kt-LFH" firstAttribute="leading" secondItem="954-g3-FZD" secondAttribute="leading" id="aGL-6Q-gwb"/>
83+ <constraint firstAttribute="bottom" secondItem="dh5-kt-LFH" secondAttribute="bottom" id="sCl-ct-Awr"/>
84+ </constraints>
85+ </view>
86+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="TriangleDown" translatesAutoresizingMaskIntoConstraints="NO" id="5dC-Lq-opV">
87+ <rect key="frame" x="184.5" y="0.0" width="45" height="29"/>
88+ <constraints>
89+ <constraint firstAttribute="width" constant="45" id="Tsw-fS-8qs"/>
90+ <constraint firstAttribute="height" constant="29" id="YWD-ja-gD5"/>
91+ </constraints>
92+ </imageView>
93+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="TriangleUp" translatesAutoresizingMaskIntoConstraints="NO" id="Igw-O9-W92">
94+ <rect key="frame" x="184.5" y="196" width="45" height="29"/>
95+ <constraints>
96+ <constraint firstAttribute="height" constant="29" id="AdE-yJ-WLL"/>
97+ <constraint firstAttribute="width" constant="45" id="Eaa-P8-3mv"/>
98+ </constraints>
99+ </imageView>
100+ <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a6N-9A-8y5">
101+ <rect key="frame" x="0.0" y="97" width="414" height="91"/>
102+ <subviews>
103+ <stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="z9p-OK-tL7">
104+ <rect key="frame" x="0.0" y="0.0" width="414" height="91"/>
105+ </stackView>
106+ </subviews>
107+ <constraints>
108+ <constraint firstItem="z9p-OK-tL7" firstAttribute="leading" secondItem="a6N-9A-8y5" secondAttribute="leading" id="66I-Xl-dE9"/>
109+ <constraint firstItem="z9p-OK-tL7" firstAttribute="width" secondItem="a6N-9A-8y5" secondAttribute="width" priority="250" id="8CZ-Pa-ROG"/>
110+ <constraint firstAttribute="bottom" secondItem="z9p-OK-tL7" secondAttribute="bottom" id="Bve-Ls-KhA"/>
111+ <constraint firstItem="z9p-OK-tL7" firstAttribute="top" secondItem="a6N-9A-8y5" secondAttribute="top" id="Qys-Ws-joK"/>
112+ <constraint firstItem="z9p-OK-tL7" firstAttribute="height" secondItem="a6N-9A-8y5" secondAttribute="height" id="a5D-0u-zAW"/>
113+ <constraint firstAttribute="trailing" secondItem="z9p-OK-tL7" secondAttribute="trailing" id="riY-nE-EUp"/>
114+ </constraints>
115+ <viewLayoutGuide key="contentLayoutGuide" id="Y0a-LG-dJH"/>
116+ <viewLayoutGuide key="frameLayoutGuide" id="bsE-qj-8ef"/>
117+ </scrollView>
118+ <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Y9G-UI-WV7">
119+ <rect key="frame" x="0.0" y="29" width="414" height="59"/>
120+ <subviews>
121+ <stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="52e-LM-cF6">
122+ <rect key="frame" x="0.0" y="0.0" width="414" height="59"/>
123+ </stackView>
124+ </subviews>
125+ <constraints>
126+ <constraint firstItem="52e-LM-cF6" firstAttribute="height" secondItem="Y9G-UI-WV7" secondAttribute="height" id="2wC-n3-oG9"/>
127+ <constraint firstItem="52e-LM-cF6" firstAttribute="leading" secondItem="Y9G-UI-WV7" secondAttribute="leading" id="GZW-kT-OtX"/>
128+ <constraint firstItem="52e-LM-cF6" firstAttribute="width" secondItem="Y9G-UI-WV7" secondAttribute="width" priority="250" id="Lb4-nJ-yt6"/>
129+ <constraint firstAttribute="trailing" secondItem="52e-LM-cF6" secondAttribute="trailing" id="edz-yx-1Bj"/>
130+ <constraint firstAttribute="bottom" secondItem="52e-LM-cF6" secondAttribute="bottom" id="qNo-Pi-gV4"/>
131+ <constraint firstItem="52e-LM-cF6" firstAttribute="top" secondItem="Y9G-UI-WV7" secondAttribute="top" id="wNf-Sa-CrY"/>
132+ </constraints>
133+ <viewLayoutGuide key="contentLayoutGuide" id="uZM-JL-J3w"/>
134+ <viewLayoutGuide key="frameLayoutGuide" id="dbW-UW-YAk"/>
135+ </scrollView>
136+ <view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fvt-zf-8tU" customClass="RadialGradientView" customModule="Hookah_Tau" customModuleProvider="target">
137+ <rect key="frame" x="0.0" y="29" width="414" height="59"/>
138+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
139+ <userDefinedRuntimeAttributes>
140+ <userDefinedRuntimeAttribute type="color" keyPath="outsideColor">
141+ <color key="value" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
142+ </userDefinedRuntimeAttribute>
143+ <userDefinedRuntimeAttribute type="color" keyPath="insideColor">
144+ <color key="value" white="0.67000000000000004" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
145+ </userDefinedRuntimeAttribute>
146+ </userDefinedRuntimeAttributes>
147+ </view>
148+ </subviews>
149+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
150+ <constraints>
151+ <constraint firstItem="Y9G-UI-WV7" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="22z-Ck-vsZ"/>
152+ <constraint firstItem="a6N-9A-8y5" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="5c8-YB-dSB"/>
153+ <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="954-g3-FZD" secondAttribute="bottom" constant="37" id="C3k-Mb-wT4"/>
154+ <constraint firstItem="Y9G-UI-WV7" firstAttribute="top" secondItem="5dC-Lq-opV" secondAttribute="bottom" id="E97-Lg-K2s"/>
155+ <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="fvt-zf-8tU" secondAttribute="trailing" id="Eeh-zB-KWe"/>
156+ <constraint firstItem="a6N-9A-8y5" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="F03-yv-41V"/>
157+ <constraint firstItem="pgz-8G-Kx4" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="G0y-2f-SkS"/>
158+ <constraint firstItem="5dC-Lq-opV" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="If5-v7-UAj"/>
159+ <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="pgz-8G-Kx4" secondAttribute="bottom" constant="137" id="Lgn-Nv-wjD"/>
160+ <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="954-g3-FZD" secondAttribute="trailing" id="MGt-d4-Win"/>
161+ <constraint firstItem="fvt-zf-8tU" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="SaI-rP-2em"/>
162+ <constraint firstItem="Igw-O9-W92" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="TtM-Bc-V1U"/>
163+ <constraint firstItem="Igw-O9-W92" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="V9u-Eu-VME"/>
164+ <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="pgz-8G-Kx4" secondAttribute="trailing" id="Z6D-PY-Jrh"/>
165+ <constraint firstItem="Igw-O9-W92" firstAttribute="top" secondItem="a6N-9A-8y5" secondAttribute="bottom" constant="8" id="f4D-nq-HMa"/>
166+ <constraint firstItem="Y9G-UI-WV7" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="gZw-8a-dTG"/>
167+ <constraint firstItem="954-g3-FZD" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="itw-0z-3i7"/>
168+ <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="fvt-zf-8tU" secondAttribute="bottom" constant="137" id="lOx-ke-O6a"/>
169+ <constraint firstItem="z9p-OK-tL7" firstAttribute="top" secondItem="52e-LM-cF6" secondAttribute="bottom" constant="9" id="ldj-Qh-p0k"/>
170+ <constraint firstItem="fvt-zf-8tU" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="29" id="pSg-dd-INI"/>
171+ <constraint firstItem="pgz-8G-Kx4" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="29" id="vfO-LG-tqR"/>
172+ <constraint firstItem="954-g3-FZD" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="97" id="vhK-2E-j3k"/>
173+ <constraint firstItem="5dC-Lq-opV" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="xOt-l0-Vzy"/>
174+ <constraint firstItem="a6N-9A-8y5" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="97" id="yyf-QB-vfF"/>
175+ </constraints>
176+ <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
177+ <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
178+ <connections>
179+ <outlet property="datesScrollView" destination="Y9G-UI-WV7" id="dbT-BM-Ckq"/>
180+ <outlet property="datesStackView" destination="52e-LM-cF6" id="6Ni-IN-sm4"/>
181+ <outlet property="scrollViewIntervals" destination="a6N-9A-8y5" id="uDW-QY-gNF"/>
182+ <outlet property="stackViewIntervals" destination="z9p-OK-tL7" id="0Mj-wX-kq7"/>
183+ </connections>
184+ <point key="canvasLocation" x="-110.40000000000001" y="63.418290854572717"/>
185+ </view>
186+ </objects>
187+ <resources>
188+ <image name="TriangleDown" width="40" height="41"/>
189+ <image name="TriangleUp" width="40" height="41"/>
190+ </resources>
191+</document>
Hookah Tau/Controllers/Client/Reservations/Steps/First/TimePointView.swiftnew file+50
@@ -0,0 +1,50 @@
1+//
2+// TimePointView.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 15/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class TimePointView: UIView {
12+
13+ // MARK: - Properties
14+
15+ @IBOutlet weak var timePoint: UIView! {
16+ didSet {
17+ timePoint.layer.cornerRadius = 2
18+ }
19+ }
20+
21+ @IBOutlet weak var heightTimePoint: NSLayoutConstraint!
22+
23+ @IBOutlet weak var timePointContainer: UIView! {
24+ didSet {
25+ timePointContainer.layer.masksToBounds = false
26+ timePointContainer.layer.shadowOffset = CGSize(width: 0, height: -3)
27+ timePointContainer.layer.shadowRadius = 1
28+ }
29+ }
30+
31+ @IBOutlet weak var timeLabel: UILabel!
32+
33+ // MARK: - Set up
34+
35+ func setUp(withTimePoint time: Int) {
36+ if time % 6 != 0 {
37+ timeLabel.isHidden = true
38+ heightTimePoint.constant = 24
39+ } else {
40+ timeLabel.isHidden = false
41+ timeLabel.text = TimePointView.getTextTimeFromTimePoint(time)
42+ }
43+ }
44+
45+ // MARK: - Static
46+
47+ static func getTextTimeFromTimePoint(_ time: Int) -> String {
48+ return "\((Int(time / 6) + 12) % 24):00"
49+ }
50+}
Hookah Tau/Controllers/Client/Reservations/Steps/First/TimePointView.xibnew file+83
@@ -0,0 +1,83 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
3+ <device id="retina4_7" orientation="portrait" appearance="light"/>
4+ <dependencies>
5+ <deployment identifier="iOS"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
7+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
9+ </dependencies>
10+ <objects>
11+ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
12+ <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
13+ <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="TimePointView" customModule="Hookah_Tau" customModuleProvider="target">
14+ <rect key="frame" x="0.0" y="0.0" width="11" height="92"/>
15+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16+ <subviews>
17+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pWD-hx-gp6">
18+ <rect key="frame" x="0.0" y="21" width="11" height="71"/>
19+ <subviews>
20+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="yHi-OK-OdD">
21+ <rect key="frame" x="0.0" y="0.0" width="11" height="1"/>
22+ <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
23+ <constraints>
24+ <constraint firstAttribute="height" constant="1" id="vFV-YQ-dLG"/>
25+ </constraints>
26+ </view>
27+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D96-RH-9hA">
28+ <rect key="frame" x="4" y="13" width="3" height="45"/>
29+ <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
30+ <constraints>
31+ <constraint firstAttribute="width" constant="3" id="2jk-1V-VpK"/>
32+ <constraint firstAttribute="height" constant="45" id="TFz-jM-jzh"/>
33+ </constraints>
34+ </view>
35+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xmA-Sn-VW1">
36+ <rect key="frame" x="0.0" y="70" width="11" height="1"/>
37+ <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
38+ <constraints>
39+ <constraint firstAttribute="height" constant="1" id="opb-0M-WVx"/>
40+ </constraints>
41+ </view>
42+ </subviews>
43+ <color key="backgroundColor" red="0.8901960784313725" green="0.8901960784313725" blue="0.8901960784313725" alpha="0.14999999999999999" colorSpace="custom" customColorSpace="calibratedRGB"/>
44+ <constraints>
45+ <constraint firstAttribute="height" constant="71" id="1YF-9X-fzU"/>
46+ <constraint firstItem="yHi-OK-OdD" firstAttribute="leading" secondItem="pWD-hx-gp6" secondAttribute="leading" id="B0T-9H-BtD"/>
47+ <constraint firstItem="yHi-OK-OdD" firstAttribute="top" secondItem="pWD-hx-gp6" secondAttribute="top" id="RNc-ds-Sgr"/>
48+ <constraint firstAttribute="trailing" secondItem="xmA-Sn-VW1" secondAttribute="trailing" id="UwV-GZ-ZJm"/>
49+ <constraint firstAttribute="bottom" secondItem="xmA-Sn-VW1" secondAttribute="bottom" id="jsu-wi-tiv"/>
50+ <constraint firstAttribute="trailing" secondItem="yHi-OK-OdD" secondAttribute="trailing" id="rV7-YM-CIi"/>
51+ <constraint firstItem="xmA-Sn-VW1" firstAttribute="leading" secondItem="pWD-hx-gp6" secondAttribute="leading" id="s0c-se-0fn"/>
52+ <constraint firstItem="D96-RH-9hA" firstAttribute="centerX" secondItem="pWD-hx-gp6" secondAttribute="centerX" id="udJ-PM-6Yh"/>
53+ <constraint firstItem="D96-RH-9hA" firstAttribute="centerY" secondItem="pWD-hx-gp6" secondAttribute="centerY" id="wez-7K-Bt1"/>
54+ <constraint firstAttribute="width" constant="11" id="y4G-wZ-gfe"/>
55+ </constraints>
56+ </view>
57+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="18:00" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iIa-WK-OHd">
58+ <rect key="frame" x="-12" y="0.0" width="35" height="16"/>
59+ <fontDescription key="fontDescription" type="system" pointSize="13"/>
60+ <nil key="textColor"/>
61+ <nil key="highlightedColor"/>
62+ </label>
63+ </subviews>
64+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
65+ <constraints>
66+ <constraint firstItem="pWD-hx-gp6" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="A6p-9g-tQu"/>
67+ <constraint firstItem="iIa-WK-OHd" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="Hss-kd-RUN"/>
68+ <constraint firstItem="pWD-hx-gp6" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="KBo-cb-dAz"/>
69+ <constraint firstItem="pWD-hx-gp6" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="NHW-lH-rza"/>
70+ <constraint firstItem="iIa-WK-OHd" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="Pfd-58-VXn"/>
71+ </constraints>
72+ <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
73+ <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
74+ <connections>
75+ <outlet property="heightTimePoint" destination="TFz-jM-jzh" id="INI-mq-Xd4"/>
76+ <outlet property="timeLabel" destination="iIa-WK-OHd" id="jze-go-adl"/>
77+ <outlet property="timePoint" destination="D96-RH-9hA" id="Oby-Tn-zvq"/>
78+ <outlet property="timePointContainer" destination="pWD-hx-gp6" id="ir6-Na-9Ve"/>
79+ </connections>
80+ <point key="canvasLocation" x="130.40000000000001" y="440.7796101949026"/>
81+ </view>
82+ </objects>
83+</document>
Hookah Tau/Controllers/Client/Tab bar/ClientTabbarCoordinator.swift+4
@@ -41,6 +41,10 @@ class ClientTabbarCoordinator: BaseCoordinator {
4141 return { navigationController in
4242 if navigationController.viewControllers.isEmpty {
4343 let profileCoordinator = ProfileCoordinator(navigationController: navigationController)
44+ profileCoordinator.didEndFlow = { [weak self, weak profileCoordinator] in
45+ self?.removeDependency(profileCoordinator)
46+ self?.didEndFlow?()
47+ }
4448 self.addDependency(profileCoordinator)
4549 profileCoordinator.start()
4650 }
Hookah Tau/Extensions+Date.swiftnew file+76
@@ -0,0 +1,76 @@
1+//
2+// Extensions+Date.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 16/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import Foundation
10+
11+struct IntervalDate {
12+ var day: Int
13+ var month: Int
14+ var year: Int
15+
16+ var minutes: Int? = nil
17+}
18+
19+extension IntervalDate {
20+ func getFullString() -> String {
21+ var result = getDateString()
22+ if let min = minutes {
23+ result += "T\(min * 10 / 60 + 12):\(min * 10 % 60):00Z"
24+ }
25+ return result
26+ }
27+
28+ func getDateString() -> String {
29+ return "\(year)-\(month)-\(day)"
30+ }
31+}
32+
33+extension DateFormatter {
34+ static let iso8601Full: DateFormatter = {
35+ let formatter = DateFormatter()
36+ formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
37+ formatter.timeZone = TimeZone(abbreviation: "UTC")
38+ return formatter
39+ }()
40+}
41+
42+
43+extension Date {
44+ static func getNext(days: Int) -> [IntervalDate] {
45+ var result = [IntervalDate]()
46+
47+ var date = Date()
48+ let calendar = Calendar.current
49+
50+ for _ in 1...days {
51+ let appendingResult = IntervalDate(day: calendar.component(.day, from: date),
52+ month: calendar.component(.month, from: date),
53+ year: calendar.component(.year, from: date))
54+ result.append(appendingResult)
55+
56+ let newDate = calendar.date(byAdding: .day, value: 1, to: date)
57+ guard let nextDate = newDate else { break }
58+ date = nextDate
59+ }
60+
61+ return result
62+ }
63+
64+ static func getDateFromCurrent(days: Int = 0, period: Int? = nil) -> IntervalDate? {
65+ let date = Date()
66+ let calendar = Calendar.current
67+
68+ let newDate = calendar.date(byAdding: .day, value: days, to: date)
69+ guard let nextDate = newDate else { return nil }
70+
71+ return IntervalDate(day: calendar.component(.day, from: nextDate),
72+ month: calendar.component(.month, from: nextDate),
73+ year: calendar.component(.year, from: nextDate),
74+ minutes: period)
75+ }
76+}
Hookah Tau/Extensions+UIView.swift+16
@@ -59,6 +59,22 @@ extension UIView {
5959 setNeedsLayout()
6060 layoutIfNeeded()
6161 }
62+
63+ func centerSubview(_ view: UIView?) {
64+ guard let view = view else {
65+ assert(false, "View mustn't be nil")
66+ return
67+ }
68+
69+ view.translatesAutoresizingMaskIntoConstraints = false
70+ addSubview(view)
71+
72+ view.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
73+ view.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
74+
75+ setNeedsLayout()
76+ layoutIfNeeded()
77+ }
6278}
6379
6480
Hookah Tau/Extenstions+IBDesignable.swiftnew file+25
@@ -0,0 +1,25 @@
1+//
2+// Extenstions+IBDesignable.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 16/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+@IBDesignable class RadialGradientView: UIView {
12+
13+ @IBInspectable var outsideColor: UIColor = UIColor.red
14+ @IBInspectable var insideColor: UIColor = UIColor.clear.withAlphaComponent(0)
15+
16+ override func draw(_ rect: CGRect) {
17+ let colors = [insideColor.cgColor, outsideColor.cgColor] as CFArray
18+ let endRadius = sqrt(pow(frame.width/2, 2) + pow(frame.height/2, 2))
19+ let center = CGPoint(x: bounds.size.width / 2, y: bounds.size.height / 2)
20+ let gradient = CGGradient(colorsSpace: nil, colors: colors, locations: nil)
21+ let context = UIGraphicsGetCurrentContext()
22+
23+ context?.drawRadialGradient(gradient!, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: endRadius, options: CGGradientDrawingOptions.drawsBeforeStartLocation)
24+ }
25+}
Hookah Tau/Models/AllReservations.swiftnew file+19
@@ -0,0 +1,19 @@
1+//
2+// AllReservations.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 15/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import Foundation
10+
11+struct AllReservations: MyCodable {
12+ var reservations: [Int: [Date: [ReservationPeriod]]]
13+ var intervals: [String: [Date: [Int]]]
14+}
15+
16+struct ReservationPeriod: MyCodable {
17+ var startTime: String
18+ var duration: Int
19+}
Hookah Tau/Models/Reservation.swiftnew file+21
@@ -0,0 +1,21 @@
1+//
2+// Reservation.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 06/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import Foundation
10+
11+
12+struct Reservation: MyCodable {
13+
14+ var uuid: UUID
15+ var establishment: Int
16+ var startTime: String
17+ var endTime: String
18+ var numberOfGuests: Int
19+ var reservedTable: Int
20+
21+}
Hookah Tau/Supporting Files/Assets.xcassets/TriangleDown.imageset/Contents.jsonnew file+12
@@ -0,0 +1,12 @@
1+{
2+ "images" : [
3+ {
4+ "idiom" : "universal",
5+ "filename" : "Triangle.pdf"
6+ }
7+ ],
8+ "info" : {
9+ "version" : 1,
10+ "author" : "xcode"
11+ }
12+}
Hookah Tau/Supporting Files/Assets.xcassets/TriangleDown.imageset/Triangle.pdfnew file

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/TriangleUp.imageset/Contents.jsonnew file+12
@@ -0,0 +1,12 @@
1+{
2+ "images" : [
3+ {
4+ "idiom" : "universal",
5+ "filename" : "TriangleUp.pdf"
6+ }
7+ ],
8+ "info" : {
9+ "version" : 1,
10+ "author" : "xcode"
11+ }
12+}
Hookah Tau/Supporting Files/Assets.xcassets/TriangleUp.imageset/TriangleUp.pdfnew file

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/map_1.imageset/Contents.jsonnew file+12
@@ -0,0 +1,12 @@
1+{
2+ "images" : [
3+ {
4+ "idiom" : "universal",
5+ "filename" : "map_1.pdf"
6+ }
7+ ],
8+ "info" : {
9+ "version" : 1,
10+ "author" : "xcode"
11+ }
12+}
Hookah Tau/Supporting Files/Assets.xcassets/map_1.imageset/map_1.pdfnew file

Binary file not shown.