git.iko.soy/dashared/hookah-tau
on develop help sign in
Hookah Tau.xcodeproj/project.pbxproj+70−2
since splitsnapshots
unifiedsplit
@@ -17,6 +17,9 @@
17 12118B9E23682049006BAEE3 /* PhoneCodeResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12118B9D23682049006BAEE3 /* PhoneCodeResolver.swift */; };
17 12118B9E23682049006BAEE3 /* PhoneCodeResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12118B9D23682049006BAEE3 /* PhoneCodeResolver.swift */; };
18 1212048C23914CFD00CAF162 /* DeleteReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1212048B23914CFD00CAF162 /* DeleteReservationResolver.swift */; };
18 1212048C23914CFD00CAF162 /* DeleteReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1212048B23914CFD00CAF162 /* DeleteReservationResolver.swift */; };
19 1212048E23915A0A00CAF162 /* ChangeReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1212048D23915A0A00CAF162 /* ChangeReservationResolver.swift */; };
19 1212048E23915A0A00CAF162 /* ChangeReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1212048D23915A0A00CAF162 /* ChangeReservationResolver.swift */; };
20+ 1220A6F423CDB1AD00365E36 /* GetClientByPhoneNumberResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1220A6F323CDB1AD00365E36 /* GetClientByPhoneNumberResolver.swift */; };
21+ 1220A6F723CDB64A00365E36 /* AdminSecondStepReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1220A6F623CDB64A00365E36 /* AdminSecondStepReservationViewController.swift */; };
22+ 1220A6FA23CDBE7E00365E36 /* AdminFinalStepReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1220A6F923CDBE7E00365E36 /* AdminFinalStepReservationCoordinator.swift */; };
20 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12219CEE2353A63E0057DDEE /* ReservationsCoordinator.swift */; };
23 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12219CEE2353A63E0057DDEE /* ReservationsCoordinator.swift */; };
21 12230AEA238FD8B3004A01E5 /* MapView2.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12230AE9238FD8B3004A01E5 /* MapView2.xib */; };
24 12230AEA238FD8B3004A01E5 /* MapView2.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12230AE9238FD8B3004A01E5 /* MapView2.xib */; };
22 12230AEC238FD8C5004A01E5 /* MapView2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12230AEB238FD8C5004A01E5 /* MapView2.swift */; };
25 12230AEC238FD8C5004A01E5 /* MapView2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12230AEB238FD8C5004A01E5 /* MapView2.swift */; };
@@ -40,6 +43,7 @@
40 124D007C23721FD400AE76B9 /* Reservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007B23721FD400AE76B9 /* Reservation.swift */; };
43 124D007C23721FD400AE76B9 /* Reservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007B23721FD400AE76B9 /* Reservation.swift */; };
41 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007E237222B200AE76B9 /* ReservationsResolver.swift */; };
44 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007E237222B200AE76B9 /* ReservationsResolver.swift */; };
42 124D0081237222C900AE76B9 /* ReservationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D0080237222C900AE76B9 /* ReservationsService.swift */; };
45 124D0081237222C900AE76B9 /* ReservationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D0080237222C900AE76B9 /* ReservationsService.swift */; };
46+ 1252D9E523CDCDB300446B6F /* ACreateReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1252D9E423CDCDB300446B6F /* ACreateReservationResolver.swift */; };
43 125AE51D2395583E00F847BD /* ChangeReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */; };
47 125AE51D2395583E00F847BD /* ChangeReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */; };
44 125AE51F2395585300F847BD /* ChangeReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */; };
48 125AE51F2395585300F847BD /* ChangeReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */; };
45 125AE5212395753400F847BD /* HFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE5202395753400F847BD /* HFunc.swift */; };
49 125AE5212395753400F847BD /* HFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE5202395753400F847BD /* HFunc.swift */; };
@@ -51,6 +55,9 @@
51 12838EB4236779C700CEF108 /* ApiResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB3236779C700CEF108 /* ApiResolver.swift */; };
55 12838EB4236779C700CEF108 /* ApiResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB3236779C700CEF108 /* ApiResolver.swift */; };
52 12838EB623677FB900CEF108 /* ApiRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB523677FB900CEF108 /* ApiRequest.swift */; };
56 12838EB623677FB900CEF108 /* ApiRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB523677FB900CEF108 /* ApiRequest.swift */; };
53 12838EB82367834900CEF108 /* MyCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB72367834900CEF108 /* MyCodable.swift */; };
57 12838EB82367834900CEF108 /* MyCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB72367834900CEF108 /* MyCodable.swift */; };
58+ 129F162723CC838200EE13FC /* AdminFirstStepReservationViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129F162623CC838200EE13FC /* AdminFirstStepReservationViewCoordinator.swift */; };
59+ 129F162C23CC8D2E00EE13FC /* AdminSecondStepReservationViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129F162B23CC8D2E00EE13FC /* AdminSecondStepReservationViewCoordinator.swift */; };
60+ 129F163023CC8EF600EE13FC /* PhoneTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129F162F23CC8EF600EE13FC /* PhoneTextField.swift */; };
54 12A075F72373535C00D749BB /* FirstStepReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A075F62373535C00D749BB /* FirstStepReservationViewController.swift */; };
61 12A075F72373535C00D749BB /* FirstStepReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A075F62373535C00D749BB /* FirstStepReservationViewController.swift */; };
55 12A075F9237353F500D749BB /* MapView1.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12A075F8237353F500D749BB /* MapView1.xib */; };
62 12A075F9237353F500D749BB /* MapView1.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12A075F8237353F500D749BB /* MapView1.xib */; };
56 12A075FB2373561A00D749BB /* Reservation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12A075FA2373561A00D749BB /* Reservation.storyboard */; };
63 12A075FB2373561A00D749BB /* Reservation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12A075FA2373561A00D749BB /* Reservation.storyboard */; };
@@ -175,6 +182,9 @@
175 12118B9D23682049006BAEE3 /* PhoneCodeResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneCodeResolver.swift; sourceTree = "<group>"; };
182 12118B9D23682049006BAEE3 /* PhoneCodeResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneCodeResolver.swift; sourceTree = "<group>"; };
176 1212048B23914CFD00CAF162 /* DeleteReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteReservationResolver.swift; sourceTree = "<group>"; };
183 1212048B23914CFD00CAF162 /* DeleteReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteReservationResolver.swift; sourceTree = "<group>"; };
177 1212048D23915A0A00CAF162 /* ChangeReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationResolver.swift; sourceTree = "<group>"; };
184 1212048D23915A0A00CAF162 /* ChangeReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationResolver.swift; sourceTree = "<group>"; };
185+ 1220A6F323CDB1AD00365E36 /* GetClientByPhoneNumberResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetClientByPhoneNumberResolver.swift; sourceTree = "<group>"; };
186+ 1220A6F623CDB64A00365E36 /* AdminSecondStepReservationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdminSecondStepReservationViewController.swift; sourceTree = "<group>"; };
187+ 1220A6F923CDBE7E00365E36 /* AdminFinalStepReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminFinalStepReservationCoordinator.swift; sourceTree = "<group>"; };
178 12219CEE2353A63E0057DDEE /* ReservationsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReservationsCoordinator.swift; sourceTree = "<group>"; };
188 12219CEE2353A63E0057DDEE /* ReservationsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReservationsCoordinator.swift; sourceTree = "<group>"; };
179 12230AE9238FD8B3004A01E5 /* MapView2.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapView2.xib; sourceTree = "<group>"; };
189 12230AE9238FD8B3004A01E5 /* MapView2.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapView2.xib; sourceTree = "<group>"; };
180 12230AEB238FD8C5004A01E5 /* MapView2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView2.swift; sourceTree = "<group>"; };
190 12230AEB238FD8C5004A01E5 /* MapView2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView2.swift; sourceTree = "<group>"; };
@@ -198,6 +208,7 @@
198 124D007B23721FD400AE76B9 /* Reservation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reservation.swift; sourceTree = "<group>"; };
208 124D007B23721FD400AE76B9 /* Reservation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reservation.swift; sourceTree = "<group>"; };
199 124D007E237222B200AE76B9 /* ReservationsResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsResolver.swift; sourceTree = "<group>"; };
209 124D007E237222B200AE76B9 /* ReservationsResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsResolver.swift; sourceTree = "<group>"; };
200 124D0080237222C900AE76B9 /* ReservationsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsService.swift; sourceTree = "<group>"; };
210 124D0080237222C900AE76B9 /* ReservationsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsService.swift; sourceTree = "<group>"; };
211+ 1252D9E423CDCDB300446B6F /* ACreateReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACreateReservationResolver.swift; sourceTree = "<group>"; };
201 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationCoordinator.swift; sourceTree = "<group>"; };
212 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationCoordinator.swift; sourceTree = "<group>"; };
202 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationViewController.swift; sourceTree = "<group>"; };
213 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationViewController.swift; sourceTree = "<group>"; };
203 125AE5202395753400F847BD /* HFunc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HFunc.swift; sourceTree = "<group>"; };
214 125AE5202395753400F847BD /* HFunc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HFunc.swift; sourceTree = "<group>"; };
@@ -208,6 +219,9 @@
208 12838EB3236779C700CEF108 /* ApiResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiResolver.swift; sourceTree = "<group>"; };
219 12838EB3236779C700CEF108 /* ApiResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiResolver.swift; sourceTree = "<group>"; };
209 12838EB523677FB900CEF108 /* ApiRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiRequest.swift; sourceTree = "<group>"; };
220 12838EB523677FB900CEF108 /* ApiRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiRequest.swift; sourceTree = "<group>"; };
210 12838EB72367834900CEF108 /* MyCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCodable.swift; sourceTree = "<group>"; };
221 12838EB72367834900CEF108 /* MyCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCodable.swift; sourceTree = "<group>"; };
222+ 129F162623CC838200EE13FC /* AdminFirstStepReservationViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminFirstStepReservationViewCoordinator.swift; sourceTree = "<group>"; };
223+ 129F162B23CC8D2E00EE13FC /* AdminSecondStepReservationViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminSecondStepReservationViewCoordinator.swift; sourceTree = "<group>"; };
224+ 129F162F23CC8EF600EE13FC /* PhoneTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneTextField.swift; sourceTree = "<group>"; };
211 12A075F62373535C00D749BB /* FirstStepReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstStepReservationViewController.swift; sourceTree = "<group>"; };
225 12A075F62373535C00D749BB /* FirstStepReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstStepReservationViewController.swift; sourceTree = "<group>"; };
212 12A075F8237353F500D749BB /* MapView1.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapView1.xib; sourceTree = "<group>"; };
226 12A075F8237353F500D749BB /* MapView1.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapView1.xib; sourceTree = "<group>"; };
213 12A075FA2373561A00D749BB /* Reservation.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Reservation.storyboard; sourceTree = "<group>"; };
227 12A075FA2373561A00D749BB /* Reservation.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Reservation.storyboard; sourceTree = "<group>"; };
@@ -392,6 +406,31 @@
392 path = Reservations;
406 path = Reservations;
393 sourceTree = "<group>";
407 sourceTree = "<group>";
394 };
408 };
409+ 1220A6F523CDB63000365E36 /* 2 */ = {
410+ isa = PBXGroup;
411+ children = (
412+ 1220A6F623CDB64A00365E36 /* AdminSecondStepReservationViewController.swift */,
413+ 129F162B23CC8D2E00EE13FC /* AdminSecondStepReservationViewCoordinator.swift */,
414+ );
415+ path = 2;
416+ sourceTree = "<group>";
417+ };
418+ 1220A6F823CDB65C00365E36 /* 1 */ = {
419+ isa = PBXGroup;
420+ children = (
421+ 129F162623CC838200EE13FC /* AdminFirstStepReservationViewCoordinator.swift */,
422+ );
423+ path = 1;
424+ sourceTree = "<group>";
425+ };
426+ 1220A6FB23CDBED900365E36 /* 3 */ = {
427+ isa = PBXGroup;
428+ children = (
429+ 1220A6F923CDBE7E00365E36 /* AdminFinalStepReservationCoordinator.swift */,
430+ );
431+ path = 3;
432+ sourceTree = "<group>";
433+ };
395 12230AED238FD8D5004A01E5 /* 1 */ = {
434 12230AED238FD8D5004A01E5 /* 1 */ = {
396 isa = PBXGroup;
435 isa = PBXGroup;
397 children = (
436 children = (
@@ -468,6 +507,7 @@
468 123D25ED239E3D50002FA32B /* Reservations */ = {
507 123D25ED239E3D50002FA32B /* Reservations */ = {
469 isa = PBXGroup;
508 isa = PBXGroup;
470 children = (
509 children = (
510+ 129F162523CC836600EE13FC /* Making a reeservation */,
471 12B3A79623ABAD9A009E2FA6 /* Views */,
511 12B3A79623ABAD9A009E2FA6 /* Views */,
472 12B3A7C123AD0751009E2FA6 /* Editing */,
512 12B3A7C123AD0751009E2FA6 /* Editing */,
473 12B3A7C223AD0762009E2FA6 /* List of reservations */,
513 12B3A7C223AD0762009E2FA6 /* List of reservations */,
@@ -562,9 +602,27 @@
562 path = API;
602 path = API;
563 sourceTree = "<group>";
603 sourceTree = "<group>";
564 };
604 };
605+ 129F162523CC836600EE13FC /* Making a reeservation */ = {
606+ isa = PBXGroup;
607+ children = (
608+ 1220A6F823CDB65C00365E36 /* 1 */,
609+ 1220A6F523CDB63000365E36 /* 2 */,
610+ 1220A6FB23CDBED900365E36 /* 3 */,
611+ );
612+ path = "Making a reeservation";
613+ sourceTree = "<group>";
614+ };
615+ 129F162823CC89EA00EE13FC /* Phone number */ = {
616+ isa = PBXGroup;
617+ children = (
618+ );
619+ path = "Phone number";
620+ sourceTree = "<group>";
621+ };
565 12B3A79623ABAD9A009E2FA6 /* Views */ = {
622 12B3A79623ABAD9A009E2FA6 /* Views */ = {
566 isa = PBXGroup;
623 isa = PBXGroup;
567 children = (
624 children = (
625+ 129F162823CC89EA00EE13FC /* Phone number */,
568 12B3A7B223AC1A1F009E2FA6 /* No reserv */,
626 12B3A7B223AC1A1F009E2FA6 /* No reserv */,
569 12B3A79723ABADB9009E2FA6 /* AdminReservationView.xib */,
627 12B3A79723ABADB9009E2FA6 /* AdminReservationView.xib */,
570 12B3A79E23ABCA21009E2FA6 /* AdminReservationView.swift */,
628 12B3A79E23ABCA21009E2FA6 /* AdminReservationView.swift */,
@@ -596,6 +654,7 @@
596 12B3A7AC23ABEABF009E2FA6 /* AReservationsResolver.swift */,
654 12B3A7AC23ABEABF009E2FA6 /* AReservationsResolver.swift */,
597 12B3A7C323AD2FCD009E2FA6 /* AChangeReservationResolver.swift */,
655 12B3A7C323AD2FCD009E2FA6 /* AChangeReservationResolver.swift */,
598 12D928AE23C47DCF0051724D /* ADeleteReservationResolver.swift */,
656 12D928AE23C47DCF0051724D /* ADeleteReservationResolver.swift */,
657+ 1252D9E423CDCDB300446B6F /* ACreateReservationResolver.swift */,
599 );
658 );
600 path = Admin;
659 path = Admin;
601 sourceTree = "<group>";
660 sourceTree = "<group>";
@@ -698,6 +757,7 @@
698 12E35077239FAFA4004BB188 /* ClientsListResolver.swift */,
757 12E35077239FAFA4004BB188 /* ClientsListResolver.swift */,
699 12E3507C239FD1F3004BB188 /* ClientReservationsResolver.swift */,
758 12E3507C239FD1F3004BB188 /* ClientReservationsResolver.swift */,
700 12D928B223C7464B0051724D /* BlocklistPutResolver.swift */,
759 12D928B223C7464B0051724D /* BlocklistPutResolver.swift */,
760+ 1220A6F323CDB1AD00365E36 /* GetClientByPhoneNumberResolver.swift */,
701 );
761 );
702 path = Resolvers;
762 path = Resolvers;
703 sourceTree = "<group>";
763 sourceTree = "<group>";
@@ -812,6 +872,7 @@
812 F3DC5A04233E89D500B5E751 /* Button.swift */,
872 F3DC5A04233E89D500B5E751 /* Button.swift */,
813 12FC40372382C93C00AB593B /* TableButtonStyle.swift */,
873 12FC40372382C93C00AB593B /* TableButtonStyle.swift */,
814 12FC40392382CB6F00AB593B /* TableButton.swift */,
874 12FC40392382CB6F00AB593B /* TableButton.swift */,
875+ 129F162F23CC8EF600EE13FC /* PhoneTextField.swift */,
815 );
876 );
816 path = Components;
877 path = Components;
817 sourceTree = "<group>";
878 sourceTree = "<group>";
@@ -1136,6 +1197,8 @@
1136 files = (
1197 files = (
1137 12EA99482362B684005D9FE9 /* AddresViewController.swift in Sources */,
1198 12EA99482362B684005D9FE9 /* AddresViewController.swift in Sources */,
1138 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */,
1199 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */,
1200+ 129F163023CC8EF600EE13FC /* PhoneTextField.swift in Sources */,
1201+ 129F162C23CC8D2E00EE13FC /* AdminSecondStepReservationViewCoordinator.swift in Sources */,
1139 12230AF723900D44004A01E5 /* EstablishmentResolver.swift in Sources */,
1202 12230AF723900D44004A01E5 /* EstablishmentResolver.swift in Sources */,
1140 1246B719235CD3AD004CBFA1 /* NoReservationsView.swift in Sources */,
1203 1246B719235CD3AD004CBFA1 /* NoReservationsView.swift in Sources */,
1141 F3895F4A233D323700FA6A37 /* CodeCoordinator.swift in Sources */,
1204 F3895F4A233D323700FA6A37 /* CodeCoordinator.swift in Sources */,
@@ -1170,6 +1233,7 @@
1170 F3895F48233D2EEA00FA6A37 /* CodeSmsViewController.swift in Sources */,
1233 F3895F48233D2EEA00FA6A37 /* CodeSmsViewController.swift in Sources */,
1171 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */,
1234 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */,
1172 12230AF423900BCB004A01E5 /* EstablishmentService.swift in Sources */,
1235 12230AF423900BCB004A01E5 /* EstablishmentService.swift in Sources */,
1236+ 129F162723CC838200EE13FC /* AdminFirstStepReservationViewCoordinator.swift in Sources */,
1173 12A07601237359BB00D749BB /* MapView1.swift in Sources */,
1237 12A07601237359BB00D749BB /* MapView1.swift in Sources */,
1174 125AE5212395753400F847BD /* HFunc.swift in Sources */,
1238 125AE5212395753400F847BD /* HFunc.swift in Sources */,
1175 12BD95B8237EDB01009614D8 /* TimePointView.swift in Sources */,
1239 12BD95B8237EDB01009614D8 /* TimePointView.swift in Sources */,
@@ -1195,9 +1259,11 @@
1195 12B3A7A323ABD594009E2FA6 /* AdminReservationsController.swift in Sources */,
1259 12B3A7A323ABD594009E2FA6 /* AdminReservationsController.swift in Sources */,
1196 F3FC7DCD2315BE610080D851 /* AppDelegate.swift in Sources */,
1260 F3FC7DCD2315BE610080D851 /* AppDelegate.swift in Sources */,
1197 12838EB623677FB900CEF108 /* ApiRequest.swift in Sources */,
1261 12838EB623677FB900CEF108 /* ApiRequest.swift in Sources */,
1262+ 1220A6FA23CDBE7E00365E36 /* AdminFinalStepReservationCoordinator.swift in Sources */,
1198 12118B9E23682049006BAEE3 /* PhoneCodeResolver.swift in Sources */,
1263 12118B9E23682049006BAEE3 /* PhoneCodeResolver.swift in Sources */,
1199 F30369BE2336924D00A8EA84 /* ClientTabbarCoordinator.swift in Sources */,
1264 F30369BE2336924D00A8EA84 /* ClientTabbarCoordinator.swift in Sources */,
1200 F3FC7DFD2315C4710080D851 /* BaseCoordinator.swift in Sources */,
1265 F3FC7DFD2315C4710080D851 /* BaseCoordinator.swift in Sources */,
1266+ 1220A6F723CDB64A00365E36 /* AdminSecondStepReservationViewController.swift in Sources */,
1201 12E35071239FA8CA004BB188 /* Extensions+String.swift in Sources */,
1267 12E35071239FA8CA004BB188 /* Extensions+String.swift in Sources */,
1202 12FC07B923C8D17600EDC55B /* DeleteOtherAdminResolver.swift in Sources */,
1268 12FC07B923C8D17600EDC55B /* DeleteOtherAdminResolver.swift in Sources */,
1203 F3DC59FF233E893400B5E751 /* Extensions+UIFont.swift in Sources */,
1269 F3DC59FF233E893400B5E751 /* Extensions+UIFont.swift in Sources */,
@@ -1216,9 +1282,11 @@
1216 12C72EDF23537D1B00AD7004 /* ProfileCoordinator.swift in Sources */,
1282 12C72EDF23537D1B00AD7004 /* ProfileCoordinator.swift in Sources */,
1217 12E3507D239FD1F3004BB188 /* ClientReservationsResolver.swift in Sources */,
1283 12E3507D239FD1F3004BB188 /* ClientReservationsResolver.swift in Sources */,
1218 12EA994E2362FCE8005D9FE9 /* AddressView.swift in Sources */,
1284 12EA994E2362FCE8005D9FE9 /* AddressView.swift in Sources */,
1285+ 1220A6F423CDB1AD00365E36 /* GetClientByPhoneNumberResolver.swift in Sources */,
1219 F3895F4C233D347E00FA6A37 /* PhoneNumberViewController.swift in Sources */,
1286 F3895F4C233D347E00FA6A37 /* PhoneNumberViewController.swift in Sources */,
1220 12EE4A76234BB8FE005B4D1A /* CodeView.swift in Sources */,
1287 12EE4A76234BB8FE005B4D1A /* CodeView.swift in Sources */,
1221 12230AF123900974004A01E5 /* TotalStorage.swift in Sources */,
1288 12230AF123900974004A01E5 /* TotalStorage.swift in Sources */,
1289+ 1252D9E523CDCDB300446B6F /* ACreateReservationResolver.swift in Sources */,
1222 12BD95B2237EC22B009614D8 /* FirstStepView.swift in Sources */,
1290 12BD95B2237EC22B009614D8 /* FirstStepView.swift in Sources */,
1223 F3EBE2472340FE87000FEE1A /* NameTextView.swift in Sources */,
1291 F3EBE2472340FE87000FEE1A /* NameTextView.swift in Sources */,
1224 120BFC7723891925001EBE89 /* ThirdStepReservationViewController.swift in Sources */,
1292 120BFC7723891925001EBE89 /* ThirdStepReservationViewController.swift in Sources */,
@@ -1398,7 +1466,7 @@
1398 buildSettings = {
1466 buildSettings = {
1399 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1467 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1400 CODE_SIGN_STYLE = Automatic;
1468 CODE_SIGN_STYLE = Automatic;
1401− CURRENT_PROJECT_VERSION = 4;
1469+ CURRENT_PROJECT_VERSION = 5;
1402 DEVELOPMENT_TEAM = 23S94LRHD8;
1470 DEVELOPMENT_TEAM = 23S94LRHD8;
1403 INFOPLIST_FILE = "Hookah Tau/Info.plist";
1471 INFOPLIST_FILE = "Hookah Tau/Info.plist";
1404 IPHONEOS_DEPLOYMENT_TARGET = 11.0;
1472 IPHONEOS_DEPLOYMENT_TARGET = 11.0;
@@ -1418,7 +1486,7 @@
1418 buildSettings = {
1486 buildSettings = {
1419 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1487 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1420 CODE_SIGN_STYLE = Automatic;
1488 CODE_SIGN_STYLE = Automatic;
1421− CURRENT_PROJECT_VERSION = 4;
1489+ CURRENT_PROJECT_VERSION = 5;
1422 DEVELOPMENT_TEAM = 23S94LRHD8;
1490 DEVELOPMENT_TEAM = 23S94LRHD8;
1423 INFOPLIST_FILE = "Hookah Tau/Info.plist";
1491 INFOPLIST_FILE = "Hookah Tau/Info.plist";
1424 IPHONEOS_DEPLOYMENT_TARGET = 11.0;
1492 IPHONEOS_DEPLOYMENT_TARGET = 11.0;
Hookah Tau/API/APIClient.swift+2
@@ -48,6 +48,8 @@ class APIClient {
48 let json = String(data: data, encoding: String.Encoding.utf8)
48 let json = String(data: data, encoding: String.Encoding.utf8)
49 print("Failure Response: \(String(describing: json))")
49 print("Failure Response: \(String(describing: json))")
50 }
50 }
51+ case 404:
52+ return GeneralError.notFound
51 case 422:
53 case 422:
52 if let data = response.data, let error = SE.fromJSONToSelf(data: data) {
54 if let data = response.data, let error = SE.fromJSONToSelf(data: data) {
53 print(error)
55 print(error)
Hookah Tau/API/ClientsService/ClientsService.swift+23
@@ -103,4 +103,27 @@ class ClientsService {
103 }
103 }
104 }
104 }
105 }
105 }
106+
107+ func getClientByPhoneNumber(userPhone: String, completion: @escaping ((Result<FullUser, GeneralError>) -> Void)) {
108+ let resolver = GetClientByPhoneNumberResolver<ClientInResponce>(userPhone: userPhone)
109+ let request = ApiRequest(resolver: resolver, httpMethod: .get)
110+
111+ apiClient.load(request: request.request) { (result) in
112+ switch result {
113+ case .failure(let err):
114+ completion(.failure(err))
115+ return
116+ case .success(let responce):
117+ guard
118+ let d = responce.data,
119+ let decData = resolver.targetClass().fromJSONToSelf(data: d)
120+ else {
121+ completion(.failure(GeneralError.decodeError))
122+ return
123+ }
124+
125+ completion(.success(decData.client))
126+ }
127+ }
128+ }
106}
129}
Hookah Tau/API/ClientsService/Resolvers/GetClientByPhoneNumberResolver.swiftnew file+35
@@ -0,0 +1,35 @@
1+//
2+// GetClientByPhoneNumberResolver.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 14/01/2020.
6+// Copyright © 2020 Daria Rednikina. All rights reserved.
7+//
8+
9+import Foundation
10+
11+struct ClientInResponce: MyCodable {
12+ var client: FullUser
13+}
14+
15+/// `GET /admin/clients/by-phone/{user id}`
16+class GetClientByPhoneNumberResolver<Responce: MyCodable>: ApiResolver {
17+
18+ var name: String {
19+ return "/clients/by-phone/\(userPhone)"
20+ }
21+
22+ var groupName: String? {
23+ return "/admin"
24+ }
25+
26+ var userPhone: String
27+
28+ init(userPhone: String) {
29+ self.userPhone = userPhone
30+ }
31+
32+ func targetClass() -> Responce.Type {
33+ return Responce.self
34+ }
35+}
Hookah Tau/API/Reservations api/ReservationsService.swift+23
@@ -205,4 +205,27 @@ class ReservationsService {
205 }
205 }
206 }
206 }
207 }
207 }
208+
209+ func createReservation(reservation: AdminCreateReservation, completion: @escaping ((Result<String, GeneralError>) -> Void)) {
210+ let resolver = ACreateReservationResolver<ACreateAdminResonce>(data: reservation)
211+ let request = ApiRequest(resolver: resolver, httpMethod: .post)
212+
213+ apiClient.load(request: request.request) { (res) in
214+ switch res {
215+ case .failure(let err):
216+ completion(.failure(err))
217+ return
218+ case .success(let responce):
219+ guard
220+ let d = responce.data,
221+ let decData = resolver.targetClass().fromJSONToSelf(data: d)
222+ else {
223+ completion(.failure(GeneralError.decodeError))
224+ return
225+ }
226+
227+ completion(.success(decData.reservationUUID))
228+ }
229+ }
230+ }
208}
231}
Hookah Tau/API/Reservations api/Resolvers/Admin/ACreateReservationResolver.swiftnew file+37
@@ -0,0 +1,37 @@
1+//
2+// ACreateReservationResolver.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 14/01/2020.
6+// Copyright © 2020 Daria Rednikina. All rights reserved.
7+//
8+
9+import Foundation
10+
11+struct ACreateAdminResonce: MyCodable {
12+ var reservationUUID: String
13+}
14+
15+class ACreateReservationResolver<Responce: MyCodable>: ApiResolver {
16+ var name: String {
17+ return "/reservations"
18+ }
19+
20+ var groupName: String? {
21+ return "/admin"
22+ }
23+
24+ var data: AdminCreateReservation
25+
26+ init(data: AdminCreateReservation) {
27+ self.data = data
28+ }
29+
30+ func parameters() -> MyCodable? {
31+ return data
32+ }
33+
34+ func targetClass() -> Responce.Type {
35+ return Responce.self
36+ }
37+}
Hookah Tau/API/ServerError.swift+1
@@ -16,6 +16,7 @@ enum GeneralError: Error {
16 case serverError(SE)
16 case serverError(SE)
17 case decodeError
17 case decodeError
18 case noData
18 case noData
19+ case notFound
19 case Error400
20 case Error400
20 case somethingWentCompletelyWrong
21 case somethingWentCompletelyWrong
21 case alamofireError
22 case alamofireError
Hookah Tau/Components/PhoneTextField.swiftnew file+63
@@ -0,0 +1,63 @@
1+//
2+// PhoneTextField.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 13/01/2020.
6+// Copyright © 2020 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class PhoneTextField: UITextField, UITextFieldDelegate {
12+
13+ override func awakeFromNib() {
14+ super.awakeFromNib()
15+
16+ self.delegate = self
17+ self.keyboardType = .numberPad
18+ }
19+
20+ func bind(withModel model: String) {
21+ self.text = model.formattedNumber()
22+ }
23+
24+ func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
25+ let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
26+ textField.text = formattedNumber(newString)
27+ return false
28+ }
29+
30+ private func formattedNumber(_ number: String) -> String {
31+ let cleanPhoneNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
32+
33+ var result = ""
34+ let phoneMask = "+X (XXX) XXX XX XX"
35+ var index = cleanPhoneNumber.startIndex
36+ for ch in phoneMask where index < cleanPhoneNumber.endIndex {
37+ if ch == "X" {
38+ result.append(cleanPhoneNumber[index])
39+ index = cleanPhoneNumber.index(after: index)
40+ } else {
41+ result.append(ch)
42+ }
43+ }
44+ return result
45+ }
46+
47+ /// +o (oxx) xxx xx xx
48+ ///
49+ /// need tor return only `x`, length is 9. And it has to have prefix +7 (9...) or +8 (9..)
50+ func getFormattedNumber() -> String? {
51+ guard let number = self.text else { return nil }
52+
53+ let cleanPhoneNumber = String(number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined())
54+ let hasPrefix = cleanPhoneNumber.hasPrefix("79") || cleanPhoneNumber.hasPrefix("89")
55+
56+ let result = String(cleanPhoneNumber.dropFirst(2))
57+ if result.count == 9 && hasPrefix {
58+ return result
59+ }
60+
61+ return nil
62+ }
63+}
Hookah Tau/Controllers/Admin/Clients/ClientsCoordinator.swift+1−4
@@ -23,10 +23,7 @@ class ClientsCoordinator: BaseCoordinator {
23 /// TODO
23 /// TODO
24 func openUserProfile(_ profile: Client) {
24 func openUserProfile(_ profile: Client) {
25 let profileCoordinator = ClientProfileCoordinator(navigationController: navigationController)
25 let profileCoordinator = ClientProfileCoordinator(navigationController: navigationController)
26− profileCoordinator.user = FullUser(uuid: profile.uuid,
26+ profileCoordinator.user = profile
27− name: profile.name,
28− phoneNumber: profile.phoneNumber,
29− isAdmin: profile.isAdmin)
30
27
31 self.addDependency(profileCoordinator)
28 self.addDependency(profileCoordinator)
32 profileCoordinator.didEndFlow = {
29 profileCoordinator.didEndFlow = {
Hookah Tau/Controllers/Admin/Clients/Profile/ClientProfileCoordinator.swift+12−2
@@ -11,7 +11,7 @@ import UIKit
11
11
12class ClientProfileCoordinator: BaseCoordinator {
12class ClientProfileCoordinator: BaseCoordinator {
13
13
14− var user: FullUser?
14+ var user: Client?
15
15
16 override func start() {
16 override func start() {
17 let storyboard = UIStoryboard(name: "ClientList", bundle: nil)
17 let storyboard = UIStoryboard(name: "ClientList", bundle: nil)
@@ -24,8 +24,18 @@ class ClientProfileCoordinator: BaseCoordinator {
24
24
25
25
26 // Создание бронирования из профиля клиента
26 // Создание бронирования из профиля клиента
27− func createReservation(forUserWithPhone phoneNumber: String) {
27+ func createReservation(forUserWithPhone phoneNumber: String, user fullUser: FullUser) {
28+ let coordinator = AdminFirstStepReservationViewCoordinator(navigationController: navigationController)
29+ coordinator.phone = phoneNumber
30+ coordinator.fullUser = fullUser
28
31
32+ addDependency(coordinator)
33+ coordinator.didFinish = { [weak self] in
34+ self?.removeDependency(coordinator)
35+ self?.navigationController?.popViewController(animated: true)
36+ }
37+
38+ coordinator.start()
29 }
39 }
30
40
31 // Просмотр (и редактирование) брони
41 // Просмотр (и редактирование) брони
Hookah Tau/Controllers/Admin/Clients/Profile/ProfileTableViewController.swift+21−5
@@ -41,7 +41,7 @@ class ProfileTableViewController: BaseViewController {
41
41
42 var reservationsService: ReservationsService?
42 var reservationsService: ReservationsService?
43
43
44− var user: FullUser?
44+ var user: Client?
45
45
46 weak var coodinator: ClientProfileCoordinator?
46 weak var coodinator: ClientProfileCoordinator?
47
47
@@ -79,19 +79,25 @@ class ProfileTableViewController: BaseViewController {
79 setupNavBar()
79 setupNavBar()
80 setupTable()
80 setupTable()
81 setupActivityIndicator()
81 setupActivityIndicator()
82− loadReservations()
82+ //loadReservations()
83 }
83 }
84
84
85 override func viewWillAppear(_ animated: Bool) {
85 override func viewWillAppear(_ animated: Bool) {
86− super.viewDidAppear(animated)
86+ super.viewWillAppear(animated)
87 tabBarController?.tabBar.isHidden = true
87 tabBarController?.tabBar.isHidden = true
88 }
88 }
89
89
90+ override func viewDidAppear(_ animated: Bool) {
91+ super.viewDidAppear(animated)
92+ loadReservations()
93+ }
94+
90 // MARK: - Setup
95 // MARK: - Setup
91
96
92 func setupNavBar() {
97 func setupNavBar() {
93 guard let u = user else { return }
98 guard let u = user else { return }
99+
94− navigationItem.title = u.name
100+ navigationItem.title = "\(u.name ?? "❔")\(u.isAdmin ? "👑" : "")\(u.isBlocked ? "❌" : "")"
95 navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(book))
101 navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(book))
96 }
102 }
97
103
@@ -182,7 +188,16 @@ class ProfileTableViewController: BaseViewController {
182 }
188 }
183
189
184 @objc func book() {
190 @objc func book() {
191+ guard
192+ let phone = user?.phoneNumber,
193+ let user = user
194+ else { return }
185
195
196+ let fullUser = FullUser(uuid: user.uuid,
197+ name: user.name,
198+ phoneNumber: user.phoneNumber,
199+ isAdmin: user.isAdmin)
200+ coodinator?.createReservation(forUserWithPhone: phone, user: fullUser)
186 }
201 }
187}
202}
188
203
@@ -207,7 +222,8 @@ extension ProfileTableViewController: UITableViewDelegate, UITableViewDataSource
207 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
222 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
208 guard let u = user else { return }
223 guard let u = user else { return }
209 let r = dataSource[indexPath.row]
224 let r = dataSource[indexPath.row]
225+ let user = FullUser(uuid: u.uuid, name: u.name, phoneNumber: u.phoneNumber, isAdmin: u.isAdmin)
210− let reservation = ReservationWithUser(reservation: r, user: u)
226+ let reservation = ReservationWithUser(reservation: r, user: user)
211 coodinator?.seeExistingReservation(data: reservation)
227 coodinator?.seeExistingReservation(data: reservation)
212 }
228 }
213
229
Hookah Tau/Controllers/Admin/Reservations/AdminReservationEditingCoordinator.swift+3−1
@@ -9,10 +9,12 @@
9import UIKit
9import UIKit
10
10
11
11
12−class AdminReservationEditingCoordinator: BaseCoordinator {
12+class AdminReservationEditingCoordinator: BaseCoordinator, ShowReservationCoordinator {
13
13
14 // MARK: - Peoperties
14 // MARK: - Peoperties
15
15
16+ var didFinish: (() -> Void)?
17+
16 var reservationData: ReservationWithUser?
18 var reservationData: ReservationWithUser?
17
19
18 // MARK: - Lifecycle
20 // MARK: - Lifecycle
Hookah Tau/Controllers/Admin/Reservations/AdminReservationEditingViewController.swift+52−21
@@ -24,22 +24,17 @@ class AdminReservationEditingViewController: BaseViewController {
24
24
25 var reservationData: ReservationWithUser?
25 var reservationData: ReservationWithUser?
26
26
27− weak var coordinator: AdminReservationEditingCoordinator?
27+ weak var coordinator: ShowReservationCoordinator?
28
28
29 var reservationService: ReservationsService?
29 var reservationService: ReservationsService?
30
30
31 var reservedPeriods: [ReservationPeriod] = [] {
31 var reservedPeriods: [ReservationPeriod] = [] {
32 didSet {
32 didSet {
33+ if let _ = reservationView {
33− setupReservationViewWithIntervals()
34+ setupReservationViewWithIntervals()
35+ }
34 }
36 }
35 }
37 }
36−
37− var saveButton: Button = {
38− let button = Button()
39− let style = BlackButtonStyle()
40− style.apply(to: button, withTitle: "СОХРАНИТЬ")
41− return button
42− }()
43
38
44 // MARK:- Lifecycle
39 // MARK:- Lifecycle
45
40
@@ -64,10 +59,8 @@ class AdminReservationEditingViewController: BaseViewController {
64 // MARK: - Setup
59 // MARK: - Setup
65
60
66 func setupButtons() {
61 func setupButtons() {
67− addStackViewWithButtons(rightBtn: saveButton,
68− constant: -mainContentView.frame.height - 10)
69
62
70− saveButton.addTarget(self, action: #selector(saveReservation), for: .touchUpInside)
63+ reservationView?.saveButton?.addTarget(self, action: #selector(saveReservation), for: .touchUpInside)
71 reservationView?.cancelButton?.addTarget(self, action: #selector(cancelReservation), for: .touchUpInside)
64 reservationView?.cancelButton?.addTarget(self, action: #selector(cancelReservation), for: .touchUpInside)
72 }
65 }
73
66
@@ -100,9 +93,14 @@ class AdminReservationEditingViewController: BaseViewController {
100 }
93 }
101
94
102 func loadReservedPeriods() {
95 func loadReservedPeriods() {
96+ guard
103− guard let model = reservationData else { return }
97+ let model = reservationData,
98+ let uuid = model.uuid
99+ else {
100+ setupReservationViewWithIntervals()
101+ return }
104
102
105− reservationService?.getReservationsAround(uuid: model.uuid, completion: { [weak self] (res) in
103+ reservationService?.getReservationsAround(uuid: uuid, completion: { [weak self] (res) in
106 switch res {
104 switch res {
107 case .failure(let err):
105 case .failure(let err):
108 self?.displayAlert(forError: err)
106 self?.displayAlert(forError: err)
@@ -120,9 +118,12 @@ class AdminReservationEditingViewController: BaseViewController {
120 guard
118 guard
121 let r = reservationView?.data,
119 let r = reservationView?.data,
122 let uuid = reservationData?.uuid
120 let uuid = reservationData?.uuid
121+ else {
122+ createReservation()
123− else { return }
123+ return
124+ }
124
125
125− saveButton.loading = true
126+ reservationView?.saveButton?.loading = true
126
127
127 reservationService?.updateReservation(startTime: r.startTime,
128 reservationService?.updateReservation(startTime: r.startTime,
128 numberOfGuests: r.numberOfGuests,
129 numberOfGuests: r.numberOfGuests,
@@ -131,26 +132,56 @@ class AdminReservationEditingViewController: BaseViewController {
131 isAdmin: true,
132 isAdmin: true,
132 completion: { [weak self] (res) in
133 completion: { [weak self] (res) in
133 if res {
134 if res {
134− self?.coordinator?.didEndFlow?()
135+ self?.coordinator?.didFinish?()
135 } else {
136 } else {
136 self?.displayAlert(with: "Что-то пошло не так! Попробуешь еще раз?")
137 self?.displayAlert(with: "Что-то пошло не так! Попробуешь еще раз?")
137 }
138 }
138
139
139− self?.saveButton.loading = false
140+ self?.reservationView?.saveButton?.loading = false
141+ })
142+ }
143+
144+ func createReservation() {
145+ guard
146+ let r = reservationData,
147+ let d = reservationData?.owner.phoneNumber else { return }
148+
149+ let data = ReservationData(establishment: r.establishment,
150+ startTime: r.startTime,
151+ endTime: r.endTime,
152+ numberOfGuests: r.numberOfGuests,
153+ reservedTable: r.reservedTable)
154+ print(data)
155+ reservationService?.createReservation(reservation: AdminCreateReservation(reservation: data, user: d), completion: { (res) in
156+ switch res {
157+ case .failure(_):
158+ self.displayAlert(with: "Что-то пошло не так!\nПопробуешь еще раз?")
159+ return
160+ case .success(let uuid):
161+ self.reservationData?.uuid = uuid
162+ self.coordinator?.didFinish?()
163+ return
164+ }
140 })
165 })
141 }
166 }
142
167
143 @objc func cancelReservation() {
168 @objc func cancelReservation() {
144 guard
169 guard
145− let uuid = reservationData?.uuid
170+ let uuid = reservationData?.uuid
171+ else {
172+ cancelPrereservation()
146− else { return }
173+ return }
147
174
148 reservationService?.deleteReservation(isAdmin: true, uuid: uuid, completion: { [weak self] (res) in
175 reservationService?.deleteReservation(isAdmin: true, uuid: uuid, completion: { [weak self] (res) in
149 if res {
176 if res {
150− self?.coordinator?.didEndFlow?()
177+ self?.coordinator?.didFinish?()
151 } else {
178 } else {
152 self?.displayAlert(with: "Что-то пошло не так!\nПопробуешь еще раз?")
179 self?.displayAlert(with: "Что-то пошло не так!\nПопробуешь еще раз?")
153 }
180 }
154 })
181 })
155 }
182 }
183+
184+ func cancelPrereservation() {
185+ coordinator?.didFinish?()
186+ }
156}
187}
Hookah Tau/Controllers/Admin/Reservations/AdminReservations.storyboard+67−3
@@ -32,14 +32,14 @@
32 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
32 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
33 <subviews>
33 <subviews>
34 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uNU-TW-vfq">
34 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uNU-TW-vfq">
35− <rect key="frame" x="0.0" y="206" width="375" height="441"/>
35+ <rect key="frame" x="0.0" y="262" width="375" height="385"/>
36 <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
36 <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
37 <constraints>
37 <constraints>
38− <constraint firstAttribute="height" constant="441" id="wfZ-i9-ruU"/>
38+ <constraint firstAttribute="height" constant="385" id="wfZ-i9-ruU"/>
39 </constraints>
39 </constraints>
40 </view>
40 </view>
41 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ghQ-Jv-1Uo">
41 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ghQ-Jv-1Uo">
42− <rect key="frame" x="0.0" y="0.0" width="375" height="198"/>
42+ <rect key="frame" x="0.0" y="0.0" width="375" height="254"/>
43 <color key="backgroundColor" systemColor="systemGreenColor" red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
43 <color key="backgroundColor" systemColor="systemGreenColor" red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
44 </view>
44 </view>
45 </subviews>
45 </subviews>
@@ -64,5 +64,69 @@
64 </objects>
64 </objects>
65 <point key="canvasLocation" x="959.20000000000005" y="158.77061469265368"/>
65 <point key="canvasLocation" x="959.20000000000005" y="158.77061469265368"/>
66 </scene>
66 </scene>
67+ <!--Admin Second Step Reservation View Controller-->
68+ <scene sceneID="VhI-Z9-iqB">
69+ <objects>
70+ <viewController storyboardIdentifier="AdminSecondStepReservationViewController" id="eNJ-Ja-201" customClass="AdminSecondStepReservationViewController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
71+ <view key="view" contentMode="scaleToFill" id="7mk-5I-JJs">
72+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
73+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
74+ <subviews>
75+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oAV-GW-iea">
76+ <rect key="frame" x="0.0" y="0.0" width="375" height="293"/>
77+ <color key="backgroundColor" systemColor="systemIndigoColor" red="0.34509803919999998" green="0.33725490200000002" blue="0.83921568629999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
78+ </view>
79+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a4v-ng-lm7">
80+ <rect key="frame" x="0.0" y="293" width="375" height="374"/>
81+ <subviews>
82+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="13" translatesAutoresizingMaskIntoConstraints="NO" id="1Bb-cO-4qW">
83+ <rect key="frame" x="20" y="22" width="335" height="88.5"/>
84+ <subviews>
85+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Номер клиента" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bME-Wr-gh7">
86+ <rect key="frame" x="62.5" y="0.0" width="210.5" height="33.5"/>
87+ <fontDescription key="fontDescription" type="boldSystem" pointSize="28"/>
88+ <nil key="textColor"/>
89+ <nil key="highlightedColor"/>
90+ </label>
91+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="+7 (988) 888-88-88" textAlignment="natural" minimumFontSize="28" translatesAutoresizingMaskIntoConstraints="NO" id="wBC-oa-ekQ" customClass="PhoneTextField" customModule="Hookah_Tau" customModuleProvider="target">
92+ <rect key="frame" x="13.5" y="46.5" width="308.5" height="42"/>
93+ <fontDescription key="fontDescription" type="boldSystem" pointSize="28"/>
94+ <textInputTraits key="textInputTraits"/>
95+ </textField>
96+ </subviews>
97+ </stackView>
98+ </subviews>
99+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
100+ <constraints>
101+ <constraint firstItem="1Bb-cO-4qW" firstAttribute="top" secondItem="a4v-ng-lm7" secondAttribute="top" constant="22" id="7fb-Up-Wmb"/>
102+ <constraint firstAttribute="trailing" secondItem="1Bb-cO-4qW" secondAttribute="trailing" constant="20" id="934-Ef-0xf"/>
103+ <constraint firstItem="1Bb-cO-4qW" firstAttribute="leading" secondItem="a4v-ng-lm7" secondAttribute="leading" constant="20" id="sr5-aO-q1p"/>
104+ <constraint firstAttribute="height" constant="374" id="uRW-2Q-OyM"/>
105+ </constraints>
106+ </view>
107+ </subviews>
108+ <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
109+ <constraints>
110+ <constraint firstItem="a4v-ng-lm7" firstAttribute="leading" secondItem="8aV-w1-NXE" secondAttribute="leading" id="OjU-Pl-gu1"/>
111+ <constraint firstItem="oAV-GW-iea" firstAttribute="trailing" secondItem="8aV-w1-NXE" secondAttribute="trailing" id="bPj-q1-pY6"/>
112+ <constraint firstItem="oAV-GW-iea" firstAttribute="top" secondItem="8aV-w1-NXE" secondAttribute="top" id="gUc-es-YHL"/>
113+ <constraint firstItem="a4v-ng-lm7" firstAttribute="bottom" secondItem="8aV-w1-NXE" secondAttribute="bottom" id="hZH-fU-zM5"/>
114+ <constraint firstItem="oAV-GW-iea" firstAttribute="leading" secondItem="8aV-w1-NXE" secondAttribute="leading" id="mos-8B-wjS"/>
115+ <constraint firstItem="a4v-ng-lm7" firstAttribute="trailing" secondItem="8aV-w1-NXE" secondAttribute="trailing" id="ntK-1r-AUW"/>
116+ <constraint firstItem="a4v-ng-lm7" firstAttribute="top" secondItem="oAV-GW-iea" secondAttribute="bottom" id="siv-Xa-Nl5"/>
117+ </constraints>
118+ <viewLayoutGuide key="safeArea" id="8aV-w1-NXE"/>
119+ </view>
120+ <connections>
121+ <outlet property="heightConstraint" destination="uRW-2Q-OyM" id="fmn-uI-ooi"/>
122+ <outlet property="mapContainerView" destination="oAV-GW-iea" id="jmP-q0-WbS"/>
123+ <outlet property="phoneContentView" destination="a4v-ng-lm7" id="W1O-A7-6EP"/>
124+ <outlet property="phoneTextField" destination="wBC-oa-ekQ" id="Btg-A3-tpm"/>
125+ </connections>
126+ </viewController>
127+ <placeholder placeholderIdentifier="IBFirstResponder" id="hNg-aQ-v7C" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
128+ </objects>
129+ <point key="canvasLocation" x="1664.8" y="158.77061469265368"/>
130+ </scene>
67 </scenes>
131 </scenes>
68</document>
132</document>
Hookah Tau/Controllers/Admin/Reservations/List of reservations/AdminReservationsController.swift+3−2
@@ -123,7 +123,8 @@ class AdminReservationsController: BaseViewController {
123 // MARK:- Button handler
123 // MARK:- Button handler
124
124
125 @objc func book() {
125 @objc func book() {
126−
126+ guard let establishmentId = id else { return }
127+ coordinator?.book(inEstablishment: establishmentId)
127 }
128 }
128
129
129 func deleteReservation(uuid: String, completion: @escaping (([ReservationWithUser]?) -> Void)) {
130 func deleteReservation(uuid: String, completion: @escaping (([ReservationWithUser]?) -> Void)) {
@@ -195,7 +196,7 @@ extension AdminReservationsController: UITableViewDelegate, UITableViewDataSourc
195
196
196 func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
197 func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
197
198
198− let uuid = activeReservations[indexPath.row].uuid
199+ guard let uuid = activeReservations[indexPath.row].uuid else { return [] }
199 let cancelButton = UITableViewRowAction(style: .normal, title: "отменить бронь") { _,_ in
200 let cancelButton = UITableViewRowAction(style: .normal, title: "отменить бронь") { _,_ in
200
201
201 self.deleteReservation(uuid: uuid) { optionalNewVal in
202 self.deleteReservation(uuid: uuid) { optionalNewVal in
Hookah Tau/Controllers/Admin/Reservations/List of reservations/AdminReservationsCoordinator.swift+16
@@ -12,6 +12,8 @@ class AdminReservationsCoordinator: BaseCoordinator {
12
12
13 // MARK: - Properties
13 // MARK: - Properties
14
14
15+ var didFinish: (() -> Void)?
16+
15 var establishmentId: Int?
17 var establishmentId: Int?
16
18
17 // MARK: - Lifecycle
19 // MARK: - Lifecycle
@@ -35,4 +37,18 @@ class AdminReservationsCoordinator: BaseCoordinator {
35 }
37 }
36 reservationCoordinator.start()
38 reservationCoordinator.start()
37 }
39 }
40+
41+ /// Сюда мы идем после нажатия кнопочки "Забронировать" или плюсика справа сверху
42+ func book(inEstablishment establishmentId: Int) {
43+ let reservationCoordinator = AdminFirstStepReservationViewCoordinator(navigationController: navigationController)
44+ reservationCoordinator.establishment = establishmentId
45+ addDependency(reservationCoordinator)
46+ reservationCoordinator.didFinish = { [weak self] in
47+ self?.navigationController?.popViewController(animated: false)
48+ self?.removeDependency(reservationCoordinator)
49+ self?.didFinish?()
50+ }
51+
52+ reservationCoordinator.start()
53+ }
38}
54}
Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/1/AdminFirstStepReservationViewCoordinator.swiftnew file+108
@@ -0,0 +1,108 @@
1+//
2+// AdminFirstStepReservationViewCoordinator.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 13/01/2020.
6+// Copyright © 2020 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+enum UserType {
12+ case admin
13+ case client
14+}
15+
16+protocol FirstStepReservationProtocol: BaseCoordinator {
17+
18+ var user: UserType { get }
19+
20+ func makeReservation(model: SecondStepModel, mapView: MapImageScroll?)
21+}
22+
23+class AdminFirstStepReservationViewCoordinator: BaseCoordinator{
24+
25+ // MARK: - Properties
26+
27+ var didFinish: (() -> Void)?
28+
29+ var establishment: Int = 1
30+
31+ var phone: String?
32+
33+ var fullUser: FullUser?
34+
35+ var model: SecondStepModel?
36+
37+ // MARK: - Lifecycle
38+
39+ override func start() {
40+ let storyboard = UIStoryboard(name: "Reservation", bundle: nil)
41+ let reservationVC = storyboard.instantiateViewController(withIdentifier: "ReservationViewController") as! FirstStepReservationViewController
42+
43+ reservationVC.coordinator = self
44+ reservationVC.establishmentId = establishment
45+
46+ navigationController?.pushViewController(reservationVC, animated: true)
47+ }
48+
49+
50+}
51+
52+extension AdminFirstStepReservationViewCoordinator: FirstStepReservationProtocol {
53+
54+ var user: UserType {
55+ get {
56+ return .admin
57+ }
58+ }
59+
60+ func makeReservation(model: SecondStepModel, mapView: MapImageScroll?) {
61+ self.model = model
62+
63+ if let p = phone {
64+ goToFinalStep(with: fullUser, phone: p)
65+ } else {
66+ goToSecondStep(model: model, mapView: mapView)
67+ }
68+ }
69+
70+ func goToFinalStep(with user: FullUser?, phone phoneNumber: String) {
71+ let finalStepCoordinator = AdminFinalStepReservationCoordinator(navigationController: navigationController)
72+ finalStepCoordinator.model = self.model
73+
74+ addDependency(finalStepCoordinator)
75+ finalStepCoordinator.didFinish = { [weak self] in
76+ self?.navigationController?.popViewController(animated: false)
77+ self?.removeDependency(finalStepCoordinator)
78+ self?.didFinish?()
79+ }
80+
81+ if let u = user {
82+ finalStepCoordinator.user = u
83+ } else {
84+ finalStepCoordinator.user = FullUser(uuid: nil,
85+ name: nil,
86+ phoneNumber: phoneNumber,
87+ isAdmin: true)
88+ }
89+
90+ finalStepCoordinator.start()
91+ }
92+
93+ func goToSecondStep(model: SecondStepModel, mapView: MapImageScroll?) {
94+ let reservationCoordinaotor = AdminSecondStepReservationViewCoordinator(navigationController: navigationController)
95+ reservationCoordinaotor.model = model
96+ reservationCoordinaotor.map = mapView
97+
98+ addDependency(reservationCoordinaotor)
99+ reservationCoordinaotor.didFinish = { [weak self] in
100+ self?.navigationController?.popViewController(animated: false)
101+ self?.removeDependency(reservationCoordinaotor)
102+ self?.didFinish?()
103+ }
104+
105+ reservationCoordinaotor.start()
106+ }
107+}
108+
Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/2/AdminSecondStepReservationViewController.swiftnew file+124
@@ -0,0 +1,124 @@
1+//
2+// AdminSecondStepReservationViewController.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 13/01/2020.
6+// Copyright © 2020 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class AdminSecondStepReservationViewController: BaseViewController {
12+
13+ // MARK: - IBAOutlets
14+
15+ @IBOutlet weak var mapContainerView: UIView!
16+
17+ @IBOutlet weak var heightConstraint: NSLayoutConstraint!
18+
19+ @IBOutlet weak var phoneTextField: PhoneTextField!
20+
21+ @IBOutlet weak var phoneContentView: UIView!
22+
23+ // MARK: - Properties
24+
25+ var table: Int?
26+
27+ var mapScrollView: MapImageScroll?
28+
29+ var clientsService: ClientsService?
30+
31+ weak var coordinator: AdminSecondStepReservationViewCoordinator?
32+
33+ let continueButton: Button = {
34+ let button = Button()
35+ let style = BlackButtonStyle()
36+ style.apply(to: button, withTitle: "ДАЛЕЕ")
37+ return button
38+ }()
39+
40+ let cancelButton: Button = {
41+ let button = Button()
42+ let style = BlackButtonStyle()
43+ style.apply(to: button, withTitle: "ОТМЕНИТЬ")
44+ return button
45+ }()
46+
47+ // MARK: - Lifecycle
48+
49+ override func viewDidLoad() {
50+ super.viewDidLoad()
51+
52+ setupMap()
53+ setupButtons()
54+ setUpKeyboard()
55+
56+ clientsService = ClientsService(apiClient: APIClient.shared)
57+ phoneTextField.becomeFirstResponder()
58+ }
59+
60+ // MARK: - Set up
61+
62+ func setupMap() {
63+ guard let t = table else { return }
64+ mapScrollView?.scrollToTable(table: t)
65+ mapContainerView.addSubviewThatFills(mapScrollView)
66+ }
67+
68+ func setupButtons() {
69+ addStackViewWithButtons(leftBtn: cancelButton,
70+ rightBtn: continueButton,
71+ constant: -phoneContentView.frame.height - 20)
72+
73+ cancelButton.addTarget(self, action: #selector(cancel), for: .touchUpInside)
74+ continueButton.addTarget(self, action: #selector(continueBooking), for: .touchUpInside)
75+ }
76+
77+ // MARK: - Keyboad
78+
79+ @objc
80+ override func handleKeyboardNotifications(notification: NSNotification) {
81+ if let userInfo = notification.userInfo {
82+ let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
83+ heightConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? keyBoardFrame.height + view.safeAreaInsets.bottom + 120.5 : 120.5
84+ bottomConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? -keyBoardFrame.height + view.safeAreaInsets.bottom - 140.5 : -140.5
85+
86+ UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
87+ self.view.layoutIfNeeded()
88+ })
89+ }
90+ }
91+
92+ // MARK: - Button handlers
93+
94+ @objc func cancel() {
95+ coordinator?.didEndFlow?()
96+ }
97+
98+ @objc func continueBooking() {
99+ continueButton.loading = true
100+
101+ guard let phone = phoneTextField.text?.toApiPhoneNumberFormat(), phone.count == 9 else {
102+ displayAlert(with: "Сначала укажи номер!")
103+ return
104+ }
105+
106+ clientsService?.getClientByPhoneNumber(userPhone: phone, completion: { [unowned self] (res) in
107+ switch res {
108+ case .failure(let err):
109+ switch err {
110+ case .notFound:
111+ self.coordinator?.continueReservation(with: nil, phone: phone)
112+ default:
113+ self.displayAlert(with: "Что-то пошло не так! Попробуй еще раз :)")
114+ }
115+ case .success(let user):
116+ self.coordinator?.continueReservation(with: user, phone: phone)
117+ }
118+
119+ self.continueButton.loading = false
120+ })
121+ }
122+
123+
124+}
Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/2/AdminSecondStepReservationViewCoordinator.swiftnew file+54
@@ -0,0 +1,54 @@
1+//
2+// AdminSecondStepReservationViewCoordinator.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 13/01/2020.
6+// Copyright © 2020 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class AdminSecondStepReservationViewCoordinator: BaseCoordinator {
12+
13+ // MARK: - Properties
14+
15+ var didFinish: (() -> Void)?
16+
17+ var map: MapImageScroll?
18+
19+ var model: SecondStepModel?
20+
21+ // MARK: - Lifecycle
22+
23+ override func start() {
24+ let storyboard = UIStoryboard(name: "AdminReservations", bundle: nil)
25+ let reservationVC = storyboard.instantiateViewController(withIdentifier: "AdminSecondStepReservationViewController") as! AdminSecondStepReservationViewController
26+ reservationVC.mapScrollView = map
27+ reservationVC.table = model?.table
28+ reservationVC.coordinator = self
29+ navigationController?.pushViewController(reservationVC, animated: true)
30+ }
31+
32+ func continueReservation(with user: FullUser?, phone phoneNumber: String) {
33+ let finalStepCoordinator = AdminFinalStepReservationCoordinator(navigationController: navigationController)
34+ finalStepCoordinator.model = self.model
35+
36+ addDependency(finalStepCoordinator)
37+ finalStepCoordinator.didFinish = { [weak self] in
38+ self?.navigationController?.popViewController(animated: false)
39+ self?.removeDependency(finalStepCoordinator)
40+ self?.didFinish?()
41+ }
42+
43+ if let u = user {
44+ finalStepCoordinator.user = u
45+ } else {
46+ finalStepCoordinator.user = FullUser(uuid: nil,
47+ name: nil,
48+ phoneNumber: phoneNumber,
49+ isAdmin: true)
50+ }
51+
52+ finalStepCoordinator.start()
53+ }
54+}
Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/3/AdminFinalStepReservationCoordinator.swiftnew file+47
@@ -0,0 +1,47 @@
1+//
2+// AdminFinalStepReservationCoordinator.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 14/01/2020.
6+// Copyright © 2020 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+protocol ShowReservationCoordinator: BaseCoordinator {
12+ var didFinish: (() -> Void)? { get }
13+}
14+
15+class AdminFinalStepReservationCoordinator: BaseCoordinator, ShowReservationCoordinator {
16+
17+ // MARK: - Properties
18+
19+ var didFinish: (() -> Void)?
20+
21+ var user: FullUser?
22+
23+ var model: SecondStepModel?
24+
25+ // MARK: - Lifecycle
26+
27+ override func start() {
28+ let storyboard = UIStoryboard(name: "AdminReservations", bundle: nil)
29+ let vc = storyboard.instantiateViewController(withIdentifier: "AdminReservationEditingViewController") as! AdminReservationEditingViewController
30+
31+ guard
32+ let model = model,
33+ let u = user else { return }
34+ vc.reservationData = ReservationWithUser(uuid: nil,
35+ establishment: model.establishment,
36+ startTime: model.startTime,
37+ endTime: model.startTime.addHours(2),
38+ numberOfGuests: 2,
39+ reservedTable: model.table,
40+ owner: u)
41+
42+ vc.reservedPeriods = model.reservedintervals
43+ vc.coordinator = self
44+
45+ navigationController?.pushViewController(vc, animated: true)
46+ }
47+}
Hookah Tau/Controllers/Admin/Reservations/Views/AdminReservationView.swift+11−4
@@ -39,6 +39,13 @@ class AdminReservationView: UIView {
39
39
40 @IBOutlet weak var intervalsStackView: UIStackView!
40 @IBOutlet weak var intervalsStackView: UIStackView!
41
41
42+ @IBOutlet weak var saveButton: Button? {
43+ didSet {
44+ let style = BlackButtonStyle()
45+ style.apply(to: saveButton, withTitle: "СОХРАНИТЬ")
46+ }
47+ }
48+
42 // MARK: - Properties
49 // MARK: - Properties
43
50
44 // констрейнты начала и конца интервала
51 // констрейнты начала и конца интервала
@@ -109,7 +116,7 @@ class AdminReservationView: UIView {
109
116
110 startDate = start
117 startDate = start
111
118
112− setUpIntervals(model.owner.isAdmin)
119+ setUpIntervals()
113
120
114 guestSlider?.maximumValue = Float((TotalStorage.standard.getTable(establishment: model.establishment, table: model.reservedTable)?.maxGuestNumber ?? 2) + 1)
121 guestSlider?.maximumValue = Float((TotalStorage.standard.getTable(establishment: model.establishment, table: model.reservedTable)?.maxGuestNumber ?? 2) + 1)
115 }
122 }
@@ -158,11 +165,11 @@ class AdminReservationView: UIView {
158 // MARK: - Setup
165 // MARK: - Setup
159
166
160 /// Тут происходит установка интервалов. Разное для клиента и админа
167 /// Тут происходит установка интервалов. Разное для клиента и админа
161− func setUpIntervals(_ isAdmin: Bool) {
168+ func setUpIntervals() {
162 guard let startPoint = startDate else { return }
169 guard let startPoint = startDate else { return }
163
170
164− let startingPoint = isAdmin ? startPoint.getAdminsStartingPoint() : Constants.clientStartingPoint
171+ let startingPoint = startPoint.getAdminsStartingPoint()
165− let endingPoint = startingPoint + (isAdmin ? Constants.adminDuration : Constants.clientDuration)
172+ let endingPoint = Constants.adminDuration
166
173
167 for period in startingPoint...endingPoint {
174 for period in startingPoint...endingPoint {
168 let timePointView = TimePointView.loadFromNib()
175 let timePointView = TimePointView.loadFromNib()
Hookah Tau/Controllers/Admin/Reservations/Views/AdminReservationView.xib+36−21
@@ -11,14 +11,14 @@
11 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
11 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
12 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
12 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
13 <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="AdminReservationView" customModule="Hookah_Tau" customModuleProvider="target">
13 <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="AdminReservationView" customModule="Hookah_Tau" customModuleProvider="target">
14− <rect key="frame" x="0.0" y="0.0" width="414" height="441"/>
14+ <rect key="frame" x="0.0" y="0.0" width="414" height="385"/>
15 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
15 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16 <subviews>
16 <subviews>
17− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="48" translatesAutoresizingMaskIntoConstraints="NO" id="AEf-R4-K1F">
17+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="24" translatesAutoresizingMaskIntoConstraints="NO" id="AEf-R4-K1F">
18− <rect key="frame" x="0.0" y="16" width="414" height="404"/>
18+ <rect key="frame" x="0.0" y="16" width="414" height="349"/>
19 <subviews>
19 <subviews>
20 <stackView opaque="NO" contentMode="scaleToFill" alignment="top" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="oh7-ka-ctS">
20 <stackView opaque="NO" contentMode="scaleToFill" alignment="top" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="oh7-ka-ctS">
21− <rect key="frame" x="21" y="0.0" width="372" height="143.5"/>
21+ <rect key="frame" x="21" y="0.0" width="372" height="136.5"/>
22 <subviews>
22 <subviews>
23 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="22" translatesAutoresizingMaskIntoConstraints="NO" id="IY6-F4-aln">
23 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="22" translatesAutoresizingMaskIntoConstraints="NO" id="IY6-F4-aln">
24 <rect key="frame" x="0.0" y="0.0" width="129" height="136.5"/>
24 <rect key="frame" x="0.0" y="0.0" width="129" height="136.5"/>
@@ -66,21 +66,35 @@
66 <constraint firstItem="hEV-kW-bBH" firstAttribute="leading" secondItem="IY6-F4-aln" secondAttribute="leading" id="tsb-PN-YGB"/>
66 <constraint firstItem="hEV-kW-bBH" firstAttribute="leading" secondItem="IY6-F4-aln" secondAttribute="leading" id="tsb-PN-YGB"/>
67 </constraints>
67 </constraints>
68 </stackView>
68 </stackView>
69− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="bottom" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="59c-nG-5Fh">
69+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="bottom" spacing="28" translatesAutoresizingMaskIntoConstraints="NO" id="Kjb-P4-v2B">
70− <rect key="frame" x="133" y="0.0" width="239" height="71.5"/>
70+ <rect key="frame" x="133" y="0.0" width="239" height="136.5"/>
71 <subviews>
71 <subviews>
72+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="bottom" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="59c-nG-5Fh">
73+ <rect key="frame" x="65" y="0.0" width="174" height="71.5"/>
74+ <subviews>
72− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Стасик" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OoG-F4-OVu">
75+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Стасик" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OoG-F4-OVu">
73− <rect key="frame" x="160.5" y="0.0" width="78.5" height="26.5"/>
76+ <rect key="frame" x="95.5" y="0.0" width="78.5" height="26.5"/>
74− <fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
77+ <fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
75− <nil key="textColor"/>
78+ <nil key="textColor"/>
76− <nil key="highlightedColor"/>
79+ <nil key="highlightedColor"/>
77− </label>
80+ </label>
78− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Xkd-xQ-cFd" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
81+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Xkd-xQ-cFd" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
79− <rect key="frame" x="65" y="34.5" width="174" height="37"/>
82+ <rect key="frame" x="0.0" y="34.5" width="174" height="37"/>
83+ <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
84+ <constraints>
85+ <constraint firstAttribute="height" constant="37" id="7Wj-WF-xzD"/>
86+ <constraint firstAttribute="width" constant="174" id="ZYo-ko-rwn"/>
87+ </constraints>
88+ <state key="normal" title="Button"/>
89+ </button>
90+ </subviews>
91+ </stackView>
92+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="npC-AF-3pj" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
93+ <rect key="frame" x="103" y="99.5" width="136" height="37"/>
80 <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
94 <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
81 <constraints>
95 <constraints>
82− <constraint firstAttribute="height" constant="37" id="7Wj-WF-xzD"/>
96+ <constraint firstAttribute="width" constant="136" id="jg5-lP-Ekd"/>
83− <constraint firstAttribute="width" constant="174" id="ZYo-ko-rwn"/>
97+ <constraint firstAttribute="height" constant="37" id="w98-8a-pmH"/>
84 </constraints>
98 </constraints>
85 <state key="normal" title="Button"/>
99 <state key="normal" title="Button"/>
86 </button>
100 </button>
@@ -89,7 +103,7 @@
89 </subviews>
103 </subviews>
90 </stackView>
104 </stackView>
91 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="9RO-aK-yNh">
105 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="9RO-aK-yNh">
92− <rect key="frame" x="21" y="191.5" width="372" height="58.5"/>
106+ <rect key="frame" x="21" y="160.5" width="372" height="58.5"/>
93 <subviews>
107 <subviews>
94 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Количество гостей: 2" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yTM-U5-XjI">
108 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Количество гостей: 2" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yTM-U5-XjI">
95 <rect key="frame" x="0.0" y="0.0" width="372" height="20.5"/>
109 <rect key="frame" x="0.0" y="0.0" width="372" height="20.5"/>
@@ -106,7 +120,7 @@
106 </subviews>
120 </subviews>
107 </stackView>
121 </stackView>
108 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vKS-ia-RxW">
122 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vKS-ia-RxW">
109− <rect key="frame" x="0.0" y="298" width="414" height="106"/>
123+ <rect key="frame" x="0.0" y="243" width="414" height="106"/>
110 <subviews>
124 <subviews>
111 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EiP-QO-PbU">
125 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EiP-QO-PbU">
112 <rect key="frame" x="0.0" y="20" width="414" height="85"/>
126 <rect key="frame" x="0.0" y="20" width="414" height="85"/>
@@ -182,10 +196,10 @@
182 </subviews>
196 </subviews>
183 <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
197 <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
184 <constraints>
198 <constraints>
185− <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="AEf-R4-K1F" secondAttribute="bottom" constant="21" id="4MN-Yl-hYv"/>
186 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="AEf-R4-K1F" secondAttribute="trailing" id="C1h-bA-S6p"/>
199 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="AEf-R4-K1F" secondAttribute="trailing" id="C1h-bA-S6p"/>
187 <constraint firstItem="AEf-R4-K1F" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="H1o-ua-Tnn"/>
200 <constraint firstItem="AEf-R4-K1F" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="H1o-ua-Tnn"/>
188− <constraint firstItem="vUN-kp-3ea" firstAttribute="top" secondItem="AEf-R4-K1F" secondAttribute="top" constant="-16" id="eYI-is-YLt"/>
201+ <constraint firstAttribute="top" secondItem="AEf-R4-K1F" secondAttribute="top" constant="-16" id="eYI-is-YLt"/>
202+ <constraint firstAttribute="bottom" secondItem="AEf-R4-K1F" secondAttribute="bottom" constant="20" id="fdG-zZ-LeV"/>
189 </constraints>
203 </constraints>
190 <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
204 <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
191 <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
205 <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
@@ -198,11 +212,12 @@
198 <outlet property="intervalsStackView" destination="bpJ-pe-tQf" id="aF0-Qm-kuh"/>
212 <outlet property="intervalsStackView" destination="bpJ-pe-tQf" id="aF0-Qm-kuh"/>
199 <outlet property="nameLabel" destination="OoG-F4-OVu" id="rnW-fG-jFs"/>
213 <outlet property="nameLabel" destination="OoG-F4-OVu" id="rnW-fG-jFs"/>
200 <outlet property="numberOfGuestLabel" destination="yTM-U5-XjI" id="z0O-94-Mp7"/>
214 <outlet property="numberOfGuestLabel" destination="yTM-U5-XjI" id="z0O-94-Mp7"/>
215+ <outlet property="saveButton" destination="npC-AF-3pj" id="Rfm-Zl-zES"/>
201 <outlet property="scrollView" destination="trF-VM-0qV" id="P5v-fg-hUW"/>
216 <outlet property="scrollView" destination="trF-VM-0qV" id="P5v-fg-hUW"/>
202 <outlet property="tableLabel" destination="qNR-EO-oMK" id="63P-AS-fgf"/>
217 <outlet property="tableLabel" destination="qNR-EO-oMK" id="63P-AS-fgf"/>
203 <outlet property="timeLabel" destination="gau-aS-vtT" id="7Iy-Cz-zdY"/>
218 <outlet property="timeLabel" destination="gau-aS-vtT" id="7Iy-Cz-zdY"/>
204 </connections>
219 </connections>
205− <point key="canvasLocation" x="137.59999999999999" y="120.98950524737631"/>
220+ <point key="canvasLocation" x="137.59999999999999" y="95.802098950524751"/>
206 </view>
221 </view>
207 </objects>
222 </objects>
208</document>
223</document>
Hookah Tau/Controllers/BaseViewController.swift+1−1
@@ -97,7 +97,7 @@ class BaseViewController: UIViewController {
97 }
97 }
98
98
99 @objc
99 @objc
100− private func handleKeyboardNotifications(notification: NSNotification){
100+ func handleKeyboardNotifications(notification: NSNotification){
101 if let userInfo = notification.userInfo {
101 if let userInfo = notification.userInfo {
102 let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
102 let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
103 bottomConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? -keyBoardFrame.height + view.safeAreaInsets.bottom - 20 : 0
103 bottomConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? -keyBoardFrame.height + view.safeAreaInsets.bottom - 20 : 0
Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepReservationCoordinator.swift+8−1
@@ -8,7 +8,7 @@
8
8
9import UIKit
9import UIKit
10
10
11−class FirstStepReservationCoordinator: BaseCoordinator {
11+class FirstStepReservationCoordinator: BaseCoordinator, FirstStepReservationProtocol {
12
12
13 // MARK: - Properties
13 // MARK: - Properties
14
14
@@ -28,6 +28,13 @@ class FirstStepReservationCoordinator: BaseCoordinator {
28 navigationController?.pushViewController(reservationVC, animated: true)
28 navigationController?.pushViewController(reservationVC, animated: true)
29 }
29 }
30
30
31+ var user: UserType {
32+ get {
33+ return .client
34+ }
35+ }
36+
37+
31 func makeReservation(model: SecondStepModel,
38 func makeReservation(model: SecondStepModel,
32 mapView: MapImageScroll?) {
39 mapView: MapImageScroll?) {
33
40
Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepReservationViewController.swift+15−6
@@ -13,7 +13,7 @@ class FirstStepReservationViewController: BaseViewController {
13
13
14 // MARK: - Properties
14 // MARK: - Properties
15
15
16− weak var coordinator: FirstStepReservationCoordinator?
16+ weak var coordinator: FirstStepReservationProtocol?
17
17
18 @IBOutlet weak var childContentView: UIView!
18 @IBOutlet weak var childContentView: UIView!
19
19
@@ -82,12 +82,21 @@ class FirstStepReservationViewController: BaseViewController {
82 }
82 }
83
83
84 func setupButtons() {
84 func setupButtons() {
85+
86+ guard let coord = coordinator else { return }
87+
88+ if coord.user == .admin {
89+ addStackViewWithButtons(rightBtn: continueButton,
90+ constant: -childContentView.frame.height - 20)
91+ } else {
85− addStackViewWithButtons(leftBtn: callButton,
92+ addStackViewWithButtons(leftBtn: callButton,
86− rightBtn: continueButton,
93+ rightBtn: continueButton,
87− constant: -childContentView.frame.height - 20)
94+ constant: -childContentView.frame.height - 20)
95+
96+ callButton.addTarget(self, action: #selector(call), for: .touchUpInside)
97+ }
88
98
89 continueButton.addTarget(self, action: #selector(continueBooking), for: .touchUpInside)
99 continueButton.addTarget(self, action: #selector(continueBooking), for: .touchUpInside)
90− callButton.addTarget(self, action: #selector(call), for: .touchUpInside)
91 }
100 }
92
101
93 func performUpdate() {
102 func performUpdate() {
@@ -178,7 +187,7 @@ extension FirstStepReservationViewController: MapUpdater {
178 let areBooked = allReservations?.intervals[date] ?? []
187 let areBooked = allReservations?.intervals[date] ?? []
179
188
180 let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
189 let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
181− let closed = isAdmin || date.isInClosingHours()
190+ let closed = !isAdmin && date.isInClosingHours()
182
191
183 if Set(areBooked).contains(tableId) || closed {
192 if Set(areBooked).contains(tableId) || closed {
184 continueButton.availiable = false
193 continueButton.availiable = false
Hookah Tau/Models/Reservation.swift+15−1
@@ -51,7 +51,7 @@ struct ReservationData: MyCodable {
51/// Структура для получения респонса на `GET /admin/reservations/{establishment id}`
51/// Структура для получения респонса на `GET /admin/reservations/{establishment id}`
52struct ReservationWithUser: MyCodable {
52struct ReservationWithUser: MyCodable {
53
53
54− var uuid: String
54+ var uuid: String?
55 var establishment: Int
55 var establishment: Int
56 var startTime: Date
56 var startTime: Date
57 var endTime: Date
57 var endTime: Date
@@ -68,6 +68,20 @@ struct ReservationWithUser: MyCodable {
68 self.reservedTable = reservation.reservedTable
68 self.reservedTable = reservation.reservedTable
69 self.owner = user
69 self.owner = user
70 }
70 }
71+
72+ init(uuid: String?, establishment: Int, startTime: Date, endTime: Date, numberOfGuests: Int, reservedTable: Int, owner: FullUser) {
73+ self.uuid = uuid
74+ self.establishment = establishment
75+ self.startTime = startTime
76+ self.endTime = endTime
77+ self.numberOfGuests = numberOfGuests
78+ self.reservedTable = reservedTable
79+ self.owner = owner
80+ }
71}
81}
72
82
83+struct AdminCreateReservation: MyCodable {
84+ var reservation: ReservationData
85+ var user: String
86+}
73
87
Hookah Tau/Models/User.swift+1−1
@@ -17,7 +17,7 @@ struct User: MyCodable {
17
17
18/// При запросах на список пользователей в аккаунте администратора.
18/// При запросах на список пользователей в аккаунте администратора.
19struct FullUser: MyCodable {
19struct FullUser: MyCodable {
20− var uuid: String
20+ var uuid: String?
21 var name: String?
21 var name: String?
22 var phoneNumber: String
22 var phoneNumber: String
23 var isAdmin: Bool
23 var isAdmin: Bool