git.iko.soy/dashared/hookah-tau
on 228f35a help sign in
191 files changed+832−7947
since splitsnapshots
unifiedsplit
DataStorage.swift+62 Hookah Tau.xcodeproj/project.pbxproj+29−483 Hookah Tau/API/APIClient.swift−3 Hookah Tau/API/Authorization api/AuthorizationService.swift+1−7 Hookah Tau/API/ClientsService/ClientsService.swift−129 Hookah Tau/API/ClientsService/Resolvers/AddOtherAdminResolver.swift−35 Hookah Tau/API/ClientsService/Resolvers/BlocklistPutResolver.swift−33 Hookah Tau/API/ClientsService/Resolvers/ClientReservationsResolver.swift−34 Hookah Tau/API/ClientsService/Resolvers/ClientsListResolver.swift−28 Hookah Tau/API/ClientsService/Resolvers/DeleteOtherAdminResolver.swift−35 Hookah Tau/API/ClientsService/Resolvers/GetClientByPhoneNumberResolver.swift−35 Hookah Tau/API/Establishments api/EstablishmentService.swift−39 Hookah Tau/API/Establishments api/Resolvers/EstablishmentResolver.swift−24 Hookah Tau/API/Reservations api/ReservationsService.swift+5−158 Hookah Tau/API/Reservations api/Resolvers/Admin/AChangeReservationResolver.swift−34 Hookah Tau/API/Reservations api/Resolvers/Admin/ACreateReservationResolver.swift−37 Hookah Tau/API/Reservations api/Resolvers/Admin/ADeleteReservationResolver.swift−34 Hookah Tau/API/Reservations api/Resolvers/Admin/AReservationsResolver.swift−35 Hookah Tau/API/Reservations api/Resolvers/ChangeReservationResolver.swift−35 Hookah Tau/API/Reservations api/Resolvers/CreateReservationResolver.swift−30 Hookah Tau/API/Reservations api/Resolvers/DeleteReservationResolver.swift−31 Hookah Tau/API/Reservations api/Resolvers/ReservationsAroundResolver.swift−35 Hookah Tau/API/ServerError.swift−1 Hookah Tau/AppDelegate.swift+4 Hookah Tau/Components/Button.swift+7−8 Hookah Tau/Components/PhoneTextField.swift−63 Hookah Tau/Components/TableButtonStyle.swift+2−2 Hookah Tau/Controllers/Admin/Clients/Cells/ClientTableViewCell.swift−53 Hookah Tau/Controllers/Admin/Clients/ClientList.storyboard−196 Hookah Tau/Controllers/Admin/Clients/ClientsCoordinator.swift−36 Hookah Tau/Controllers/Admin/Clients/ClientsViewController.swift−239 Hookah Tau/Controllers/Admin/Clients/Profile/ClientProfileCoordinator.swift−52 Hookah Tau/Controllers/Admin/Clients/Profile/ProfileTableViewController.swift−257 Hookah Tau/Controllers/Admin/Reservations/AdminAddressCoordinator.swift−35 Hookah Tau/Controllers/Admin/Reservations/AdminReservationEditingCoordinator.swift−31 Hookah Tau/Controllers/Admin/Reservations/AdminReservationEditingViewController.swift−187 Hookah Tau/Controllers/Admin/Reservations/AdminReservations.storyboard−132 Hookah Tau/Controllers/Admin/Reservations/List of reservations/AdminReservationsController.swift−219 Hookah Tau/Controllers/Admin/Reservations/List of reservations/AdminReservationsCoordinator.swift−54 Hookah Tau/Controllers/Admin/Reservations/List of reservations/Cell/AdminReservationCellView.swift−84 Hookah Tau/Controllers/Admin/Reservations/List of reservations/Cell/AdminReservationCellView.xib−83 Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/1/AdminFirstStepReservationViewCoordinator.swift−108 Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/2/AdminSecondStepReservationViewController.swift−124 Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/2/AdminSecondStepReservationViewCoordinator.swift−54 Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/3/AdminFinalStepReservationCoordinator.swift−47 Hookah Tau/Controllers/Admin/Reservations/Views/AdminReservationView.swift−371 Hookah Tau/Controllers/Admin/Reservations/Views/AdminReservationView.xib−223 Hookah Tau/Controllers/Admin/Reservations/Views/No reserv/AdminNoReservationsView.swift−27 Hookah Tau/Controllers/Admin/Reservations/Views/No reserv/AdminNoReservationsView.xib−54 Hookah Tau/Controllers/Admin/Tab bar/Admin.storyboard−84 Hookah Tau/Controllers/Admin/Tab bar/AdminTabbarController.swift−48 Hookah Tau/Controllers/Admin/Tab bar/AdminTabbarCoordinator.swift−73 Hookah Tau/Controllers/ApplicationCoordinator.swift+1−8 Hookah Tau/Controllers/BaseTableViewController.swift−28 Hookah Tau/Controllers/BaseViewController.swift+3−3 Hookah Tau/Controllers/Client/Profile/ProfileChangeCoordinator.swift+4−6 Hookah Tau/Controllers/Client/Profile/ProfileChangeViewController.swift+3−22 Hookah Tau/Controllers/Client/Profile/Views/ChangeView.swift+1−32 Hookah Tau/Controllers/Client/Profile/Views/ChangeView.xib+1−1 Hookah Tau/Controllers/Client/Profile/Views/ProfileView.xib+5−5 Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsCoordinator.swift−14 Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsViewController.swift+14−105 Hookah Tau/Controllers/Client/Reservations/Adress of reservation/AddresViewController.swift+4−30 Hookah Tau/Controllers/Client/Reservations/Adress of reservation/AddressCoordinator.swift+2−16 Hookah Tau/Controllers/Client/Reservations/Cells/Address/AddressCell.swift−4 Hookah Tau/Controllers/Client/Reservations/Cells/Address/AddressView.swift+2−6 Hookah Tau/Controllers/Client/Reservations/Cells/Address/AddressView.xib+26−28 Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationCell.swift+2−3 Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationView.swift+61−11 Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationView.xib+55−7 Hookah Tau/Controllers/Client/Reservations/Maps/2/MapView2.swift−152 Hookah Tau/Controllers/Client/Reservations/Maps/2/MapView2.xib−155 Hookah Tau/Controllers/Client/Reservations/Maps/MapView.swift+3−31 Hookah Tau/Controllers/Client/Reservations/Maps/1/MapView1.swift → Hookah Tau/Controllers/Client/Reservations/Maps/MapView1.swift+21−24 Hookah Tau/Controllers/Client/Reservations/Maps/1/MapView1.xib → Hookah Tau/Controllers/Client/Reservations/Maps/MapView1.xib+28−36 Hookah Tau/Controllers/Client/Reservations/Reservation.storyboard+4−86 Hookah Tau/Controllers/Client/Reservations/SecondStepReservationViewController.swift+89 Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepReservationCoordinator.swift−62 Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepReservationViewController.swift−142 Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepView.swift−351 Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepReservationCoordinator.swift−57 Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepReservationViewController.swift−156 Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepView.swift−177 Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepView.xib−144 Hookah Tau/Controllers/Client/Reservations/Steps/Common/DateView.swift → Hookah Tau/Controllers/Client/Reservations/Steps/First/DateView.swift Hookah Tau/Controllers/Client/Reservations/Steps/Common/DateView.xib → Hookah Tau/Controllers/Client/Reservations/Steps/First/DateView.xib+2−2 Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepView.swift → Hookah Tau/Controllers/Client/Reservations/Steps/First/FirstStepView.swift+15−84 Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepView.xib → Hookah Tau/Controllers/Client/Reservations/Steps/First/FirstStepView.xib+21−56 Hookah Tau/Controllers/Client/Reservations/Steps/Common/TimePointView.swift → Hookah Tau/Controllers/Client/Reservations/Steps/First/TimePointView.swift+1−1 Hookah Tau/Controllers/Client/Reservations/Steps/Common/TimePointView.xib → Hookah Tau/Controllers/Client/Reservations/Steps/First/TimePointView.xib Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepReservationCoordinator.swift → Hookah Tau/Controllers/Client/Reservations/Steps/FirstStepReservationCoordinator.swift+4−17 Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepReservationViewController.swift → Hookah Tau/Controllers/Client/Reservations/Steps/FirstStepReservationViewController.swift+14−51 Hookah Tau/Controllers/Client/Reservations/Steps/Second/SecondStepView.swift+189 Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepView.xib → Hookah Tau/Controllers/Client/Reservations/Steps/Second/SecondStepView.xib+27−23 Hookah Tau/Controllers/Client/Reservations/Steps/SecondStepReservationCoordinator.swift+38 Hookah Tau/Controllers/Client/Reservations/Steps/change /ChangeReservationCoordinator.swift−36 Hookah Tau/Controllers/Client/Reservations/Steps/change /ChangeReservationViewController.swift−152 Hookah Tau/Controllers/Client/Tab bar/Client.storyboard+6−10 Hookah Tau/Controllers/Client/Tab bar/ClientTabbarController.swift+6−6 Hookah Tau/Controllers/Client/Tab bar/ClientTabbarCoordinator.swift+3−3 Hookah Tau/Controllers/Picker view/IntervalPickerView.swift−265 Hookah Tau/Controllers/Picker view/IntervalPickerView.xib−84 Hookah Tau/DB/DataStorage.swift−115 Hookah Tau/DB/TotalStorage.swift−124 Hookah Tau/Extensions+Date.swift+23−134 Hookah Tau/Extensions+String.swift−36 Hookah Tau/HFunc.swift−68 Hookah Tau/Info.plist+3−5 Hookah Tau/Models/AllReservations.swift+17−8 Hookah Tau/Models/Reservation.swift+3−69 Hookah Tau/Models/User.swift−27 Hookah Tau/Supporting Files/Assets.xcassets/1.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/1.imageset/place 1.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_1.imageset/1_1.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_1.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/1_2.imageset/1_2.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_2.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/1_3.imageset/1_3.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_3.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/1_4.imageset/1_4.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_4.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/1_5.imageset/1_5.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_5.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/1_6.imageset/1_6.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_6.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/1_7.imageset/1_7.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_7.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/1_8.imageset/1_8.pdf Hookah Tau/Supporting Files/Assets.xcassets/1_8.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/2.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/2.imageset/place 2.pdf Hookah Tau/Supporting Files/Assets.xcassets/2_2.imageset/2_2.pdf Hookah Tau/Supporting Files/Assets.xcassets/2_2.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/2_3.imageset/2_3.pdf Hookah Tau/Supporting Files/Assets.xcassets/2_3.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/2_4.imageset/2_4.pdf Hookah Tau/Supporting Files/Assets.xcassets/2_4.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/2_5.imageset/2_5.pdf Hookah Tau/Supporting Files/Assets.xcassets/2_5.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/2_6.imageset/2_6.pdf Hookah Tau/Supporting Files/Assets.xcassets/2_6.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/2_7.imageset/2_7.pdf Hookah Tau/Supporting Files/Assets.xcassets/2_7.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/2_8.imageset/2_8.pdf Hookah Tau/Supporting Files/Assets.xcassets/2_8.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/1024.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/120-1.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/120.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/152.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/167.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/180.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/20.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/29.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/40-1.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/40-2.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/40.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/58-1.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/58.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/60.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/76.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/80-1.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/80.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/87.png Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json+18−36 Hookah Tau/Supporting Files/Assets.xcassets/Group.imageset/Group.pdf Hookah Tau/Supporting Files/Assets.xcassets/Group.imageset/Contents.json → Hookah Tau/Supporting Files/Assets.xcassets/Map.imageset/Contents.json+1−1 Hookah Tau/Supporting Files/Assets.xcassets/Map.imageset/Map.pdf Hookah Tau/Supporting Files/Assets.xcassets/Tick.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/Tick.imageset/Path.pdf Hookah Tau/Supporting Files/Assets.xcassets/admin.imageset/Contents.json−12 Hookah Tau/Supporting Files/Assets.xcassets/admin.imageset/admin.pdf Hookah Tau/Supporting Files/Assets.xcassets/arrow.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/arrow.imageset/arrow.pdf Hookah Tau/Supporting Files/Assets.xcassets/blacklist.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/blacklist.imageset/blacklist.pdf Hookah Tau/Supporting Files/Assets.xcassets/handle_left.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/handle_left.imageset/handle.pdf Hookah Tau/Supporting Files/Assets.xcassets/map_1.imageset/Contents.json−3 Hookah Tau/Supporting Files/Assets.xcassets/map_2.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/map_2.imageset/place 2.pdf Hookah Tau/Supporting Files/Assets.xcassets/peoplee.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/peoplee.imageset/peoplee.pdf Hookah Tau/Supporting Files/Assets.xcassets/person.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/person.imageset/person.pdf Hookah Tau/Supporting Files/Assets.xcassets/phone.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/phone.imageset/Medium-M.pdf Hookah Tau/Supporting Files/Assets.xcassets/stack.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/stack.imageset/Light-S.pdf Hookah Tau/Supporting Files/Assets.xcassets/stack2.imageset/Contents.json−15 Hookah Tau/Supporting Files/Assets.xcassets/stack2.imageset/stack2.pdf Hookah Tau/Views/Phone/PhoneView.swift+2−1
DataStorage.swiftnew file+62
@@ -0,0 +1,62 @@
1+//
2+// DataStorage.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 01/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+/// Класс для хранения промежуточного состояния регистрации,
12+/// данных пользователя, ...
13+class DataStorage {
14+
15+ enum Keys: String {
16+ case name
17+ case phone
18+ case isAdmin
19+ case loggedIn
20+ }
21+
22+ private init() {}
23+
24+ static let standard = DataStorage()
25+
26+ /// Номер телефона для процесса регистрации/авторизации
27+ var phone: String?
28+ /// Имя введенное при регистрации
29+ var name: String?
30+
31+ /// Метод для сохранения данных пользователя в приложении,
32+ /// используется для сохранения объекта, полученного после успешной
33+ /// авторизации, регистрации
34+ func saveUserModel(_ user: User) {
35+ let name = user.name
36+ let phone = user.phoneNumber
37+ let isAdmin = user.isAdmin
38+
39+ UserDefaults.standard.setValue(name, forKey: Keys.name.rawValue)
40+ UserDefaults.standard.setValue(phone, forKey: Keys.phone.rawValue)
41+ UserDefaults.standard.setValue(isAdmin, forKey: Keys.isAdmin.rawValue)
42+ }
43+
44+ func getUserModel() -> User? {
45+ guard
46+ let name = UserDefaults.standard.string(forKey: Keys.name.rawValue),
47+ let phone = UserDefaults.standard.string(forKey: Keys.phone.rawValue)
48+ else { return nil }
49+
50+ let isAdmin = UserDefaults.standard.bool(forKey: Keys.isAdmin.rawValue)
51+
52+ return User(name: name, phoneNumber: phone, isAdmin: isAdmin)
53+ }
54+
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+ }
62+}
Hookah Tau.xcodeproj/project.pbxproj+29−483
@@ -9,32 +9,12 @@
99/* Begin PBXBuildFile section */
1010 12050569238048CE00801618 /* Extensions+Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12050568238048CE00801618 /* Extensions+Date.swift */; };
1111 1205056B2380588C00801618 /* Extenstions+IBDesignable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1205056A2380588C00801618 /* Extenstions+IBDesignable.swift */; };
12− 120BFC7723891925001EBE89 /* ThirdStepReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120BFC7623891925001EBE89 /* ThirdStepReservationViewController.swift */; };
13− 120BFC7923891942001EBE89 /* ThirdStepReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120BFC7823891942001EBE89 /* ThirdStepReservationCoordinator.swift */; };
14− 120BFC7C23891965001EBE89 /* ThirdStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120BFC7B23891965001EBE89 /* ThirdStepView.swift */; };
15− 120BFC7E23891975001EBE89 /* ThirdStepView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 120BFC7D23891975001EBE89 /* ThirdStepView.xib */; };
1612 12118B9C23682022006BAEE3 /* RegistrationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12118B9B23682022006BAEE3 /* RegistrationResolver.swift */; };
1713 12118B9E23682049006BAEE3 /* PhoneCodeResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12118B9D23682049006BAEE3 /* PhoneCodeResolver.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 */; };
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 */; };
2314 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12219CEE2353A63E0057DDEE /* ReservationsCoordinator.swift */; };
24− 12230AEA238FD8B3004A01E5 /* MapView2.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12230AE9238FD8B3004A01E5 /* MapView2.xib */; };
25− 12230AEC238FD8C5004A01E5 /* MapView2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12230AEB238FD8C5004A01E5 /* MapView2.swift */; };
26− 12230AF123900974004A01E5 /* TotalStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12230AF023900974004A01E5 /* TotalStorage.swift */; };
27− 12230AF423900BCB004A01E5 /* EstablishmentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12230AF323900BCB004A01E5 /* EstablishmentService.swift */; };
28− 12230AF723900D44004A01E5 /* EstablishmentResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12230AF623900D44004A01E5 /* EstablishmentResolver.swift */; };
29− 12230AFA23901029004A01E5 /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12230AF923901029004A01E5 /* DataStorage.swift */; };
30− 12230AFC239034D3004A01E5 /* SecondStepReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12230AFB239034D3004A01E5 /* SecondStepReservationViewController.swift */; };
3115 123615CF235510BC00D1122A /* ProfileView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 123615CE235510BC00D1122A /* ProfileView.xib */; };
3216 123615D12355141600D1122A /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123615D02355141600D1122A /* ProfileView.swift */; };
3317 12387337234BB98700D1F1AB /* CodeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12387336234BB98700D1F1AB /* CodeView.xib */; };
34− 123D25F0239E3E11002FA32B /* AdminAddressCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123D25EF239E3E11002FA32B /* AdminAddressCoordinator.swift */; };
35− 123D25F2239E3E44002FA32B /* ClientsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123D25F1239E3E44002FA32B /* ClientsCoordinator.swift */; };
36− 123D25F4239E3FF5002FA32B /* ClientsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123D25F3239E3FF5002FA32B /* ClientsViewController.swift */; };
37− 123D25F7239E5839002FA32B /* ClientTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123D25F6239E5839002FA32B /* ClientTableViewCell.swift */; };
3818 1246B717235CD186004CBFA1 /* NoReservationsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1246B716235CD186004CBFA1 /* NoReservationsView.xib */; };
3919 1246B719235CD3AD004CBFA1 /* NoReservationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1246B718235CD3AD004CBFA1 /* NoReservationsView.swift */; };
4020 1246B71C235CDF3A004CBFA1 /* ReservationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1246B71B235CDF3A004CBFA1 /* ReservationCell.swift */; };
@@ -43,10 +23,6 @@
4323 124D007C23721FD400AE76B9 /* Reservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007B23721FD400AE76B9 /* Reservation.swift */; };
4424 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007E237222B200AE76B9 /* ReservationsResolver.swift */; };
4525 124D0081237222C900AE76B9 /* ReservationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D0080237222C900AE76B9 /* ReservationsService.swift */; };
46− 1252D9E523CDCDB300446B6F /* ACreateReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1252D9E423CDCDB300446B6F /* ACreateReservationResolver.swift */; };
47− 125AE51D2395583E00F847BD /* ChangeReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */; };
48− 125AE51F2395585300F847BD /* ChangeReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */; };
49− 125AE5212395753400F847BD /* HFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE5202395753400F847BD /* HFunc.swift */; };
5026 12838EA9236764A600CEF108 /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EA8236764A600CEF108 /* APIClient.swift */; };
5127 12838EAC2367689600CEF108 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 12838EAB2367689600CEF108 /* Alamofire */; };
5228 12838EAE2367701300CEF108 /* AuthorizationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EAD2367701300CEF108 /* AuthorizationService.swift */; };
@@ -55,33 +31,12 @@
5531 12838EB4236779C700CEF108 /* ApiResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB3236779C700CEF108 /* ApiResolver.swift */; };
5632 12838EB623677FB900CEF108 /* ApiRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EB523677FB900CEF108 /* ApiRequest.swift */; };
5733 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 */; };
6134 12A075F72373535C00D749BB /* FirstStepReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A075F62373535C00D749BB /* FirstStepReservationViewController.swift */; };
6235 12A075F9237353F500D749BB /* MapView1.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12A075F8237353F500D749BB /* MapView1.xib */; };
6336 12A075FB2373561A00D749BB /* Reservation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12A075FA2373561A00D749BB /* Reservation.storyboard */; };
6437 12A075FD237357E900D749BB /* FirstStepReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A075FC237357E900D749BB /* FirstStepReservationCoordinator.swift */; };
6538 12A075FF237358F200D749BB /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A075FE237358F200D749BB /* MapView.swift */; };
6639 12A07601237359BB00D749BB /* MapView1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A07600237359BB00D749BB /* MapView1.swift */; };
67− 12B3A79823ABADB9009E2FA6 /* AdminReservationView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12B3A79723ABADB9009E2FA6 /* AdminReservationView.xib */; };
68− 12B3A79A23ABB4E2009E2FA6 /* IntervalPickerView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12B3A79923ABB4E2009E2FA6 /* IntervalPickerView.xib */; };
69− 12B3A79C23ABB8ED009E2FA6 /* IntervalPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A79B23ABB8ED009E2FA6 /* IntervalPickerView.swift */; };
70− 12B3A79F23ABCA21009E2FA6 /* AdminReservationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A79E23ABCA21009E2FA6 /* AdminReservationView.swift */; };
71− 12B3A7A323ABD594009E2FA6 /* AdminReservationsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7A223ABD594009E2FA6 /* AdminReservationsController.swift */; };
72− 12B3A7A523ABDA25009E2FA6 /* AdminReservationsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7A423ABDA25009E2FA6 /* AdminReservationsCoordinator.swift */; };
73− 12B3A7A823ABDDB1009E2FA6 /* AdminReservationCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7A723ABDDB1009E2FA6 /* AdminReservationCellView.swift */; };
74− 12B3A7AA23ABDDC1009E2FA6 /* AdminReservations.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12B3A7A923ABDDC1009E2FA6 /* AdminReservations.storyboard */; };
75− 12B3A7AD23ABEABF009E2FA6 /* AReservationsResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7AC23ABEABF009E2FA6 /* AReservationsResolver.swift */; };
76− 12B3A7AF23AC1872009E2FA6 /* AdminNoReservationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7AE23AC1872009E2FA6 /* AdminNoReservationsView.swift */; };
77− 12B3A7B123AC1885009E2FA6 /* AdminNoReservationsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12B3A7B023AC1885009E2FA6 /* AdminNoReservationsView.xib */; };
78− 12B3A7B423AC1D09009E2FA6 /* AdminReservationCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12B3A7B323AC1D09009E2FA6 /* AdminReservationCellView.xib */; };
79− 12B3A7B923ACCD83009E2FA6 /* AddOtherAdminResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7B823ACCD83009E2FA6 /* AddOtherAdminResolver.swift */; };
80− 12B3A7BC23ACFD75009E2FA6 /* ReservationsAroundResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7BB23ACFD75009E2FA6 /* ReservationsAroundResolver.swift */; };
81− 12B3A7BE23AD0049009E2FA6 /* AdminReservationEditingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7BD23AD0048009E2FA6 /* AdminReservationEditingViewController.swift */; };
82− 12B3A7C023AD0749009E2FA6 /* AdminReservationEditingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7BF23AD0749009E2FA6 /* AdminReservationEditingCoordinator.swift */; };
83− 12B3A7C423AD2FCD009E2FA6 /* AChangeReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B3A7C323AD2FCD009E2FA6 /* AChangeReservationResolver.swift */; };
84− 12B4447C238EF25C000B6B16 /* CreateReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B4447B238EF25C000B6B16 /* CreateReservationResolver.swift */; };
8540 12B6A60F235B857A00898B31 /* ProfileChangeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B6A60E235B857A00898B31 /* ProfileChangeCoordinator.swift */; };
8641 12B6A611235B8EC500898B31 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B6A610235B8EC500898B31 /* User.swift */; };
8742 12B6A613235B9B4300898B31 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B6A612235B9B4300898B31 /* BaseViewController.swift */; };
@@ -91,26 +46,13 @@
9146 12BD95B2237EC22B009614D8 /* FirstStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BD95B1237EC22B009614D8 /* FirstStepView.swift */; };
9247 12BD95B6237ED8AC009614D8 /* TimePointView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12BD95B5237ED8AB009614D8 /* TimePointView.xib */; };
9348 12BD95B8237EDB01009614D8 /* TimePointView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BD95B7237EDB01009614D8 /* TimePointView.swift */; };
94− 12BE4B332399A52E00FC974B /* AdminTabbarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BE4B322399A52E00FC974B /* AdminTabbarCoordinator.swift */; };
95− 12BE4B352399A60A00FC974B /* AdminTabbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BE4B342399A60A00FC974B /* AdminTabbarController.swift */; };
96− 12BE4B372399A98200FC974B /* Admin.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12BE4B362399A98200FC974B /* Admin.storyboard */; };
97− 12C0B4BB239E5A3A00562BA3 /* ClientList.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12C0B4BA239E5A3A00562BA3 /* ClientList.storyboard */; };
9849 12C72EDF23537D1B00AD7004 /* ProfileCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C72EDE23537D1B00AD7004 /* ProfileCoordinator.swift */; };
9950 12C72EE1235380D400AD7004 /* ProfileClientViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C72EE0235380D400AD7004 /* ProfileClientViewController.swift */; };
10051 12C72EE3235380EB00AD7004 /* ReservationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C72EE2235380EB00AD7004 /* ReservationsViewController.swift */; };
10152 12D8FA2D237F003800305F57 /* DateView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12D8FA2C237F003800305F57 /* DateView.xib */; };
10253 12D8FA2F237F00E200305F57 /* DateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D8FA2E237F00E200305F57 /* DateView.swift */; };
10354 12D8FA31237F08C700305F57 /* AllReservations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D8FA30237F08C700305F57 /* AllReservations.swift */; };
104− 12D928AF23C47DCF0051724D /* ADeleteReservationResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D928AE23C47DCF0051724D /* ADeleteReservationResolver.swift */; };
105− 12D928B123C486380051724D /* BaseTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D928B023C486380051724D /* BaseTableViewController.swift */; };
106− 12D928B323C7464B0051724D /* BlocklistPutResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D928B223C7464B0051724D /* BlocklistPutResolver.swift */; };
10755 12DBEEB223539F2100AF1BB6 /* Client.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12DBEEB123539F2100AF1BB6 /* Client.storyboard */; };
108− 12E35071239FA8CA004BB188 /* Extensions+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E35070239FA8CA004BB188 /* Extensions+String.swift */; };
109− 12E35074239FAF52004BB188 /* ClientsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E35073239FAF52004BB188 /* ClientsService.swift */; };
110− 12E35078239FAFA4004BB188 /* ClientsListResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E35077239FAFA4004BB188 /* ClientsListResolver.swift */; };
111− 12E3507B239FCFB2004BB188 /* ProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E3507A239FCFB2004BB188 /* ProfileTableViewController.swift */; };
112− 12E3507D239FD1F3004BB188 /* ClientReservationsResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E3507C239FD1F3004BB188 /* ClientReservationsResolver.swift */; };
113− 12E3507F239FDFC2004BB188 /* ClientProfileCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E3507E239FDFC2004BB188 /* ClientProfileCoordinator.swift */; };
11456 12EA99462362B674005D9FE9 /* AddressCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EA99452362B674005D9FE9 /* AddressCoordinator.swift */; };
11557 12EA99482362B684005D9FE9 /* AddresViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EA99472362B684005D9FE9 /* AddresViewController.swift */; };
11658 12EA994C2362F8EF005D9FE9 /* AddressView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12EA994B2362F8EF005D9FE9 /* AddressView.xib */; };
@@ -118,12 +60,13 @@
11860 12EB698123661CB300E4D1CE /* AddressCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EB698023661CB300E4D1CE /* AddressCell.swift */; };
11961 12EE4A76234BB8FE005B4D1A /* CodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EE4A75234BB8FE005B4D1A /* CodeView.swift */; };
12062 12F73B022357AD7B007D4476 /* ProfileChangeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12F73B012357AD7B007D4476 /* ProfileChangeViewController.swift */; };
63+ 12F9652723868DA300FCA696 /* SecondStepReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12F9652623868DA300FCA696 /* SecondStepReservationViewController.swift */; };
12164 12F9652A23868E6000FCA696 /* SecondStepView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12F9652923868E6000FCA696 /* SecondStepView.xib */; };
12265 12F9652C23868E7200FCA696 /* SecondStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12F9652B23868E7200FCA696 /* SecondStepView.swift */; };
12366 12F9652E23869F3100FCA696 /* SecondStepReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12F9652D23869F3100FCA696 /* SecondStepReservationCoordinator.swift */; };
124− 12FC07B923C8D17600EDC55B /* DeleteOtherAdminResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12FC07B823C8D17600EDC55B /* DeleteOtherAdminResolver.swift */; };
12567 12FC40382382C93D00AB593B /* TableButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12FC40372382C93C00AB593B /* TableButtonStyle.swift */; };
12668 12FC403A2382CB6F00AB593B /* TableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12FC40392382CB6F00AB593B /* TableButton.swift */; };
69+ 12FE4042236B8B050012391E /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12FE4041236B8B050012391E /* DataStorage.swift */; };
12770 F30369B5233679EA00A8EA84 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F30369B4233679EA00A8EA84 /* LaunchScreen.storyboard */; };
12871 F30369BE2336924D00A8EA84 /* ClientTabbarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F30369BD2336924D00A8EA84 /* ClientTabbarCoordinator.swift */; };
12972 F30369C02336925800A8EA84 /* ClientTabbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F30369BF2336925800A8EA84 /* ClientTabbarController.swift */; };
@@ -174,32 +117,12 @@
174117/* Begin PBXFileReference section */
175118 12050568238048CE00801618 /* Extensions+Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extensions+Date.swift"; sourceTree = "<group>"; };
176119 1205056A2380588C00801618 /* Extenstions+IBDesignable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extenstions+IBDesignable.swift"; sourceTree = "<group>"; };
177− 120BFC7623891925001EBE89 /* ThirdStepReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdStepReservationViewController.swift; sourceTree = "<group>"; };
178− 120BFC7823891942001EBE89 /* ThirdStepReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdStepReservationCoordinator.swift; sourceTree = "<group>"; };
179− 120BFC7B23891965001EBE89 /* ThirdStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdStepView.swift; sourceTree = "<group>"; };
180− 120BFC7D23891975001EBE89 /* ThirdStepView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ThirdStepView.xib; sourceTree = "<group>"; };
181120 12118B9B23682022006BAEE3 /* RegistrationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationResolver.swift; sourceTree = "<group>"; };
182121 12118B9D23682049006BAEE3 /* PhoneCodeResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneCodeResolver.swift; sourceTree = "<group>"; };
183− 1212048B23914CFD00CAF162 /* DeleteReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteReservationResolver.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>"; };
188122 12219CEE2353A63E0057DDEE /* ReservationsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReservationsCoordinator.swift; sourceTree = "<group>"; };
189− 12230AE9238FD8B3004A01E5 /* MapView2.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapView2.xib; sourceTree = "<group>"; };
190− 12230AEB238FD8C5004A01E5 /* MapView2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView2.swift; sourceTree = "<group>"; };
191− 12230AF023900974004A01E5 /* TotalStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalStorage.swift; sourceTree = "<group>"; };
192− 12230AF323900BCB004A01E5 /* EstablishmentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EstablishmentService.swift; sourceTree = "<group>"; };
193− 12230AF623900D44004A01E5 /* EstablishmentResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EstablishmentResolver.swift; sourceTree = "<group>"; };
194− 12230AF923901029004A01E5 /* DataStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = "<group>"; };
195− 12230AFB239034D3004A01E5 /* SecondStepReservationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecondStepReservationViewController.swift; sourceTree = "<group>"; };
196123 123615CE235510BC00D1122A /* ProfileView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ProfileView.xib; sourceTree = "<group>"; };
197124 123615D02355141600D1122A /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = "<group>"; };
198125 12387336234BB98700D1F1AB /* CodeView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CodeView.xib; sourceTree = "<group>"; };
199− 123D25EF239E3E11002FA32B /* AdminAddressCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminAddressCoordinator.swift; sourceTree = "<group>"; };
200− 123D25F1239E3E44002FA32B /* ClientsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientsCoordinator.swift; sourceTree = "<group>"; };
201− 123D25F3239E3FF5002FA32B /* ClientsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientsViewController.swift; sourceTree = "<group>"; };
202− 123D25F6239E5839002FA32B /* ClientTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientTableViewCell.swift; sourceTree = "<group>"; };
203126 1246B716235CD186004CBFA1 /* NoReservationsView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NoReservationsView.xib; sourceTree = "<group>"; };
204127 1246B718235CD3AD004CBFA1 /* NoReservationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoReservationsView.swift; sourceTree = "<group>"; };
205128 1246B71B235CDF3A004CBFA1 /* ReservationCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationCell.swift; sourceTree = "<group>"; };
@@ -208,10 +131,6 @@
208131 124D007B23721FD400AE76B9 /* Reservation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reservation.swift; sourceTree = "<group>"; };
209132 124D007E237222B200AE76B9 /* ReservationsResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsResolver.swift; sourceTree = "<group>"; };
210133 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>"; };
212− 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationCoordinator.swift; sourceTree = "<group>"; };
213− 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationViewController.swift; sourceTree = "<group>"; };
214− 125AE5202395753400F847BD /* HFunc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HFunc.swift; sourceTree = "<group>"; };
215134 12838EA8236764A600CEF108 /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = "<group>"; };
216135 12838EAD2367701300CEF108 /* AuthorizationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorizationService.swift; sourceTree = "<group>"; };
217136 12838EAF236777D400CEF108 /* ServerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerError.swift; sourceTree = "<group>"; };
@@ -219,33 +138,12 @@
219138 12838EB3236779C700CEF108 /* ApiResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiResolver.swift; sourceTree = "<group>"; };
220139 12838EB523677FB900CEF108 /* ApiRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiRequest.swift; sourceTree = "<group>"; };
221140 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>"; };
225141 12A075F62373535C00D749BB /* FirstStepReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstStepReservationViewController.swift; sourceTree = "<group>"; };
226142 12A075F8237353F500D749BB /* MapView1.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapView1.xib; sourceTree = "<group>"; };
227143 12A075FA2373561A00D749BB /* Reservation.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Reservation.storyboard; sourceTree = "<group>"; };
228144 12A075FC237357E900D749BB /* FirstStepReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstStepReservationCoordinator.swift; sourceTree = "<group>"; };
229145 12A075FE237358F200D749BB /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = "<group>"; };
230146 12A07600237359BB00D749BB /* MapView1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView1.swift; sourceTree = "<group>"; };
231− 12B3A79723ABADB9009E2FA6 /* AdminReservationView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AdminReservationView.xib; sourceTree = "<group>"; };
232− 12B3A79923ABB4E2009E2FA6 /* IntervalPickerView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IntervalPickerView.xib; sourceTree = "<group>"; };
233− 12B3A79B23ABB8ED009E2FA6 /* IntervalPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntervalPickerView.swift; sourceTree = "<group>"; };
234− 12B3A79E23ABCA21009E2FA6 /* AdminReservationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminReservationView.swift; sourceTree = "<group>"; };
235− 12B3A7A223ABD594009E2FA6 /* AdminReservationsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminReservationsController.swift; sourceTree = "<group>"; };
236− 12B3A7A423ABDA25009E2FA6 /* AdminReservationsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminReservationsCoordinator.swift; sourceTree = "<group>"; };
237− 12B3A7A723ABDDB1009E2FA6 /* AdminReservationCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminReservationCellView.swift; sourceTree = "<group>"; };
238− 12B3A7A923ABDDC1009E2FA6 /* AdminReservations.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AdminReservations.storyboard; sourceTree = "<group>"; };
239− 12B3A7AC23ABEABF009E2FA6 /* AReservationsResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AReservationsResolver.swift; sourceTree = "<group>"; };
240− 12B3A7AE23AC1872009E2FA6 /* AdminNoReservationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminNoReservationsView.swift; sourceTree = "<group>"; };
241− 12B3A7B023AC1885009E2FA6 /* AdminNoReservationsView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AdminNoReservationsView.xib; sourceTree = "<group>"; };
242− 12B3A7B323AC1D09009E2FA6 /* AdminReservationCellView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AdminReservationCellView.xib; sourceTree = "<group>"; };
243− 12B3A7B823ACCD83009E2FA6 /* AddOtherAdminResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOtherAdminResolver.swift; sourceTree = "<group>"; };
244− 12B3A7BB23ACFD75009E2FA6 /* ReservationsAroundResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsAroundResolver.swift; sourceTree = "<group>"; };
245− 12B3A7BD23AD0048009E2FA6 /* AdminReservationEditingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminReservationEditingViewController.swift; sourceTree = "<group>"; };
246− 12B3A7BF23AD0749009E2FA6 /* AdminReservationEditingCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminReservationEditingCoordinator.swift; sourceTree = "<group>"; };
247− 12B3A7C323AD2FCD009E2FA6 /* AChangeReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AChangeReservationResolver.swift; sourceTree = "<group>"; };
248− 12B4447B238EF25C000B6B16 /* CreateReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateReservationResolver.swift; sourceTree = "<group>"; };
249147 12B6A60E235B857A00898B31 /* ProfileChangeCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileChangeCoordinator.swift; sourceTree = "<group>"; };
250148 12B6A610235B8EC500898B31 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
251149 12B6A612235B9B4300898B31 /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = "<group>"; };
@@ -255,26 +153,13 @@
255153 12BD95B1237EC22B009614D8 /* FirstStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstStepView.swift; sourceTree = "<group>"; };
256154 12BD95B5237ED8AB009614D8 /* TimePointView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TimePointView.xib; sourceTree = "<group>"; };
257155 12BD95B7237EDB01009614D8 /* TimePointView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimePointView.swift; sourceTree = "<group>"; };
258− 12BE4B322399A52E00FC974B /* AdminTabbarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminTabbarCoordinator.swift; sourceTree = "<group>"; };
259− 12BE4B342399A60A00FC974B /* AdminTabbarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminTabbarController.swift; sourceTree = "<group>"; };
260− 12BE4B362399A98200FC974B /* Admin.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Admin.storyboard; sourceTree = "<group>"; };
261− 12C0B4BA239E5A3A00562BA3 /* ClientList.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ClientList.storyboard; sourceTree = "<group>"; };
262156 12C72EDE23537D1B00AD7004 /* ProfileCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileCoordinator.swift; sourceTree = "<group>"; };
263157 12C72EE0235380D400AD7004 /* ProfileClientViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileClientViewController.swift; sourceTree = "<group>"; };
264158 12C72EE2235380EB00AD7004 /* ReservationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsViewController.swift; sourceTree = "<group>"; };
265159 12D8FA2C237F003800305F57 /* DateView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DateView.xib; sourceTree = "<group>"; };
266160 12D8FA2E237F00E200305F57 /* DateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateView.swift; sourceTree = "<group>"; };
267161 12D8FA30237F08C700305F57 /* AllReservations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllReservations.swift; sourceTree = "<group>"; };
268− 12D928AE23C47DCF0051724D /* ADeleteReservationResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADeleteReservationResolver.swift; sourceTree = "<group>"; };
269− 12D928B023C486380051724D /* BaseTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTableViewController.swift; sourceTree = "<group>"; };
270− 12D928B223C7464B0051724D /* BlocklistPutResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlocklistPutResolver.swift; sourceTree = "<group>"; };
271162 12DBEEB123539F2100AF1BB6 /* Client.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Client.storyboard; sourceTree = "<group>"; };
272− 12E35070239FA8CA004BB188 /* Extensions+String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extensions+String.swift"; sourceTree = "<group>"; };
273− 12E35073239FAF52004BB188 /* ClientsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientsService.swift; sourceTree = "<group>"; };
274− 12E35077239FAFA4004BB188 /* ClientsListResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientsListResolver.swift; sourceTree = "<group>"; };
275− 12E3507A239FCFB2004BB188 /* ProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTableViewController.swift; sourceTree = "<group>"; };
276− 12E3507C239FD1F3004BB188 /* ClientReservationsResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientReservationsResolver.swift; sourceTree = "<group>"; };
277− 12E3507E239FDFC2004BB188 /* ClientProfileCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientProfileCoordinator.swift; sourceTree = "<group>"; };
278163 12EA99452362B674005D9FE9 /* AddressCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressCoordinator.swift; sourceTree = "<group>"; };
279164 12EA99472362B684005D9FE9 /* AddresViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddresViewController.swift; sourceTree = "<group>"; };
280165 12EA994B2362F8EF005D9FE9 /* AddressView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AddressView.xib; sourceTree = "<group>"; };
@@ -282,12 +167,13 @@
282167 12EB698023661CB300E4D1CE /* AddressCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressCell.swift; sourceTree = "<group>"; };
283168 12EE4A75234BB8FE005B4D1A /* CodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeView.swift; sourceTree = "<group>"; };
284169 12F73B012357AD7B007D4476 /* ProfileChangeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileChangeViewController.swift; sourceTree = "<group>"; };
170+ 12F9652623868DA300FCA696 /* SecondStepReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SecondStepReservationViewController.swift; path = "Hookah Tau/Controllers/Client/Reservations/SecondStepReservationViewController.swift"; sourceTree = SOURCE_ROOT; };
285171 12F9652923868E6000FCA696 /* SecondStepView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SecondStepView.xib; sourceTree = "<group>"; };
286172 12F9652B23868E7200FCA696 /* SecondStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondStepView.swift; sourceTree = "<group>"; };
287173 12F9652D23869F3100FCA696 /* SecondStepReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondStepReservationCoordinator.swift; sourceTree = "<group>"; };
288− 12FC07B823C8D17600EDC55B /* DeleteOtherAdminResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteOtherAdminResolver.swift; sourceTree = "<group>"; };
289174 12FC40372382C93C00AB593B /* TableButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableButtonStyle.swift; sourceTree = "<group>"; };
290175 12FC40392382CB6F00AB593B /* TableButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableButton.swift; sourceTree = "<group>"; };
176+ 12FE4041236B8B050012391E /* DataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = SOURCE_ROOT; };
291177 F30369B4233679EA00A8EA84 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
292178 F30369BD2336924D00A8EA84 /* ClientTabbarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientTabbarCoordinator.swift; sourceTree = "<group>"; };
293179 F30369BF2336925800A8EA84 /* ClientTabbarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientTabbarController.swift; sourceTree = "<group>"; };
@@ -350,17 +236,6 @@
350236/* End PBXFrameworksBuildPhase section */
351237
352238/* Begin PBXGroup section */
353− 120BFC7A2389194B001EBE89 /* 3 */ = {
354− isa = PBXGroup;
355− children = (
356− 120BFC7623891925001EBE89 /* ThirdStepReservationViewController.swift */,
357− 120BFC7823891942001EBE89 /* ThirdStepReservationCoordinator.swift */,
358− 120BFC7B23891965001EBE89 /* ThirdStepView.swift */,
359− 120BFC7D23891975001EBE89 /* ThirdStepView.xib */,
360− );
361− path = 3;
362− sourceTree = "<group>";
363− };
364239 12118B9A2368187B006BAEE3 /* Authorization api */ = {
365240 isa = PBXGroup;
366241 children = (
@@ -406,86 +281,6 @@
406281 path = Reservations;
407282 sourceTree = "<group>";
408283 };
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− };
434− 12230AED238FD8D5004A01E5 /* 1 */ = {
435− isa = PBXGroup;
436− children = (
437− 12A075F8237353F500D749BB /* MapView1.xib */,
438− 12A07600237359BB00D749BB /* MapView1.swift */,
439− );
440− path = 1;
441− sourceTree = "<group>";
442− };
443− 12230AEE238FD8DE004A01E5 /* 2 */ = {
444− isa = PBXGroup;
445− children = (
446− 12230AE9238FD8B3004A01E5 /* MapView2.xib */,
447− 12230AEB238FD8C5004A01E5 /* MapView2.swift */,
448− );
449− path = 2;
450− sourceTree = "<group>";
451− };
452− 12230AEF239008F8004A01E5 /* Common */ = {
453− isa = PBXGroup;
454− children = (
455− 12BD95B7237EDB01009614D8 /* TimePointView.swift */,
456− 12BD95B5237ED8AB009614D8 /* TimePointView.xib */,
457− 12D8FA2E237F00E200305F57 /* DateView.swift */,
458− 12D8FA2C237F003800305F57 /* DateView.xib */,
459− );
460− path = Common;
461− sourceTree = "<group>";
462− };
463− 12230AF223900BB6004A01E5 /* Establishments api */ = {
464− isa = PBXGroup;
465− children = (
466− 12230AF323900BCB004A01E5 /* EstablishmentService.swift */,
467− 12230AF523900D32004A01E5 /* Resolvers */,
468− );
469− path = "Establishments api";
470− sourceTree = "<group>";
471− };
472− 12230AF523900D32004A01E5 /* Resolvers */ = {
473− isa = PBXGroup;
474− children = (
475− 12230AF623900D44004A01E5 /* EstablishmentResolver.swift */,
476− );
477− path = Resolvers;
478− sourceTree = "<group>";
479− };
480− 12230AF823901000004A01E5 /* DB */ = {
481− isa = PBXGroup;
482− children = (
483− 12230AF923901029004A01E5 /* DataStorage.swift */,
484− 12230AF023900974004A01E5 /* TotalStorage.swift */,
485− );
486− path = DB;
487− sourceTree = "<group>";
488− };
489284 123615D22355141D00D1122A /* Views */ = {
490285 isa = PBXGroup;
491286 children = (
@@ -497,46 +292,6 @@
497292 path = Views;
498293 sourceTree = "<group>";
499294 };
500− 123D25EC239E3D47002FA32B /* Profile */ = {
501− isa = PBXGroup;
502− children = (
503− );
504− path = Profile;
505− sourceTree = "<group>";
506− };
507− 123D25ED239E3D50002FA32B /* Reservations */ = {
508− isa = PBXGroup;
509− children = (
510− 129F162523CC836600EE13FC /* Making a reeservation */,
511− 12B3A79623ABAD9A009E2FA6 /* Views */,
512− 12B3A7C123AD0751009E2FA6 /* Editing */,
513− 12B3A7C223AD0762009E2FA6 /* List of reservations */,
514− 123D25EF239E3E11002FA32B /* AdminAddressCoordinator.swift */,
515− 12B3A7A923ABDDC1009E2FA6 /* AdminReservations.storyboard */,
516− );
517− path = Reservations;
518− sourceTree = "<group>";
519− };
520− 123D25EE239E3D61002FA32B /* Clients */ = {
521− isa = PBXGroup;
522− children = (
523− 12E35079239FCF91004BB188 /* Profile */,
524− 123D25F5239E57D6002FA32B /* Cells */,
525− 123D25F1239E3E44002FA32B /* ClientsCoordinator.swift */,
526− 123D25F3239E3FF5002FA32B /* ClientsViewController.swift */,
527− 12C0B4BA239E5A3A00562BA3 /* ClientList.storyboard */,
528− );
529− path = Clients;
530− sourceTree = "<group>";
531− };
532− 123D25F5239E57D6002FA32B /* Cells */ = {
533− isa = PBXGroup;
534− children = (
535− 123D25F6239E5839002FA32B /* ClientTableViewCell.swift */,
536− );
537− path = Cells;
538− sourceTree = "<group>";
539− };
540295 1246B71A235CD4C5004CBFA1 /* Views */ = {
541296 isa = PBXGroup;
542297 children = (
@@ -567,25 +322,11 @@
567322 124D00822372233000AE76B9 /* Resolvers */ = {
568323 isa = PBXGroup;
569324 children = (
570− 12B3A7AB23ABEAAB009E2FA6 /* Admin */,
571325 124D007E237222B200AE76B9 /* ReservationsResolver.swift */,
572− 12B4447B238EF25C000B6B16 /* CreateReservationResolver.swift */,
573− 1212048B23914CFD00CAF162 /* DeleteReservationResolver.swift */,
574− 1212048D23915A0A00CAF162 /* ChangeReservationResolver.swift */,
575− 12B3A7BB23ACFD75009E2FA6 /* ReservationsAroundResolver.swift */,
576326 );
577327 path = Resolvers;
578328 sourceTree = "<group>";
579329 };
580− 125AE51B2395582900F847BD /* change */ = {
581− isa = PBXGroup;
582− children = (
583− 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */,
584− 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */,
585− );
586− path = "change ";
587− sourceTree = "<group>";
588− };
589330 12838EB923679AEB00CEF108 /* API */ = {
590331 isa = PBXGroup;
591332 children = (
@@ -594,105 +335,18 @@
594335 12838EAF236777D400CEF108 /* ServerError.swift */,
595336 12838EB523677FB900CEF108 /* ApiRequest.swift */,
596337 12838EB72367834900CEF108 /* MyCodable.swift */,
597− 12E35072239FAF41004BB188 /* ClientsService */,
598− 12230AF223900BB6004A01E5 /* Establishments api */,
599338 124D007D2372229500AE76B9 /* Reservations api */,
600339 12118B9A2368187B006BAEE3 /* Authorization api */,
601340 );
602341 path = API;
603342 sourceTree = "<group>";
604343 };
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− };
622− 12B3A79623ABAD9A009E2FA6 /* Views */ = {
623− isa = PBXGroup;
624− children = (
625− 129F162823CC89EA00EE13FC /* Phone number */,
626− 12B3A7B223AC1A1F009E2FA6 /* No reserv */,
627− 12B3A79723ABADB9009E2FA6 /* AdminReservationView.xib */,
628− 12B3A79E23ABCA21009E2FA6 /* AdminReservationView.swift */,
629− );
630− path = Views;
631− sourceTree = "<group>";
632− };
633− 12B3A79D23ABB8F4009E2FA6 /* Picker view */ = {
634− isa = PBXGroup;
635− children = (
636− 12B3A79923ABB4E2009E2FA6 /* IntervalPickerView.xib */,
637− 12B3A79B23ABB8ED009E2FA6 /* IntervalPickerView.swift */,
638− );
639− path = "Picker view";
640− sourceTree = "<group>";
641− };
642− 12B3A7A623ABDD92009E2FA6 /* Cell */ = {
643− isa = PBXGroup;
644− children = (
645− 12B3A7A723ABDDB1009E2FA6 /* AdminReservationCellView.swift */,
646− 12B3A7B323AC1D09009E2FA6 /* AdminReservationCellView.xib */,
647− );
648− path = Cell;
649− sourceTree = "<group>";
650− };
651− 12B3A7AB23ABEAAB009E2FA6 /* Admin */ = {
652− isa = PBXGroup;
653− children = (
654− 12B3A7AC23ABEABF009E2FA6 /* AReservationsResolver.swift */,
655− 12B3A7C323AD2FCD009E2FA6 /* AChangeReservationResolver.swift */,
656− 12D928AE23C47DCF0051724D /* ADeleteReservationResolver.swift */,
657− 1252D9E423CDCDB300446B6F /* ACreateReservationResolver.swift */,
658− );
659− path = Admin;
660− sourceTree = "<group>";
661− };
662− 12B3A7B223AC1A1F009E2FA6 /* No reserv */ = {
663− isa = PBXGroup;
664− children = (
665− 12B3A7AE23AC1872009E2FA6 /* AdminNoReservationsView.swift */,
666− 12B3A7B023AC1885009E2FA6 /* AdminNoReservationsView.xib */,
667− );
668− path = "No reserv";
669− sourceTree = "<group>";
670− };
671− 12B3A7C123AD0751009E2FA6 /* Editing */ = {
672− isa = PBXGroup;
673− children = (
674− 12B3A7BF23AD0749009E2FA6 /* AdminReservationEditingCoordinator.swift */,
675− 12B3A7BD23AD0048009E2FA6 /* AdminReservationEditingViewController.swift */,
676− );
677− name = Editing;
678− sourceTree = "<group>";
679− };
680− 12B3A7C223AD0762009E2FA6 /* List of reservations */ = {
681− isa = PBXGroup;
682− children = (
683− 12B3A7A623ABDD92009E2FA6 /* Cell */,
684− 12B3A7A223ABD594009E2FA6 /* AdminReservationsController.swift */,
685− 12B3A7A423ABDA25009E2FA6 /* AdminReservationsCoordinator.swift */,
686− );
687− path = "List of reservations";
688− sourceTree = "<group>";
689− };
690344 12BD95AE237EBE52009614D8 /* Maps */ = {
691345 isa = PBXGroup;
692346 children = (
693347 12A075FE237358F200D749BB /* MapView.swift */,
694− 12230AED238FD8D5004A01E5 /* 1 */,
695− 12230AEE238FD8DE004A01E5 /* 2 */,
348+ 12A07600237359BB00D749BB /* MapView1.swift */,
349+ 12A075F8237353F500D749BB /* MapView1.xib */,
696350 );
697351 path = Maps;
698352 sourceTree = "<group>";
@@ -700,34 +354,27 @@
700354 12BD95B3237EC231009614D8 /* Steps */ = {
701355 isa = PBXGroup;
702356 children = (
703− 125AE51B2395582900F847BD /* change */,
704− 12230AEF239008F8004A01E5 /* Common */,
705− 12BD95B4237EC23A009614D8 /* 1 */,
706− 12F9652823868E4900FCA696 /* 2 */,
707− 120BFC7A2389194B001EBE89 /* 3 */,
708− );
709− path = Steps;
710− sourceTree = "<group>";
711− };
712− 12BD95B4237EC23A009614D8 /* 1 */ = {
713− isa = PBXGroup;
714− children = (
357+ 12F9652623868DA300FCA696 /* SecondStepReservationViewController.swift */,
358+ 12F9652D23869F3100FCA696 /* SecondStepReservationCoordinator.swift */,
715359 12A075F62373535C00D749BB /* FirstStepReservationViewController.swift */,
716360 12A075FC237357E900D749BB /* FirstStepReservationCoordinator.swift */,
717− 12BD95B1237EC22B009614D8 /* FirstStepView.swift */,
718− 12BD95AF237EBEDE009614D8 /* FirstStepView.xib */,
361+ 12F9652823868E4900FCA696 /* Second */,
362+ 12BD95B4237EC23A009614D8 /* First */,
719363 );
720− path = 1;
364+ path = Steps;
721365 sourceTree = "<group>";
722366 };
723− 12BE4B312399A51500FC974B /* Tab bar */ = {
367+ 12BD95B4237EC23A009614D8 /* First */ = {
724368 isa = PBXGroup;
725369 children = (
726− 12BE4B322399A52E00FC974B /* AdminTabbarCoordinator.swift */,
727− 12BE4B342399A60A00FC974B /* AdminTabbarController.swift */,
728− 12BE4B362399A98200FC974B /* Admin.storyboard */,
370+ 12BD95AF237EBEDE009614D8 /* FirstStepView.xib */,
371+ 12D8FA2C237F003800305F57 /* DateView.xib */,
372+ 12D8FA2E237F00E200305F57 /* DateView.swift */,
373+ 12BD95B5237ED8AB009614D8 /* TimePointView.xib */,
374+ 12BD95B7237EDB01009614D8 /* TimePointView.swift */,
375+ 12BD95B1237EC22B009614D8 /* FirstStepView.swift */,
729376 );
730− path = "Tab bar";
377+ path = First;
731378 sourceTree = "<group>";
732379 };
733380 12C72EDB235367CF00AD7004 /* Tab bar */ = {
@@ -740,37 +387,6 @@
740387 path = "Tab bar";
741388 sourceTree = "<group>";
742389 };
743− 12E35072239FAF41004BB188 /* ClientsService */ = {
744− isa = PBXGroup;
745− children = (
746− 12E35073239FAF52004BB188 /* ClientsService.swift */,
747− 12E35075239FAF8F004BB188 /* Resolvers */,
748− );
749− path = ClientsService;
750− sourceTree = "<group>";
751− };
752− 12E35075239FAF8F004BB188 /* Resolvers */ = {
753− isa = PBXGroup;
754− children = (
755− 12FC07B823C8D17600EDC55B /* DeleteOtherAdminResolver.swift */,
756− 12B3A7B823ACCD83009E2FA6 /* AddOtherAdminResolver.swift */,
757− 12E35077239FAFA4004BB188 /* ClientsListResolver.swift */,
758− 12E3507C239FD1F3004BB188 /* ClientReservationsResolver.swift */,
759− 12D928B223C7464B0051724D /* BlocklistPutResolver.swift */,
760− 1220A6F323CDB1AD00365E36 /* GetClientByPhoneNumberResolver.swift */,
761− );
762− path = Resolvers;
763− sourceTree = "<group>";
764− };
765− 12E35079239FCF91004BB188 /* Profile */ = {
766− isa = PBXGroup;
767− children = (
768− 12E3507A239FCFB2004BB188 /* ProfileTableViewController.swift */,
769− 12E3507E239FDFC2004BB188 /* ClientProfileCoordinator.swift */,
770− );
771− path = Profile;
772− sourceTree = "<group>";
773− };
774390 12EA99492362B9F5005D9FE9 /* Adress of reservation */ = {
775391 isa = PBXGroup;
776392 children = (
@@ -818,15 +434,13 @@
818434 path = Code;
819435 sourceTree = "<group>";
820436 };
821− 12F9652823868E4900FCA696 /* 2 */ = {
437+ 12F9652823868E4900FCA696 /* Second */ = {
822438 isa = PBXGroup;
823439 children = (
824− 12230AFB239034D3004A01E5 /* SecondStepReservationViewController.swift */,
825− 12F9652D23869F3100FCA696 /* SecondStepReservationCoordinator.swift */,
826− 12F9652B23868E7200FCA696 /* SecondStepView.swift */,
827440 12F9652923868E6000FCA696 /* SecondStepView.xib */,
441+ 12F9652B23868E7200FCA696 /* SecondStepView.swift */,
828442 );
829− path = 2;
443+ path = Second;
830444 sourceTree = "<group>";
831445 };
832446 F30369B623367B2300A8EA84 /* Supporting Files */ = {
@@ -844,8 +458,6 @@
844458 F3FC7DFC2315C4710080D851 /* BaseCoordinator.swift */,
845459 F3FC7DFA2315C25D0080D851 /* ApplicationCoordinator.swift */,
846460 12B6A612235B9B4300898B31 /* BaseViewController.swift */,
847− 12D928B023C486380051724D /* BaseTableViewController.swift */,
848− 12B3A79D23ABB8F4009E2FA6 /* Picker view */,
849461 F30369BB2336845F00A8EA84 /* Admin */,
850462 F30369BA2336845400A8EA84 /* Client */,
851463 F30369B82336842600A8EA84 /* Authentication */,
@@ -872,7 +484,6 @@
872484 F3DC5A04233E89D500B5E751 /* Button.swift */,
873485 12FC40372382C93C00AB593B /* TableButtonStyle.swift */,
874486 12FC40392382CB6F00AB593B /* TableButton.swift */,
875− 129F162F23CC8EF600EE13FC /* PhoneTextField.swift */,
876487 );
877488 path = Components;
878489 sourceTree = "<group>";
@@ -890,10 +501,6 @@
890501 F30369BB2336845F00A8EA84 /* Admin */ = {
891502 isa = PBXGroup;
892503 children = (
893− 123D25ED239E3D50002FA32B /* Reservations */,
894− 123D25EE239E3D61002FA32B /* Clients */,
895− 123D25EC239E3D47002FA32B /* Profile */,
896− 12BE4B312399A51500FC974B /* Tab bar */,
897504 );
898505 path = Admin;
899506 sourceTree = "<group>";
@@ -997,14 +604,12 @@
997604 F3FC7DCB2315BE610080D851 /* Hookah Tau */ = {
998605 isa = PBXGroup;
999606 children = (
1000− 12230AF823901000004A01E5 /* DB */,
607+ 12FE4041236B8B050012391E /* DataStorage.swift */,
1001608 F3FC7DCC2315BE610080D851 /* AppDelegate.swift */,
1002609 F3DC59FE233E893400B5E751 /* Extensions+UIFont.swift */,
1003610 F31E20C62348DDB900BEA215 /* Extensions+UIView.swift */,
1004611 12050568238048CE00801618 /* Extensions+Date.swift */,
1005612 1205056A2380588C00801618 /* Extenstions+IBDesignable.swift */,
1006− 12E35070239FA8CA004BB188 /* Extensions+String.swift */,
1007− 125AE5202395753400F847BD /* HFunc.swift */,
1008613 12838EB923679AEB00CEF108 /* API */,
1009614 F30369BC2336861100A8EA84 /* Models */,
1010615 F3199E59233FD7F700F3C17A /* Views */,
@@ -1145,19 +750,12 @@
1145750 buildActionMask = 2147483647;
1146751 files = (
1147752 F3199E5B233FE08200F3C17A /* PhoneView.xib in Resources */,
1148− 12B3A7AA23ABDDC1009E2FA6 /* AdminReservations.storyboard in Resources */,
1149− 12B3A7B423AC1D09009E2FA6 /* AdminReservationCellView.xib in Resources */,
1150− 12C0B4BB239E5A3A00562BA3 /* ClientList.storyboard in Resources */,
1151− 12BE4B372399A98200FC974B /* Admin.storyboard in Resources */,
1152753 12DBEEB223539F2100AF1BB6 /* Client.storyboard in Resources */,
1153754 12D8FA2D237F003800305F57 /* DateView.xib in Resources */,
1154− 12B3A79A23ABB4E2009E2FA6 /* IntervalPickerView.xib in Resources */,
1155755 12387337234BB98700D1F1AB /* CodeView.xib in Resources */,
1156756 12B6A615235BB36C00898B31 /* ChangeView.xib in Resources */,
1157757 F3851B2C2340A280009EE0B6 /* TitleTextView.xib in Resources */,
1158758 12F9652A23868E6000FCA696 /* SecondStepView.xib in Resources */,
1159− 120BFC7E23891975001EBE89 /* ThirdStepView.xib in Resources */,
1160− 12230AEA238FD8B3004A01E5 /* MapView2.xib in Resources */,
1161759 1246B71E235CDF8A004CBFA1 /* ReservationView.xib in Resources */,
1162760 12BD95B6237ED8AC009614D8 /* TimePointView.xib in Resources */,
1163761 12A075F9237353F500D749BB /* MapView1.xib in Resources */,
@@ -1165,8 +763,6 @@
1165763 12BD95B0237EBEDF009614D8 /* FirstStepView.xib in Resources */,
1166764 F30369B5233679EA00A8EA84 /* LaunchScreen.storyboard in Resources */,
1167765 1246B717235CD186004CBFA1 /* NoReservationsView.xib in Resources */,
1168− 12B3A7B123AC1885009E2FA6 /* AdminNoReservationsView.xib in Resources */,
1169− 12B3A79823ABADB9009E2FA6 /* AdminReservationView.xib in Resources */,
1170766 F3FC7DD42315BE630080D851 /* Assets.xcassets in Resources */,
1171767 12EA994C2362F8EF005D9FE9 /* AddressView.xib in Resources */,
1172768 F3EBE2452340FDA7000FEE1A /* NameTextView.xib in Resources */,
@@ -1197,119 +793,71 @@
1197793 files = (
1198794 12EA99482362B684005D9FE9 /* AddresViewController.swift in Sources */,
1199795 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */,
1200− 129F163023CC8EF600EE13FC /* PhoneTextField.swift in Sources */,
1201− 129F162C23CC8D2E00EE13FC /* AdminSecondStepReservationViewCoordinator.swift in Sources */,
1202− 12230AF723900D44004A01E5 /* EstablishmentResolver.swift in Sources */,
1203796 1246B719235CD3AD004CBFA1 /* NoReservationsView.swift in Sources */,
1204797 F3895F4A233D323700FA6A37 /* CodeCoordinator.swift in Sources */,
1205− 12B3A7B923ACCD83009E2FA6 /* AddOtherAdminResolver.swift in Sources */,
1206− 12E3507F239FDFC2004BB188 /* ClientProfileCoordinator.swift in Sources */,
1207− 12D928B323C7464B0051724D /* BlocklistPutResolver.swift in Sources */,
1208798 12838EB4236779C700CEF108 /* ApiResolver.swift in Sources */,
1209799 12838EA9236764A600CEF108 /* APIClient.swift in Sources */,
1210800 123615D12355141600D1122A /* ProfileView.swift in Sources */,
1211801 12F73B022357AD7B007D4476 /* ProfileChangeViewController.swift in Sources */,
1212802 F3851B2E2340A444009EE0B6 /* TitleTextView.swift in Sources */,
1213− 125AE51F2395585300F847BD /* ChangeReservationViewController.swift in Sources */,
1214803 12EA99462362B674005D9FE9 /* AddressCoordinator.swift in Sources */,
1215804 12B6A613235B9B4300898B31 /* BaseViewController.swift in Sources */,
1216− 12BE4B332399A52E00FC974B /* AdminTabbarCoordinator.swift in Sources */,
1217− 12230AFA23901029004A01E5 /* DataStorage.swift in Sources */,
1218− 12B3A7A823ABDDB1009E2FA6 /* AdminReservationCellView.swift in Sources */,
1219805 F3FC7DFF2315C8D70080D851 /* NameCoordinator.swift in Sources */,
1220− 123D25F7239E5839002FA32B /* ClientTableViewCell.swift in Sources */,
1221− 120BFC7C23891965001EBE89 /* ThirdStepView.swift in Sources */,
1222− 123D25F0239E3E11002FA32B /* AdminAddressCoordinator.swift in Sources */,
1223806 F3FC7DCF2315BE610080D851 /* NameViewController.swift in Sources */,
1224− 12B3A79F23ABCA21009E2FA6 /* AdminReservationView.swift in Sources */,
1225807 12838EB82367834900CEF108 /* MyCodable.swift in Sources */,
1226808 F3DC5A05233E89D500B5E751 /* Button.swift in Sources */,
1227809 F3FC7DFB2315C25D0080D851 /* ApplicationCoordinator.swift in Sources */,
1228− 12B3A7BE23AD0049009E2FA6 /* AdminReservationEditingViewController.swift in Sources */,
1229− 12BE4B352399A60A00FC974B /* AdminTabbarController.swift in Sources */,
1230810 12FC403A2382CB6F00AB593B /* TableButton.swift in Sources */,
1231− 12D928AF23C47DCF0051724D /* ADeleteReservationResolver.swift in Sources */,
1232811 12EB698123661CB300E4D1CE /* AddressCell.swift in Sources */,
1233812 F3895F48233D2EEA00FA6A37 /* CodeSmsViewController.swift in Sources */,
1234813 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */,
1235− 12230AF423900BCB004A01E5 /* EstablishmentService.swift in Sources */,
1236− 129F162723CC838200EE13FC /* AdminFirstStepReservationViewCoordinator.swift in Sources */,
1237814 12A07601237359BB00D749BB /* MapView1.swift in Sources */,
1238− 125AE5212395753400F847BD /* HFunc.swift in Sources */,
1239815 12BD95B8237EDB01009614D8 /* TimePointView.swift in Sources */,
1240816 12838EB2236779A000CEF108 /* AuthResolver.swift in Sources */,
817+ 12FE4042236B8B050012391E /* DataStorage.swift in Sources */,
1241818 12A075F72373535C00D749BB /* FirstStepReservationViewController.swift in Sources */,
1242− 12E35078239FAFA4004BB188 /* ClientsListResolver.swift in Sources */,
1243819 1246B71C235CDF3A004CBFA1 /* ReservationCell.swift in Sources */,
1244− 12E3507B239FCFB2004BB188 /* ProfileTableViewController.swift in Sources */,
1245− 1212048C23914CFD00CAF162 /* DeleteReservationResolver.swift in Sources */,
1246820 12A075FD237357E900D749BB /* FirstStepReservationCoordinator.swift in Sources */,
1247821 124D0081237222C900AE76B9 /* ReservationsService.swift in Sources */,
1248822 1246B720235CDF9E004CBFA1 /* ReservationView.swift in Sources */,
1249− 12B3A7A523ABDA25009E2FA6 /* AdminReservationsCoordinator.swift in Sources */,
1250− 123D25F4239E3FF5002FA32B /* ClientsViewController.swift in Sources */,
1251823 12050569238048CE00801618 /* Extensions+Date.swift in Sources */,
1252824 124D007C23721FD400AE76B9 /* Reservation.swift in Sources */,
1253825 12D8FA2F237F00E200305F57 /* DateView.swift in Sources */,
1254− 123D25F2239E3E44002FA32B /* ClientsCoordinator.swift in Sources */,
1255826 12F9652E23869F3100FCA696 /* SecondStepReservationCoordinator.swift in Sources */,
1256827 F3895F4E233D348B00FA6A37 /* PhoneCoordinator.swift in Sources */,
1257828 12B6A617235BB37D00898B31 /* ChangeView.swift in Sources */,
1258− 12230AEC238FD8C5004A01E5 /* MapView2.swift in Sources */,
1259− 12B3A7A323ABD594009E2FA6 /* AdminReservationsController.swift in Sources */,
1260829 F3FC7DCD2315BE610080D851 /* AppDelegate.swift in Sources */,
1261830 12838EB623677FB900CEF108 /* ApiRequest.swift in Sources */,
1262− 1220A6FA23CDBE7E00365E36 /* AdminFinalStepReservationCoordinator.swift in Sources */,
1263831 12118B9E23682049006BAEE3 /* PhoneCodeResolver.swift in Sources */,
1264832 F30369BE2336924D00A8EA84 /* ClientTabbarCoordinator.swift in Sources */,
1265833 F3FC7DFD2315C4710080D851 /* BaseCoordinator.swift in Sources */,
1266− 1220A6F723CDB64A00365E36 /* AdminSecondStepReservationViewController.swift in Sources */,
1267− 12E35071239FA8CA004BB188 /* Extensions+String.swift in Sources */,
1268− 12FC07B923C8D17600EDC55B /* DeleteOtherAdminResolver.swift in Sources */,
1269834 F3DC59FF233E893400B5E751 /* Extensions+UIFont.swift in Sources */,
1270835 F3895F53233D5EEB00FA6A37 /* BlackButtonStyle.swift in Sources */,
836+ 12F9652723868DA300FCA696 /* SecondStepReservationViewController.swift in Sources */,
1271837 12F9652C23868E7200FCA696 /* SecondStepView.swift in Sources */,
1272− 120BFC7923891942001EBE89 /* ThirdStepReservationCoordinator.swift in Sources */,
1273− 12B3A7BC23ACFD75009E2FA6 /* ReservationsAroundResolver.swift in Sources */,
1274838 12118B9C23682022006BAEE3 /* RegistrationResolver.swift in Sources */,
1275− 12B3A7C423AD2FCD009E2FA6 /* AChangeReservationResolver.swift in Sources */,
1276839 F30369C02336925800A8EA84 /* ClientTabbarController.swift in Sources */,
1277− 12B3A7C023AD0749009E2FA6 /* AdminReservationEditingCoordinator.swift in Sources */,
1278840 F31E20C72348DDB900BEA215 /* Extensions+UIView.swift in Sources */,
1279841 F3851B302340A513009EE0B6 /* RegistationViewModel.swift in Sources */,
1280− 12B3A7AF23AC1872009E2FA6 /* AdminNoReservationsView.swift in Sources */,
1281842 12838EAE2367701300CEF108 /* AuthorizationService.swift in Sources */,
1282843 12C72EDF23537D1B00AD7004 /* ProfileCoordinator.swift in Sources */,
1283− 12E3507D239FD1F3004BB188 /* ClientReservationsResolver.swift in Sources */,
1284844 12EA994E2362FCE8005D9FE9 /* AddressView.swift in Sources */,
1285− 1220A6F423CDB1AD00365E36 /* GetClientByPhoneNumberResolver.swift in Sources */,
1286845 F3895F4C233D347E00FA6A37 /* PhoneNumberViewController.swift in Sources */,
1287846 12EE4A76234BB8FE005B4D1A /* CodeView.swift in Sources */,
1288− 12230AF123900974004A01E5 /* TotalStorage.swift in Sources */,
1289− 1252D9E523CDCDB300446B6F /* ACreateReservationResolver.swift in Sources */,
1290847 12BD95B2237EC22B009614D8 /* FirstStepView.swift in Sources */,
1291848 F3EBE2472340FE87000FEE1A /* NameTextView.swift in Sources */,
1292− 120BFC7723891925001EBE89 /* ThirdStepReservationViewController.swift in Sources */,
1293849 F3DC5A01233E896300B5E751 /* ButtonStyle.swift in Sources */,
1294850 12A075FF237358F200D749BB /* MapView.swift in Sources */,
1295851 1205056B2380588C00801618 /* Extenstions+IBDesignable.swift in Sources */,
1296− 12E35074239FAF52004BB188 /* ClientsService.swift in Sources */,
1297852 12C72EE1235380D400AD7004 /* ProfileClientViewController.swift in Sources */,
1298853 F31E20C92348E0F300BEA215 /* AuthorizationViewController.swift in Sources */,
1299− 1212048E23915A0A00CAF162 /* ChangeReservationResolver.swift in Sources */,
1300− 12230AFC239034D3004A01E5 /* SecondStepReservationViewController.swift in Sources */,
1301854 F3851B2923409F8A009EE0B6 /* PhoneView.swift in Sources */,
1302− 12D928B123C486380051724D /* BaseTableViewController.swift in Sources */,
1303855 12C72EE3235380EB00AD7004 /* ReservationsViewController.swift in Sources */,
1304856 12B6A611235B8EC500898B31 /* User.swift in Sources */,
1305− 12B3A7AD23ABEABF009E2FA6 /* AReservationsResolver.swift in Sources */,
1306− 12B4447C238EF25C000B6B16 /* CreateReservationResolver.swift in Sources */,
1307857 12B6A60F235B857A00898B31 /* ProfileChangeCoordinator.swift in Sources */,
1308− 12B3A79C23ABB8ED009E2FA6 /* IntervalPickerView.swift in Sources */,
1309858 12FC40382382C93D00AB593B /* TableButtonStyle.swift in Sources */,
1310859 12D8FA31237F08C700305F57 /* AllReservations.swift in Sources */,
1311860 12838EB0236777D400CEF108 /* ServerError.swift in Sources */,
1312− 125AE51D2395583E00F847BD /* ChangeReservationCoordinator.swift in Sources */,
1313861 );
1314862 runOnlyForDeploymentPostprocessing = 0;
1315863 };
@@ -1466,15 +1014,14 @@
14661014 buildSettings = {
14671015 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
14681016 CODE_SIGN_STYLE = Automatic;
1469− CURRENT_PROJECT_VERSION = 5;
1470− DEVELOPMENT_TEAM = 23S94LRHD8;
1017+ DEVELOPMENT_TEAM = 9Z6LFGKA9G;
14711018 INFOPLIST_FILE = "Hookah Tau/Info.plist";
14721019 IPHONEOS_DEPLOYMENT_TARGET = 11.0;
14731020 LD_RUNPATH_SEARCH_PATHS = (
14741021 "$(inherited)",
14751022 "@executable_path/Frameworks",
14761023 );
1477− PRODUCT_BUNDLE_IDENTIFIER = "com.hookahtau.Hookah-Tau1";
1024+ PRODUCT_BUNDLE_IDENTIFIER = "com.hookahtau.Hookah-Tau";
14781025 PRODUCT_NAME = "$(TARGET_NAME)";
14791026 SWIFT_VERSION = 5.0;
14801027 TARGETED_DEVICE_FAMILY = "1,2";
@@ -1486,15 +1033,14 @@
14861033 buildSettings = {
14871034 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
14881035 CODE_SIGN_STYLE = Automatic;
1489− CURRENT_PROJECT_VERSION = 5;
1490− DEVELOPMENT_TEAM = 23S94LRHD8;
1036+ DEVELOPMENT_TEAM = 9Z6LFGKA9G;
14911037 INFOPLIST_FILE = "Hookah Tau/Info.plist";
14921038 IPHONEOS_DEPLOYMENT_TARGET = 11.0;
14931039 LD_RUNPATH_SEARCH_PATHS = (
14941040 "$(inherited)",
14951041 "@executable_path/Frameworks",
14961042 );
1497− PRODUCT_BUNDLE_IDENTIFIER = "com.hookahtau.Hookah-Tau1";
1043+ PRODUCT_BUNDLE_IDENTIFIER = "com.hookahtau.Hookah-Tau";
14981044 PRODUCT_NAME = "$(TARGET_NAME)";
14991045 SWIFT_VERSION = 5.0;
15001046 TARGETED_DEVICE_FAMILY = "1,2";
Hookah Tau/API/APIClient.swift−3
@@ -48,11 +48,8 @@ class APIClient {
4848 let json = String(data: data, encoding: String.Encoding.utf8)
4949 print("Failure Response: \(String(describing: json))")
5050 }
51− case 404:
52− return GeneralError.notFound
5351 case 422:
5452 if let data = response.data, let error = SE.fromJSONToSelf(data: data) {
55− print(error)
5653 return GeneralError.serverError(error)
5754 }
5855
Hookah Tau/API/Authorization api/AuthorizationService.swift+1−7
@@ -39,7 +39,6 @@ class AuthorizationService {
3939 }
4040
4141 completion(.success(decodedData.isUserRegistered))
42− return
4342 }
4443 }
4544 }
@@ -66,7 +65,6 @@ class AuthorizationService {
6665
6766 self.setCookies(response: response)
6867 completion(.success(decodedData))
69− return
7068 }
7169 }
7270 }
@@ -82,9 +80,7 @@ class AuthorizationService {
8280 apiClient.load(request: request.request) { result in
8381 switch result {
8482 case .failure(let err):
85− print(err)
8683 completion(.failure(err))
87− return
8884 case .success(let response):
8985 guard
9086 let unwrappedData = response.data,
@@ -96,7 +92,6 @@ class AuthorizationService {
9692
9793 self.setCookies(response: response)
9894 completion(.success(decodedData))
99− return
10095 }
10196 }
10297 }
@@ -109,7 +104,6 @@ class AuthorizationService {
109104 return
110105 }
111106 let cookies = HTTPCookie.cookies(withResponseHeaderFields: fieldss, for: url)
112− HTTPCookieStorage.shared.setCookies(cookies, for: url, mainDocumentURL: nil)
113− DataStorage.standard.setCookies(cookies, forURL: url)
107+ HTTPCookieStorage.shared.setCookie(cookies[0])
114108 }
115109}
Hookah Tau/API/ClientsService/ClientsService.swiftdeleted−129
@@ -1,129 +0,0 @@
1−//
2−// ClientsService.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 10/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−class ClientsService {
12− private var apiClient: APIClient
13−
14− init(apiClient: APIClient) {
15− self.apiClient = apiClient
16− }
17−
18− func loadClientsList(completion: @escaping ((Result<[Client], GeneralError>) -> Void)) {
19− let resolver = ClientsListResolver<ClientsResponce>()
20− let request = ApiRequest(resolver: resolver, httpMethod: .get)
21−
22− apiClient.load(request: request.request) { (res) in
23− switch res {
24− case .success(let responce):
25− guard
26− let d = responce.data,
27− let decodedData = resolver.targetClass().fromJSONToSelf(data: d)
28− else {
29− completion(.failure(GeneralError.decodeError))
30− return }
31−
32− completion(.success(decodedData.clients))
33− return
34− case .failure(let err):
35− completion(.failure(err))
36− return
37− }
38− }
39− }
40−
41− func loadReservationsForUser(withUUID uuid: String,
42− completion: @escaping ((Result<[Reservation], GeneralError>) -> Void)) {
43− let resolver = ClientReservationsResolver<UserReservationsResponce>(userId: uuid)
44− let request = ApiRequest(resolver: resolver, httpMethod: .get)
45−
46− apiClient.load(request: request.request) { (res) in
47− switch res {
48− case .failure(let err):
49− completion(.failure(err))
50− return
51− case .success(let responce):
52− guard
53− let d = responce.data,
54− let decData = resolver.targetClass().fromJSONToSelf(data: d)
55− else {
56− completion(.failure(GeneralError.decodeError))
57− return
58− }
59−
60− completion(.success(decData.reservations))
61− return
62− }
63− }
64−
65− }
66−
67− /// Метод для удаления или добавления пользователя в чс
68− func changeBlockList(whatToDo: CrudMethod, phone: String, completion: @escaping ((Bool) -> Void)) {
69− let resolver = BlocklistPutResolver(blockList: [phone])
70− let request = ApiRequest(resolver: resolver, httpMethod: whatToDo)
71−
72− apiClient.load(request: request.request) { (res) in
73− switch res {
74− case .failure:
75− completion(false)
76− return
77− case .success:
78− completion(true)
79− return
80− }
81− }
82− }
83−
84− /// Метод для изменения статуса админки
85− func changeAdmin(crud: CrudMethod, data: String, completion: @escaping ((Bool) -> Void)) {
86− var resolver: ApiResolver!
87− if crud == .put {
88− resolver = AddOtherAdminResolver(phone: data)
89− } else {
90− resolver = DeleteOtherAdminResolver(uuid: data)
91− }
92−
93− let request = ApiRequest(resolver: resolver, httpMethod: crud)
94−
95− apiClient.load(request: request.request) { result in
96− switch result {
97− case .failure:
98− completion(false)
99− return
100− case .success:
101− completion(true)
102− return
103− }
104− }
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− }
129−}
Hookah Tau/API/ClientsService/Resolvers/AddOtherAdminResolver.swiftdeleted−35
@@ -1,35 +0,0 @@
1−//
2−// AddOtherAdminResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 20/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−/// `PUT /admin/other`
12−class AddOtherAdminResolver: ApiResolver {
13− /// Request struct
14− struct Request: MyCodable {
15− var newAdmin: String
16− }
17−
18− var name: String {
19− return "/other"
20− }
21−
22− var groupName: String? {
23− return "/admin"
24− }
25−
26− var phone: String
27−
28− init(phone: String) {
29− self.phone = phone
30− }
31−
32− func parameters() -> MyCodable? {
33− return Request(newAdmin: phone)
34− }
35−}
Hookah Tau/API/ClientsService/Resolvers/BlocklistPutResolver.swiftdeleted−33
@@ -1,33 +0,0 @@
1−//
2−// BlocklistPutResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 09/01/2020.
6−// Copyright © 2020 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−struct RequestBlocklist: MyCodable {
12− var blockList: [String]
13−}
14−
15−class BlocklistPutResolver: ApiResolver {
16− var name: String {
17− return "/blocklist"
18− }
19−
20− var groupName: String? {
21− return "/admin"
22− }
23−
24− var blockList: [String]
25−
26− init(blockList: [String]) {
27− self.blockList = blockList
28− }
29−
30− func parameters() -> MyCodable? {
31− return RequestBlocklist(blockList: blockList)
32− }
33−}
Hookah Tau/API/ClientsService/Resolvers/ClientReservationsResolver.swiftdeleted−34
@@ -1,34 +0,0 @@
1−//
2−// ClientReservations.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 10/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−struct UserReservationsResponce: MyCodable {
12− var reservations: [Reservation]
13−}
14−
15−class ClientReservationsResolver<Responce: MyCodable>: ApiResolver {
16−
17− var name: String {
18− return "/clients/\(userId)/reservations"
19− }
20−
21− var groupName: String? {
22− return "/admin"
23− }
24−
25− var userId: String
26−
27− init(userId: String) {
28− self.userId = userId
29− }
30−
31− func targetClass() -> Responce.Type {
32− return Responce.self
33− }
34−}
Hookah Tau/API/ClientsService/Resolvers/ClientsListResolver.swiftdeleted−28
@@ -1,28 +0,0 @@
1−//
2−// ClientsListResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 10/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−struct ClientsResponce: MyCodable {
12− var clients: [Client]
13−}
14−
15−class ClientsListResolver<Responce: MyCodable>: ApiResolver {
16−
17− var name: String {
18− return "/clients"
19− }
20−
21− var groupName: String? {
22− return "/admin"
23− }
24−
25− func targetClass() -> Responce.Type {
26− return Responce.self
27− }
28−}
Hookah Tau/API/ClientsService/Resolvers/DeleteOtherAdminResolver.swiftdeleted−35
@@ -1,35 +0,0 @@
1−//
2−// DeleteOtherAdminResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 10/01/2020.
6−// Copyright © 2020 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−
12−class DeleteOtherAdminResolver: ApiResolver {
13−
14− var name: String {
15− return "/other"
16− }
17−
18− var groupName: String? {
19− return "/admin"
20− }
21−
22− struct Request: MyCodable {
23− let badAdmin: String
24− }
25−
26− let uuid: String
27−
28− init(uuid: String) {
29− self.uuid = uuid
30− }
31−
32− func parameters() -> MyCodable? {
33− return Request(badAdmin: self.uuid)
34− }
35−}
Hookah Tau/API/ClientsService/Resolvers/GetClientByPhoneNumberResolver.swiftdeleted−35
@@ -1,35 +0,0 @@
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/Establishments api/EstablishmentService.swiftdeleted−39
@@ -1,39 +0,0 @@
1−//
2−// EstablishmentService.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 28/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−class EstablishmentSevice {
12− private var apiClient: APIClient
13−
14− init(apiClient: APIClient) {
15− self.apiClient = apiClient
16− }
17−
18− func loadAdmins(completion: @escaping ((Result<[Int: String], GeneralError>) -> Void)) {
19− let resolver = EstablishmentResolver<[Int: String]>()
20− let request = ApiRequest(resolver: resolver, httpMethod: .get)
21−
22− apiClient.load(request: request.request) { result in
23− switch result {
24− case .failure(let err):
25− completion(.failure(err))
26− case .success(let response):
27− guard
28− let data = response.data,
29− let decondedData = try? JSONDecoder().decode([Int: String].self, from: data)
30− else {
31− completion(.failure(.decodeError))
32− return
33− }
34−
35− completion(.success(decondedData))
36− }
37− }
38− }
39−}
Hookah Tau/API/Establishments api/Resolvers/EstablishmentResolver.swiftdeleted−24
@@ -1,24 +0,0 @@
1−//
2−// EstablishmentReslver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 28/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−
12−class EstablishmentResolver<Response>: ApiResolver {
13− var name: String {
14− return "/admins"
15− }
16−
17− var groupName: String? {
18− return "/establishments"
19− }
20−
21− func targetClass() -> Response.Type {
22− return Response.self
23− }
24−}
Hookah Tau/API/Reservations api/ReservationsService.swift+5−158
@@ -40,60 +40,17 @@ class ReservationsService {
4040 }
4141 }
4242
43− func deleteReservation(isAdmin: Bool, uuid: String, completion: @escaping ((Bool) -> Void)) {
44− var resolver: ApiResolver!
45− if isAdmin {
46− resolver = ADeleteReservationResolver(uuid: uuid)
47− } else {
48− resolver = DeleteReservationResolver(uuid: uuid)
49− }
50−
51− let request = ApiRequest(resolver: resolver, httpMethod: .delete)
43+ func deleteReservation() {
5244
53− apiClient.load(request: request.request) { result in
54− switch result {
55− case .failure:
56− completion(false)
57− return
58− case .success:
59− completion(true)
60− return
61− }
62− }
6345 }
6446
65− func updateReservation(startTime: Date,
66− numberOfGuests: Int,
67− endTime: Date,
68− uuid: String,
69− isAdmin: Bool,
70− completion: @escaping ((Bool) -> Void)) {
71−
72− let reservation = ChangeReservationResolver.Request(startTime: startTime,
73− uuid: uuid,
74− numberOfGuests: numberOfGuests,
75− endTime: endTime)
76− var resolver: ApiResolver!
77− if isAdmin {
78− resolver = AChangeReservationResolver(data: reservation)
79− } else {
80− resolver = ChangeReservationResolver(data: reservation)
81− }
47+ func updateReservation() {
8248
83− let request = ApiRequest(resolver: resolver, httpMethod: .put)
84−
85− apiClient.load(request: request.request) { result in
86− switch result {
87− case .failure:
88− completion(false)
89− return
90− case .success:
91− completion(true)
92− return
93− }
94− }
9549 }
9650
51+ func createReservation() {
52+
53+ }
9754
9855 func getAllReservations(establishmentID: Int,
9956 completion: @escaping ((Result<AllReservations, GeneralError>) -> Void)) {
@@ -118,114 +75,4 @@ class ReservationsService {
11875 }
11976 }
12077 }
121−
122− func createReservation(data: ReservationData,
123− completion: @escaping ((Result<Reservation, GeneralError>) -> Void)) {
124− // for 1 time use
125− struct Response: MyCodable {
126− var reservationUUID: String
127− }
128−
129− // local map for output
130− func map(data: ReservationData, id: String) -> Reservation {
131−
132− return Reservation(uuid: id,
133− establishment: data.establishment,
134− startTime: data.startTime,
135− endTime: data.endTime,
136− numberOfGuests: data.numberOfGuests,
137− reservedTable: data.reservedTable)
138− }
139−
140− let resolver = CreateReservationResolver<Response>(data: data)
141− let request = ApiRequest(resolver: resolver, httpMethod: .post)
142−
143− apiClient.load(request: request.request) { result in
144− switch result {
145− case .failure(let err):
146− completion(.failure(err))
147− case .success(let response):
148− guard
149− let d = response.data,
150− let id = resolver.targetClass().fromJSONToSelf(data: d)?.reservationUUID
151− else {
152− completion(.failure(GeneralError.decodeError))
153− return
154− }
155−
156− completion(.success(map(data: data, id: id)))
157− }
158− }
159− }
160−
161− func getAdminReservations(establishmentId: Int, completion: @escaping ((Result<[ReservationWithUser], GeneralError>)-> Void)) {
162− let resolver = AReservationsResolver<AReservationResponse>(establishmentId: establishmentId)
163− let request = ApiRequest(resolver: resolver, httpMethod: .get)
164−
165− apiClient.load(request: request.request) { (res) in
166− switch res {
167− case .failure(let err):
168− completion(.failure(err))
169− return
170− case .success(let response):
171− guard
172− let d = response.data,
173− let decodedData = resolver.targetClass().fromJSONToSelf(data: d)
174− else {
175− completion(.failure(GeneralError.decodeError))
176− return
177− }
178−
179− completion(.success(decodedData.reservations))
180− return
181− }
182− }
183− }
184−
185− func getReservationsAround(uuid: String, completion: @escaping((Result<[ReservationPeriod], GeneralError>) -> Void)) {
186− let resolver = ReservationsAroundResolver<ReservationsAroundResponse>(reservationId: uuid)
187− let request = ApiRequest(resolver: resolver, httpMethod: .get)
188−
189− apiClient.load(request: request.request) { (res) in
190− switch res {
191− case .failure(let err):
192− completion(.failure(err))
193− return
194− case .success(let response):
195− guard
196− let d = response.data,
197− let decodedData = resolver.targetClass().fromJSONToSelf(data: d)
198− else {
199− completion(.failure(GeneralError.decodeError))
200− return
201− }
202−
203− completion(.success(decodedData.reservations))
204− return
205− }
206− }
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− }
23178}
Hookah Tau/API/Reservations api/Resolvers/Admin/AChangeReservationResolver.swiftdeleted−34
@@ -1,34 +0,0 @@
1−//
2−// AChangeReservationResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 20/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−
12−/// `PUT /admin/reservations`
13−
14−class AChangeReservationResolver: ApiResolver {
15−
16− var name: String {
17− return "/reservations"
18− }
19−
20− var groupName: String? {
21− return "/admin"
22− }
23−
24− var data: ChangeReservationResolver.Request
25−
26− init(data: ChangeReservationResolver.Request) {
27− self.data = data
28− }
29−
30− func parameters() -> MyCodable? {
31− return data
32− }
33−}
34−
Hookah Tau/API/Reservations api/Resolvers/Admin/ACreateReservationResolver.swiftdeleted−37
@@ -1,37 +0,0 @@
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/Reservations api/Resolvers/Admin/ADeleteReservationResolver.swiftdeleted−34
@@ -1,34 +0,0 @@
1−//
2−// ADeleteReservationResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 07/01/2020.
6−// Copyright © 2020 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−class ADeleteReservationResolver: ApiResolver {
12−
13− struct Request: MyCodable {
14− var reservation: String
15− }
16−
17− var name: String {
18− return "/reservations"
19− }
20−
21− var groupName: String? {
22− return "/admin"
23− }
24−
25− var uuid: String
26−
27− init(uuid: String) {
28− self.uuid = uuid
29− }
30−
31− func parameters() -> MyCodable? {
32− return Request(reservation: uuid)
33− }
34−}
Hookah Tau/API/Reservations api/Resolvers/Admin/AReservationsResolver.swiftdeleted−35
@@ -1,35 +0,0 @@
1−//
2−// AReservationsResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 19/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−struct AReservationResponse: MyCodable {
12− var reservations: [ReservationWithUser]
13−}
14−
15−/// `/admin/reservations/{establishment id}`
16−class AReservationsResolver<Response: MyCodable>: ApiResolver {
17−
18− var name: String {
19− return "/reservations/\(establishmentId)"
20− }
21−
22− var groupName: String? {
23− return "/admin"
24− }
25−
26− var establishmentId: Int
27−
28− init(establishmentId: Int) {
29− self.establishmentId = establishmentId
30− }
31−
32− func targetClass() -> Response.Type {
33− return Response.self
34− }
35−}
Hookah Tau/API/Reservations api/Resolvers/ChangeReservationResolver.swiftdeleted−35
@@ -1,35 +0,0 @@
1−//
2−// ChangeReservationResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 29/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−class ChangeReservationResolver: ApiResolver {
12−
13− /// Структура запроса с возможными данными для
14− /// изменением бронирования
15− struct Request: MyCodable {
16− var startTime: Date
17− var uuid: String
18− var numberOfGuests: Int
19− var endTime: Date
20− }
21−
22− var name: String {
23− return "/reservations"
24− }
25−
26− var data: Request
27−
28− init(data: Request) {
29− self.data = data
30− }
31−
32− func parameters() -> MyCodable? {
33− return data
34− }
35−}
Hookah Tau/API/Reservations api/Resolvers/CreateReservationResolver.swiftdeleted−30
@@ -1,30 +0,0 @@
1−//
2−// CreateReservationResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 27/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−class CreateReservationResolver<Response: Codable>: ApiResolver {
12−
13− var name: String {
14− return "/reservations"
15− }
16−
17− var data: ReservationData
18−
19− init(data: ReservationData) {
20− self.data = data
21− }
22−
23− func parameters() -> MyCodable? {
24− return data
25− }
26−
27− func targetClass() -> Response.Type {
28− return Response.self
29− }
30−}
Hookah Tau/API/Reservations api/Resolvers/DeleteReservationResolver.swiftdeleted−31
@@ -1,31 +0,0 @@
1−//
2−// DeleteReservationResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 29/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−
12−class DeleteReservationResolver: ApiResolver {
13−
14− struct Request: MyCodable {
15− var reservationUUID: String
16− }
17−
18− var name: String {
19− return "/reservations"
20− }
21−
22− var uuid: String
23−
24− init(uuid: String) {
25− self.uuid = uuid
26− }
27−
28− func parameters() -> MyCodable? {
29− return Request(reservationUUID: uuid)
30− }
31−}
Hookah Tau/API/Reservations api/Resolvers/ReservationsAroundResolver.swiftdeleted−35
@@ -1,35 +0,0 @@
1−//
2−// ReservationsAroundResolver.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 20/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−struct ReservationsAroundResponse: MyCodable {
12− var reservations: [ReservationPeriod]
13−}
14−
15−/// ` GET /reservations/around/{reservation id}`
16−class ReservationsAroundResolver<Response: MyCodable>: ApiResolver {
17−
18− var groupName: String? {
19− return "/reservations"
20− }
21−
22− var name: String {
23− return "/around/\(reservationId)"
24− }
25−
26− var reservationId: String
27−
28− init(reservationId: String) {
29− self.reservationId = reservationId
30− }
31−
32− func targetClass() -> Response.Type {
33− return Response.self
34− }
35−}
Hookah Tau/API/ServerError.swift−1
@@ -16,7 +16,6 @@ enum GeneralError: Error {
1616 case serverError(SE)
1717 case decodeError
1818 case noData
19− case notFound
2019 case Error400
2120 case somethingWentCompletelyWrong
2221 case alamofireError
Hookah Tau/AppDelegate.swift+4
@@ -28,6 +28,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2828 return true
2929 }
3030
31+ func relaunch(){
32+ applicationCoordinator?.start()
33+ }
34+
3135 func applicationWillResignActive(_ application: UIApplication) {
3236 // 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.
3337 // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
Hookah Tau/Components/Button.swift+7−8
@@ -22,11 +22,10 @@ class Button: UIButton {
2222
2323 override var isEnabled: Bool {
2424 didSet {
25− alpha = isEnabled ? 1 : 0.8
25+ //alpha = isEnabled ? 1 : 0.8
2626 }
2727 }
2828
29− /// State when chosen table is Booked
3029 public var availiable = true {
3130 willSet {
3231 willUpdateBookingState(newValue: availiable)
@@ -52,12 +51,12 @@ class Button: UIButton {
5251 }
5352
5453 private func willUpdateBookingState(newValue avaliable: Bool) {
55− isEnabled = avaliable
54+ isEnabled = !avaliable
5655
57−// if availiable {
58−// style?.changeToAvailiableState(button: self)
59−// } else {
60−// style?.changeToBookedState(button: self)
61−// }
56+ if availiable {
57+ style?.changeToAvailiableState(button: self)
58+ } else {
59+ style?.changeToBookedState(button: self)
60+ }
6261 }
6362}
Hookah Tau/Components/PhoneTextField.swiftdeleted−63
@@ -1,63 +0,0 @@
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/Components/TableButtonStyle.swift+2−2
@@ -25,7 +25,7 @@ class TableStyle {
2525 let stripe = CALayer()
2626
2727 stripe.frame = CGRect(x: 0, y: -10, width: 2, height: 500)
28− stripe.backgroundColor = UIColor.white.cgColor
28+ stripe.backgroundColor = UIColor.black.cgColor
2929 stripe.transform = CATransform3DMakeRotation(0.52, 0, 0, 1.0)
3030
3131 replicatorLayer.instanceCount = 60
@@ -61,7 +61,7 @@ class TableButtonStyle {
6161 }
6262
6363 func setBooked(button: TableButton) {
64− button.backgroundColor = Booked.fillColor
64+ TableStyle.setStripes(for: button)
6565 }
6666
6767 func setAvaliable(button: TableButton) {
Hookah Tau/Controllers/Admin/Clients/Cells/ClientTableViewCell.swiftdeleted−53
@@ -1,53 +0,0 @@
1−//
2−// ClientTableViewCell.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 09/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−let clientTableViewCellId = "ClientTableViewCell"
12−
13−class ClientTableViewCell: UITableViewCell {
14−
15− // MARK: - IBAOutlets
16−
17− @IBOutlet weak var nameLabel: UILabel!
18−
19− @IBOutlet weak var phoneNumberLabel: UILabel!
20−
21− @IBOutlet weak var numberOfReservationsLabel: UILabel!
22−
23−
24− @IBOutlet weak var blockListLabel: UILabel!
25−
26− @IBOutlet weak var isAdminLabel: UILabel!
27−
28−
29−
30− // MARK: - Lifecycle
31−
32− override func awakeFromNib() {
33− super.awakeFromNib()
34− // Initialization code
35− }
36−
37− override func setSelected(_ selected: Bool, animated: Bool) {
38− super.setSelected(selected, animated: animated)
39−
40− // Configure the view for the selected state
41− }
42−
43− // MARK: - Bind
44−
45− func bind(withModel model: Client) {
46− blockListLabel.isHidden = !model.isBlocked
47− isAdminLabel.isHidden = !model.isAdmin
48− nameLabel.text = model.name ?? "❔"
49− phoneNumberLabel.text = model.phoneNumber.formattedNumber()
50− numberOfReservationsLabel.text = model.reservationCount > 99 ? "99+" : "\(model.reservationCount)"
51− }
52−
53−}
Hookah Tau/Controllers/Admin/Clients/ClientList.storyboarddeleted−196
@@ -1,196 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
7− <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8− <capability name="Stack View standard spacing" minToolsVersion="9.0"/>
9− <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
10− </dependencies>
11− <scenes>
12− <!--Clients View Controller-->
13− <scene sceneID="U7X-Jx-osU">
14− <objects>
15− <tableViewController storyboardIdentifier="ClientsViewController" id="Wfj-Ux-iLR" customClass="ClientsViewController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
16− <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="qFn-ia-vVI">
17− <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
18− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
19− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
20− <prototypes>
21− <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="ClientTableViewCell" rowHeight="69" id="QPb-0v-yOO" customClass="ClientTableViewCell" customModule="Hookah_Tau" customModuleProvider="target">
22− <rect key="frame" x="0.0" y="28" width="375" height="69"/>
23− <autoresizingMask key="autoresizingMask"/>
24− <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="QPb-0v-yOO" id="48D-Q7-dBg">
25− <rect key="frame" x="0.0" y="0.0" width="375" height="69"/>
26− <autoresizingMask key="autoresizingMask"/>
27− <subviews>
28− <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="fhd-NM-rld">
29− <rect key="frame" x="16" y="8" width="343" height="53"/>
30− <subviews>
31− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="top" translatesAutoresizingMaskIntoConstraints="NO" id="vNV-bN-3No">
32− <rect key="frame" x="0.0" y="0.0" width="179" height="53"/>
33− <subviews>
34− <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="uoO-w2-5yG">
35− <rect key="frame" x="0.0" y="0.0" width="78.5" height="26.5"/>
36− <subviews>
37− <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="4Cp-jh-0Gq">
38− <rect key="frame" x="0.0" y="0.0" width="78.5" height="26.5"/>
39− <fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
40− <color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
41− <nil key="highlightedColor"/>
42− </label>
43− </subviews>
44− </stackView>
45− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="+7 (901) 733-01-79" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0gY-h5-AV2">
46− <rect key="frame" x="0.0" y="29" width="179" height="24"/>
47− <fontDescription key="fontDescription" type="system" pointSize="20"/>
48− <nil key="textColor"/>
49− <nil key="highlightedColor"/>
50− </label>
51− </subviews>
52− </stackView>
53− <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="tJg-ju-bFY">
54− <rect key="frame" x="219.5" y="0.0" width="123.5" height="53"/>
55− <subviews>
56− <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="4et-BC-7iY">
57− <rect key="frame" x="0.0" y="14.5" width="103.5" height="24"/>
58− <subviews>
59− <stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="BHD-cD-L1c">
60− <rect key="frame" x="0.0" y="0.0" width="51" height="24"/>
61− <subviews>
62− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="❌" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MaQ-TW-666">
63− <rect key="frame" x="0.0" y="0.0" width="23" height="24"/>
64− <fontDescription key="fontDescription" type="system" pointSize="17"/>
65− <nil key="textColor"/>
66− <nil key="highlightedColor"/>
67− </label>
68− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="👑" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0Xa-FL-GVr">
69− <rect key="frame" x="28" y="0.0" width="23" height="24"/>
70− <fontDescription key="fontDescription" type="system" pointSize="17"/>
71− <nil key="textColor"/>
72− <nil key="highlightedColor"/>
73− </label>
74− </subviews>
75− </stackView>
76− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="99+" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Gzo-kW-60Z">
77− <rect key="frame" x="66" y="0.0" width="37.5" height="24"/>
78− <fontDescription key="fontDescription" type="system" pointSize="20"/>
79− <nil key="textColor"/>
80− <nil key="highlightedColor"/>
81− </label>
82− </subviews>
83− </stackView>
84− <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrow" translatesAutoresizingMaskIntoConstraints="NO" id="DrQ-Ss-gIT">
85− <rect key="frame" x="111.5" y="16.5" width="12" height="20"/>
86− </imageView>
87− </subviews>
88− <constraints>
89− <constraint firstAttribute="width" constant="123.5" id="eeb-nt-pTB"/>
90− </constraints>
91− </stackView>
92− </subviews>
93− </stackView>
94− </subviews>
95− <constraints>
96− <constraint firstItem="fhd-NM-rld" firstAttribute="leading" secondItem="48D-Q7-dBg" secondAttribute="leading" constant="16" id="EDr-e5-ffF"/>
97− <constraint firstAttribute="trailing" secondItem="fhd-NM-rld" secondAttribute="trailing" constant="16" id="jMD-pP-Fcj"/>
98− <constraint firstAttribute="bottom" secondItem="fhd-NM-rld" secondAttribute="bottom" constant="8" id="lGU-2k-95p"/>
99− <constraint firstItem="fhd-NM-rld" firstAttribute="top" secondItem="48D-Q7-dBg" secondAttribute="top" constant="8" id="yPf-vR-dW7"/>
100− </constraints>
101− </tableViewCellContentView>
102− <connections>
103− <outlet property="blockListLabel" destination="MaQ-TW-666" id="Us0-tw-9tj"/>
104− <outlet property="isAdminLabel" destination="0Xa-FL-GVr" id="fzz-2t-Lda"/>
105− <outlet property="nameLabel" destination="4Cp-jh-0Gq" id="g6e-c0-x0u"/>
106− <outlet property="numberOfReservationsLabel" destination="Gzo-kW-60Z" id="9J2-S4-fKq"/>
107− <outlet property="phoneNumberLabel" destination="0gY-h5-AV2" id="rdb-GS-ceF"/>
108− </connections>
109− </tableViewCell>
110− </prototypes>
111− <connections>
112− <outlet property="dataSource" destination="Wfj-Ux-iLR" id="uby-48-VjA"/>
113− <outlet property="delegate" destination="Wfj-Ux-iLR" id="oeU-I8-pfI"/>
114− </connections>
115− </tableView>
116− </tableViewController>
117− <placeholder placeholderIdentifier="IBFirstResponder" id="epE-4n-L3K" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
118− </objects>
119− <point key="canvasLocation" x="0.80000000000000004" y="-112.89355322338831"/>
120− </scene>
121− <!--Profile Table View Controller-->
122− <scene sceneID="APa-VZ-6hd">
123− <objects>
124− <viewController storyboardIdentifier="ProfileTableViewController" id="ZVH-jf-rtc" customClass="ProfileTableViewController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
125− <view key="view" contentMode="scaleToFill" id="rcq-M9-CvR">
126− <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
127− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
128− <subviews>
129− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ciO-ia-Oob">
130− <rect key="frame" x="0.0" y="0.0" width="375" height="65"/>
131− <subviews>
132− <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="IBA-bj-CWK">
133− <rect key="frame" x="8" y="16" width="359" height="37"/>
134− <subviews>
135− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4WC-gi-jbD" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
136− <rect key="frame" x="0.0" y="0.0" width="180" height="37"/>
137− <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
138− <constraints>
139− <constraint firstAttribute="width" constant="180" id="bJA-V9-gw9"/>
140− <constraint firstAttribute="height" constant="37" id="pdo-AO-o8a"/>
141− </constraints>
142− <state key="normal" title="Button"/>
143− </button>
144− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gfq-ql-lka" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
145− <rect key="frame" x="224" y="0.0" width="135" height="37"/>
146− <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
147− <constraints>
148− <constraint firstAttribute="width" constant="135" id="Xn3-v6-SLp"/>
149− <constraint firstAttribute="height" constant="37" id="z68-vW-NjK"/>
150− </constraints>
151− <state key="normal" title="Button"/>
152− </button>
153− </subviews>
154− </stackView>
155− </subviews>
156− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
157− <constraints>
158− <constraint firstItem="IBA-bj-CWK" firstAttribute="leading" secondItem="ciO-ia-Oob" secondAttribute="leading" constant="8" id="WZS-Vq-tuP"/>
159− <constraint firstAttribute="trailing" secondItem="IBA-bj-CWK" secondAttribute="trailing" constant="8" id="Yk3-D1-1kg"/>
160− <constraint firstItem="IBA-bj-CWK" firstAttribute="top" secondItem="ciO-ia-Oob" secondAttribute="top" constant="16" id="fWO-oj-NuN"/>
161− <constraint firstItem="IBA-bj-CWK" firstAttribute="leading" secondItem="ciO-ia-Oob" secondAttribute="leading" constant="8" id="gP2-jh-5El"/>
162− <constraint firstAttribute="height" constant="65" id="pzZ-zw-kbc"/>
163− </constraints>
164− </view>
165− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="T0s-lX-Z5m">
166− <rect key="frame" x="0.0" y="65" width="375" height="602"/>
167− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
168− </view>
169− </subviews>
170− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
171− <constraints>
172− <constraint firstItem="ciO-ia-Oob" firstAttribute="trailing" secondItem="tIS-3m-xwG" secondAttribute="trailing" id="3An-sM-OCN"/>
173− <constraint firstItem="ciO-ia-Oob" firstAttribute="top" secondItem="tIS-3m-xwG" secondAttribute="top" id="5zl-uZ-sTi"/>
174− <constraint firstItem="T0s-lX-Z5m" firstAttribute="leading" secondItem="tIS-3m-xwG" secondAttribute="leading" id="7qA-Hh-3Us"/>
175− <constraint firstItem="T0s-lX-Z5m" firstAttribute="trailing" secondItem="tIS-3m-xwG" secondAttribute="trailing" id="9VD-9Q-wGX"/>
176− <constraint firstItem="T0s-lX-Z5m" firstAttribute="top" secondItem="ciO-ia-Oob" secondAttribute="bottom" id="RSL-fo-wIb"/>
177− <constraint firstItem="ciO-ia-Oob" firstAttribute="leading" secondItem="tIS-3m-xwG" secondAttribute="leading" id="Tuq-su-gbn"/>
178− <constraint firstItem="T0s-lX-Z5m" firstAttribute="bottom" secondItem="tIS-3m-xwG" secondAttribute="bottom" id="iQj-LM-Im9"/>
179− </constraints>
180− <viewLayoutGuide key="safeArea" id="tIS-3m-xwG"/>
181− </view>
182− <connections>
183− <outlet property="contentView" destination="T0s-lX-Z5m" id="9Z0-5T-f7Z"/>
184− <outlet property="copyButton" destination="gfq-ql-lka" id="BNi-Ip-AyF"/>
185− <outlet property="phoneButton" destination="4WC-gi-jbD" id="xlf-g7-CzU"/>
186− </connections>
187− </viewController>
188− <placeholder placeholderIdentifier="IBFirstResponder" id="g4Y-1k-Lxr" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
189− </objects>
190− <point key="canvasLocation" x="1188" y="-113"/>
191− </scene>
192− </scenes>
193− <resources>
194− <image name="arrow" width="12" height="20"/>
195− </resources>
196−</document>
Hookah Tau/Controllers/Admin/Clients/ClientsCoordinator.swiftdeleted−36
@@ -1,36 +0,0 @@
1−//
2−// ClientsCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 09/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−
12−class ClientsCoordinator: BaseCoordinator {
13−
14− override func start() {
15− let storyboard = UIStoryboard(name: "ClientList", bundle: nil)
16− let viewController = storyboard.instantiateViewController(withIdentifier: "ClientsViewController") as? ClientsViewController
17− viewController?.coordinator = self
18− guard let vc = viewController else { return }
19− navigationController?.navigationBar.prefersLargeTitles = true
20− navigationController?.viewControllers = [vc]
21− }
22−
23− /// TODO
24− func openUserProfile(_ profile: Client) {
25− let profileCoordinator = ClientProfileCoordinator(navigationController: navigationController)
26− profileCoordinator.user = profile
27−
28− self.addDependency(profileCoordinator)
29− profileCoordinator.didEndFlow = {
30− self.removeDependency(profileCoordinator)
31− self.navigationController?.popViewController(animated: true)
32− }
33−
34− profileCoordinator.start()
35− }
36−}
Hookah Tau/Controllers/Admin/Clients/ClientsViewController.swiftdeleted−239
@@ -1,239 +0,0 @@
1−//
2−// ClientsViewController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 09/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class ClientsViewController: BaseTableViewController {
12−
13− // MARK: - Properties
14−
15− var dataSource: [Client] = [] {
16− didSet {
17− tableView.reloadData()
18− }
19− }
20−
21− var filteredDataSource: [Client] = []
22−
23− var clientsService: ClientsService?
24−
25− weak var coordinator: ClientsCoordinator?
26−
27− var searchControl: UISearchController?
28−
29− var isFiltering: Bool {
30− return searchControl?.isActive ?? false && !searchBarIsEmpty()
31− }
32−
33− func searchBarIsEmpty() -> Bool {
34− return searchControl?.searchBar.text?.isEmpty ?? true
35− }
36−
37− // MARK: - Lifecycle
38−
39− override func viewDidLoad() {
40− super.viewDidLoad()
41−
42− setupNavigationBar()
43− setupSearchController()
44− clientsService = ClientsService(apiClient: APIClient.shared)
45− }
46−
47− override func viewWillAppear(_ animated: Bool) {
48− super.viewWillAppear(animated)
49− tabBarController?.tabBar.isHidden = false
50− }
51−
52− override func viewDidAppear(_ animated: Bool) {
53− super.viewDidAppear(animated)
54− loadClients()
55− }
56−
57− // MARK: - Setup
58−
59− func setupNavigationBar() {
60−
61− navigationItem.title = "Клиенты"
62− navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareCSVFile))
63− }
64−
65− func setupSearchController() {
66− searchControl = UISearchController(searchResultsController: nil)
67− navigationItem.searchController = searchControl
68− navigationItem.hidesSearchBarWhenScrolling = false
69− searchControl?.obscuresBackgroundDuringPresentation = false
70− definesPresentationContext = true
71− searchControl?.searchResultsUpdater = self
72− }
73−
74− // MARK: - Api calls
75−
76− /// Загружаем клиентов кальянки
77− func loadClients() {
78− clientsService?.loadClientsList(completion: { [ weak self ] (res) in
79− switch res {
80− case .failure(let err):
81− print(err)
82− case .success(let arr):
83− self?.dataSource = arr
84− }
85− })
86− }
87−
88− // MARK: - Button handlers
89−
90− /// https://developer.apple.com/design/human-interface-guidelines/ios/views/activity-views/
91− @objc func shareCSVFile() {
92− //Your CSV text
93− let str = HFunc.main.exportClientsToCSV(dataSource)
94− let filename = getDocumentsDirectory().appendingPathComponent("clients.csv")
95−
96− do {
97− try str.write(toFile: filename, atomically: true, encoding: String.Encoding.utf8)
98−
99− let fileData = NSURL(fileURLWithPath: filename)
100−
101− let objectsToShare = [fileData]
102− let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
103−
104− self.present(activityVC, animated: true, completion: nil)
105−
106− } catch {
107− self.displayAlert(with: "По какой-то причине не могу сохранить файл!")
108− }
109− }
110−
111− func getDocumentsDirectory() -> NSString {
112− let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
113− let documentsDirectory = paths[0]
114− return documentsDirectory as NSString
115− }
116−
117− // MARK: - Change blocklist status
118−
119− func updateUserBlockStatus(wasBlocked: Bool, phone: String, indexPath: IndexPath) {
120− let crudMethod = wasBlocked ? CrudMethod.delete : CrudMethod.put
121− clientsService?.changeBlockList(whatToDo: crudMethod, phone: phone, completion: { (res) in
122− if res {
123− self.tableView?.beginUpdates()
124− self.tableView?.reloadRows(at: [indexPath], with: .automatic)
125− if self.isFiltering {
126− self.filteredDataSource[indexPath.row].isBlocked = !wasBlocked
127− let changed = self.filteredDataSource[indexPath.row]
128− let filtered = self.dataSource.map { (one: Client) -> Client in
129− if one.uuid == changed.uuid {
130− return changed
131− } else { return one } }
132− self.dataSource = filtered
133− } else {
134− self.dataSource[indexPath.row].isBlocked = !wasBlocked
135− }
136− self.tableView?.endUpdates()
137− } else {
138− self.displayAlert(with: "Не удалось \(wasBlocked ? "удалить" : "добавить") пользователя \(wasBlocked ? "из" : "в") чс! Попробуйте еще раз!")
139− return
140− }
141− })
142− }
143−
144− func updateAdminStatus(user: Client, indexPath: IndexPath) {
145−
146− let wasAdmin = user.isAdmin
147− let crudMethod = wasAdmin ? CrudMethod.delete : CrudMethod.put
148− let data = user.isAdmin ? user.uuid : user.phoneNumber
149−
150− clientsService?.changeAdmin(crud: crudMethod, data: data, completion: { (res) in
151− if res {
152− self.tableView?.beginUpdates()
153− self.tableView?.reloadRows(at: [indexPath], with: .automatic)
154− if self.isFiltering {
155− self.filteredDataSource[indexPath.row].isAdmin = !wasAdmin
156− let changed = self.filteredDataSource[indexPath.row]
157− let filtered = self.dataSource.map { (one: Client) -> Client in
158− if one.uuid == changed.uuid {
159− return changed
160− } else { return one } }
161− self.dataSource = filtered
162− } else {
163− self.dataSource[indexPath.row].isAdmin = !wasAdmin
164− }
165− self.tableView?.endUpdates()
166− } else {
167− self.displayAlert(with: "Не удалось \(wasAdmin ? "распромоутить" : "запромоутить") пользователя! Попробуйте еще раз!")
168− return
169− }
170− })
171− }
172−}
173−
174−// MARK: - Tableview
175−
176−extension ClientsViewController {
177−
178− override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
179− let cell = tableView.dequeueReusableCell(withIdentifier: clientTableViewCellId, for: indexPath) as! ClientTableViewCell
180−
181− let userModel = isFiltering ? filteredDataSource[indexPath.row] : dataSource[indexPath.row]
182− cell.bind(withModel: userModel)
183−
184− return cell
185− }
186−
187− override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
188− return isFiltering ? filteredDataSource.count : dataSource.count
189− }
190−
191− override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
192− let user = isFiltering ? filteredDataSource[indexPath.row] : dataSource[indexPath.row]
193− coordinator?.openUserProfile(user)
194− searchControl?.dismiss(animated: true, completion: nil)
195− }
196−
197− // Update
198−
199− override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
200− return true
201− }
202−
203− override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
204−
205− let user = isFiltering ? filteredDataSource[indexPath.row] : dataSource[indexPath.row]
206− let blockButton = UITableViewRowAction(style: .normal, title: "\(!user.isBlocked ? "в чс" : "убрать из чс")") { _,_ in
207−
208− self.updateUserBlockStatus(wasBlocked: user.isBlocked, phone: user.phoneNumber, indexPath: indexPath)
209− }
210−
211− blockButton.backgroundColor = .black
212−
213− return [blockButton]
214− }
215−
216− override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
217−
218− let user = isFiltering ? filteredDataSource[indexPath.row] : dataSource[indexPath.row]
219−
220− let promote = UIContextualAction(style: .normal, title: "\(!user.isAdmin ? "дать админку" : "забрать админку")") { (_, _, _) in
221− self.updateAdminStatus(user: user, indexPath: indexPath)
222− }
223− promote.backgroundColor = .black
224−
225− return UISwipeActionsConfiguration(actions: [promote])
226− }
227−}
228−
229−extension ClientsViewController: UISearchResultsUpdating {
230− func filterContentForSearchText(_ searchText: String, scope: String = "All")
231− {
232− filteredDataSource = dataSource.filter { ($0.name?.lowercased().contains(searchText.lowercased()) ?? false) || ($0.phoneNumber.lowercased().contains(searchText.lowercased())) }
233− tableView.reloadData()
234− }
235−
236− func updateSearchResults(for searchController: UISearchController) {
237− filterContentForSearchText(searchController.searchBar.text ?? "")
238− }
239−}
Hookah Tau/Controllers/Admin/Clients/Profile/ClientProfileCoordinator.swiftdeleted−52
@@ -1,52 +0,0 @@
1−//
2−// ClientProfileCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 10/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−
12−class ClientProfileCoordinator: BaseCoordinator {
13−
14− var user: Client?
15−
16− override func start() {
17− let storyboard = UIStoryboard(name: "ClientList", bundle: nil)
18− let viewController = storyboard.instantiateViewController(withIdentifier: "ProfileTableViewController") as? ProfileTableViewController
19− viewController?.user = user
20− viewController?.coodinator = self
21− guard let vc = viewController else { return }
22− navigationController?.pushViewController(vc, animated: true)
23− }
24−
25−
26− // Создание бронирования из профиля клиента
27− func createReservation(forUserWithPhone phoneNumber: String, user fullUser: FullUser) {
28− let coordinator = AdminFirstStepReservationViewCoordinator(navigationController: navigationController)
29− coordinator.phone = phoneNumber
30− coordinator.fullUser = fullUser
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()
39− }
40−
41− // Просмотр (и редактирование) брони
42− func seeExistingReservation(data: ReservationWithUser) {
43− let reservationCoordinator = AdminReservationEditingCoordinator(navigationController: navigationController)
44− addDependency(reservationCoordinator)
45− reservationCoordinator.reservationData = data
46− reservationCoordinator.didEndFlow = { [weak self] in
47− self?.removeDependency(reservationCoordinator)
48− self?.navigationController?.popViewController(animated: true)
49− }
50− reservationCoordinator.start()
51− }
52−}
Hookah Tau/Controllers/Admin/Clients/Profile/ProfileTableViewController.swiftdeleted−257
@@ -1,257 +0,0 @@
1−//
2−// ProfileTableViewController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 10/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class ProfileTableViewController: BaseViewController {
12−
13− // MARK: - IBAOutlets
14−
15− @IBOutlet weak var phoneButton: Button! {
16− didSet {
17− guard let u = user else { return }
18−
19− let style = BlackButtonStyle()
20− style.apply(to: phoneButton, withTitle: u.phoneNumber.formattedNumber())
21− phoneButton.addTarget(self, action: #selector(callUser), for: .touchUpInside)
22− }
23− }
24−
25− @IBOutlet weak var copyButton: Button! {
26− didSet {
27− let style = BlackButtonStyle()
28− style.apply(to: copyButton, withTitle: "СКОПИРОВАТЬ")
29− copyButton.addTarget(self, action: #selector(copyNumber(_:)), for: .touchUpInside)
30− }
31− }
32−
33−
34− @IBOutlet weak var contentView: UIView!
35−
36− // MARK: - properties
37−
38− var tableView: UITableView?
39−
40− var clientsService: ClientsService?
41−
42− var reservationsService: ReservationsService?
43−
44− var user: Client?
45−
46− weak var coodinator: ClientProfileCoordinator?
47−
48− var noReserationsYetView: AdminNoReservationsView?
49−
50− var activityIndicator: UIActivityIndicatorView?
51−
52− var refreshControl: UIRefreshControl?
53−
54− var dataSource: [Reservation] = [] {
55− didSet {
56− guard let empty = noReserationsYetView else { return }
57− if dataSource.isEmpty {
58− empty.alpha = 1
59− tableView?.alpha = 0
60− } else {
61− empty.alpha = 0
62− tableView?.alpha = 1
63− }
64−
65− refreshControl?.endRefreshing()
66− activityIndicator?.stopAnimating()
67− tableView?.reloadData()
68− }
69− }
70−
71− // MARK: - Lifecycle
72−
73− override func viewDidLoad() {
74− super.viewDidLoad()
75−
76− clientsService = ClientsService(apiClient: APIClient.shared)
77− reservationsService = ReservationsService(apiClient: APIClient.shared)
78−
79− setupNavBar()
80− setupTable()
81− setupActivityIndicator()
82− //loadReservations()
83− }
84−
85− override func viewWillAppear(_ animated: Bool) {
86− super.viewWillAppear(animated)
87− tabBarController?.tabBar.isHidden = true
88− }
89−
90− override func viewDidAppear(_ animated: Bool) {
91− super.viewDidAppear(animated)
92− loadReservations()
93− }
94−
95− // MARK: - Setup
96−
97− func setupNavBar() {
98− guard let u = user else { return }
99−
100− navigationItem.title = "\(u.name ?? "❔")\(u.isAdmin ? "👑" : "")\(u.isBlocked ? "❌" : "")"
101− navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(book))
102− }
103−
104− func setupTable() {
105− tableView = UITableView()
106−
107− // refresh control
108− refreshControl = UIRefreshControl()
109− refreshControl?.addTarget(self, action: #selector(refresh), for: .valueChanged)
110− tableView?.refreshControl = refreshControl
111−
112− tableView?.dataSource = self
113− tableView?.delegate = self
114−
115− noReserationsYetView = AdminNoReservationsView.loadFromNib()
116− noReserationsYetView?.setup(withTitle: "У этого пользователя пока нет ни одной брони :(")
117− noReserationsYetView?.bookButton?.addTarget(self, action: #selector(book), for: .touchUpInside)
118− contentView.addSubviewThatFills(noReserationsYetView)
119− noReserationsYetView?.alpha = 0
120−
121− tableView?.register(ReservationCell.self, forCellReuseIdentifier: reservationCell)
122−
123− contentView.addSubviewThatFills(tableView)
124−
125− tableView?.alpha = 0
126− }
127−
128− func setupActivityIndicator() {
129−
130− activityIndicator = UIActivityIndicatorView()
131− view.addSubviewThatFills(activityIndicator)
132− activityIndicator?.startAnimating()
133−
134− }
135−
136− // MARK: - Api calls
137−
138− func loadReservations() {
139− guard let uuid = user?.uuid else { return }
140− clientsService?.loadReservationsForUser(withUUID: uuid,
141− completion: { [weak self] (res) in
142− switch res {
143− case .failure(let err):
144− self?.displayAlert(forError: err)
145− case .success(let data):
146− self?.dataSource = data
147− }
148− })
149− }
150−
151−
152− func deleteReservation(uuid: String, completion: @escaping (([Reservation]?) -> Void)) {
153− reservationsService?.deleteReservation(isAdmin: true, uuid: uuid) { result in
154− if result {
155− let newReservations = self.dataSource.filter { $0.uuid != uuid }
156− completion(newReservations)
157− return
158− }
159−
160− completion(nil)
161− }
162− }
163−
164− // MARK: - Button handlers
165−
166− @objc func callUser() {
167− guard
168− let u = user,
169− let urlPhone = URL(string: "tel://79\(u.phoneNumber)")
170− else { return }
171−
172− UIApplication.shared.open(urlPhone)
173− }
174−
175− @objc func copyNumber(_ sender: UIButton) {
176− guard
177− let u = user
178− else { return }
179− //Copy a string to the pasteboard.
180− UIPasteboard.general.string = "79\(u.phoneNumber)"
181−
182− //Alert
183− self.displayAlert(with: "Номер скопирован!")
184− }
185−
186− @objc func refresh() {
187− loadReservations()
188− }
189−
190− @objc func book() {
191− guard
192− let phone = user?.phoneNumber,
193− let user = user
194− else { return }
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)
201− }
202−}
203−
204−// MARK: - Table view data source
205−
206−extension ProfileTableViewController: UITableViewDelegate, UITableViewDataSource {
207−
208− func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
209− return dataSource.count
210− }
211−
212− func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
213− let cell = tableView.dequeueReusableCell(withIdentifier: reservationCell, for: indexPath) as! ReservationCell
214−
215− cell.bind(withModel: dataSource[indexPath.row])
216−
217− return cell
218− }
219−
220− // tap
221−
222− func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
223− guard let u = user else { return }
224− let r = dataSource[indexPath.row]
225− let user = FullUser(uuid: u.uuid, name: u.name, phoneNumber: u.phoneNumber, isAdmin: u.isAdmin)
226− let reservation = ReservationWithUser(reservation: r, user: user)
227− coodinator?.seeExistingReservation(data: reservation)
228− }
229−
230− // Update
231−
232− func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
233− return true
234− }
235−
236− func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
237−
238− let uuid = dataSource[indexPath.row].uuid
239− let cancelButton = UITableViewRowAction(style: .normal, title: "отменить бронь") { _,_ in
240−
241− self.deleteReservation(uuid: uuid) { optionalNewVal in
242− if let newval = optionalNewVal {
243− self.tableView?.beginUpdates()
244− self.tableView?.deleteRows(at: [indexPath], with: .automatic)
245− self.dataSource = newval
246− self.tableView?.endUpdates()
247− } else {
248− self.displayAlert(with: "Не удалось удалить вашу бронь! Попробуйте еще раз!")
249− }
250− }
251− }
252−
253− cancelButton.backgroundColor = .black
254−
255− return [cancelButton]
256− }
257−}
Hookah Tau/Controllers/Admin/Reservations/AdminAddressCoordinator.swiftdeleted−35
@@ -1,35 +0,0 @@
1−//
2−// AdminAddressCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 09/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−class AdminAddressCoordinator: BaseCoordinator {
12−
13− override func start() {
14− let addressViewController = AddresViewController()
15− addressViewController.coordinator = self
16− navigationController?.viewControllers = [addressViewController]
17−
18− guard let id = DataStorage.standard.getEstablishmentChoice() else { return }
19− openReservations(forEstablishment: id)
20− }
21−
22− private func openReservations(forEstablishment id: Int) {
23− let reservationsCoordinator = AdminReservationsCoordinator(navigationController: navigationController)
24− addDependency(reservationsCoordinator)
25− reservationsCoordinator.establishmentId = id
26− reservationsCoordinator.start()
27− }
28−}
29−
30−extension AdminAddressCoordinator: AddressMapper {
31− func chooseAddress(establishmentId id: Int) {
32− DataStorage.standard.setupEstablishmentChoice(id: id)
33− openReservations(forEstablishment: id)
34− }
35−}
Hookah Tau/Controllers/Admin/Reservations/AdminReservationEditingCoordinator.swiftdeleted−31
@@ -1,31 +0,0 @@
1−//
2−// AdminReservationEditingCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 20/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−
12−class AdminReservationEditingCoordinator: BaseCoordinator, ShowReservationCoordinator {
13−
14− // MARK: - Peoperties
15−
16− var didFinish: (() -> Void)?
17−
18− var reservationData: ReservationWithUser?
19−
20− // MARK: - Lifecycle
21−
22− override func start() {
23− let storyboard = UIStoryboard(name: "AdminReservations", bundle: nil)
24− let vc = storyboard.instantiateViewController(withIdentifier: "AdminReservationEditingViewController") as! AdminReservationEditingViewController
25− vc.reservationData = reservationData
26− vc.coordinator = self
27−
28− navigationController?.pushViewController(vc, animated: true)
29− }
30−
31−}
Hookah Tau/Controllers/Admin/Reservations/AdminReservationEditingViewController.swiftdeleted−187
@@ -1,187 +0,0 @@
1−//
2−// AdminReservationEditingViewController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 20/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class AdminReservationEditingViewController: BaseViewController {
12−
13− // MARK:- IBAOutlets
14−
15− @IBOutlet weak var tableContentView: UIView!
16−
17− @IBOutlet weak var mainContentView: UIView!
18−
19− // MARK:- Properties
20−
21− var mapView: MapImageScroll?
22−
23− var reservationView: AdminReservationView?
24−
25− var reservationData: ReservationWithUser?
26−
27− weak var coordinator: ShowReservationCoordinator?
28−
29− var reservationService: ReservationsService?
30−
31− var reservedPeriods: [ReservationPeriod] = [] {
32− didSet {
33− if let _ = reservationView {
34− setupReservationViewWithIntervals()
35− }
36− }
37− }
38−
39− // MARK:- Lifecycle
40−
41− override func viewDidLoad() {
42− super.viewDidLoad()
43−
44− setupContentViews()
45−
46− reservationService = ReservationsService(apiClient: APIClient.shared)
47−
48− loadReservedPeriods()
49−
50− setupButtons()
51− }
52−
53− override func viewWillAppear(_ animated: Bool) {
54− super.viewWillAppear(animated)
55−
56− tabBarController?.tabBar.isHidden = true
57− }
58−
59− // MARK: - Setup
60−
61− func setupButtons() {
62−
63− reservationView?.saveButton?.addTarget(self, action: #selector(saveReservation), for: .touchUpInside)
64− reservationView?.cancelButton?.addTarget(self, action: #selector(cancelReservation), for: .touchUpInside)
65− }
66−
67− func setupContentViews() {
68− guard
69− let model = reservationData
70− else { return }
71−
72− if model.establishment == 1 {
73− mapView = MapView1.loadFromNib()
74− } else {
75− mapView = MapView2.loadFromNib()
76− }
77−
78− navigationItem.title = TotalStorage.standard.getEstablishment(model.establishment)?.address
79−
80− mapView?.isUserInteractionEnabled = false
81−
82− tableContentView.addSubviewThatFills(mapView)
83− mapView?.scrollToTable(table: model.reservedTable)
84−
85− reservationView = AdminReservationView.loadFromNib()
86− reservationView?.bind(withModel: model)
87−
88− mainContentView.addSubviewThatFills(reservationView)
89− }
90−
91− func setupReservationViewWithIntervals() {
92− reservationView?.bind(withIntervals: reservedPeriods)
93− }
94−
95− func loadReservedPeriods() {
96− guard
97− let model = reservationData,
98− let uuid = model.uuid
99− else {
100− setupReservationViewWithIntervals()
101− return }
102−
103− reservationService?.getReservationsAround(uuid: uuid, completion: { [weak self] (res) in
104− switch res {
105− case .failure(let err):
106− self?.displayAlert(forError: err)
107− return
108− case .success(let reserv):
109− self?.reservedPeriods = reserv
110− return
111− }
112− })
113− }
114−
115− // MARK:- Handlers
116−
117− @objc func saveReservation() {
118− guard
119− let r = reservationView?.data,
120− let uuid = reservationData?.uuid
121− else {
122− createReservation()
123− return
124− }
125−
126− reservationView?.saveButton?.loading = true
127−
128− reservationService?.updateReservation(startTime: r.startTime,
129− numberOfGuests: r.numberOfGuests,
130− endTime: r.endTime,
131− uuid: uuid,
132− isAdmin: true,
133− completion: { [weak self] (res) in
134− if res {
135− self?.coordinator?.didFinish?()
136− } else {
137− self?.displayAlert(with: "Что-то пошло не так! Попробуешь еще раз?")
138− }
139−
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− }
165− })
166− }
167−
168− @objc func cancelReservation() {
169− guard
170− let uuid = reservationData?.uuid
171− else {
172− cancelPrereservation()
173− return }
174−
175− reservationService?.deleteReservation(isAdmin: true, uuid: uuid, completion: { [weak self] (res) in
176− if res {
177− self?.coordinator?.didFinish?()
178− } else {
179− self?.displayAlert(with: "Что-то пошло не так!\nПопробуешь еще раз?")
180− }
181− })
182− }
183−
184− func cancelPrereservation() {
185− coordinator?.didFinish?()
186− }
187−}
Hookah Tau/Controllers/Admin/Reservations/AdminReservations.storyboarddeleted−132
@@ -1,132 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
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− <!--Admin Reservations Controller-->
12− <scene sceneID="3G1-PQ-PoW">
13− <objects>
14− <viewController storyboardIdentifier="AdminReservationsController" id="Imn-L1-YIQ" customClass="AdminReservationsController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
15− <view key="view" contentMode="scaleToFill" id="DoI-oD-1Zy">
16− <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
17− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
19− <viewLayoutGuide key="safeArea" id="QBQ-KH-Pid"/>
20− </view>
21− </viewController>
22− <placeholder placeholderIdentifier="IBFirstResponder" id="Rnh-3m-3dv" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
23− </objects>
24− <point key="canvasLocation" x="111" y="159"/>
25− </scene>
26− <!--Admin Reservation Editing View Controller-->
27− <scene sceneID="hWe-Nm-jBL">
28− <objects>
29− <viewController storyboardIdentifier="AdminReservationEditingViewController" id="BgQ-ca-cuZ" customClass="AdminReservationEditingViewController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
30− <view key="view" contentMode="scaleToFill" id="tjV-EU-XvW">
31− <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
32− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
33− <subviews>
34− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uNU-TW-vfq">
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"/>
37− <constraints>
38− <constraint firstAttribute="height" constant="385" id="wfZ-i9-ruU"/>
39− </constraints>
40− </view>
41− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ghQ-Jv-1Uo">
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"/>
44− </view>
45− </subviews>
46− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
47− <constraints>
48− <constraint firstItem="ghQ-Jv-1Uo" firstAttribute="leading" secondItem="qeh-vb-wIH" secondAttribute="leading" id="6ue-fN-8T9"/>
49− <constraint firstAttribute="bottom" secondItem="uNU-TW-vfq" secondAttribute="bottom" constant="20" symbolic="YES" id="CEP-Ac-DSe"/>
50− <constraint firstItem="uNU-TW-vfq" firstAttribute="leading" secondItem="qeh-vb-wIH" secondAttribute="leading" id="Ff2-mz-GAH"/>
51− <constraint firstItem="ghQ-Jv-1Uo" firstAttribute="top" secondItem="qeh-vb-wIH" secondAttribute="top" id="MMC-Og-ggL"/>
52− <constraint firstItem="uNU-TW-vfq" firstAttribute="trailing" secondItem="qeh-vb-wIH" secondAttribute="trailing" id="fRe-ZZ-rez"/>
53− <constraint firstItem="ghQ-Jv-1Uo" firstAttribute="trailing" secondItem="qeh-vb-wIH" secondAttribute="trailing" id="hPh-8O-if8"/>
54− <constraint firstItem="uNU-TW-vfq" firstAttribute="top" secondItem="ghQ-Jv-1Uo" secondAttribute="bottom" constant="8" symbolic="YES" id="rDO-oM-rwy"/>
55− </constraints>
56− <viewLayoutGuide key="safeArea" id="qeh-vb-wIH"/>
57− </view>
58− <connections>
59− <outlet property="mainContentView" destination="uNU-TW-vfq" id="Fy6-pC-ach"/>
60− <outlet property="tableContentView" destination="ghQ-Jv-1Uo" id="GN2-MW-a2J"/>
61− </connections>
62− </viewController>
63− <placeholder placeholderIdentifier="IBFirstResponder" id="LNT-df-eny" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
64− </objects>
65− <point key="canvasLocation" x="959.20000000000005" y="158.77061469265368"/>
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>
131− </scenes>
132−</document>
Hookah Tau/Controllers/Admin/Reservations/List of reservations/AdminReservationsController.swiftdeleted−219
@@ -1,219 +0,0 @@
1−//
2−// AdminReservationsController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 19/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class AdminReservationsController: BaseViewController {
12−
13− // MARK:- Properties
14−
15− /// Establishment id
16− var id: Int?
17−
18− var tableView: UITableView? = {
19− let tableView = UITableView()
20− tableView.backgroundColor = .white
21− return tableView
22− }()
23−
24− var contentView: UIView = {
25− let view = UIView()
26− view.translatesAutoresizingMaskIntoConstraints = false
27− return view
28− }()
29−
30− var noReservationsView: AdminNoReservationsView?
31−
32− var reservationsService: ReservationsService?
33−
34− weak var coordinator: AdminReservationsCoordinator?
35−
36− var refrControl: UIRefreshControl?
37−
38− var activityIndicator: UIActivityIndicatorView?
39−
40− var activeReservations: [ReservationWithUser] = [] {
41− didSet {
42− guard let empty = noReservationsView else { return }
43− if activeReservations.isEmpty {
44− contentView.bringSubviewToFront(empty)
45− empty.alpha = 1
46− } else {
47− contentView.sendSubviewToBack(empty)
48− tableView?.alpha = 1
49− }
50− activityIndicator?.stopAnimating()
51− tableView?.reloadData()
52− }
53− }
54−
55− override func viewDidLoad() {
56− super.viewDidLoad()
57−
58− reservationsService = ReservationsService(apiClient: APIClient.shared)
59− setupRefreshControl()
60− setUpContentView()
61− setupNavBar()
62− }
63−
64− override func viewDidAppear(_ animated: Bool) {
65− super.viewDidAppear(animated)
66−
67− performUpdate()
68− tabBarController?.tabBar.isHidden = false
69− }
70−
71− // MARK:- Setup
72−
73− func setupNavBar() {
74− self.navigationItem.title = "Брони"
75− navigationController?.navigationBar.prefersLargeTitles = true
76− navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(book))
77− }
78−
79− func setUpContentView() {
80− self.view.addSubviewThatFills(contentView)
81−
82− activityIndicator = UIActivityIndicatorView()
83− contentView.addSubviewThatFills(activityIndicator)
84− activityIndicator?.startAnimating()
85−
86− // empty
87− noReservationsView = AdminNoReservationsView.loadFromNib()
88− contentView.addSubviewThatFills(noReservationsView)
89− noReservationsView?.bookButton?.addTarget(self, action: #selector(book), for: .touchUpInside)
90−
91− noReservationsView?.alpha = 0
92−
93− // table
94− contentView.addSubviewThatFills(tableView)
95−
96− setUpTableView()
97− }
98−
99− func setUpTableView() {
100− tableView?.delegate = self
101− tableView?.dataSource = self
102−
103− tableView?.alpha = 0
104−
105− tableView?.register(AdminReservationCell.self, forCellReuseIdentifier: adminReservationCellId)
106− }
107−
108− func performUpdate() {
109−
110− guard let id = id else { return }
111−
112− reservationsService?.getAdminReservations(establishmentId: id, completion: { [weak self] (result) in
113− switch result {
114− case .success(let reservations):
115− self?.activeReservations = reservations
116− case .failure(let err):
117− self?.displayAlert(forError: err)
118− }
119− self?.refrControl?.endRefreshing()
120− })
121− }
122−
123− // MARK:- Button handler
124−
125− @objc func book() {
126− guard let establishmentId = id else { return }
127− coordinator?.book(inEstablishment: establishmentId)
128− }
129−
130− func deleteReservation(uuid: String, completion: @escaping (([ReservationWithUser]?) -> Void)) {
131− reservationsService?.deleteReservation(isAdmin: true, uuid: uuid) { result in
132− if result {
133− let newReservations = self.activeReservations.filter { $0.uuid != uuid }
134− completion(newReservations)
135− return
136− }
137−
138− completion(nil)
139− }
140− }
141−
142− // MARK: - Refresh control
143−
144− @objc func refreshData( _ ff: UIRefreshControl) {
145− performUpdate()
146− }
147−
148− func setupRefreshControl() {
149− refrControl = UIRefreshControl()
150− tableView?.refreshControl = refrControl
151− refrControl?.addTarget(self, action: #selector(refreshData(_:)), for: .valueChanged)
152− }
153−
154−}
155−
156−
157−// MARK: - Table view data source
158−
159−extension AdminReservationsController: UITableViewDelegate, UITableViewDataSource {
160−
161− func numberOfSections(in tableView: UITableView) -> Int {
162− return 1
163− }
164−
165− func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
166− return activeReservations.count
167− }
168−
169− func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
170− let cell = tableView.dequeueReusableCell(withIdentifier: adminReservationCellId, for: indexPath) as! AdminReservationCell
171−
172− cell.bind(withModel: activeReservations[indexPath.row])
173− return cell
174− }
175−
176− func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
177− let reservation = activeReservations[indexPath.row]
178− coordinator?.seeExistingReservation(data: reservation)
179− }
180−
181− // Dimesions
182−
183− func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
184− return UITableView.automaticDimension
185− }
186−
187− func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
188− return 180.0
189− }
190−
191− // Update
192−
193− func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
194− return true
195− }
196−
197− func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
198−
199− guard let uuid = activeReservations[indexPath.row].uuid else { return [] }
200− let cancelButton = UITableViewRowAction(style: .normal, title: "отменить бронь") { _,_ in
201−
202− self.deleteReservation(uuid: uuid) { optionalNewVal in
203− if let newval = optionalNewVal {
204− self.tableView?.beginUpdates()
205− self.tableView?.deleteRows(at: [indexPath], with: .automatic)
206− self.activeReservations = newval
207− self.tableView?.endUpdates()
208− } else {
209− self.displayAlert(with: "Не удалось удалить вашу бронь! Попробуйте еще раз!")
210− }
211− }
212− }
213−
214− cancelButton.backgroundColor = .black
215−
216− return [cancelButton]
217− }
218−
219−}
Hookah Tau/Controllers/Admin/Reservations/List of reservations/AdminReservationsCoordinator.swiftdeleted−54
@@ -1,54 +0,0 @@
1−//
2−// AdminReservationsCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 19/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class AdminReservationsCoordinator: BaseCoordinator {
12−
13− // MARK: - Properties
14−
15− var didFinish: (() -> Void)?
16−
17− var establishmentId: Int?
18−
19− // MARK: - Lifecycle
20−
21− override func start() {
22− let storyboard = UIStoryboard(name: "AdminReservations", bundle: nil)
23− let vc = storyboard.instantiateViewController(withIdentifier: "AdminReservationsController") as! AdminReservationsController
24− vc.id = establishmentId
25− vc.coordinator = self
26−
27− navigationController?.pushViewController(vc, animated: true)
28− }
29−
30− func seeExistingReservation(data: ReservationWithUser) {
31− let reservationCoordinator = AdminReservationEditingCoordinator(navigationController: navigationController)
32− addDependency(reservationCoordinator)
33− reservationCoordinator.reservationData = data
34− reservationCoordinator.didEndFlow = { [weak self] in
35− self?.removeDependency(reservationCoordinator)
36− self?.navigationController?.popViewController(animated: true)
37− }
38− reservationCoordinator.start()
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− }
54−}
Hookah Tau/Controllers/Admin/Reservations/List of reservations/Cell/AdminReservationCellView.swiftdeleted−84
@@ -1,84 +0,0 @@
1−//
2−// AdminReservationCell.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 19/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−let adminReservationCellId = "AdminReservationCell"
12−
13−class AdminReservationCell: UITableViewCell {
14− // MARK: - Properties
15−
16− var reservationCellView: AdminReservationCellView?
17−
18− // MARK: - Init
19−
20− override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
21− {
22− super.init(style: style, reuseIdentifier: reuseIdentifier)
23−
24− reservationCellView = AdminReservationCellView.loadFromNib()
25− contentView.addSubviewThatFills(reservationCellView)
26−
27− self.selectionStyle = .none
28− }
29−
30− required init?(coder aDecoder: NSCoder)
31− {
32− fatalError("init(coder:) has not been implemented")
33− }
34−
35− // MARK: - Data
36−
37− func bind(withModel model: ReservationWithUser) {
38− reservationCellView?.bind(withModel: model)
39− }
40−}
41−
42−class AdminReservationCellView: UIView {
43−
44− // MARK:- IBAOutlets
45−
46− @IBOutlet weak var tableImage: UIImageView?
47−
48− @IBOutlet weak var guestNumber: UILabel?
49−
50− @IBOutlet weak var dateLabel: UILabel?
51−
52− @IBOutlet weak var timeLabel: UILabel?
53−
54− @IBOutlet weak var personLabel: UILabel?
55−
56− // MARK: - Lifecycle
57−
58− override func awakeFromNib() {
59− super.awakeFromNib()
60− // Initialization code
61− }
62−
63− // MARK: - bind
64−
65− func bind(withModel model: ReservationWithUser) {
66− let (date, time) = Date.format(model.startTime, model.endTime)
67−
68− dateLabel?.text = date
69− timeLabel?.text = time
70−
71− guestNumber?.text = setPeople(number: model.numberOfGuests)
72− personLabel?.text = model.owner.name ?? "❔❔❔"
73− tableImage?.image = TotalStorage.standard.getTable(establishment: model.establishment, table: model.reservedTable)?.image
74− }
75−
76− func setPeople(number: Int) -> String {
77− switch number {
78− case 2...4:
79− return "\(number) человека"
80− default:
81− return "\(number) человек"
82− }
83− }
84−}
Hookah Tau/Controllers/Admin/Reservations/List of reservations/Cell/AdminReservationCellView.xibdeleted−83
@@ -1,83 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
7− <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8− <capability name="Stack View standard spacing" minToolsVersion="9.0"/>
9− <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
10− </dependencies>
11− <objects>
12− <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
13− <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
14− <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="AdminReservationCellView" customModule="Hookah_Tau" customModuleProvider="target">
15− <rect key="frame" x="0.0" y="0.0" width="414" height="180"/>
16− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
17− <subviews>
18− <stackView opaque="NO" contentMode="scaleToFill" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="au9-nK-XbR">
19− <rect key="frame" x="20" y="20" width="374" height="140"/>
20− <subviews>
21− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="top" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="rCf-m8-E3w">
22− <rect key="frame" x="0.0" y="0.0" width="248" height="140"/>
23− <subviews>
24− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Стасик" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KV8-UG-2ws">
25− <rect key="frame" x="0.0" y="0.0" width="54" height="19.5"/>
26− <fontDescription key="fontDescription" type="system" pointSize="16"/>
27− <color key="textColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="calibratedRGB"/>
28− <nil key="highlightedColor"/>
29− </label>
30− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="nsQ-SE-3vW">
31− <rect key="frame" x="0.0" y="47" width="102" height="45"/>
32− <subviews>
33− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="27 марта" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9k3-E5-XKR">
34− <rect key="frame" x="0.0" y="0.0" width="76.5" height="20.5"/>
35− <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
36− <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
37− <nil key="highlightedColor"/>
38− </label>
39− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3:00 — 5:30" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IdW-5d-DS0">
40− <rect key="frame" x="0.0" y="24.5" width="102" height="20.5"/>
41− <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
42− <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
43− <nil key="highlightedColor"/>
44− </label>
45− </subviews>
46− </stackView>
47− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3 человека" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VhL-qH-zM9">
48− <rect key="frame" x="0.0" y="119.5" width="89" height="20.5"/>
49− <fontDescription key="fontDescription" type="system" pointSize="17"/>
50− <nil key="textColor"/>
51− <nil key="highlightedColor"/>
52− </label>
53− </subviews>
54− </stackView>
55− <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="1_7" translatesAutoresizingMaskIntoConstraints="NO" id="Oa6-n7-joV">
56− <rect key="frame" x="256" y="0.0" width="118" height="140"/>
57− </imageView>
58− </subviews>
59− </stackView>
60− </subviews>
61− <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
62− <constraints>
63− <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="au9-nK-XbR" secondAttribute="trailing" constant="20" id="Afx-VC-Cb6"/>
64− <constraint firstItem="au9-nK-XbR" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="20" id="P5E-WG-AYe"/>
65− <constraint firstItem="au9-nK-XbR" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" constant="-20" id="Z6h-RB-tvj"/>
66− <constraint firstItem="au9-nK-XbR" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="20" id="fJE-La-qC6"/>
67− </constraints>
68− <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
69− <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
70− <connections>
71− <outlet property="dateLabel" destination="9k3-E5-XKR" id="wBe-yq-PN9"/>
72− <outlet property="guestNumber" destination="VhL-qH-zM9" id="Ent-pM-uER"/>
73− <outlet property="personLabel" destination="KV8-UG-2ws" id="eYB-qn-fJL"/>
74− <outlet property="tableImage" destination="Oa6-n7-joV" id="cyD-bY-OpP"/>
75− <outlet property="timeLabel" destination="IdW-5d-DS0" id="ddO-Dx-LDK"/>
76− </connections>
77− <point key="canvasLocation" x="137.59999999999999" y="90.854572713643179"/>
78− </view>
79− </objects>
80− <resources>
81− <image name="1_7" width="118" height="133"/>
82− </resources>
83−</document>
Hookah Tau/Controllers/Admin/Reservations/Making a reeservation/1/AdminFirstStepReservationViewCoordinator.swiftdeleted−108
@@ -1,108 +0,0 @@
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.swiftdeleted−124
@@ -1,124 +0,0 @@
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.swiftdeleted−54
@@ -1,54 +0,0 @@
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.swiftdeleted−47
@@ -1,47 +0,0 @@
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.swiftdeleted−371
@@ -1,371 +0,0 @@
1−//
2−// AdminReservationView.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 19/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class AdminReservationView: UIView {
12−
13− // MARK:- IBAOutlets
14−
15− @IBOutlet weak var tableLabel: UILabel?
16−
17− @IBOutlet weak var dateLabel: UILabel?
18−
19− @IBOutlet weak var timeLabel: UILabel?
20−
21− @IBOutlet weak var cancelButton: Button? {
22− didSet {
23− let style = BlackButtonStyle()
24− style.apply(to: cancelButton, withTitle: "ОТМЕНИТЬ")
25− }
26− }
27−
28− @IBOutlet weak var nameLabel: UILabel?
29−
30− @IBOutlet weak var callButton: Button?
31−
32− @IBOutlet weak var numberOfGuestLabel: UILabel?
33−
34− @IBOutlet weak var guestSlider: UISlider?
35−
36− @IBOutlet weak var intervalsContainerView: UIView?
37−
38− @IBOutlet weak var scrollView: UIScrollView!
39−
40− @IBOutlet weak var intervalsStackView: UIStackView!
41−
42− @IBOutlet weak var saveButton: Button? {
43− didSet {
44− let style = BlackButtonStyle()
45− style.apply(to: saveButton, withTitle: "СОХРАНИТЬ")
46− }
47− }
48−
49− // MARK: - Properties
50−
51− // констрейнты начала и конца интервала
52− var startLeadingConstraint: NSLayoutConstraint!
53− var endLeadingConstraint: NSLayoutConstraint!
54−
55− var startPoint: UIImageView = {
56− var view = UIImageView()
57− view.isUserInteractionEnabled = true
58− view.image = #imageLiteral(resourceName: "handle_left")
59− view.translatesAutoresizingMaskIntoConstraints = false
60− return view
61− }()
62−
63− var endPoint: UIImageView = {
64− var view = UIImageView()
65− view.isUserInteractionEnabled = true
66− view.image = #imageLiteral(resourceName: "Group")
67− view.translatesAutoresizingMaskIntoConstraints = false
68− return view
69− }()
70−
71− /// Интервал
72− var fillInterval: UIView = {
73− var view = UIView()
74− view.backgroundColor = #colorLiteral(red: 0, green: 0.5921568627, blue: 1, alpha: 0.3426262843)
75− view.translatesAutoresizingMaskIntoConstraints = false
76− return view
77− }()
78−
79− /// Время начала вертелки.
80− /// Для клиента это 12:00 смены (надо вызвать метод для получения текущей смены).
81− /// Для администратора это `t` - 24h
82− var startDate: Date?
83−
84− // MARK:- Properties
85−
86− var intervalPickerView: IntervalPickerView?
87−
88− /// Модель вьюшки.
89− /// Обновляем каждый раз когда меняется время и дата
90− var data: ReservationData?
91−
92− var model: ReservationWithUser?
93−
94− // MARK: - Setup
95−
96− func bind(withModel model: ReservationWithUser) {
97− let style = BlackButtonStyle()
98− style.apply(to: callButton, withTitle: model.owner.phoneNumber.formattedNumber())
99−
100−
101− let (date, time) = Date.format(model.startTime, model.endTime)
102− dateLabel?.text = date
103− timeLabel?.text = time
104−
105− tableLabel?.text = "\(model.reservedTable) столик"
106− nameLabel?.text = "\(model.owner.name ?? "❔")"
107−
108− data = ReservationData(establishment: model.establishment,
109− startTime: model.startTime,
110− endTime: model.endTime,
111− numberOfGuests: model.numberOfGuests,
112− reservedTable: model.reservedTable)
113− self.model = model
114−
115− let (start, _) = model.owner.isAdmin ? model.startTime.getAdminStartingAndEndPoint() : model.startTime.getClientStartingAndEndPoint()
116−
117− startDate = start
118−
119− setUpIntervals()
120−
121− guestSlider?.maximumValue = Float((TotalStorage.standard.getTable(establishment: model.establishment, table: model.reservedTable)?.maxGuestNumber ?? 2) + 1)
122− }
123−
124− func bind(withIntervals intervals: [ReservationPeriod]) {
125− guard
126− let data = data,
127− let isAdmin = model?.owner.isAdmin
128− else { return }
129−
130− setUpReservedIntervals(intervals, isAdmin)
131− setUpBookingPeriod(data.startTime, data.endTime)
132− }
133−
134− func updateDateAndTime(withData d: ReservationData?) {
135− guard let d = d else { return }
136− let (date, time) = Date.format(d.startTime, d.endTime)
137−
138− dateLabel?.text = date
139− timeLabel?.text = time
140− }
141−
142− @IBAction func valueChanged(_ sender: UISlider) {
143− let value = Int(sender.value)
144−
145− if sender.value == sender.maximumValue {
146− numberOfGuestLabel?.text = "Количество гостей: \(Int(value) - 1)+"
147− } else {
148− numberOfGuestLabel?.text = "Количество гостей: \(value)"
149− }
150−
151− guard let d = data else { return }
152−
153− data = ReservationData(establishment: d.establishment,
154− startTime: d.startTime,
155− endTime: d.endTime,
156− numberOfGuests: value,
157− reservedTable: d.reservedTable)
158− }
159−
160−
161− func getNumberOfCalians(_ sliderValue: Int) -> String {
162− return "Минимальное количество кальянов: \(sliderValue > 6 ? 2 : 1)"
163− }
164−
165− // MARK: - Setup
166−
167− /// Тут происходит установка интервалов. Разное для клиента и админа
168− func setUpIntervals() {
169− guard let startPoint = startDate else { return }
170−
171− let startingPoint = startPoint.getAdminsStartingPoint()
172− let endingPoint = Constants.adminDuration
173−
174− for period in startingPoint...endingPoint {
175− let timePointView = TimePointView.loadFromNib()
176− timePointView?.setUp(withTimePoint: period)
177− let view = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 106))
178− view.addSubviewThatFills(timePointView)
179− intervalsStackView.addArrangedSubview(view)
180− }
181− }
182−
183−
184− private func setUpBookingPeriod(_ startTime: Date, _ endTime: Date? = nil) {
185− self.scrollView.addSubview(startPoint)
186− self.scrollView.addSubview(endPoint)
187− self.scrollView.addSubview(fillInterval)
188−
189− guard let startDate = startDate else { return }
190−
191− let startConstr = CGFloat(startTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint)
192−
193− scrollView.setContentOffset(CGPoint(x: startConstr - 50, y: 0), animated: true)
194−
195− startLeadingConstraint = startPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
196− constant: startConstr)
197−
198− if let end = endTime {
199− let endConstr = CGFloat(end.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint)
200− endLeadingConstraint = endPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
201− constant: endConstr)
202− } else {
203− endLeadingConstraint = endPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
204− constant:startConstr + Constants.minBookingLength)
205− }
206−
207− NSLayoutConstraint.activate([
208−
209− startPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
210− endPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
211−
212− startPoint.widthAnchor.constraint(equalToConstant: Constants.pointWidth),
213− endPoint.widthAnchor.constraint(equalToConstant: Constants.pointWidth),
214−
215− startPoint.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
216− endPoint.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
217−
218− startLeadingConstraint,
219− endLeadingConstraint,
220−
221− fillInterval.leftAnchor.constraint(equalTo: startPoint.rightAnchor, constant: 0),
222− fillInterval.rightAnchor.constraint(equalTo: endPoint.leftAnchor, constant: 0),
223−
224− fillInterval.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
225− fillInterval.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0)
226− ])
227−
228− let scrollViewPanStartGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanStart(recognizer:)))
229− startPoint.addGestureRecognizer(scrollViewPanStartGesture)
230−
231− let scrollViewPanEndGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanEnd(recognizer:)))
232− endPoint.addGestureRecognizer(scrollViewPanEndGesture)
233− }
234−
235− func setUpReservedIntervals(_ reservations: [ReservationPeriod], _ isAdmin: Bool) {
236−
237− for reservation in reservations {
238− let uiview = UIView(frame: CGRect(x: 0, y: 0, width: Constants.widthTimePoint * reservation.duration, height: Constants.heightIntervals))
239− uiview.backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 0.5)
240−
241−
242− uiview.translatesAutoresizingMaskIntoConstraints = false
243− scrollView.addSubview(uiview)
244−
245− guard let startDate = startDate else { return }
246−
247− let s = reservation.startTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint
248− let d = reservation.duration * Constants.widthTimePoint
249−
250− let startTime = s < 0 ? 0 : s
251−
252− let total = (isAdmin ? Constants.adminDuration : Constants.clientDuration) * Constants.widthTimePoint
253− var duration = 0
254− if s < 0 {
255− duration = reservation.endTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint
256− } else {
257− duration = (s + d) > total ? total - s : d
258− }
259−
260− NSLayoutConstraint.activate([
261− uiview.bottomAnchor.constraint(equalToSystemSpacingBelow: scrollView.bottomAnchor, multiplier: 0),
262− uiview.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
263− constant: CGFloat(Constants.widthTimePoint / 2 + startTime)),
264− uiview.widthAnchor.constraint(equalToConstant: CGFloat(duration)),
265− uiview.heightAnchor.constraint(equalToConstant: CGFloat(Constants.heightIntervals))
266− ])
267− }
268− }
269−
270− // MARK: - Pan
271−
272− @objc func handlePanStart(recognizer:UIPanGestureRecognizer) {
273−
274− let translation = recognizer.translation(in: self.intervalsStackView)
275− let duration = abs(startLeadingConstraint.constant + translation.x - endLeadingConstraint.constant)
276−
277− if let view = recognizer.view, duration >= Constants.minBookingLength {
278− startLeadingConstraint.constant += translation.x
279−
280− changeTime(startLeadingConstraint, .start)
281−
282− view.setNeedsUpdateConstraints()
283− }
284−
285− recognizer.setTranslation(CGPoint.zero, in: self.intervalsStackView)
286− }
287−
288− @objc func handlePanEnd(recognizer:UIPanGestureRecognizer) {
289−
290− let translation = recognizer.translation(in: self.intervalsStackView)
291− let duration = abs(startLeadingConstraint.constant - (endLeadingConstraint.constant + translation.x))
292−
293− if let view = recognizer.view, duration >= Constants.minBookingLength {
294− endLeadingConstraint.constant += translation.x
295−
296− changeTime(endLeadingConstraint, .end)
297− view.setNeedsUpdateConstraints()
298− }
299−
300− recognizer.setTranslation(CGPoint.zero, in: self.intervalsStackView)
301− }
302−
303− func changeTime(_ constraint: NSLayoutConstraint, _ period: Period) {
304− guard let startDate = startDate, let d = data else { return }
305−
306− let offset = Int(constraint.constant) % Constants.widthTimePoint
307−
308− if offset == 0 {
309− let p = Int(constraint.constant) / Constants.widthTimePoint
310− let time = startDate.addPeriods(p)
311−
312− switch period {
313− case .start:
314− data = ReservationData(establishment: d.establishment,
315− startTime: time,
316− endTime: d.endTime,
317− numberOfGuests: d.numberOfGuests,
318− reservedTable: d.reservedTable)
319− case .end:
320− data = ReservationData(establishment: d.establishment,
321− startTime: d.startTime,
322− endTime: time,
323− numberOfGuests: d.numberOfGuests,
324− reservedTable: d.reservedTable)
325− }
326−
327− updateDateAndTime(withData: data)
328− }
329− }
330−}
331−
332−// MARK: - Nested types
333−
334−extension AdminReservationView {
335− enum Constants {
336− static let widthTimePoint = 11
337−
338− static let adminDuration = 288
339− static let clientDuration = 90
340− // 12:00 = 12 * 6
341− static let clientStartingPoint = 72
342−
343− static let pointWidth: CGFloat = 19
344− static let pointHeight: CGFloat = 85
345−
346− static let minBookingLength: CGFloat = 132
347−
348− static let heightIntervals = 85
349− }
350−
351− enum Period {
352− case start
353− case end
354− }
355−}
356−
357−
358−extension AdminReservationView: PickerViewUpdater {
359−
360− func update(withModel model: IntervalPickerModel) {
361− guard let d = data else { return }
362−
363− data = ReservationData(establishment: d.establishment,
364− startTime: model.startTime,
365− endTime: model.endTime,
366− numberOfGuests: d.numberOfGuests,
367− reservedTable: d.reservedTable)
368−
369− updateDateAndTime(withData: data)
370− }
371−}
Hookah Tau/Controllers/Admin/Reservations/Views/AdminReservationView.xibdeleted−223
@@ -1,223 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
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="AdminReservationView" customModule="Hookah_Tau" customModuleProvider="target">
14− <rect key="frame" x="0.0" y="0.0" width="414" height="385"/>
15− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16− <subviews>
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="349"/>
19− <subviews>
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="136.5"/>
22− <subviews>
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"/>
25− <subviews>
26− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="hEV-kW-bBH">
27− <rect key="frame" x="0.0" y="0.0" width="129" height="77.5"/>
28− <subviews>
29− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="7 столик" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qNR-EO-oMK">
30− <rect key="frame" x="0.0" y="0.0" width="93" height="26.5"/>
31− <fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
32− <nil key="textColor"/>
33− <nil key="highlightedColor"/>
34− </label>
35− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="29 марта" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KHM-Yj-bBa">
36− <rect key="frame" x="0.0" y="31.5" width="78" height="20.5"/>
37− <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
38− <nil key="textColor"/>
39− <nil key="highlightedColor"/>
40− </label>
41− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3:00 — 5:00ffff" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gau-aS-vtT">
42− <rect key="frame" x="0.0" y="57" width="129" height="20.5"/>
43− <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
44− <nil key="textColor"/>
45− <nil key="highlightedColor"/>
46− </label>
47− </subviews>
48− <constraints>
49− <constraint firstAttribute="trailing" secondItem="gau-aS-vtT" secondAttribute="trailing" id="OYu-7e-8pX"/>
50− <constraint firstItem="gau-aS-vtT" firstAttribute="leading" secondItem="hEV-kW-bBH" secondAttribute="leading" id="egK-i8-r2N"/>
51− </constraints>
52− </stackView>
53− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iiD-uf-IDp" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
54− <rect key="frame" x="0.0" y="99.5" width="109" height="37"/>
55− <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
56− <constraints>
57− <constraint firstAttribute="width" constant="109" id="11r-IB-3r0"/>
58− <constraint firstAttribute="height" constant="37" id="aej-Xt-jCJ"/>
59− </constraints>
60− <state key="normal" title="Button"/>
61− </button>
62− </subviews>
63− <constraints>
64− <constraint firstAttribute="trailing" secondItem="hEV-kW-bBH" secondAttribute="trailing" id="7MI-YT-uHi"/>
65− <constraint firstAttribute="width" constant="129" id="BQh-sd-jbL"/>
66− <constraint firstItem="hEV-kW-bBH" firstAttribute="leading" secondItem="IY6-F4-aln" secondAttribute="leading" id="tsb-PN-YGB"/>
67− </constraints>
68− </stackView>
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="136.5"/>
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>
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">
76− <rect key="frame" x="95.5" y="0.0" width="78.5" height="26.5"/>
77− <fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
78− <nil key="textColor"/>
79− <nil key="highlightedColor"/>
80− </label>
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">
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"/>
94− <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
95− <constraints>
96− <constraint firstAttribute="width" constant="136" id="jg5-lP-Ekd"/>
97− <constraint firstAttribute="height" constant="37" id="w98-8a-pmH"/>
98− </constraints>
99− <state key="normal" title="Button"/>
100− </button>
101− </subviews>
102− </stackView>
103− </subviews>
104− </stackView>
105− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="9RO-aK-yNh">
106− <rect key="frame" x="21" y="160.5" width="372" height="58.5"/>
107− <subviews>
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">
109− <rect key="frame" x="0.0" y="0.0" width="372" height="20.5"/>
110− <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
111− <nil key="textColor"/>
112− <nil key="highlightedColor"/>
113− </label>
114− <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="2" minValue="1" maxValue="8" translatesAutoresizingMaskIntoConstraints="NO" id="Lqw-9Z-34d">
115− <rect key="frame" x="-2" y="28.5" width="376" height="31"/>
116− <connections>
117− <action selector="valueChanged:" destination="iN0-l3-epB" eventType="valueChanged" id="OwE-Nq-PHY"/>
118− </connections>
119− </slider>
120− </subviews>
121− </stackView>
122− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vKS-ia-RxW">
123− <rect key="frame" x="0.0" y="243" width="414" height="106"/>
124− <subviews>
125− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EiP-QO-PbU">
126− <rect key="frame" x="0.0" y="20" width="414" height="85"/>
127− <subviews>
128− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OpX-io-LgH">
129− <rect key="frame" x="0.0" y="0.0" width="414" height="1"/>
130− <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
131− <constraints>
132− <constraint firstAttribute="height" constant="1" id="k2D-mj-31b"/>
133− </constraints>
134− </view>
135− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fOe-cM-riJ">
136− <rect key="frame" x="0.0" y="84" width="414" height="1"/>
137− <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
138− <constraints>
139− <constraint firstAttribute="height" constant="1" id="A2B-su-3Hi"/>
140− </constraints>
141− </view>
142− </subviews>
143− <color key="backgroundColor" red="0.8901960784313725" green="0.8901960784313725" blue="0.8901960784313725" alpha="0.6951519692" colorSpace="calibratedRGB"/>
144− <constraints>
145− <constraint firstItem="OpX-io-LgH" firstAttribute="top" secondItem="EiP-QO-PbU" secondAttribute="top" id="73d-6U-4Jc"/>
146− <constraint firstAttribute="height" constant="85" id="JMc-tA-wHe"/>
147− <constraint firstAttribute="trailing" secondItem="fOe-cM-riJ" secondAttribute="trailing" id="JVQ-ub-pEy"/>
148− <constraint firstItem="OpX-io-LgH" firstAttribute="leading" secondItem="EiP-QO-PbU" secondAttribute="leading" id="hBd-hJ-yz7"/>
149− <constraint firstAttribute="bottom" secondItem="fOe-cM-riJ" secondAttribute="bottom" id="im0-y1-nC8"/>
150− <constraint firstItem="fOe-cM-riJ" firstAttribute="leading" secondItem="EiP-QO-PbU" secondAttribute="leading" id="qH9-Ww-nd5"/>
151− <constraint firstAttribute="trailing" secondItem="OpX-io-LgH" secondAttribute="trailing" id="ueR-ZM-ELi"/>
152− </constraints>
153− </view>
154− <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="trF-VM-0qV">
155− <rect key="frame" x="0.0" y="0.0" width="414" height="106"/>
156− <subviews>
157− <stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bpJ-pe-tQf">
158− <rect key="frame" x="0.0" y="0.0" width="414" height="106"/>
159− </stackView>
160− </subviews>
161− <constraints>
162− <constraint firstAttribute="bottom" secondItem="bpJ-pe-tQf" secondAttribute="bottom" id="BxY-h0-LHi"/>
163− <constraint firstItem="bpJ-pe-tQf" firstAttribute="leading" secondItem="trF-VM-0qV" secondAttribute="leading" id="Ec5-Lb-NsX"/>
164− <constraint firstAttribute="trailing" secondItem="bpJ-pe-tQf" secondAttribute="trailing" id="d0a-8z-CE6"/>
165− <constraint firstItem="bpJ-pe-tQf" firstAttribute="width" secondItem="trF-VM-0qV" secondAttribute="width" priority="250" id="mYw-sK-G8B"/>
166− <constraint firstItem="bpJ-pe-tQf" firstAttribute="height" secondItem="trF-VM-0qV" secondAttribute="height" id="wdB-oa-hvt"/>
167− <constraint firstItem="bpJ-pe-tQf" firstAttribute="top" secondItem="trF-VM-0qV" secondAttribute="top" id="x6e-gw-nXA"/>
168− </constraints>
169− <viewLayoutGuide key="contentLayoutGuide" id="QAB-NG-eb4"/>
170− <viewLayoutGuide key="frameLayoutGuide" id="xUW-w2-Jj1"/>
171− </scrollView>
172− </subviews>
173− <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
174− <constraints>
175− <constraint firstAttribute="bottom" secondItem="trF-VM-0qV" secondAttribute="bottom" id="4kT-64-W5t"/>
176− <constraint firstItem="trF-VM-0qV" firstAttribute="top" secondItem="vKS-ia-RxW" secondAttribute="top" id="M4X-6f-0WX"/>
177− <constraint firstItem="trF-VM-0qV" firstAttribute="leading" secondItem="vKS-ia-RxW" secondAttribute="leading" id="ZXK-Vm-o6S"/>
178− <constraint firstAttribute="trailing" secondItem="trF-VM-0qV" secondAttribute="trailing" id="a2R-kF-NcS"/>
179− <constraint firstAttribute="height" constant="106" id="ebp-l7-k9Z"/>
180− <constraint firstItem="EiP-QO-PbU" firstAttribute="leading" secondItem="vKS-ia-RxW" secondAttribute="leading" id="fHc-26-5lu"/>
181− <constraint firstAttribute="bottom" secondItem="EiP-QO-PbU" secondAttribute="bottom" constant="1" id="kxj-VY-srA"/>
182− <constraint firstAttribute="trailing" secondItem="EiP-QO-PbU" secondAttribute="trailing" id="sbQ-sE-GAh"/>
183− </constraints>
184− </view>
185− </subviews>
186− <constraints>
187− <constraint firstItem="vKS-ia-RxW" firstAttribute="leading" secondItem="AEf-R4-K1F" secondAttribute="leading" id="0cO-AV-PJL"/>
188− <constraint firstAttribute="trailing" secondItem="oh7-ka-ctS" secondAttribute="trailing" constant="21" id="KeE-6F-h5x"/>
189− <constraint firstAttribute="trailing" secondItem="9RO-aK-yNh" secondAttribute="trailing" constant="21" id="Kh6-4l-QJO"/>
190− <constraint firstAttribute="bottom" secondItem="vKS-ia-RxW" secondAttribute="bottom" id="TKW-xo-b61"/>
191− <constraint firstItem="9RO-aK-yNh" firstAttribute="leading" secondItem="AEf-R4-K1F" secondAttribute="leading" constant="21" id="Teg-kp-nZt"/>
192− <constraint firstItem="oh7-ka-ctS" firstAttribute="leading" secondItem="AEf-R4-K1F" secondAttribute="leading" constant="21" id="mJ2-gh-vCg"/>
193− <constraint firstAttribute="trailing" secondItem="vKS-ia-RxW" secondAttribute="trailing" id="uDV-uM-jby"/>
194− </constraints>
195− </stackView>
196− </subviews>
197− <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
198− <constraints>
199− <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="AEf-R4-K1F" secondAttribute="trailing" id="C1h-bA-S6p"/>
200− <constraint firstItem="AEf-R4-K1F" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="H1o-ua-Tnn"/>
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"/>
203− </constraints>
204− <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
205− <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
206− <connections>
207− <outlet property="callButton" destination="Xkd-xQ-cFd" id="B3w-gf-Yqg"/>
208− <outlet property="cancelButton" destination="iiD-uf-IDp" id="zwd-eJ-GsP"/>
209− <outlet property="dateLabel" destination="KHM-Yj-bBa" id="iS8-eN-OFW"/>
210− <outlet property="guestSlider" destination="Lqw-9Z-34d" id="cEj-JF-J4D"/>
211− <outlet property="intervalsContainerView" destination="vKS-ia-RxW" id="0Ig-rh-hXD"/>
212− <outlet property="intervalsStackView" destination="bpJ-pe-tQf" id="aF0-Qm-kuh"/>
213− <outlet property="nameLabel" destination="OoG-F4-OVu" id="rnW-fG-jFs"/>
214− <outlet property="numberOfGuestLabel" destination="yTM-U5-XjI" id="z0O-94-Mp7"/>
215− <outlet property="saveButton" destination="npC-AF-3pj" id="Rfm-Zl-zES"/>
216− <outlet property="scrollView" destination="trF-VM-0qV" id="P5v-fg-hUW"/>
217− <outlet property="tableLabel" destination="qNR-EO-oMK" id="63P-AS-fgf"/>
218− <outlet property="timeLabel" destination="gau-aS-vtT" id="7Iy-Cz-zdY"/>
219− </connections>
220− <point key="canvasLocation" x="137.59999999999999" y="95.802098950524751"/>
221− </view>
222− </objects>
223−</document>
Hookah Tau/Controllers/Admin/Reservations/Views/No reserv/AdminNoReservationsView.swiftdeleted−27
@@ -1,27 +0,0 @@
1−//
2−// AdminNoReservationsView.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 19/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class AdminNoReservationsView: UIView {
12−
13− // MARK: - IBAOutlets
14−
15− @IBOutlet weak var titleLabel: UILabel?
16−
17− @IBOutlet weak var bookButton: Button? {
18− didSet {
19− let style = BlackButtonStyle()
20− style.apply(to: bookButton, withTitle: "ЗАБРОНИРОВАТЬ")
21− }
22− }
23−
24− func setup(withTitle title: String) {
25− titleLabel?.text = title
26− }
27−}
Hookah Tau/Controllers/Admin/Reservations/Views/No reserv/AdminNoReservationsView.xibdeleted−54
@@ -1,54 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
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="AdminNoReservationsView" customModule="Hookah_Tau" customModuleProvider="target">
14− <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
15− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16− <subviews>
17− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="46" translatesAutoresizingMaskIntoConstraints="NO" id="Ytd-08-vB9">
18− <rect key="frame" x="107" y="382" width="200" height="142"/>
19− <subviews>
20− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="В вашем заведении пока не забронирован ни один столик :(" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Svd-DB-3Zu">
21− <rect key="frame" x="4" y="0.0" width="192" height="61"/>
22− <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
23− <nil key="textColor"/>
24− <nil key="highlightedColor"/>
25− </label>
26− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="y3F-ua-mLb" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
27− <rect key="frame" x="12.5" y="107" width="175" height="35"/>
28− <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
29− <constraints>
30− <constraint firstAttribute="width" constant="175" id="LnY-Iu-4e6"/>
31− <constraint firstAttribute="height" constant="35" id="oN3-oc-fHx"/>
32− </constraints>
33− <state key="normal" title="Button"/>
34− </button>
35− </subviews>
36− <constraints>
37− <constraint firstAttribute="width" constant="200" id="pgG-jg-faG"/>
38− </constraints>
39− </stackView>
40− </subviews>
41− <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
42− <constraints>
43− <constraint firstItem="Ytd-08-vB9" firstAttribute="centerY" secondItem="vUN-kp-3ea" secondAttribute="centerY" id="ewL-z8-YVD"/>
44− <constraint firstItem="Ytd-08-vB9" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="txy-j9-mF1"/>
45− </constraints>
46− <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
47− <connections>
48− <outlet property="bookButton" destination="y3F-ua-mLb" id="aC4-gz-Gqd"/>
49− <outlet property="titleLabel" destination="Svd-DB-3Zu" id="n8Z-Wq-vzC"/>
50− </connections>
51− <point key="canvasLocation" x="137.68115942028987" y="91.741071428571431"/>
52− </view>
53− </objects>
54−</document>
Hookah Tau/Controllers/Admin/Tab bar/Admin.storyboarddeleted−84
@@ -1,84 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
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− <!--Клиенты-->
12− <scene sceneID="Q3i-Bo-7ns">
13− <objects>
14− <viewController id="Ifn-72-mgx" customClass="UINavigationController" sceneMemberID="viewController">
15− <view key="view" contentMode="scaleToFill" id="R2t-qa-IDx">
16− <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
17− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
19− <viewLayoutGuide key="safeArea" id="yHG-bf-ndj"/>
20− </view>
21− <tabBarItem key="tabBarItem" title="Клиенты" image="peoplee" id="9K1-uc-72H"/>
22− </viewController>
23− <placeholder placeholderIdentifier="IBFirstResponder" id="8X9-ca-bCi" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
24− </objects>
25− <point key="canvasLocation" x="1061" y="-327"/>
26− </scene>
27− <!--Профиль-->
28− <scene sceneID="cAb-sw-24k">
29− <objects>
30− <viewController id="Jsm-cH-XbJ" customClass="UINavigationController" sceneMemberID="viewController">
31− <view key="view" contentMode="scaleToFill" id="s24-jW-vhb">
32− <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
33− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
34− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
35− <viewLayoutGuide key="safeArea" id="f96-UV-eoi"/>
36− </view>
37− <tabBarItem key="tabBarItem" title="Профиль" image="person" id="ziF-T0-lg1"/>
38− </viewController>
39− <placeholder placeholderIdentifier="IBFirstResponder" id="qqi-vY-Mog" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
40− </objects>
41− <point key="canvasLocation" x="1061" y="433"/>
42− </scene>
43− <!--Брони-->
44− <scene sceneID="p6D-Gs-DUK">
45− <objects>
46− <viewController id="Tc3-UW-Fwi" customClass="UINavigationController" sceneMemberID="viewController">
47− <view key="view" contentMode="scaleToFill" id="dmc-GR-czf">
48− <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
49− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
50− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
51− <viewLayoutGuide key="safeArea" id="z8c-Ub-USh"/>
52− </view>
53− <tabBarItem key="tabBarItem" title="Брони" image="stack" id="szW-oN-ixR"/>
54− </viewController>
55− <placeholder placeholderIdentifier="IBFirstResponder" id="1ST-zr-4Zs" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
56− </objects>
57− <point key="canvasLocation" x="1062" y="-1047"/>
58− </scene>
59− <!--Admin Tabbar Controller-->
60− <scene sceneID="cWI-V1-4ZB">
61− <objects>
62− <tabBarController storyboardIdentifier="AdminTabbarController" id="mgG-ir-mFF" customClass="AdminTabbarController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
63− <tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="src-m7-O6h">
64− <rect key="frame" x="0.0" y="0.0" width="414" height="49"/>
65− <autoresizingMask key="autoresizingMask"/>
66− <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
67− </tabBar>
68− <connections>
69− <segue destination="Tc3-UW-Fwi" kind="relationship" relationship="viewControllers" id="K4a-6A-WdW"/>
70− <segue destination="Ifn-72-mgx" kind="relationship" relationship="viewControllers" id="NdV-rq-bli"/>
71− <segue destination="Jsm-cH-XbJ" kind="relationship" relationship="viewControllers" id="2PQ-04-zRb"/>
72− </connections>
73− </tabBarController>
74− <placeholder placeholderIdentifier="IBFirstResponder" id="oiC-tc-RNa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
75− </objects>
76− <point key="canvasLocation" x="-817" y="-251"/>
77− </scene>
78− </scenes>
79− <resources>
80− <image name="peoplee" width="51" height="25"/>
81− <image name="person" width="25" height="24"/>
82− <image name="stack" width="25" height="24"/>
83− </resources>
84−</document>
Hookah Tau/Controllers/Admin/Tab bar/AdminTabbarController.swiftdeleted−48
@@ -1,48 +0,0 @@
1−//
2−// AdminTabbarController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 05/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class AdminTabbarController: UITabBarController {
12−
13− // MARK: - Properties
14−
15− var onViewDidLoad: TabbarClosure?
16− var onReservationsFlow: TabbarClosure?
17− var onClientsFlow: TabbarClosure?
18− var onProfileFlow: TabbarClosure?
19−
20− // MARK: - Lifecycle
21−
22− override func viewDidLoad() {
23− super.viewDidLoad()
24−
25− delegate = self
26− if let controller = customizableViewControllers?.first as? UINavigationController {
27− onViewDidLoad?(controller)
28− }
29− }
30−
31− func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
32− {
33−
34− guard let controller = viewControllers?[selectedIndex] as? UINavigationController else { return }
35−
36− switch selectedIndex {
37− case 0:
38− onReservationsFlow?(controller)
39− case 1:
40− onClientsFlow?(controller)
41− default:
42− onProfileFlow?(controller)
43− }
44− }
45−
46−}
47−
48−extension AdminTabbarController: UITabBarControllerDelegate {}
Hookah Tau/Controllers/Admin/Tab bar/AdminTabbarCoordinator.swiftdeleted−73
@@ -1,73 +0,0 @@
1−//
2−// AdminTabbarCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 05/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−
12−class AdminTabbarCoordinator: BaseCoordinator {
13−
14− /// Мы тут определяем что происходит с таббарами
15− override func start() {
16− let storyboard = UIStoryboard(name: "Admin", bundle: nil)
17− let tabbarView = storyboard.instantiateViewController(withIdentifier: "AdminTabbarController") as? AdminTabbarController
18−
19− tabbarView?.onViewDidLoad = runReservationsFlow()
20− tabbarView?.onClientsFlow = runClientsFlow()
21− tabbarView?.onProfileFlow = runProfileFlow()
22− tabbarView?.onReservationsFlow = runReservationsFlow()
23−
24− let appDelegate = UIApplication.shared.delegate as? AppDelegate
25− guard let appD = appDelegate else { return }
26− appD.window?.rootViewController = tabbarView
27− }
28−
29− private func runReservationsFlow() -> TabbarClosure {
30− return { [unowned self] navigationController in
31− if navigationController.viewControllers.isEmpty {
32− let addressCoordinator = AdminAddressCoordinator(navigationController: navigationController)
33− self.addDependency(addressCoordinator)
34−
35− addressCoordinator.didEndFlow = {
36− self.removeDependency(addressCoordinator)
37− }
38−
39− addressCoordinator.start()
40− }
41− }
42− }
43−
44− private func runClientsFlow() -> TabbarClosure {
45− return { [unowned self] navigationController in
46− if navigationController.viewControllers.isEmpty {
47− let clientsCoordinator = ClientsCoordinator(navigationController: navigationController)
48− self.addDependency(clientsCoordinator)
49−
50− clientsCoordinator.didEndFlow = {
51− self.removeDependency(clientsCoordinator)
52− }
53−
54− clientsCoordinator.start()
55− }
56− }
57− }
58−
59− private func runProfileFlow() -> TabbarClosure {
60− return { [unowned self] navigationController in
61− if navigationController.viewControllers.isEmpty {
62− let profileCoordinator = ProfileCoordinator(navigationController: navigationController)
63− profileCoordinator.didEndFlow = { [weak self, weak profileCoordinator] in
64− self?.removeDependency(profileCoordinator)
65− self?.didEndFlow?()
66− }
67− self.addDependency(profileCoordinator)
68− profileCoordinator.start()
69− }
70− }
71− }
72−
73−}
Hookah Tau/Controllers/ApplicationCoordinator.swift+1−8
@@ -42,13 +42,7 @@ class ApplicationCoordinator: BaseCoordinator {
4242 }
4343
4444 private func runAdminFlow() {
45− let tabbarCoordinator = AdminTabbarCoordinator(navigationController: navigationController)
46− tabbarCoordinator.didEndFlow = { [weak self, weak tabbarCoordinator] in
47− self?.start()
48− self?.removeDependency(tabbarCoordinator)
49− }
50− addDependency(tabbarCoordinator)
51− tabbarCoordinator.start()
45+
5246 }
5347
5448 private func runClientFlow() {
@@ -72,7 +66,6 @@ extension ApplicationCoordinator {
7266 let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
7367
7468 if !isAuthorized {
75− DataStorage.standard.setLoggedInState(false)
7669 return .auth
7770 }
7871
Hookah Tau/Controllers/BaseTableViewController.swiftdeleted−28
@@ -1,28 +0,0 @@
1−//
2−// BaseTableViewController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 07/01/2020.
6−// Copyright © 2020 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class BaseTableViewController: UITableViewController {
12−
13− // MARK: - Alert
14−
15− func displayAlert(forError error: GeneralError = GeneralError.noData, with message: String? = nil) {
16− var title: String? = message == nil ? error.localizedDescription : message
17− switch error {
18− case .serverError(let se):
19− title = se.error
20− fallthrough // да тоже произведение искусства
21− default:
22− let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
23− alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
24− self.present(alert, animated: true, completion: nil)
25− }
26− }
27−
28−}
Hookah Tau/Controllers/BaseViewController.swift+3−3
@@ -97,7 +97,7 @@ class BaseViewController: UIViewController {
9797 }
9898
9999 @objc
100− func handleKeyboardNotifications(notification: NSNotification){
100+ private func handleKeyboardNotifications(notification: NSNotification){
101101 if let userInfo = notification.userInfo {
102102 let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
103103 bottomConstraint?.constant = notification.name == UIResponder.keyboardWillShowNotification ? -keyBoardFrame.height + view.safeAreaInsets.bottom - 20 : 0
@@ -110,8 +110,8 @@ class BaseViewController: UIViewController {
110110
111111 // MARK: - Alert
112112
113− func displayAlert(forError error: GeneralError = GeneralError.noData, with message: String? = nil) {
114− var title: String? = message == nil ? error.localizedDescription : message
113+ func displayAlert(forError error: GeneralError) {
114+ var title: String? = error.localizedDescription
115115 switch error {
116116 case .serverError(let se):
117117 title = se.error
Hookah Tau/Controllers/Client/Profile/ProfileChangeCoordinator.swift+4−6
@@ -29,12 +29,10 @@ class ProfileChangeCoordinator: BaseCoordinator {
2929 }
3030
3131 /// Done
32− func update(withModel model: User?) {
33− if let model = model {
34− for controller in navigationController?.viewControllers ?? [] {
35− guard let updatableController = controller as? UserUpdate else { continue }
36− updatableController.updateUser(withModel: model)
37− }
32+ func update(withModel model: User) {
33+ for controller in navigationController?.viewControllers ?? [] {
34+ guard let updatableController = controller as? UserUpdate else { continue }
35+ updatableController.updateUser(withModel: model)
3836 }
3937
4038 didEndFlow?()
Hookah Tau/Controllers/Client/Profile/ProfileChangeViewController.swift+3−22
@@ -23,8 +23,6 @@ class ProfileChangeViewController: BaseViewController {
2323
2424 var changeView: ChangeView?
2525
26− var settingsService: ClientsService?
27−
2826 var contentView: UIView = {
2927 let view = UIView()
3028 view.translatesAutoresizingMaskIntoConstraints = false
@@ -59,8 +57,6 @@ class ProfileChangeViewController: BaseViewController {
5957
6058 setUpView()
6159 setUpKeyboard()
62−
63− settingsService = ClientsService(apiClient: APIClient.shared)
6460 }
6561
6662 func setUpView() {
@@ -90,30 +86,15 @@ class ProfileChangeViewController: BaseViewController {
9086 var userModel = model.userModel
9187 switch model.editingOption {
9288 case .invite:
93− addNewAdmin(phone: text.toApiPhoneNumberFormat())
89+ print("New person is added")
90+ return
9491 case .name:
95− // TODO:-f
9692 userModel.name = text
97− coordinator?.update(withModel: userModel)
9893 case .phone:
99− // TODO:-
10094 userModel.phoneNumber = text
101− coordinator?.update(withModel: userModel)
10295 }
10396
97+ coordinator?.update(withModel: userModel)
10498 }
10599
106− func addNewAdmin(phone: String) {
107− doneButton.loading = true
108−
109− settingsService?.changeAdmin(crud: CrudMethod.put, data: phone) { [weak self] res in
110− if res {
111− self?.coordinator?.update(withModel: nil)
112− } else {
113− self?.displayAlert(with: "Что-то пошло не так!\nПопробуй еще раз")
114− }
115−
116− self?.doneButton.loading = false
117− }
118− }
119100}
Hookah Tau/Controllers/Client/Profile/Views/ChangeView.swift+1−32
@@ -11,20 +11,15 @@ import UIKit
1111
1212class ChangeView: UIView {
1313
14− var type: EditingOption = .invite
15−
1614 @IBOutlet weak var titleLabel: UILabel?
1715
1816 @IBOutlet weak var textField: UITextField?
1917
2018 func bind(withModel model: ChangeModel) {
21− self.textField?.delegate = self
22− self.type = model.editingOption
23−
2419 switch model.editingOption {
2520 case .invite:
2621 titleLabel?.text = "Добавить администратора"
27− textField?.placeholder = "+ 7 (888) 888-88-88"
22+ textField?.placeholder = "+ 7 888 888 88 88"
2823 textField?.keyboardType = .numberPad
2924 case .name:
3025 titleLabel?.text = "Имя"
@@ -37,29 +32,3 @@ class ChangeView: UIView {
3732 }
3833 }
3934}
40−
41−extension ChangeView: UITextFieldDelegate {
42−
43− func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
44− let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
45− textField.text = formattedNumber(newString)
46− return false
47− }
48−
49− private func formattedNumber(_ number: String) -> String {
50− let cleanPhoneNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
51−
52− var result = ""
53− let phoneMask = "+X (XXX) XXX XX XX"
54− var index = cleanPhoneNumber.startIndex
55− for ch in phoneMask where index < cleanPhoneNumber.endIndex {
56− if ch == "X" {
57− result.append(cleanPhoneNumber[index])
58− index = cleanPhoneNumber.index(after: index)
59− } else {
60− result.append(ch)
61− }
62− }
63− return result
64− }
65−}
Hookah Tau/Controllers/Client/Profile/Views/ChangeView.xib+1−1
@@ -17,7 +17,7 @@
1717 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="19Q-ZO-gm4">
1818 <rect key="frame" x="20" y="11" width="335" height="83.5"/>
1919 <subviews>
20− <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="oB7-uQ-xmw">
20+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Имя" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oB7-uQ-xmw">
2121 <rect key="frame" x="0.0" y="0.0" width="335" height="33.5"/>
2222 <fontDescription key="fontDescription" type="boldSystem" pointSize="28"/>
2323 <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
Hookah Tau/Controllers/Client/Profile/Views/ProfileView.xib+5−5
@@ -28,7 +28,7 @@
2828 </label>
2929 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jpS-Vl-9C3">
3030 <rect key="frame" x="0.0" y="44" width="374" height="50"/>
31− <color key="backgroundColor" systemColor="systemBlueColor" red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
31+ <color key="backgroundColor" systemColor="systemBlueColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
3232 <constraints>
3333 <constraint firstAttribute="width" constant="374" id="9z3-UR-zHl"/>
3434 <constraint firstAttribute="height" constant="50" id="Hr9-hL-I1c"/>
@@ -47,7 +47,7 @@
4747 </label>
4848 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SVP-b8-AJi">
4949 <rect key="frame" x="0.0" y="41.5" width="374" height="50"/>
50− <color key="backgroundColor" systemColor="systemRedColor" red="1" green="0.23137254901960785" blue="0.18823529411764706" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
50+ <color key="backgroundColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
5151 <constraints>
5252 <constraint firstAttribute="width" constant="374" id="2Ra-kt-T1F"/>
5353 <constraint firstAttribute="height" constant="50" id="iGE-m0-EQ2"/>
@@ -58,7 +58,7 @@
5858 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="wcw-Ss-ld4">
5959 <rect key="frame" x="0.0" y="245.5" width="374" height="91.5"/>
6060 <subviews>
61− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NQB-i0-WVL">
61+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NQB-i0-WVL">
6262 <rect key="frame" x="0.0" y="0.0" width="71.5" height="33.5"/>
6363 <fontDescription key="fontDescription" type="boldSystem" pointSize="28"/>
6464 <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -66,7 +66,7 @@
6666 </label>
6767 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dyQ-12-OMI">
6868 <rect key="frame" x="0.0" y="41.5" width="374" height="50"/>
69− <color key="backgroundColor" systemColor="systemIndigoColor" red="0.34509803921568627" green="0.33725490196078434" blue="0.83921568627450982" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
69+ <color key="backgroundColor" systemColor="systemIndigoColor" red="0.34509803919999998" green="0.33725490200000002" blue="0.83921568629999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
7070 <constraints>
7171 <constraint firstAttribute="height" constant="50" id="SYN-47-LUA"/>
7272 <constraint firstAttribute="width" constant="374" id="hQD-KD-teb"/>
@@ -78,7 +78,7 @@
7878 </stackView>
7979 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="oKK-WM-xZ3" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
8080 <rect key="frame" x="20" y="446" width="374" height="37"/>
81− <color key="backgroundColor" systemColor="opaqueSeparatorColor" red="0.77647058823529413" green="0.77647058823529413" blue="0.78431372549019607" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
81+ <color key="backgroundColor" systemColor="opaqueSeparatorColor" red="0.77647058820000003" green="0.77647058820000003" blue="0.7843137255" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
8282 <constraints>
8383 <constraint firstAttribute="height" constant="37" id="I8c-3h-mMu"/>
8484 </constraints>
Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsCoordinator.swift−14
@@ -29,18 +29,4 @@ class ReservationsCoordinator: BaseCoordinator {
2929 }
3030 addressCoordinator.start()
3131 }
32−
33− func viewReservation(_ reservation: Reservation) {
34− let thirdStepRCoordinator = ThirdStepReservationCoordinator(navigationController: navigationController)
35− addDependency(thirdStepRCoordinator)
36−
37− thirdStepRCoordinator.resrvation = reservation
38−
39− thirdStepRCoordinator.didFinish = { [weak self] in
40− self?.removeDependency(thirdStepRCoordinator)
41− self?.navigationController?.popViewController(animated: true)
42− }
43−
44− thirdStepRCoordinator.start()
45− }
4632}
Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsViewController.swift+14−105
@@ -8,23 +8,15 @@
88
99import UIKit
1010
11+let reservationCell = "ReservationCell"
12+
1113class ReservationsViewController: BaseViewController {
1214
1315 // MARK: - Properties
1416
1517 var activeReservations: [Reservation] = [] {
1618 didSet {
17− guard let empty = noReservationsView else { return }
18− if activeReservations.isEmpty {
19− contentView.bringSubviewToFront(empty)
20− empty.alpha = 1
21− } else {
22− contentView.sendSubviewToBack(empty)
23− tableView?.alpha = 1
24− }
25−
26− activityIndicator.stopAnimating()
27− tableView?.reloadData()
19+ setUpContentView()
2820 }
2921 }
3022
@@ -40,13 +32,7 @@ class ReservationsViewController: BaseViewController {
4032
4133 var noReservationsView: NoReservationsView?
4234
43− var tableView: UITableView? = {
44− let tableView = UITableView()
45− tableView.backgroundColor = .white
46− return tableView
47− }()
48−
49− var activityIndicator = UIActivityIndicatorView()
35+ var tableView: UITableView?
5036
5137 // MARK: - Lifecycle
5238
@@ -56,18 +42,6 @@ class ReservationsViewController: BaseViewController {
5642 setUpNavigationBar()
5743
5844 reservationsService = ReservationsService(apiClient: APIClient.shared)
59− navigationController?.navigationBar.prefersLargeTitles = true
60− setUpContentView()
61− }
62−
63− override func viewWillAppear(_ animated: Bool) {
64− super.viewWillAppear(animated)
65−
66− tabBarController?.tabBar.isHidden = false
67− }
68−
69− override func viewDidAppear(_ animated: Bool) {
70− super.viewDidAppear(animated)
7145
7246 performUpdate()
7347 }
@@ -77,29 +51,23 @@ class ReservationsViewController: BaseViewController {
7751 func setUpContentView() {
7852 self.view.addSubviewThatFills(contentView)
7953
80− contentView.addSubviewThatFills(activityIndicator)
81− activityIndicator.startAnimating()
82−
83− // empty
84− noReservationsView = NoReservationsView.loadFromNib()
85− contentView.addSubviewThatFills(noReservationsView)
86− noReservationsView?.makeReservationButton?.addTarget(self, action: #selector(tapToMakeReservation), for: .touchUpInside)
87−
88− noReservationsView?.alpha = 0
89−
90− // table
91− contentView.addSubviewThatFills(tableView)
92−
54+ if activeReservations.isEmpty {
55+ noReservationsView = NoReservationsView.loadFromNib()
56+ contentView.addSubviewThatFills(noReservationsView)
57+ noReservationsView?.makeReservationButton?.addTarget(self, action: #selector(tapToMakeReservation), for: .touchUpInside)
58+ } else {
59+ tableView = UITableView()
60+ contentView.addSubviewThatFills(tableView)
61+ tableView?.reloadData()
62+ }
63+
9364 setUpTableView()
94− setupRefreshControl()
9565 }
9666
9767 func setUpTableView() {
9868 tableView?.delegate = self
9969 tableView?.dataSource = self
10070
101− tableView?.alpha = 0
102−
10371 tableView?.register(ReservationCell.self, forCellReuseIdentifier: reservationCell)
10472 }
10573
@@ -127,35 +95,9 @@ class ReservationsViewController: BaseViewController {
12795 case .failure(let err):
12896 self?.displayAlert(forError: err)
12997 }
130− self?.refrControl?.endRefreshing()
13198 })
13299 }
133100
134− func deleteReservation(uuid: String, completion: @escaping (([Reservation]?) -> Void)) {
135− reservationsService?.deleteReservation(isAdmin: false, uuid: uuid) { result in
136− if result {
137− let newReservations = self.activeReservations.filter { $0.uuid != uuid }
138− completion(newReservations)
139− return
140− }
141−
142− completion(nil)
143− }
144− }
145−
146− // MARK: - Refresh control
147−
148− var refrControl: UIRefreshControl?
149−
150− func setupRefreshControl() {
151− refrControl = UIRefreshControl()
152− tableView?.refreshControl = refrControl
153− refrControl?.addTarget(self, action: #selector(refreshData(_:)), for: .valueChanged)
154− }
155−
156− @objc func refreshData( _ ff: UIRefreshControl) {
157− performUpdate()
158− }
159101}
160102
161103extension ReservationsViewController: UITableViewDelegate, UITableViewDataSource {
@@ -170,11 +112,6 @@ extension ReservationsViewController: UITableViewDelegate, UITableViewDataSource
170112 return cell
171113 }
172114
173− func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
174− let reservation = activeReservations[indexPath.row]
175− coordinator?.viewReservation(reservation)
176− }
177−
178115 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
179116 return UITableView.automaticDimension
180117 }
@@ -182,32 +119,4 @@ extension ReservationsViewController: UITableViewDelegate, UITableViewDataSource
182119 func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
183120 return 180.0
184121 }
185−
186− // Update
187−
188− func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
189− return true
190− }
191−
192− func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
193−
194− let uuid = activeReservations[indexPath.row].uuid
195− let cancelButton = UITableViewRowAction(style: .normal, title: "отменить бронь") { _,_ in
196−
197− self.deleteReservation(uuid: uuid) { optionalNewVal in
198− if let newval = optionalNewVal {
199− self.tableView?.beginUpdates()
200− self.tableView?.deleteRows(at: [indexPath], with: .automatic)
201− self.activeReservations = newval
202− self.tableView?.endUpdates()
203− } else {
204− self.displayAlert(with: "Не удалось удалить вашу бронь! Попробуйте еще раз!")
205− }
206− }
207− }
208−
209− cancelButton.backgroundColor = .black
210−
211− return [cancelButton]
212− }
213122}
Hookah Tau/Controllers/Client/Reservations/Adress of reservation/AddresViewController.swift+4−30
@@ -12,11 +12,11 @@ class AddresViewController: BaseViewController {
1212
1313 // MARK: - Properties
1414
15− weak var coordinator: AddressMapper?
15+ weak var coordinator: AddressCoordinator?
1616
1717 var tableView: UITableView?
1818
19− var dataSource: [Int]? = [1, 2]
19+ var dataSource: [Int]? = [1]
2020
2121 // MARK: - Lifecycle
2222
@@ -24,7 +24,6 @@ class AddresViewController: BaseViewController {
2424 view.backgroundColor = .white
2525 navigationItem.title = "Заведения"
2626
27− navigationController?.navigationBar.prefersLargeTitles = true
2827 setUpTableView()
2928 }
3029
@@ -60,13 +59,6 @@ extension AddresViewController: UITableViewDelegate, UITableViewDataSource {
6059 let cell = tableView.dequeueReusableCell(withIdentifier: addressCellIdentifier,
6160 for: indexPath) as! AddressCell
6261
63− guard
64− let val = dataSource?[indexPath.row],
65− let model = TotalStorage.standard.getEstablishment(val)
66− else { return cell }
67−
68− cell.bind(withModel: model)
69−
7062 return cell
7163 }
7264
@@ -78,27 +70,9 @@ extension AddresViewController: UITableViewDelegate, UITableViewDataSource {
7870 let establishment = dataSource?[indexPath.row]
7971 guard let id = establishment else { return }
8072
81− coordinator?.chooseAddress(establishmentId: id)
73+ coordinator?.chooseTableAndTime(inEstablishment: id)
8274 }
8375
84− func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
85− return true
86− }
8776
88− func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
89−
90− guard
91− let val = dataSource?[indexPath.row],
92− let phone = TotalStorage.standard.getEstablishment(val)?.admin,
93− let urlPhone = URL(string: "tel://79\(phone)")
94− else { return nil }
95−
96− let editButton = UITableViewRowAction(style: .normal, title: "🤙🏻") { _,_ in
97− UIApplication.shared.open(urlPhone)
98− }
99−
100− editButton.backgroundColor = .black
101−
102− return [editButton]
103− }
77+
10478}
Hookah Tau/Controllers/Client/Reservations/Adress of reservation/AddressCoordinator.swift+2−16
@@ -8,10 +8,6 @@
88
99import UIKit
1010
11−protocol AddressMapper: class {
12− func chooseAddress(establishmentId id: Int)
13−}
14−
1511class AddressCoordinator: BaseCoordinator {
1612
1713 // MARK: - Properties
@@ -33,23 +29,13 @@ class AddressCoordinator: BaseCoordinator {
3329
3430 /// continue with reservation
3531 /// TODO: pass some data
36− private func chooseTableAndTime(inEstablishment id: Int) {
32+ func chooseTableAndTime(inEstablishment id: Int) {
3733 let reservationCoordinator = FirstStepReservationCoordinator(navigationController: navigationController)
38− reservationCoordinator.establishment = id
39−
4034 addDependency(reservationCoordinator)
4135 reservationCoordinator.didFinish = { [weak self] in
4236 self?.removeDependency(reservationCoordinator)
43− self?.navigationController?.popViewController(animated: false)
44− self?.didFinish?()
37+ self?.navigationController?.popViewController(animated: true)
4538 }
46−
4739 reservationCoordinator.start()
4840 }
4941}
50−
51−extension AddressCoordinator: AddressMapper {
52− func chooseAddress(establishmentId id: Int) {
53− chooseTableAndTime(inEstablishment: id)
54− }
55−}
Hookah Tau/Controllers/Client/Reservations/Cells/Address/AddressCell.swift−4
@@ -27,10 +27,6 @@ class AddressCell: UITableViewCell {
2727
2828 selectionStyle = .none
2929 }
30−
31− func bind(withModel model: TotalStorage.EstablishmentData) {
32− addressView?.bind(withModel: model)
33− }
3430
3531 required init?(coder aDecoder: NSCoder)
3632 {
Hookah Tau/Controllers/Client/Reservations/Cells/Address/AddressView.swift+2−6
@@ -18,12 +18,8 @@ class AddressView: UIView {
1818
1919 @IBOutlet weak var tableCountLabel: UILabel?
2020
21− @IBOutlet weak var mapImageView: UIImageView?
21+ @IBOutlet weak var callAdminButton: UIButton?
2222
23− func bind(withModel model: TotalStorage.EstablishmentData) {
24− addressLabel?.text = model.address
25− tableCountLabel?.text = "\(model.maxTableNumber) столов"
26− mapImageView?.image = model.image
27− }
23+ @IBOutlet weak var mapImageView: UIImageView?
2824
2925}
Hookah Tau/Controllers/Client/Reservations/Cells/Address/AddressView.xib+26−28
@@ -15,45 +15,42 @@
1515 <rect key="frame" x="0.0" y="0.0" width="375" height="168"/>
1616 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1717 <subviews>
18− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="top" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="CqA-Dd-eAx">
18+ <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="CqA-Dd-eAx">
1919 <rect key="frame" x="16" y="16" width="343" height="136"/>
2020 <subviews>
21− <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="VqZ-I8-mm0">
22− <rect key="frame" x="0.0" y="0.0" width="200" height="136"/>
21+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="bottom" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="wiw-lV-dNd">
22+ <rect key="frame" x="0.0" y="16" width="164.5" height="104.5"/>
2323 <subviews>
24− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="bottom" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="wiw-lV-dNd">
25− <rect key="frame" x="0.0" y="0.0" width="200" height="136"/>
24+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Покровский, 11" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9py-8w-XFJ">
25+ <rect key="frame" x="0.0" y="0.0" width="164.5" height="26.5"/>
26+ <fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
27+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
28+ <nil key="highlightedColor"/>
29+ </label>
30+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="bottom" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="lyA-et-Gg5">
31+ <rect key="frame" x="54" y="56.5" width="110.5" height="48"/>
2632 <subviews>
27− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Гороховский пер. 12c5, апт. 205" textAlignment="right" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9py-8w-XFJ">
28− <rect key="frame" x="7" y="0.0" width="193" height="53"/>
29− <fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
33+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3:00 — 12:00" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SrE-GD-vqp">
34+ <rect key="frame" x="0.0" y="0.0" width="110.5" height="20.5"/>
35+ <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
3036 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
3137 <nil key="highlightedColor"/>
3238 </label>
33− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="bottom" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="lyA-et-Gg5">
34− <rect key="frame" x="89.5" y="88" width="110.5" height="48"/>
35− <subviews>
36− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3:00 — 12:00" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SrE-GD-vqp">
37− <rect key="frame" x="0.0" y="0.0" width="110.5" height="20.5"/>
38− <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
39− <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
40− <nil key="highlightedColor"/>
41− </label>
42− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="8 столов" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9nc-mT-R6o">
43− <rect key="frame" x="44.5" y="28.5" width="66" height="19.5"/>
44− <fontDescription key="fontDescription" type="system" pointSize="16"/>
45− <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
46− <nil key="highlightedColor"/>
47− </label>
48− </subviews>
49− </stackView>
39+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="8 столов" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9nc-mT-R6o">
40+ <rect key="frame" x="44.5" y="28.5" width="66" height="19.5"/>
41+ <fontDescription key="fontDescription" type="system" pointSize="16"/>
42+ <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
43+ <nil key="highlightedColor"/>
44+ </label>
5045 </subviews>
51− <constraints>
52− <constraint firstAttribute="width" constant="200" id="Lgy-TT-MRN"/>
53− </constraints>
5446 </stackView>
5547 </subviews>
5648 </stackView>
49+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GTd-he-e50">
50+ <rect key="frame" x="227" y="53" width="116" height="30"/>
51+ <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
52+ <state key="normal" title="Большая кнопка"/>
53+ </button>
5754 </subviews>
5855 </stackView>
5956 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Map" translatesAutoresizingMaskIntoConstraints="NO" id="2Oj-R4-qoR">
@@ -78,6 +75,7 @@
7875 <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
7976 <connections>
8077 <outlet property="addressLabel" destination="9py-8w-XFJ" id="RzN-vT-9co"/>
78+ <outlet property="callAdminButton" destination="GTd-he-e50" id="bdq-pP-al5"/>
8179 <outlet property="mapImageView" destination="2Oj-R4-qoR" id="3ao-l1-GTd"/>
8280 <outlet property="openHoursLabel" destination="SrE-GD-vqp" id="gAb-rI-1wP"/>
8381 <outlet property="tableCountLabel" destination="9nc-mT-R6o" id="tlM-MK-qTx"/>
Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationCell.swift+2−3
@@ -8,8 +8,6 @@
88
99import UIKit
1010
11−let reservationCell = "ReservationCell"
12−
1311class ReservationCell: UITableViewCell {
1412
1513 // MARK: - Properties
@@ -36,6 +34,7 @@ class ReservationCell: UITableViewCell {
3634 // MARK: - Data
3735
3836 func bind(withModel model: Reservation) {
39− reservationCellView?.bind(withModel: model)
37+ self.reservationCellView?.maxPeopleLabel?.text = "\(model.numberOfGuests)"
4038 }
39+
4140}
Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationView.swift+61−11
@@ -21,18 +21,68 @@ class ReservationView: UIView {
2121 @IBOutlet weak var maxPeopleLabel: UILabel?
2222
2323 @IBOutlet weak var tableImageView: UIImageView?
24−
25− func bind(withModel model: Reservation) {
26− guard let table = TotalStorage.standard.getTable(establishment: model.establishment, table: model.reservedTable),
27− let establishment = TotalStorage.standard.getEstablishment(model.establishment)
28− else { return }
24+
25+ @IBOutlet weak var cancelButton: Button? {
26+ didSet {
27+ let style = BlackButtonStyle()
28+ style.apply(to: cancelButton, withTitle: "ОТМЕНИТЬ")
29+ }
30+ }
31+
32+ @IBOutlet weak var changeButton: Button? {
33+ didSet {
34+ let style = BlackButtonStyle()
35+ style.apply(to: changeButton, withTitle: "ИЗМЕНИТЬ")
36+ }
37+ }
38+
39+ @IBOutlet weak var swipableView: UIView?
40+
41+
42+ override func awakeFromNib() {
43+ super.awakeFromNib()
44+
45+ }
46+
47+ // https://developer.apple.com/videos/play/wwdc2015/229/
48+ @IBAction func swipeImageView(_ recognizer: UIPanGestureRecognizer) {
49+ let translation = recognizer.translation(in: self.swipableView)
50+ guard let view = recognizer.view else { return }
51+
52+ let point = CGPoint(x: view.center.x + translation.x, y: view.center.y)
53+ if self.swipableView?.bounds.contains(point) == true {
54+ view.center = point
55+ }
2956
30− tableImageView?.image = table.image
31− adressLabel?.text = establishment.address
32− maxPeopleLabel?.text = "\(model.numberOfGuests) " + (2...4 ~= model.numberOfGuests ? "человека" : "человек")
57+ recognizer.setTranslation(CGPoint.zero, in: self.swipableView)
58+
59+ if recognizer.state == .ended {
60+ // 1
61+ let velocity = recognizer.velocity(in: self.swipableView)
62+ let magnitude = sqrt((velocity.x * velocity.x) + (velocity.y * velocity.y))
63+ let slideMultiplier = magnitude / 300
64+ print("magnitude: \(magnitude), slideMultiplier: \(slideMultiplier)")
65+
66+ // 2
67+ let slideFactor = 0.1 * slideMultiplier //Increase for more of a slide
68+ // 3
69+ var finalPoint = CGPoint(x:view.center.x + (velocity.x * slideFactor),
70+ y:view.center.y)
71+ // 4
72+ finalPoint.x = min(max(finalPoint.x, 0), self.swipableView?.bounds.size.width ?? 0.0 - view.bounds.width / 2 )
73+
74+ // 5
75+ UIView.animate(withDuration: Double(slideFactor * 2),
76+ delay: 0,
77+ // 6
78+ options: UIView.AnimationOptions.curveEaseOut,
79+ animations: { view.center = finalPoint },
80+ completion: nil)
81+ }
82+ }
83+
84+ private func checkArea(_ coord: CGPoint) {
3385
34− let (date, time) = Date.format(model.startTime, model.endTime)
35− dateLabel?.text = date
36− timeLabel?.text = time
3786 }
87+
3888}
Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationView.xib+55−7
@@ -16,12 +16,12 @@
1616 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1717 <subviews>
1818 <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="gQe-LE-1cq">
19− <rect key="frame" x="20" y="20" width="374" height="140"/>
19+ <rect key="frame" x="20" y="22" width="374" height="136"/>
2020 <subviews>
2121 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="25" translatesAutoresizingMaskIntoConstraints="NO" id="Ujo-xw-Sa3">
22− <rect key="frame" x="0.0" y="2" width="243" height="136"/>
22+ <rect key="frame" x="0.0" y="0.0" width="256" height="136"/>
2323 <subviews>
24− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Покровский, 11" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QIM-G6-tcZ">
24+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Покровский, 11" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QIM-G6-tcZ">
2525 <rect key="frame" x="0.0" y="0.0" width="122" height="20.5"/>
2626 <fontDescription key="fontDescription" type="system" pointSize="17"/>
2727 <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -52,8 +52,36 @@
5252 </label>
5353 </subviews>
5454 </stackView>
55+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="18" translatesAutoresizingMaskIntoConstraints="NO" id="KIf-G6-yu0">
56+ <rect key="frame" x="264" y="24" width="110" height="88"/>
57+ <subviews>
58+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7Kd-Rw-JdQ" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
59+ <rect key="frame" x="0.0" y="0.0" width="110" height="35"/>
60+ <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
61+ <constraints>
62+ <constraint firstAttribute="width" constant="110" id="db3-Z9-qoz"/>
63+ <constraint firstAttribute="height" constant="35" id="fvx-DS-94n"/>
64+ </constraints>
65+ <state key="normal" title="Отменить"/>
66+ </button>
67+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="L1q-Xa-K3y" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
68+ <rect key="frame" x="0.0" y="53" width="110" height="35"/>
69+ <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
70+ <constraints>
71+ <constraint firstAttribute="height" constant="35" id="29E-JH-Mv8"/>
72+ <constraint firstAttribute="width" constant="110" id="UCh-du-cnE"/>
73+ </constraints>
74+ <state key="normal" title="Изменить"/>
75+ </button>
76+ </subviews>
77+ </stackView>
78+ </subviews>
79+ </stackView>
80+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="m4Q-p5-icZ">
81+ <rect key="frame" x="144" y="0.0" width="250" height="180"/>
82+ <subviews>
5583 <imageView clipsSubviews="YES" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Table" translatesAutoresizingMaskIntoConstraints="NO" id="4u1-cy-ujz">
56− <rect key="frame" x="251" y="0.0" width="123" height="140"/>
84+ <rect key="frame" x="127" y="20" width="123" height="140"/>
5785 <gestureRecognizers/>
5886 <constraints>
5987 <constraint firstAttribute="width" constant="123" id="3ZG-yo-kHP"/>
@@ -61,30 +89,50 @@
6189 <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="123" id="weI-IM-eIN"/>
6290 <constraint firstAttribute="height" constant="140" id="xVK-aV-obb"/>
6391 </constraints>
92+ <connections>
93+ <outletCollection property="gestureRecognizers" destination="PRF-YF-b6m" appends="YES" id="DjN-h4-Tdp"/>
94+ </connections>
6495 </imageView>
6596 </subviews>
66− </stackView>
97+ <color key="backgroundColor" red="0.012039811643835616" green="0.56175085616438358" blue="0.76225385273972601" alpha="0.2090378852739726" colorSpace="custom" customColorSpace="sRGB"/>
98+ <constraints>
99+ <constraint firstItem="4u1-cy-ujz" firstAttribute="top" secondItem="m4Q-p5-icZ" secondAttribute="top" constant="20" id="E3a-gf-bth"/>
100+ <constraint firstAttribute="width" constant="250" id="JQc-Wc-jc0"/>
101+ <constraint firstAttribute="trailing" secondItem="4u1-cy-ujz" secondAttribute="trailing" id="JfQ-6n-41A"/>
102+ <constraint firstAttribute="bottom" secondItem="4u1-cy-ujz" secondAttribute="bottom" constant="20" id="gNA-cS-SKe"/>
103+ <constraint firstAttribute="height" constant="180" id="uWH-MW-jqV"/>
104+ </constraints>
105+ </view>
67106 </subviews>
68107 <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
69108 <constraints>
70109 <constraint firstItem="gQe-LE-1cq" firstAttribute="centerY" secondItem="vUN-kp-3ea" secondAttribute="centerY" id="0yM-pg-c5m"/>
71− <constraint firstItem="gQe-LE-1cq" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="20" id="TQU-8e-jES"/>
110+ <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="m4Q-p5-icZ" secondAttribute="trailing" constant="20" id="8aC-G7-xGp"/>
111+ <constraint firstItem="m4Q-p5-icZ" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="D3I-d9-a60"/>
72112 <constraint firstItem="gQe-LE-1cq" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="20" id="guw-kE-R18"/>
73− <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="gQe-LE-1cq" secondAttribute="bottom" constant="20" id="pgS-KL-ECQ"/>
74113 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="gQe-LE-1cq" secondAttribute="trailing" constant="20" id="rw9-VV-8S5"/>
75114 <constraint firstItem="gQe-LE-1cq" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="vQj-YK-exg"/>
115+ <constraint firstItem="m4Q-p5-icZ" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="yMN-Gy-814"/>
76116 </constraints>
77117 <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
78118 <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
79119 <connections>
80120 <outlet property="adressLabel" destination="QIM-G6-tcZ" id="bRM-hB-jwH"/>
121+ <outlet property="cancelButton" destination="7Kd-Rw-JdQ" id="3wP-jU-Vlz"/>
122+ <outlet property="changeButton" destination="L1q-Xa-K3y" id="Uot-1g-x9O"/>
81123 <outlet property="dateLabel" destination="lUJ-we-26h" id="cMr-gz-ofj"/>
82124 <outlet property="maxPeopleLabel" destination="fYQ-YQ-Bw4" id="Utn-Bd-dVK"/>
125+ <outlet property="swipableView" destination="m4Q-p5-icZ" id="1gn-M1-Lfg"/>
83126 <outlet property="tableImageView" destination="4u1-cy-ujz" id="d1Z-TE-u1y"/>
84127 <outlet property="timeLabel" destination="EOi-j1-jQM" id="CV4-G4-wUw"/>
85128 </connections>
86129 <point key="canvasLocation" x="165" y="350"/>
87130 </view>
131+ <panGestureRecognizer minimumNumberOfTouches="1" id="PRF-YF-b6m">
132+ <connections>
133+ <action selector="swipeImageView:" destination="iN0-l3-epB" id="zIb-fN-SWJ"/>
134+ </connections>
135+ </panGestureRecognizer>
88136 </objects>
89137 <resources>
90138 <image name="Table" width="102" height="117"/>
Hookah Tau/Controllers/Client/Reservations/Maps/2/MapView2.swiftdeleted−152
@@ -1,152 +0,0 @@
1−//
2−// MapView2.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 28/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class MapView2: MapImageScroll {
12−
13− // MARK: - Tables
14−
15− @IBOutlet weak var table2: TableButton! {
16− didSet {
17− let style = TableButtonStyle()
18− style.apply(to: table2)
19− }
20− }
21−
22− @IBOutlet weak var table3: TableButton!{
23− didSet {
24− let style = TableButtonStyle()
25− style.apply(to: table3)
26− }
27− }
28−
29− @IBOutlet weak var table4: TableButton! {
30− didSet {
31− let style = TableButtonStyle()
32− style.apply(to: table4)
33− }
34− }
35−
36− @IBOutlet weak var table5: TableButton! {
37− didSet {
38− let style = TableButtonStyle()
39− style.apply(to: table5)
40− }
41− }
42−
43− @IBOutlet weak var table6: TableButton! {
44− didSet {
45− let style = TableButtonStyle()
46− style.apply(to: table6)
47− }
48− }
49−
50− @IBOutlet weak var table7: TableButton! {
51− didSet {
52− let style = TableButtonStyle()
53− style.apply(to: table7)
54− }
55− }
56−
57− @IBOutlet weak var table8: TableButton! {
58− didSet {
59− let style = TableButtonStyle()
60− style.apply(to: table8)
61− }
62− }
63−
64− override var handler: MapHandler? {
65− didSet {
66− handleTap(button: table8, id: 8)
67− }
68− }
69−
70− // MARK: - Super props
71−
72− @IBOutlet weak var scrollView: UIScrollView! {
73− didSet {
74− super.scrollViewParent = scrollView
75− }
76− }
77−
78− @IBOutlet weak var image: UIImageView! {
79− didSet {
80− super.img = image
81− }
82− }
83−
84− @IBOutlet weak var shadow: UIView! {
85− didSet {
86− super.shadowView = shadow
87− shadow.alpha = 0
88− }
89− }
90−
91− // MARK: - Lifecycle
92−
93− override func awakeFromNib() {
94− super.awakeFromNib()
95−
96− self.scrollView.delegate = self
97− self.scrollView.delaysContentTouches = false
98−
99− tables[2] = table2
100− tables[3] = table3
101− tables[4] = table4
102− tables[5] = table5
103− tables[6] = table6
104− tables[7] = table7
105− tables[8] = table8
106−
107− tables.values.forEach { image.addSubview($0) }
108− image.addSubview(shadowView)
109−
110− configureFor(image.frame.size)
111− }
112−
113− // MARK: - Taps
114−
115− @IBAction func tap2(_ sender: TableButton) {
116− handleTap(button: sender, id: 2)
117− }
118−
119− @IBAction func tap3(_ sender: TableButton) {
120− handleTap(button: sender, id: 3)
121− }
122−
123− @IBAction func tap4(_ sender: TableButton) {
124− handleTap(button: sender, id: 4)
125− }
126−
127− @IBAction func tap5(_ sender: TableButton) {
128− handleTap(button: sender, id: 5)
129− }
130−
131− @IBAction func tap6(_ sender: TableButton) {
132− handleTap(button: sender, id: 6)
133− }
134−
135− @IBAction func tap7(_ sender: TableButton) {
136− handleTap(button: sender, id: 7)
137− }
138−
139− @IBAction func tap8(_ sender: TableButton) {
140− handleTap(button: sender, id: 8)
141− }
142−
143−}
144−
145−// MARK: - Scroll view
146−
147−extension MapView2: UIScrollViewDelegate {
148−
149− func viewForZooming(in scrollView: UIScrollView) -> UIView? {
150− self.image
151− }
152−}
Hookah Tau/Controllers/Client/Reservations/Maps/2/MapView2.xibdeleted−155
@@ -1,155 +0,0 @@
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="MapView2" 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="emi-wK-dKY">
18− <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
19− <subviews>
20− <imageView clipsSubviews="YES" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="map_2" translatesAutoresizingMaskIntoConstraints="NO" id="Obf-Cs-bNe">
21− <rect key="frame" x="0.0" y="0.0" width="683" height="329"/>
22− </imageView>
23− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N1V-4M-SuG" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
24− <rect key="frame" x="70" y="18" width="92" height="66"/>
25− <constraints>
26− <constraint firstAttribute="width" constant="92" id="Cd4-io-y5G"/>
27− <constraint firstAttribute="height" constant="66" id="wSz-LG-S6h"/>
28− </constraints>
29− <connections>
30− <action selector="tap8:" destination="iN0-l3-epB" eventType="touchUpInside" id="23l-0c-N7c"/>
31− </connections>
32− </button>
33− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2KA-Fl-otO" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
34− <rect key="frame" x="190" y="17" width="104" height="95"/>
35− <constraints>
36− <constraint firstAttribute="height" constant="95" id="aIs-ch-V6c"/>
37− <constraint firstAttribute="width" constant="104" id="vje-NJ-ttB"/>
38− </constraints>
39− <connections>
40− <action selector="tap7:" destination="iN0-l3-epB" eventType="touchUpInside" id="GuY-TU-Mbv"/>
41− </connections>
42− </button>
43− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Uyw-7g-fgk" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
44− <rect key="frame" x="190" y="190" width="68" height="94"/>
45− <constraints>
46− <constraint firstAttribute="width" constant="68" id="IyU-Gp-dLh"/>
47− <constraint firstAttribute="height" constant="94" id="N7G-Ua-jrx"/>
48− </constraints>
49− <connections>
50− <action selector="tap4:" destination="iN0-l3-epB" eventType="touchUpInside" id="mUZ-2d-VkM"/>
51− </connections>
52− </button>
53− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Sko-xU-trE" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
54− <rect key="frame" x="286" y="177" width="103" height="118"/>
55− <constraints>
56− <constraint firstAttribute="width" constant="103" id="7QV-8e-19v"/>
57− <constraint firstAttribute="height" constant="118" id="ApA-IR-eB1"/>
58− </constraints>
59− <connections>
60− <action selector="tap3:" destination="iN0-l3-epB" eventType="touchUpInside" id="Vx6-bj-c44"/>
61− </connections>
62− </button>
63− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pMi-ey-nl3" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
64− <rect key="frame" x="323" y="18" width="102" height="95"/>
65− <constraints>
66− <constraint firstAttribute="width" constant="102" id="9Pn-tv-fnZ"/>
67− <constraint firstAttribute="height" constant="95" id="PXg-Gy-7TO"/>
68− </constraints>
69− <connections>
70− <action selector="tap6:" destination="iN0-l3-epB" eventType="touchUpInside" id="ge0-j5-gLW"/>
71− </connections>
72− </button>
73− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="S2Z-ye-LWO" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
74− <rect key="frame" x="455" y="18" width="102" height="94"/>
75− <constraints>
76− <constraint firstAttribute="width" constant="102" id="E4e-Gs-QYc"/>
77− <constraint firstAttribute="height" constant="94" id="NLu-i5-Mr6"/>
78− </constraints>
79− <connections>
80− <action selector="tap5:" destination="iN0-l3-epB" eventType="touchUpInside" id="LkA-Xo-cwd"/>
81− </connections>
82− </button>
83− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QLb-ch-cuY" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
84− <rect key="frame" x="426" y="164" width="131" height="146"/>
85− <constraints>
86− <constraint firstAttribute="width" constant="131" id="I3b-2n-Bgm"/>
87− <constraint firstAttribute="height" constant="146" id="Tlu-Sy-7GC"/>
88− </constraints>
89− <connections>
90− <action selector="tap2:" destination="iN0-l3-epB" eventType="touchUpInside" id="7N9-GF-PKo"/>
91− </connections>
92− </button>
93− <view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Kvb-P4-fah">
94− <rect key="frame" x="0.0" y="0.0" width="683" height="329"/>
95− <color key="backgroundColor" white="1" alpha="0.6951519691780822" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
96− </view>
97− </subviews>
98− <constraints>
99− <constraint firstItem="Sko-xU-trE" firstAttribute="top" secondItem="pMi-ey-nl3" secondAttribute="bottom" constant="64" id="6aW-Tf-64S"/>
100− <constraint firstItem="2KA-Fl-otO" firstAttribute="leading" secondItem="N1V-4M-SuG" secondAttribute="trailing" constant="28" id="7Ei-ax-wx6"/>
101− <constraint firstItem="N1V-4M-SuG" firstAttribute="leading" secondItem="Obf-Cs-bNe" secondAttribute="leading" constant="70" id="7Rw-z2-eKD"/>
102− <constraint firstItem="2KA-Fl-otO" firstAttribute="top" secondItem="Obf-Cs-bNe" secondAttribute="top" constant="17" id="Cos-le-6UH"/>
103− <constraint firstItem="Obf-Cs-bNe" firstAttribute="trailing" secondItem="QLb-ch-cuY" secondAttribute="trailing" constant="126" id="FhV-De-jji"/>
104− <constraint firstItem="Obf-Cs-bNe" firstAttribute="height" secondItem="emi-wK-dKY" secondAttribute="height" priority="250" id="H4t-Mm-gPX"/>
105− <constraint firstItem="QLb-ch-cuY" firstAttribute="top" secondItem="S2Z-ye-LWO" secondAttribute="bottom" constant="52" id="HJJ-ia-caS"/>
106− <constraint firstItem="Uyw-7g-fgk" firstAttribute="top" secondItem="2KA-Fl-otO" secondAttribute="bottom" constant="78" id="MOn-dn-UV6"/>
107− <constraint firstItem="Kvb-P4-fah" firstAttribute="trailing" secondItem="Obf-Cs-bNe" secondAttribute="trailing" id="N0a-np-nCu"/>
108− <constraint firstItem="Sko-xU-trE" firstAttribute="leading" secondItem="Uyw-7g-fgk" secondAttribute="trailing" constant="28" id="SRb-lA-XTw"/>
109− <constraint firstAttribute="trailing" secondItem="Obf-Cs-bNe" secondAttribute="trailing" id="Saf-Tc-0J5"/>
110− <constraint firstItem="pMi-ey-nl3" firstAttribute="top" secondItem="Obf-Cs-bNe" secondAttribute="top" constant="18" id="Vov-VH-rha"/>
111− <constraint firstAttribute="bottom" secondItem="Obf-Cs-bNe" secondAttribute="bottom" id="WPI-RB-B4A"/>
112− <constraint firstItem="Kvb-P4-fah" firstAttribute="leading" secondItem="Obf-Cs-bNe" secondAttribute="leading" id="YgQ-Rl-iQD"/>
113− <constraint firstItem="Kvb-P4-fah" firstAttribute="top" secondItem="Obf-Cs-bNe" secondAttribute="top" id="aPY-ua-gcI"/>
114− <constraint firstItem="pMi-ey-nl3" firstAttribute="leading" secondItem="2KA-Fl-otO" secondAttribute="trailing" constant="29" id="aR4-Q4-cQ3"/>
115− <constraint firstItem="Obf-Cs-bNe" firstAttribute="width" secondItem="emi-wK-dKY" secondAttribute="width" priority="250" id="dkc-x7-EPa"/>
116− <constraint firstItem="S2Z-ye-LWO" firstAttribute="top" secondItem="Obf-Cs-bNe" secondAttribute="top" constant="18" id="e7Q-BO-paM"/>
117− <constraint firstItem="S2Z-ye-LWO" firstAttribute="leading" secondItem="pMi-ey-nl3" secondAttribute="trailing" constant="30" id="kwk-Ex-x1d"/>
118− <constraint firstItem="Kvb-P4-fah" firstAttribute="bottom" secondItem="Obf-Cs-bNe" secondAttribute="bottom" id="nF9-OF-52s"/>
119− <constraint firstItem="QLb-ch-cuY" firstAttribute="leading" secondItem="Sko-xU-trE" secondAttribute="trailing" constant="37" id="pYH-nL-sHE"/>
120− <constraint firstItem="N1V-4M-SuG" firstAttribute="top" secondItem="Obf-Cs-bNe" secondAttribute="top" constant="18" id="uVj-fC-gUh"/>
121− <constraint firstItem="Obf-Cs-bNe" firstAttribute="top" secondItem="emi-wK-dKY" secondAttribute="top" id="uXg-WE-LVS"/>
122− <constraint firstItem="Obf-Cs-bNe" firstAttribute="leading" secondItem="emi-wK-dKY" secondAttribute="leading" id="zgm-8D-6cN"/>
123− </constraints>
124− <viewLayoutGuide key="contentLayoutGuide" id="heY-yN-cxj"/>
125− <viewLayoutGuide key="frameLayoutGuide" id="Si0-40-mPV"/>
126− </scrollView>
127− </subviews>
128− <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
129− <constraints>
130− <constraint firstItem="emi-wK-dKY" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="0jl-ST-MHN"/>
131− <constraint firstItem="emi-wK-dKY" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="AsB-3G-0nu"/>
132− <constraint firstItem="emi-wK-dKY" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="g8Y-gE-OhP"/>
133− <constraint firstItem="emi-wK-dKY" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="rLX-cv-To7"/>
134− </constraints>
135− <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
136− <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
137− <connections>
138− <outlet property="image" destination="Obf-Cs-bNe" id="X9U-1H-cye"/>
139− <outlet property="scrollView" destination="emi-wK-dKY" id="9ZQ-1W-Ig5"/>
140− <outlet property="shadow" destination="Kvb-P4-fah" id="Qaa-1I-iuh"/>
141− <outlet property="table2" destination="QLb-ch-cuY" id="13h-54-jLj"/>
142− <outlet property="table3" destination="Sko-xU-trE" id="6rG-Ov-XI4"/>
143− <outlet property="table4" destination="Uyw-7g-fgk" id="je7-hC-uEg"/>
144− <outlet property="table5" destination="S2Z-ye-LWO" id="WjB-f2-q3D"/>
145− <outlet property="table6" destination="pMi-ey-nl3" id="XsT-cC-4o9"/>
146− <outlet property="table7" destination="2KA-Fl-otO" id="baj-Ek-51Q"/>
147− <outlet property="table8" destination="N1V-4M-SuG" id="8a7-Kv-JqN"/>
148− </connections>
149− <point key="canvasLocation" x="138.40000000000001" y="120.98950524737631"/>
150− </view>
151− </objects>
152− <resources>
153− <image name="map_2" width="683" height="329"/>
154− </resources>
155−</document>
Hookah Tau/Controllers/Client/Reservations/Maps/MapView.swift+3−31
@@ -11,36 +11,15 @@ import UIKit
1111
1212class MapImageScroll: UIView {
1313
14− weak var handler: MapHandler?
14+ weak var handler: MapHandler?
1515
1616 var scrollViewParent: UIScrollView!
1717
18− var shadowView: UIView!
19−
20− var img: UIImageView!
21−
2218 var tables: [Int: TableButton] = [:]
2319
24− var zoomScale: CGFloat = 1.2
25−
26− func scrollToTable(table: Int) {
27− guard let tableButton = tables[table] else { return }
28−
29− tableButton.select()
30− img.bringSubviewToFront(shadowView)
31− img.bringSubviewToFront(tableButton)
32−
33− shadowView.alpha = 1
34−
35− scrollViewParent.zoom(to: tableButton.frame, animated: true)
36− scrollViewParent.contentOffset = CGPoint(x: scrollViewParent.contentOffset.x, y: scrollViewParent.contentOffset.y + 100)
37− scrollViewParent.setZoomScale(zoomScale, animated: true)
38− }
20+ func scrollToTable(table: Int) { }
3921
40− func scrollBack() {
41− img.sendSubviewToBack(shadowView)
42− shadowView.alpha = 0
43− }
22+ var img: UIImageView!
4423
4524 func configureFor(_ imageSize: CGSize) {
4625 self.scrollViewParent.contentSize = imageSize
@@ -83,13 +62,6 @@ class MapImageScroll: UIView {
8362 self.scrollViewParent.maximumZoomScale = maxScale
8463 self.scrollViewParent.minimumZoomScale = minScale
8564 }
86−
87− // Method for handling button taps.
88− func handleTap(button: TableButton, id: Int) {
89− tables.values.forEach { $0.unselect() }
90− button.select()
91− handler?.handleTap(withId: id)
92− }
9365}
9466
9567extension MapImageScroll {
Hookah Tau/Controllers/Client/Reservations/Maps/1/MapView1.swift → Hookah Tau/Controllers/Client/Reservations/Maps/MapView1.swiftrenamed+21−24
@@ -16,20 +16,6 @@ class MapView1: MapImageScroll, UIScrollViewDelegate {
1616
1717 // MARK: - Properties
1818
19− @IBOutlet weak var shadow: UIView! {
20− didSet {
21− super.shadowView = shadow
22− shadow.alpha = 0
23− }
24− }
25−
26− override var handler: MapHandler? {
27− didSet {
28− handleTap(button: firstTable, id: 1)
29− }
30− }
31−
32−
3319 @IBOutlet weak var scrollView: UIScrollView! {
3420 didSet {
3521 super.scrollViewParent = scrollView
@@ -47,10 +33,10 @@ class MapView1: MapImageScroll, UIScrollViewDelegate {
4733 let style = TableButtonStyle()
4834 style.apply(to: firstTable)
4935 firstTable.transform = CGAffineTransform(rotationAngle: CGFloat(-Double.pi / 4));
36+ firstTable.select()
5037 }
5138 }
5239
53−
5440 @IBOutlet weak var secondTable: TableButton! {
5541 didSet {
5642 let style = TableButtonStyle()
@@ -108,7 +94,6 @@ class MapView1: MapImageScroll, UIScrollViewDelegate {
10894 self.scrollView.delegate = self
10995 self.scrollView.delaysContentTouches = false
11096
111− image.addSubview(shadow)
11297 image.addSubview(firstTable)
11398 image.addSubview(secondTable)
11499 image.addSubview(trirdTable)
@@ -131,40 +116,52 @@ class MapView1: MapImageScroll, UIScrollViewDelegate {
131116 }
132117
133118 @IBAction func chooseSecondTable(_ sender: TableButton) {
134− handleTap(button: sender, id: 2)
119+ tables.values.forEach { $0.unselect() }
120+ secondTable.select()
121+ handler?.handleTap(withId: 2)
135122 }
136123
137124 @IBAction func chooseFifthTable(_ sender: TableButton) {
138− handleTap(button: sender, id: 5)
125+ tables.values.forEach { $0.unselect() }
126+ fifthTable.select()
127+ handler?.handleTap(withId: 5)
139128 }
140129
141130 @IBAction func choseSeventhTable(_ sender: TableButton) {
142− handleTap(button: sender, id: 7)
143131 }
144132
145133 @IBAction func chooseFirstTable(_ sender: TableButton) {
146− handleTap(button: sender, id: 1)
134+ tables.values.forEach { $0.unselect() }
135+ firstTable.select()
136+ handler?.handleTap(withId: 1)
147137 }
148138
149139 @IBAction func chooseThirdTable(_ sender: TableButton) {
150− handleTap(button: sender, id: 3)
151140 }
152141
153142 @IBAction func choose4thTable(_ sender: TableButton) {
154− handleTap(button: sender, id: 4)
155143 }
156144
157145 @IBAction func choose6thTable(_ sender: TableButton) {
158− handleTap(button: sender, id: 6)
159146 }
160147
161148 @IBAction func choose8thTable(_ sender: TableButton) {
162− handleTap(button: sender, id: 8)
163149 }
164150
151+
165152 // MARK: - Scroll view
166153
167154 func viewForZooming(in scrollView: UIScrollView) -> UIView? {
168155 self.image
169156 }
157+
158+
159+ override func scrollToTable(table: Int) {
160+ guard let tableButton = tables[table] else { return }
161+
162+ scrollView.setZoomScale(1.2, animated: true)
163+ scrollView.setContentOffset(tableButton.frame.origin, animated: true)
164+
165+ scrollView.scrollRectToVisible(tableButton.frame, animated: true)
166+ }
170167}
Hookah Tau/Controllers/Client/Reservations/Maps/1/MapView1.xib → Hookah Tau/Controllers/Client/Reservations/Maps/MapView1.xibrenamed+28−36
@@ -1,9 +1,9 @@
11<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
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">
33 <device id="retina4_7" orientation="portrait" appearance="light"/>
44 <dependencies>
55 <deployment identifier="iOS"/>
6− <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
77 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
88 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
99 </dependencies>
@@ -18,25 +18,14 @@
1818 <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
1919 <subviews>
2020 <imageView clipsSubviews="YES" 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="636"/>
21+ <rect key="frame" x="0.0" y="0.0" width="536" height="639"/>
2222 </imageView>
23− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Y23-Wu-4BW" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
24− <rect key="frame" x="44" y="37" width="102" height="119"/>
25− <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
26− <constraints>
27− <constraint firstAttribute="width" constant="102" id="EKZ-Ny-4RQ"/>
28− <constraint firstAttribute="height" constant="119" id="u1N-5d-cFR"/>
29− </constraints>
30− <connections>
31− <action selector="chooseFirstTable:" destination="iN0-l3-epB" eventType="touchUpInside" id="1O9-7Q-a8g"/>
32− </connections>
33− </button>
3423 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xsw-fJ-8cN" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
35− <rect key="frame" x="209" y="116" width="131" height="117"/>
24+ <rect key="frame" x="209" y="116" width="131" height="119"/>
3625 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
3726 <constraints>
3827 <constraint firstAttribute="width" constant="131" id="2xi-Oz-ceC"/>
39− <constraint firstAttribute="height" constant="117" id="xPD-fh-9Zg"/>
28+ <constraint firstAttribute="height" constant="119" id="xPD-fh-9Zg"/>
4029 </constraints>
4130 <connections>
4231 <action selector="chooseSecondTable:" destination="iN0-l3-epB" eventType="touchUpInside" id="5XE-gZ-DyJ"/>
@@ -54,10 +43,10 @@
5443 </connections>
5544 </button>
5645 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fw9-l6-N8a" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
57− <rect key="frame" x="60" y="350" width="102" height="120"/>
46+ <rect key="frame" x="60" y="353" width="102" height="118"/>
5847 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
5948 <constraints>
60− <constraint firstAttribute="height" constant="120" id="2Vp-Ip-7cO"/>
49+ <constraint firstAttribute="height" constant="118" id="2Vp-Ip-7cO"/>
6150 <constraint firstAttribute="width" constant="102" id="2hI-75-UCM"/>
6251 </constraints>
6352 <connections>
@@ -65,10 +54,10 @@
6554 </connections>
6655 </button>
6756 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KJZ-Nl-7hH" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
68− <rect key="frame" x="222" y="273" width="104" height="120"/>
57+ <rect key="frame" x="222" y="275" width="104" height="119"/>
6958 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
7059 <constraints>
71− <constraint firstAttribute="height" constant="120" id="Ifu-kd-YHH"/>
60+ <constraint firstAttribute="height" constant="119" id="Ifu-kd-YHH"/>
7261 <constraint firstAttribute="width" constant="104" id="phm-aP-6dx"/>
7362 </constraints>
7463 <connections>
@@ -76,7 +65,7 @@
7665 </connections>
7766 </button>
7867 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mUw-im-1BC" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
79− <rect key="frame" x="222" y="433" width="92" height="67"/>
68+ <rect key="frame" x="222" y="434" width="92" height="67"/>
8069 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
8170 <constraints>
8271 <constraint firstAttribute="width" constant="92" id="AJ6-ku-4R3"/>
@@ -86,11 +75,22 @@
8675 <action selector="choose8thTable:" destination="iN0-l3-epB" eventType="touchUpInside" id="C8U-7T-Bsc"/>
8776 </connections>
8877 </button>
78+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Bns-fd-Wv4" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
79+ <rect key="frame" x="44" y="43" width="102" height="125"/>
80+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
81+ <constraints>
82+ <constraint firstAttribute="width" constant="102" id="l7h-tW-FfX"/>
83+ <constraint firstAttribute="height" constant="125" id="nDu-wc-Ll7"/>
84+ </constraints>
85+ <connections>
86+ <action selector="chooseFirstTable:" destination="iN0-l3-epB" eventType="touchUpInside" id="uc3-Si-PiX"/>
87+ </connections>
88+ </button>
8989 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aIM-Qn-Uhl" customClass="TableButton" customModule="Hookah_Tau" customModuleProvider="target">
90− <rect key="frame" x="386" y="116" width="131" height="119"/>
90+ <rect key="frame" x="386" y="116" width="130" height="119"/>
9191 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
9292 <constraints>
93− <constraint firstAttribute="width" constant="131" id="Lhq-jM-PQ0"/>
93+ <constraint firstAttribute="width" constant="130" id="Lhq-jM-PQ0"/>
9494 <constraint firstAttribute="height" constant="119" id="vsx-u8-L6o"/>
9595 </constraints>
9696 <connections>
@@ -108,22 +108,19 @@
108108 <action selector="choose4thTable:" destination="iN0-l3-epB" eventType="touchUpInside" id="U5p-In-FEa"/>
109109 </connections>
110110 </button>
111− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zbE-1g-Qz4">
112− <rect key="frame" x="0.0" y="0.0" width="536" height="636"/>
113− <color key="backgroundColor" white="1" alpha="0.69999999999999996" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
114− </view>
115111 </subviews>
116112 <constraints>
117113 <constraint firstItem="btD-Wl-3P6" firstAttribute="leading" secondItem="Fw9-l6-N8a" secondAttribute="trailing" constant="-162" id="1lP-Gg-qgW"/>
118114 <constraint firstItem="btD-Wl-3P6" firstAttribute="leading" secondItem="onR-hl-Q2x" secondAttribute="trailing" constant="-162" id="1vg-zK-zAf"/>
119− <constraint firstItem="Y23-Wu-4BW" firstAttribute="leading" secondItem="BDw-f7-kaJ" secondAttribute="leading" constant="44" id="913-M2-zhQ"/>
120115 <constraint firstItem="btD-Wl-3P6" firstAttribute="leading" secondItem="FuE-LV-NBR" secondAttribute="leading" id="ALg-fi-eby"/>
116+ <constraint firstItem="btD-Wl-3P6" firstAttribute="leading" secondItem="Bns-fd-Wv4" secondAttribute="trailing" constant="-146" id="Dd1-Ql-NS9"/>
121117 <constraint firstItem="Fw9-l6-N8a" firstAttribute="top" secondItem="btD-Wl-3P6" secondAttribute="bottom" constant="-286" id="DyF-KK-1VM"/>
122118 <constraint firstItem="btD-Wl-3P6" firstAttribute="top" secondItem="FuE-LV-NBR" secondAttribute="top" id="EKh-3k-EL9"/>
123119 <constraint firstItem="mUw-im-1BC" firstAttribute="top" secondItem="KJZ-Nl-7hH" secondAttribute="bottom" constant="40" id="GaI-BE-NZy"/>
124120 <constraint firstItem="btD-Wl-3P6" firstAttribute="width" secondItem="FuE-LV-NBR" secondAttribute="width" priority="250" id="MDs-kk-aza"/>
125121 <constraint firstItem="btD-Wl-3P6" firstAttribute="top" secondItem="aIM-Qn-Uhl" secondAttribute="bottom" constant="-235" id="NwR-U0-V6F"/>
126− <constraint firstItem="mUw-im-1BC" firstAttribute="top" secondItem="btD-Wl-3P6" secondAttribute="bottom" constant="-203" id="UXz-DD-dPH"/>
122+ <constraint firstAttribute="bottom" secondItem="Bns-fd-Wv4" secondAttribute="bottom" constant="471" id="TL4-ma-hIl"/>
123+ <constraint firstItem="mUw-im-1BC" firstAttribute="top" secondItem="btD-Wl-3P6" secondAttribute="bottom" constant="-205" id="UXz-DD-dPH"/>
127124 <constraint firstItem="mUw-im-1BC" firstAttribute="leading" secondItem="Fw9-l6-N8a" secondAttribute="trailing" constant="60" id="V4u-ko-iFV"/>
128125 <constraint firstItem="KJZ-Nl-7hH" firstAttribute="top" secondItem="xsw-fJ-8cN" secondAttribute="bottom" constant="40" id="XFV-l2-chC"/>
129126 <constraint firstItem="btD-Wl-3P6" firstAttribute="top" secondItem="onR-hl-Q2x" secondAttribute="bottom" constant="-332" id="XNT-i4-1l8"/>
@@ -132,10 +129,10 @@
132129 <constraint firstItem="wpi-6E-c5p" firstAttribute="leading" secondItem="KJZ-Nl-7hH" secondAttribute="trailing" constant="73" id="cy7-0f-qGh"/>
133130 <constraint firstItem="wpi-6E-c5p" firstAttribute="top" secondItem="aIM-Qn-Uhl" secondAttribute="bottom" constant="40" id="dek-gp-H4X"/>
134131 <constraint firstItem="btD-Wl-3P6" firstAttribute="height" secondItem="FuE-LV-NBR" secondAttribute="height" priority="250" id="fSd-Le-0Bc"/>
132+ <constraint firstItem="btD-Wl-3P6" firstAttribute="top" secondItem="Bns-fd-Wv4" secondAttribute="bottom" constant="-168" id="gCy-q0-NO1"/>
135133 <constraint firstAttribute="bottom" secondItem="btD-Wl-3P6" secondAttribute="bottom" id="neR-bl-aSU"/>
136134 <constraint firstItem="KJZ-Nl-7hH" firstAttribute="leading" secondItem="onR-hl-Q2x" secondAttribute="trailing" constant="60" id="pka-Xh-e1c"/>
137135 <constraint firstItem="xsw-fJ-8cN" firstAttribute="leading" secondItem="onR-hl-Q2x" secondAttribute="trailing" constant="47" id="r9E-ps-zBG"/>
138− <constraint firstItem="Y23-Wu-4BW" firstAttribute="top" secondItem="BDw-f7-kaJ" secondAttribute="top" constant="37" id="rgb-Sa-T0E"/>
139136 </constraints>
140137 <viewLayoutGuide key="contentLayoutGuide" id="BDw-f7-kaJ"/>
141138 <viewLayoutGuide key="frameLayoutGuide" id="KRK-7M-mdV"/>
@@ -145,24 +142,19 @@
145142 <constraints>
146143 <constraint firstItem="FuE-LV-NBR" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="0zj-Rn-Ogr"/>
147144 <constraint firstItem="FuE-LV-NBR" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="87c-vf-vMB"/>
148− <constraint firstItem="btD-Wl-3P6" firstAttribute="trailing" secondItem="zbE-1g-Qz4" secondAttribute="trailing" id="ASF-YJ-jez"/>
149− <constraint firstItem="zbE-1g-Qz4" firstAttribute="leading" secondItem="btD-Wl-3P6" secondAttribute="leading" id="Ec8-Qz-Dn3"/>
150− <constraint firstItem="btD-Wl-3P6" firstAttribute="bottom" secondItem="zbE-1g-Qz4" secondAttribute="bottom" id="UFk-wW-dCx"/>
151145 <constraint firstItem="FuE-LV-NBR" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="bhi-Ox-g2b"/>
152− <constraint firstItem="zbE-1g-Qz4" firstAttribute="top" secondItem="btD-Wl-3P6" secondAttribute="top" id="j32-id-sD4"/>
153146 <constraint firstItem="FuE-LV-NBR" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="jLf-Pz-gy1"/>
154147 </constraints>
155148 <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
156149 <connections>
157150 <outlet property="eighthTable" destination="mUw-im-1BC" id="x44-wS-xJg"/>
158151 <outlet property="fifthTable" destination="KJZ-Nl-7hH" id="KXs-8a-Fo8"/>
159− <outlet property="firstTable" destination="Y23-Wu-4BW" id="9m3-Oy-Gwc"/>
152+ <outlet property="firstTable" destination="Bns-fd-Wv4" id="r5r-DX-4AD"/>
160153 <outlet property="forthTable" destination="wpi-6E-c5p" id="26b-bH-kEA"/>
161154 <outlet property="image" destination="btD-Wl-3P6" id="Ou2-hT-jap"/>
162155 <outlet property="scrollView" destination="FuE-LV-NBR" id="pWc-cI-eXE"/>
163156 <outlet property="secondTable" destination="xsw-fJ-8cN" id="2vH-LX-qF0"/>
164157 <outlet property="seventhTable" destination="Fw9-l6-N8a" id="Jwb-yY-Opx"/>
165− <outlet property="shadow" destination="zbE-1g-Qz4" id="tHA-7d-6Aa"/>
166158 <outlet property="sixthTable" destination="onR-hl-Q2x" id="Zi7-hJ-KLq"/>
167159 <outlet property="trirdTable" destination="aIM-Qn-Uhl" id="aFd-cB-neE"/>
168160 </connections>
Hookah Tau/Controllers/Client/Reservations/Reservation.storyboard+4−86
@@ -1,9 +1,9 @@
11<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
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">
33 <device id="retina6_1" orientation="portrait" appearance="light"/>
44 <dependencies>
55 <deployment identifier="iOS"/>
6− <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
77 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
88 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
99 </dependencies>
@@ -49,10 +49,10 @@
4949 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
5050 <subviews>
5151 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NBJ-7w-vpV">
52− <rect key="frame" x="0.0" y="544" width="414" height="352"/>
52+ <rect key="frame" x="0.0" y="502" width="414" height="394"/>
5353 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
5454 <constraints>
55− <constraint firstAttribute="height" constant="352" id="KKm-d5-Srx"/>
55+ <constraint firstAttribute="height" constant="394" id="KKm-d5-Srx"/>
5656 </constraints>
5757 </view>
5858 </subviews>
@@ -72,87 +72,5 @@
7272 </objects>
7373 <point key="canvasLocation" x="706" y="-38"/>
7474 </scene>
75− <!--Third Step Reservation View Controller-->
76− <scene sceneID="zRo-J6-3SG">
77− <objects>
78− <viewController storyboardIdentifier="ThirdStepReservationViewController" id="BZu-JB-b3i" customClass="ThirdStepReservationViewController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
79− <view key="view" contentMode="scaleToFill" id="3b8-mw-Gl1">
80− <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
81− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
82− <subviews>
83− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e2X-iN-FVj">
84− <rect key="frame" x="0.0" y="556" width="414" height="340"/>
85− <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
86− <constraints>
87− <constraint firstAttribute="height" constant="340" id="5U9-DA-Asv"/>
88− </constraints>
89− </view>
90− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lUx-gC-C8T">
91− <rect key="frame" x="0.0" y="44" width="414" height="512"/>
92− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
93− </view>
94− </subviews>
95− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
96− <constraints>
97− <constraint firstItem="e2X-iN-FVj" firstAttribute="top" secondItem="lUx-gC-C8T" secondAttribute="bottom" id="3gm-hP-Bdu"/>
98− <constraint firstItem="e2X-iN-FVj" firstAttribute="trailing" secondItem="gXx-re-YYI" secondAttribute="trailing" id="3mf-Ee-0xt"/>
99− <constraint firstItem="e2X-iN-FVj" firstAttribute="leading" secondItem="gXx-re-YYI" secondAttribute="leading" id="H2H-uv-zpb"/>
100− <constraint firstItem="gXx-re-YYI" firstAttribute="trailing" secondItem="lUx-gC-C8T" secondAttribute="trailing" id="N8u-eH-14m"/>
101− <constraint firstAttribute="bottom" secondItem="e2X-iN-FVj" secondAttribute="bottom" id="nQM-9e-gfE"/>
102− <constraint firstItem="lUx-gC-C8T" firstAttribute="leading" secondItem="gXx-re-YYI" secondAttribute="leading" id="oir-mE-qlS"/>
103− <constraint firstItem="gXx-re-YYI" firstAttribute="top" secondItem="lUx-gC-C8T" secondAttribute="top" id="zDp-B5-m8M"/>
104− </constraints>
105− <viewLayoutGuide key="safeArea" id="gXx-re-YYI"/>
106− </view>
107− <connections>
108− <outlet property="containerView" destination="e2X-iN-FVj" id="6Zy-M4-sSA"/>
109− <outlet property="contentForMap" destination="lUx-gC-C8T" id="LBl-cs-Yav"/>
110− </connections>
111− </viewController>
112− <placeholder placeholderIdentifier="IBFirstResponder" id="En2-ct-Lfj" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
113− </objects>
114− <point key="canvasLocation" x="1457.9710144927537" y="-38.169642857142854"/>
115− </scene>
116− <!--Change Reservation View Controller-->
117− <scene sceneID="zZt-Ob-8J3">
118− <objects>
119− <viewController storyboardIdentifier="ChangeReservationViewController" id="qmR-St-vh2" customClass="ChangeReservationViewController" customModule="Hookah_Tau" customModuleProvider="target" sceneMemberID="viewController">
120− <view key="view" contentMode="scaleToFill" id="mnl-c9-WGz">
121− <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
122− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
123− <subviews>
124− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kon-kQ-rMb">
125− <rect key="frame" x="0.0" y="502" width="414" height="394"/>
126− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
127− <constraints>
128− <constraint firstAttribute="height" constant="394" id="Ppm-PI-ASV"/>
129− </constraints>
130− </view>
131− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6Dy-xy-vQH">
132− <rect key="frame" x="0.0" y="0.0" width="414" height="502"/>
133− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
134− </view>
135− </subviews>
136− <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
137− <constraints>
138− <constraint firstItem="kon-kQ-rMb" firstAttribute="leading" secondItem="Oj9-9F-isg" secondAttribute="leading" id="5wF-Rc-6Na"/>
139− <constraint firstAttribute="bottom" secondItem="kon-kQ-rMb" secondAttribute="bottom" id="IAO-aj-hyT"/>
140− <constraint firstItem="kon-kQ-rMb" firstAttribute="top" secondItem="6Dy-xy-vQH" secondAttribute="bottom" id="W6B-dA-vrO"/>
141− <constraint firstItem="6Dy-xy-vQH" firstAttribute="leading" secondItem="Oj9-9F-isg" secondAttribute="leading" id="WKh-xt-L3z"/>
142− <constraint firstItem="kon-kQ-rMb" firstAttribute="trailing" secondItem="Oj9-9F-isg" secondAttribute="trailing" id="cZG-IB-ohm"/>
143− <constraint firstItem="6Dy-xy-vQH" firstAttribute="top" secondItem="mnl-c9-WGz" secondAttribute="top" id="iK5-6K-mEo"/>
144− <constraint firstItem="6Dy-xy-vQH" firstAttribute="trailing" secondItem="Oj9-9F-isg" secondAttribute="trailing" id="rrY-dK-bTz"/>
145− </constraints>
146− <viewLayoutGuide key="safeArea" id="Oj9-9F-isg"/>
147− </view>
148− <connections>
149− <outlet property="childContentView" destination="kon-kQ-rMb" id="5DH-RF-lEQ"/>
150− <outlet property="mapContentView" destination="6Dy-xy-vQH" id="5Cu-uI-WT3"/>
151− </connections>
152− </viewController>
153− <placeholder placeholderIdentifier="IBFirstResponder" id="H8g-xl-PmS" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
154− </objects>
155− <point key="canvasLocation" x="2350.7246376811595" y="-38.169642857142854"/>
156− </scene>
15775 </scenes>
15876</document>
Hookah Tau/Controllers/Client/Reservations/SecondStepReservationViewController.swiftnew file+89
@@ -0,0 +1,89 @@
1+//
2+// SecondStepReservationViewController.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 21/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+class SecondStepReservationViewController: BaseViewController {
12+
13+ // MARK: - Properties
14+
15+ weak var coordinator: SecondStepReservationCoordinator?
16+
17+ @IBOutlet weak var childContentView: UIView!
18+
19+ var secondStepView: SecondStepView?
20+
21+ /// map view from the previous screen
22+ var mapView: MapImageScroll?
23+
24+ var model: SecondStepModel?
25+
26+ /// booked periods for this table for this date
27+ var bookedPeriods: [ReservationPeriod] = [] {
28+ didSet {
29+ secondStepView?.setUpReservedIntervals(bookedPeriods)
30+ }
31+ }
32+
33+ let confirmButton: Button = {
34+ let button = Button()
35+ let style = BlackButtonStyle()
36+ style.apply(to: button, withTitle: "ПОДТВЕРДИТЬ")
37+ //button.addTarget(self, action: #selector(doneChanging), for: .touchUpInside)
38+ return button
39+ }()
40+
41+ let cancelButton: Button = {
42+ let button = Button()
43+ let style = BlackButtonStyle()
44+ style.apply(to: button, withTitle: "ОТМЕНИТЬ")
45+ return button
46+ }()
47+
48+ // MARK: - Lifecycle
49+
50+ override func viewDidLoad() {
51+ super.viewDidLoad()
52+
53+ setupMap()
54+ setupChildContainer()
55+ setupButtons()
56+
57+ }
58+
59+ // MARK: - Setup
60+
61+ func setupChildContainer() {
62+
63+ secondStepView = SecondStepView.loadFromNib()
64+ childContentView.addSubviewThatFills(secondStepView)
65+ guard let model = model else { return }
66+ secondStepView?.bind(model: model)
67+ }
68+
69+ func setupMap() {
70+ view.addSubviewThatFills(mapView)
71+
72+ mapView?.isUserInteractionEnabled = false
73+ mapView?.scrollToTable(table: model?.table ?? 0)
74+
75+ guard let map = mapView else { return }
76+ view.sendSubviewToBack(map)
77+ }
78+
79+ func setupButtons() {
80+ addStackViewWithButtons(leftBtn: cancelButton,
81+ rightBtn: confirmButton,
82+ constant: -childContentView.frame.height - 20)
83+ cancelButton.addTarget(self, action: #selector(cancelChange), for: .touchUpInside)
84+ }
85+
86+ @objc func cancelChange() {
87+ coordinator?.cancel(mapView)
88+ }
89+}
Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepReservationCoordinator.swiftdeleted−62
@@ -1,62 +0,0 @@
1−//
2−// SecondStepReservationCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 21/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−
12−class SecondStepReservationCoordinator: BaseCoordinator {
13−
14− // MARK: - Properties
15−
16− var didFinish: (() -> Void)?
17−
18− var goBack: ((MapImageScroll?) -> Void)?
19−
20− var model: SecondStepModel?
21−
22− var mapView: MapImageScroll?
23−
24− var onBooking: ((MapImageScroll, Reservation) -> Void)?
25−
26− var vc: SecondStepReservationViewController?
27−
28− // MARK: - Lifecycle
29−
30− override func start() {
31− let storyboard = UIStoryboard(name: "Reservation", bundle: nil)
32− vc = storyboard.instantiateViewController(withIdentifier: "SecondStepReservationViewController") as? SecondStepReservationViewController
33−
34− guard let viewController = vc else { return }
35−
36− viewController.model = model
37− viewController.mapView = mapView
38− viewController.coordinator = self
39−
40− navigationController?.pushViewController(viewController, animated: false)
41− }
42−
43− func cancel(_ mapView: MapImageScroll?) {
44− goBack?(mapView)
45− }
46−
47− func book(_ mapView: MapImageScroll?, reservation: Reservation) {
48− let coordinator = ThirdStepReservationCoordinator(navigationController: navigationController)
49− addDependency(coordinator)
50−
51− coordinator.didFinish = { [weak self] in
52− self?.navigationController?.popViewController(animated: false)
53− self?.removeDependency(coordinator)
54− self?.didFinish?()
55− }
56−
57− coordinator.mapView = mapView
58− coordinator.resrvation = reservation
59−
60− coordinator.start()
61− }
62−}
Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepReservationViewController.swiftdeleted−142
@@ -1,142 +0,0 @@
1−//
2−// SecondStepReservationViewController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 21/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class SecondStepReservationViewController: BaseViewController {
12−
13− // MARK: - Properties
14−
15− @IBOutlet weak var childContentView: UIView!
16−
17− var secondStepView: SecondStepView?
18−
19− /// координатор
20− weak var coordinator: SecondStepReservationCoordinator?
21−
22− /// service для создания бронирования
23− var reservationService: ReservationsService?
24−
25− /// map view from the previous screen
26− var mapView: MapImageScroll?
27−
28− var model: SecondStepModel?
29−
30− /// address of the building to display in nav bar title
31− var address: String = "Покровский бр., 11"
32−
33− let confirmButton: 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− setupNavBar()
53− setupMap()
54− setupChildContainer()
55− setupButtons()
56−
57− reservationService = ReservationsService(apiClient: APIClient.shared)
58− }
59−
60− override func viewWillAppear(_ animated: Bool) {
61− super.viewWillAppear(animated)
62−
63− tabBarController?.tabBar.isHidden = true
64− }
65−
66−
67− // MARK: - Setup
68−
69− func setupNavBar() {
70− navigationItem.hidesBackButton = true
71− navigationItem.title = address
72− }
73−
74− func setupChildContainer() {
75−
76− secondStepView = SecondStepView.loadFromNib()
77− childContentView.addSubviewThatFills(secondStepView)
78− guard let model = model else { return }
79− secondStepView?.bind(model: model)
80− }
81−
82− func setupMap() {
83− guard let map = mapView else { return }
84− view.addSubview(map)
85−
86− NSLayoutConstraint.activate([
87− map.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
88− map.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
89− map.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
90− map.bottomAnchor.constraint(equalTo: childContentView.topAnchor, constant: 0)
91− ])
92−
93− let width = view.frame.width
94−
95− mapView?.scrollViewParent.setContentOffset(CGPoint(x: 0, y: 100), animated: false)
96− mapView?.scrollViewParent.contentInset = UIEdgeInsets(top: 0,
97− left: width / 2,
98− bottom: -100,
99− right: width / 2)
100− mapView?.isUserInteractionEnabled = false
101− view.sendSubviewToBack(map)
102− }
103−
104− override func viewDidAppear(_ animated: Bool) {
105− super.viewDidAppear(animated)
106−
107− mapView?.scrollToTable(table: model?.table ?? 0)
108− }
109−
110− func setupButtons() {
111− addStackViewWithButtons(leftBtn: cancelButton,
112− rightBtn: confirmButton,
113− constant: -childContentView.frame.height - 20)
114− cancelButton.addTarget(self, action: #selector(cancelChange), for: .touchUpInside)
115− confirmButton.addTarget(self, action: #selector(book), for: .touchUpInside)
116− }
117−
118− // MARK: - Button handlers
119−
120− @objc func cancelChange() {
121− coordinator?.cancel(mapView)
122− }
123−
124− @objc func book() {
125− guard let booking = secondStepView?.data else { return }
126− confirmButton.loading = true
127−
128− print(booking)
129−
130− reservationService?.createReservation(data: booking, completion: { [weak self] (result) in
131− switch result {
132− case .failure:
133− self?.displayAlert(with: "Не удалось совершить бронирование :(")
134−
135− case .success(let reservation):
136− self?.coordinator?.book(self?.mapView, reservation: reservation)
137− }
138−
139− self?.confirmButton.loading = false
140− })
141− }
142−}
Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepView.swiftdeleted−351
@@ -1,351 +0,0 @@
1−//
2−// SecondStepView.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 21/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−/// стол, начало, интервалы (???), establishment
12−struct SecondStepModel {
13− var establishment: Int
14− var table: Int
15− var startTime: Date
16− var endTime: Date? = nil
17− var reservedintervals: [ReservationPeriod]
18−}
19−
20−class SecondStepView: UIView {
21−
22− // MARK: - IBAOutlets
23−
24− @IBOutlet weak var totalBookingLabel: UILabel!
25−
26− @IBOutlet weak var specialLabel: UILabel! {
27− didSet {
28− let m = NSMutableAttributedString(string: "Если Вам нужно что-то особенное, Вы можете связаться с администратором ")
29−
30− let image1Attachment = NSTextAttachment()
31− image1Attachment.bounds = CGRect(x: 0, y: -3, width: 15, height: 15)
32− image1Attachment.image = #imageLiteral(resourceName: "phone")
33− let image1String = NSMutableAttributedString(attachment: image1Attachment)
34− m.append(image1String)
35− specialLabel.attributedText = m
36−
37− let gr = UITapGestureRecognizer(target: self, action: #selector(callAlmin))
38− specialLabel.addGestureRecognizer(gr)
39− }
40− }
41−
42−
43− @IBOutlet weak var numberOfGuestsLabel: UILabel!
44−
45− @IBOutlet weak var guestSlider: UISlider!
46−
47− @IBOutlet weak var scrollView: UIScrollView!
48−
49− @IBOutlet weak var intervalsStackView: UIStackView!
50−
51− // MARK: - Peoperties
52−
53− /// Время начала вертелки.
54− /// Для клиента это 12:00 смены (надо вызвать метод для получения текущей смены).
55− /// Для администратора это `t` - 24h
56− var startDate: Date?
57−
58− /// Модель вьюшки
59− var data: ReservationData? {
60− didSet {
61− guard let d = data else { return }
62− let (date, time) = Date.format(d.startTime, d.endTime)
63− totalBookingLabel.text = "Забронировать \(d.reservedTable) столик на \(d.numberOfGuests) человека \(date) \(time)?"
64− }
65− }
66−
67− /// Модель с которой мы приходим в эту вьюшку
68− var model: SecondStepModel? {
69− didSet {
70− guard let model = model else { return }
71−
72− data = ReservationData(establishment: model.establishment,
73− startTime: model.startTime,
74− endTime: model.endTime ?? model.startTime.addHours(2),
75− numberOfGuests: Int(guestSlider.value),
76− reservedTable: model.table)
77−
78− // isAdmin
79− let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
80−
81− let (start, _) = isAdmin ? model.startTime.getAdminStartingAndEndPoint() : model.startTime.getClientStartingAndEndPoint()
82−
83− startDate = start
84−
85− setUpIntervals(isAdmin)
86− setUpReservedIntervals(model.reservedintervals, isAdmin)
87− setUpBookingPeriod(model.startTime, model.endTime)
88− }
89− }
90−
91− // констрейнты начала и конца интервала
92− var startLeadingConstraint: NSLayoutConstraint!
93− var endLeadingConstraint: NSLayoutConstraint!
94−
95− var startPoint: UIImageView = {
96− var view = UIImageView()
97− view.isUserInteractionEnabled = true
98− view.image = #imageLiteral(resourceName: "handle_left")
99− view.translatesAutoresizingMaskIntoConstraints = false
100− return view
101− }()
102−
103− var endPoint: UIImageView = {
104− var view = UIImageView()
105− view.isUserInteractionEnabled = true
106− view.image = #imageLiteral(resourceName: "Group")
107− view.translatesAutoresizingMaskIntoConstraints = false
108− return view
109− }()
110−
111− /// Интервал
112− var fillInterval: UIView = {
113− var view = UIView()
114− view.backgroundColor = #colorLiteral(red: 0, green: 0.5921568627, blue: 1, alpha: 0.3426262843)
115− view.translatesAutoresizingMaskIntoConstraints = false
116− return view
117− }()
118−
119− // MARK: - Lifecycle
120−
121− override func awakeFromNib() {
122− super.awakeFromNib()
123−
124− scrollView.delegate = self
125−
126− scrollView.showsHorizontalScrollIndicator = false
127− }
128−
129− @IBAction func sliderValueChanged(_ sender: UISlider) {
130− let value = Int(sender.value)
131− numberOfGuestsLabel.text = "Количество гостей: \(value)"
132−
133− guard let d = data else { return }
134−
135− data = ReservationData(establishment: d.establishment,
136− startTime: d.startTime,
137− endTime: d.endTime,
138− numberOfGuests: value,
139− reservedTable: d.reservedTable)
140− }
141−
142− @objc func callAlmin() {
143− guard
144− let m = model?.establishment,
145− let phone = TotalStorage.standard.getEstablishment(m)?.admin,
146− let urlPhone = URL(string: "tel://79\(phone)") else { return }
147−
148− UIApplication.shared.open(urlPhone)
149− }
150−
151− // MARK: - Setup
152−
153− /// Тут происходит установка интервалов. Разное для клиента и админа
154− func setUpIntervals(_ isAdmin: Bool) {
155− guard let startPoint = startDate else { return }
156−
157− let startingPoint = isAdmin ? startPoint.getAdminsStartingPoint() : Constants.clientStartingPoint
158− let endingPoint = startingPoint + (isAdmin ? Constants.adminDuration : Constants.clientDuration)
159−
160− for period in startingPoint...endingPoint {
161− let timePointView = TimePointView.loadFromNib()
162− timePointView?.setUp(withTimePoint: period)
163− let view = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 106))
164− view.addSubviewThatFills(timePointView)
165− intervalsStackView.addArrangedSubview(view)
166− }
167− }
168−
169−
170− private func setUpBookingPeriod(_ startTime: Date, _ endTime: Date? = nil) {
171− self.scrollView.addSubview(startPoint)
172− self.scrollView.addSubview(endPoint)
173− self.scrollView.addSubview(fillInterval)
174−
175− guard let startDate = startDate else { return }
176−
177− let startConstr = CGFloat(startTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint)
178−
179− scrollView.setContentOffset(CGPoint(x: startConstr - 50, y: 0), animated: true)
180−
181− startLeadingConstraint = startPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
182− constant: startConstr)
183−
184− if let end = endTime {
185− let endConstr = CGFloat(end.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint)
186− endLeadingConstraint = endPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
187− constant: endConstr)
188− } else {
189− endLeadingConstraint = endPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
190− constant:startConstr + Constants.minBookingLength)
191− }
192−
193− NSLayoutConstraint.activate([
194−
195− startPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
196− endPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
197−
198− startPoint.widthAnchor.constraint(equalToConstant: Constants.pointWidth),
199− endPoint.widthAnchor.constraint(equalToConstant: Constants.pointWidth),
200−
201− startPoint.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
202− endPoint.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
203−
204− startLeadingConstraint,
205− endLeadingConstraint,
206−
207− fillInterval.leftAnchor.constraint(equalTo: startPoint.rightAnchor, constant: 0),
208− fillInterval.rightAnchor.constraint(equalTo: endPoint.leftAnchor, constant: 0),
209−
210− fillInterval.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
211− fillInterval.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0)
212− ])
213−
214− let scrollViewPanStartGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanStart(recognizer:)))
215− startPoint.addGestureRecognizer(scrollViewPanStartGesture)
216−
217− let scrollViewPanEndGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanEnd(recognizer:)))
218− endPoint.addGestureRecognizer(scrollViewPanEndGesture)
219− }
220−
221− func setUpReservedIntervals(_ reservations: [ReservationPeriod], _ isAdmin: Bool) {
222−
223− for reservation in reservations {
224− let uiview = UIView(frame: CGRect(x: 0, y: 0, width: Constants.widthTimePoint * reservation.duration, height: Constants.heightIntervals))
225− uiview.backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 0.5)
226−
227−
228− uiview.translatesAutoresizingMaskIntoConstraints = false
229− scrollView.addSubview(uiview)
230−
231− guard let startDate = startDate else { return }
232−
233− let s = reservation.startTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint
234− let d = reservation.duration * Constants.widthTimePoint
235−
236− let startTime = s < 0 ? 0 : s
237−
238− let total = (isAdmin ? Constants.adminDuration : Constants.clientDuration) * Constants.widthTimePoint
239− var duration = 0
240− if s < 0 {
241− duration = reservation.endTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint
242− } else {
243− duration = (s + d) > total ? total - s : d
244− }
245−
246− NSLayoutConstraint.activate([
247− uiview.bottomAnchor.constraint(equalToSystemSpacingBelow: scrollView.bottomAnchor, multiplier: 0),
248− uiview.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
249− constant: CGFloat(Constants.widthTimePoint / 2 + startTime)),
250− uiview.widthAnchor.constraint(equalToConstant: CGFloat(duration)),
251− uiview.heightAnchor.constraint(equalToConstant: CGFloat(Constants.heightIntervals))
252− ])
253− }
254− }
255−
256− func bind(model: SecondStepModel) {
257− self.model = model
258−
259− guard let table = TotalStorage.standard.getTable(establishment: model.establishment,
260− table: model.table) else { return }
261− self.guestSlider.maximumValue = Float(table.maxGuestNumber)
262− }
263−
264− // MARK: - Pan
265−
266− @objc func handlePanStart(recognizer:UIPanGestureRecognizer) {
267−
268− let translation = recognizer.translation(in: self.intervalsStackView)
269− let duration = abs(startLeadingConstraint.constant + translation.x - endLeadingConstraint.constant)
270−
271− if let view = recognizer.view, duration >= Constants.minBookingLength {
272− startLeadingConstraint.constant += translation.x
273−
274− changeTime(startLeadingConstraint, .start)
275−
276− view.setNeedsUpdateConstraints()
277− }
278−
279− recognizer.setTranslation(CGPoint.zero, in: self.intervalsStackView)
280− }
281−
282− @objc func handlePanEnd(recognizer:UIPanGestureRecognizer) {
283−
284− let translation = recognizer.translation(in: self.intervalsStackView)
285− let duration = abs(startLeadingConstraint.constant - (endLeadingConstraint.constant + translation.x))
286−
287− if let view = recognizer.view, duration >= Constants.minBookingLength {
288− endLeadingConstraint.constant += translation.x
289−
290− changeTime(endLeadingConstraint, .end)
291− view.setNeedsUpdateConstraints()
292− }
293−
294− recognizer.setTranslation(CGPoint.zero, in: self.intervalsStackView)
295− }
296−
297− func changeTime(_ constraint: NSLayoutConstraint, _ period: Period) {
298− guard let startDate = startDate, let d = data else { return }
299−
300− let offset = Int(constraint.constant) % Constants.widthTimePoint
301−
302− if offset == 0 {
303− let p = Int(constraint.constant) / Constants.widthTimePoint
304− let time = startDate.addPeriods(p)
305−
306− switch period {
307− case .start:
308− data = ReservationData(establishment: d.establishment,
309− startTime: time,
310− endTime: d.endTime,
311− numberOfGuests: d.numberOfGuests,
312− reservedTable: d.reservedTable)
313− case .end:
314− data = ReservationData(establishment: d.establishment,
315− startTime: d.startTime,
316− endTime: time,
317− numberOfGuests: d.numberOfGuests,
318− reservedTable: d.reservedTable)
319− }
320− }
321− }
322−}
323−
324−extension SecondStepView: UIScrollViewDelegate {
325−
326−}
327−
328−// MARK: - Nested types
329−
330−extension SecondStepView {
331− enum Constants {
332− static let widthTimePoint = 11
333−
334− static let adminDuration = 288
335− static let clientDuration = 90
336− // 12:00 = 12 * 6
337− static let clientStartingPoint = 72
338−
339− static let pointWidth: CGFloat = 19
340− static let pointHeight: CGFloat = 85
341−
342− static let minBookingLength: CGFloat = 132
343−
344− static let heightIntervals = 85
345− }
346−
347− enum Period {
348− case start
349− case end
350− }
351−}
Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepReservationCoordinator.swiftdeleted−57
@@ -1,57 +0,0 @@
1−//
2−// ThirdStepReservationCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 23/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class ThirdStepReservationCoordinator: BaseCoordinator {
12−
13− // MARK: - Properties
14−
15− var didFinish: (() -> Void)?
16−
17− var mapView: MapImageScroll?
18−
19− /// Объект регистрации, созданной или существующей
20− var resrvation: Reservation?
21−
22− var reservationVC: ThirdStepReservationViewController?
23−
24− // MARK: - Lifecycle
25−
26− override func start() {
27− let storyboard = UIStoryboard(name: "Reservation", bundle: nil)
28− reservationVC = storyboard.instantiateViewController(withIdentifier: "ThirdStepReservationViewController") as? ThirdStepReservationViewController
29−
30− reservationVC?.coordinator = self
31− reservationVC?.mapView = mapView
32− reservationVC?.reservation = resrvation
33−
34− guard let r = reservationVC else { return }
35− navigationController?.pushViewController(r, animated: false)
36− }
37−
38− /// You need to pass reservation object and map describing booked table
39− func change(_ reservation: Reservation) {
40− let changeCoordinator = ChangeReservationCoordinator(navigationController: navigationController)
41−
42− changeCoordinator.reservation = reservation
43−
44− changeCoordinator.didFinish = { [weak self] res in
45− self?.removeDependency(changeCoordinator)
46− self?.navigationController?.popViewController(animated: false)
47− self?.reservationVC?.reservation = res
48− }
49−
50− changeCoordinator.start()
51− }
52−
53− /// Goes back to `allReservations` screen
54− func close() {
55− didFinish?()
56− }
57−}
Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepReservationViewController.swiftdeleted−156
@@ -1,156 +0,0 @@
1−//
2−// ThirdStepReservationViewController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 23/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class ThirdStepReservationViewController: BaseViewController {
12−
13− // MARK: - IBAOutlets
14−
15− @IBOutlet weak var containerView: UIView!
16−
17− @IBOutlet weak var contentForMap: UIView!
18−
19− // MARK: - Properties
20−
21− var mapView: MapImageScroll?
22−
23− weak var coordinator: ThirdStepReservationCoordinator?
24−
25− var thirdStepView: ThirdStepView?
26−
27− var reservation: Reservation? {
28− didSet {
29− guard let r = reservation,
30− let data = TotalStorage.standard.getEstablishment(r.establishment)
31− else { return }
32−
33− navigationItem.title = data.address
34−
35− guard let res = reservation else { return }
36− thirdStepView?.bind(withModel: res)
37− }
38− }
39−
40− var reservationService: ReservationsService?
41−
42− /// "Отменить бронь"
43− let cancelButton: Button = {
44− let button = Button()
45− let style = BlackButtonStyle()
46− style.apply(to: button, withTitle: "ОТМЕНИТЬ БРОНЬ")
47− return button
48− }()
49−
50− /// "Изменить бронь"
51− let changeButton: Button = {
52− let button = Button()
53− let style = BlackButtonStyle()
54− style.apply(to: button, withTitle: "ИЗМЕНИТЬ")
55− return button
56− }()
57−
58− // MARK: - Lifecycle
59−
60− override func viewDidLoad() {
61− super.viewDidLoad()
62−
63− navigationItem.hidesBackButton = true
64− setupContainer()
65− setupButtons()
66− setupMap()
67−
68− reservationService = ReservationsService(apiClient: APIClient.shared)
69− navigationController?.navigationBar.prefersLargeTitles = false
70− }
71−
72− override func viewWillAppear(_ animated: Bool) {
73− super.viewWillAppear(animated)
74−
75− tabBarController?.tabBar.isHidden = true
76− }
77−
78− // MARK: - Setup
79−
80− func setupMap() {
81− guard let reservation = reservation else {
82− return
83− }
84−
85− let width = view.frame.width
86− if reservation.establishment == 1 {
87− mapView = MapView1.loadFromNib()
88− mapView?.scrollViewParent.contentInset = UIEdgeInsets(top: 0,
89− left: width / 2,
90− bottom: 200,
91− right: width / 2)
92−
93− mapView?.scrollViewParent.setContentOffset(CGPoint(x: 0, y: 50), animated: false)
94− } else {
95− mapView = MapView2.loadFromNib()
96− mapView?.scrollViewParent.setContentOffset(CGPoint(x: 0, y: -100), animated: false)
97− mapView?.scrollViewParent.contentInset = UIEdgeInsets(top: 100,
98− left: width / 2,
99− bottom: 100,
100− right: width / 2)
101− }
102−
103− contentForMap.addSubviewThatFills(mapView)
104−
105− mapView?.isUserInteractionEnabled = false
106− mapView?.scrollToTable(table: reservation.reservedTable)
107− }
108−
109− func setupContainer() {
110− thirdStepView = ThirdStepView.loadFromNib()
111− containerView.addSubviewThatFills(thirdStepView)
112−
113− guard let res = reservation else { return }
114− thirdStepView?.bind(withModel: res)
115− }
116−
117− func setupButtons() {
118− addStackViewWithButtons(leftBtn: cancelButton,
119− rightBtn: changeButton,
120− constant: -containerView.frame.height - 20)
121−
122− changeButton.addTarget(self, action: #selector(change), for: .touchUpInside)
123− cancelButton.addTarget(self, action: #selector(cancelBooking), for: .touchUpInside)
124− thirdStepView?.closeButton.addTarget(self, action: #selector(close), for: .touchUpInside)
125− }
126−
127−
128− // MARK: - handlers for buttons
129−
130− @objc func change() {
131− guard
132− let res = reservation
133− else { return }
134−
135− coordinator?.change(res)
136− }
137−
138− @objc func cancelBooking() {
139− guard let res = reservation else { return }
140−
141− cancelButton.loading = true
142− reservationService?.deleteReservation(isAdmin: false, uuid: res.uuid, completion: { [weak self] (result) in
143− self?.cancelButton.loading = false
144−
145− if result {
146− self?.close()
147− } else {
148− self?.displayAlert(with: "Не удалось отменить бронь, попробуйте еще раз!")
149− }
150− })
151− }
152−
153− @objc func close() {
154− coordinator?.close()
155− }
156−}
Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepView.swiftdeleted−177
@@ -1,177 +0,0 @@
1−//
2−// ThirdStepView.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 23/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−struct ThirdStepViewModel {
12− var timeIntervalView: UIView
13−}
14−
15−class ThirdStepView: UIView {
16−
17− // MARK: - IBAOutlets
18−
19− @IBOutlet weak var totalLabel: UILabel!
20−
21− @IBOutlet weak var infoLabel: UILabel!
22−
23− @IBOutlet weak var closeButton: Button! {
24− didSet {
25− let style = BlackButtonStyle()
26− style.apply(to: closeButton, withTitle: "ЗАКРЫТЬ")
27− }
28− }
29−
30− @IBOutlet weak var timeInterval: UIView!
31−
32− @IBOutlet weak var stackView: UIStackView!
33−
34− @IBOutlet weak var scrollView: UIScrollView!
35−
36− // MARK: - Properties
37−
38− /// Время начала вертелки.
39− var startDate: Date?
40−
41− // констрейнты начала и конца интервала
42− var startLeadingConstraint: NSLayoutConstraint!
43− var endLeadingConstraint: NSLayoutConstraint!
44−
45− var reservation: Reservation? {
46− didSet {
47− // isAdmin
48− let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
49− startDate = reservation?.startTime.addHours(-1)
50−
51− setupStackView(isAdmin)
52− setUpBookingPeriod()
53− }
54− }
55−
56− // MARK: - bind
57−
58− func bind(withModel model: Reservation) {
59− reservation = model
60− let date = format(model.startTime, model.endTime)
61−
62− totalLabel.text = "Забронирован \(model.reservedTable) столик на \(model.numberOfGuests)-х\n \(date)"
63−
64− infoLabel.text = "Минимальное количество кальянов: \(countTotalNumber(model.numberOfGuests))"
65− }
66−
67− private func format(_ startDate: Date, _ endDate: Date) -> String {
68− let dateFormatter = DateFormatter()
69− dateFormatter.calendar = Calendar.current
70− dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
71− dateFormatter.dateFormat = "MM.dd, с HH:mm по"
72−
73− var newDateString = "\(dateFormatter.string(from: startDate))"
74−
75− dateFormatter.dateFormat = "HH:mm"
76− newDateString += " \(dateFormatter.string(from: endDate))"
77−
78− return newDateString
79− }
80−
81− private func countTotalNumber(_ people: Int) -> Int {
82− let num = people > 6 ? 2 : 1
83− return num
84− }
85−
86− var startPoint: UIView = {
87− var view = UIView()
88− view.backgroundColor = #colorLiteral(red: 0.2901960784, green: 0.5647058824, blue: 0.8862745098, alpha: 1)
89− view.translatesAutoresizingMaskIntoConstraints = false
90− return view
91− }()
92−
93− var endPoint: UIView = {
94− var view = UIView()
95− view.backgroundColor = #colorLiteral(red: 0.2901960784, green: 0.5647058824, blue: 0.8862745098, alpha: 1)
96− view.translatesAutoresizingMaskIntoConstraints = false
97− return view
98− }()
99−
100− /// Интервал
101− var fillInterval: UIView = {
102− var view = UIView()
103− view.backgroundColor = #colorLiteral(red: 0, green: 0.5921568627, blue: 1, alpha: 0.3426262843)
104− view.translatesAutoresizingMaskIntoConstraints = false
105− return view
106− }()
107−
108− func setupStackView(_ isAdmin: Bool) {
109− guard let startPoint = startDate else { return }
110−
111− let startingPoint = startPoint.getAdminsStartingPoint()
112− let endingPoint = startingPoint + (isAdmin ? Constants.adminDuration : Constants.clientDuration)
113−
114− for period in startingPoint...endingPoint {
115− let timePointView = TimePointView.loadFromNib()
116− timePointView?.setUp(withTimePoint: period)
117− let view = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 106))
118− view.addSubviewThatFills(timePointView)
119− stackView.addArrangedSubview(view)
120− }
121− }
122−
123− func setUpBookingPeriod() {
124− self.scrollView.addSubview(startPoint)
125− self.scrollView.addSubview(endPoint)
126− self.scrollView.addSubview(fillInterval)
127−
128− guard
129− let startDate = startDate,
130− let startTime = reservation?.startTime,
131− let endTime = reservation?.endTime else { return }
132−
133− let startConstr = CGFloat(startTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint) + 3
134− startLeadingConstraint = startPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
135− constant: startConstr)
136−
137− let endConstr = CGFloat(endTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint) + 3
138− endLeadingConstraint = endPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
139− constant: endConstr)
140−
141− scrollView.setContentOffset(CGPoint(x: startConstr - 50, y: 0), animated: true)
142−
143− NSLayoutConstraint.activate([
144−
145− startPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
146− endPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
147−
148− startPoint.widthAnchor.constraint(equalToConstant: Constants.pointWidth),
149− endPoint.widthAnchor.constraint(equalToConstant: Constants.pointWidth),
150−
151− startPoint.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
152− endPoint.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
153−
154− startLeadingConstraint,
155− endLeadingConstraint,
156−
157− fillInterval.leftAnchor.constraint(equalTo: startPoint.rightAnchor, constant: 0),
158− fillInterval.rightAnchor.constraint(equalTo: endPoint.leftAnchor, constant: 0),
159−
160− fillInterval.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
161− fillInterval.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0)
162− ])
163− }
164−}
165−
166−extension ThirdStepView {
167− enum Constants {
168− static let widthTimePoint = 11
169− static let pointWidth: CGFloat = 5
170− static let pointHeight: CGFloat = 85
171−
172− static let adminDuration = 288
173− static let clientDuration = 90
174− // 12:00 = 12 * 6
175− static let clientStartingPoint = 72
176− }
177−}
Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepView.xibdeleted−144
@@ -1,144 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
7− <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8− <capability name="Stack View standard spacing" minToolsVersion="9.0"/>
9− <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
10− </dependencies>
11− <objects>
12− <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
13− <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
14− <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="ThirdStepView" customModule="Hookah_Tau" customModuleProvider="target">
15− <rect key="frame" x="0.0" y="0.0" width="414" height="340"/>
16− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
17− <subviews>
18− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="center" spacing="21" translatesAutoresizingMaskIntoConstraints="NO" id="DL4-0a-WxC">
19− <rect key="frame" x="20" y="20" width="374" height="82.5"/>
20− <subviews>
21− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Забронирован 7 столик на 3 человека 29 марта с 3:00 до 5:30!" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xHF-9h-q9F">
22− <rect key="frame" x="19.5" y="0.0" width="335" height="41"/>
23− <fontDescription key="fontDescription" type="system" pointSize="17"/>
24− <nil key="textColor"/>
25− <nil key="highlightedColor"/>
26− </label>
27− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Минимальное количество кальянов: 2" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7xJ-nJ-IFN">
28− <rect key="frame" x="27.5" y="62" width="319" height="20.5"/>
29− <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
30− <nil key="textColor"/>
31− <nil key="highlightedColor"/>
32− </label>
33− </subviews>
34− </stackView>
35− <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="0H2-jJ-gOj">
36− <rect key="frame" x="20" y="132.5" width="374" height="45"/>
37− <subviews>
38− <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Tick" translatesAutoresizingMaskIntoConstraints="NO" id="lcW-xm-Gb7">
39− <rect key="frame" x="0.0" y="0.0" width="230" height="45"/>
40− </imageView>
41− <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QjM-My-aZ0" customClass="Button" customModule="Hookah_Tau" customModuleProvider="target">
42− <rect key="frame" x="238" y="4" width="136" height="37"/>
43− <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
44− <constraints>
45− <constraint firstAttribute="width" constant="136" id="No6-wb-pIe"/>
46− <constraint firstAttribute="height" constant="37" id="SOm-Gm-2i0"/>
47− </constraints>
48− <state key="normal" title="Button"/>
49− </button>
50− </subviews>
51− </stackView>
52− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ByV-f1-mVO">
53− <rect key="frame" x="0.0" y="207.5" width="414" height="106"/>
54− <subviews>
55− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JpA-EH-PLI">
56− <rect key="frame" x="0.0" y="21" width="414" height="85"/>
57− <subviews>
58− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TgV-cB-bMd">
59− <rect key="frame" x="0.0" y="0.0" width="414" height="1"/>
60− <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
61− <constraints>
62− <constraint firstAttribute="height" constant="1" id="kOS-eB-bWd"/>
63− </constraints>
64− </view>
65− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nzW-L7-eY8">
66− <rect key="frame" x="0.0" y="84" width="414" height="1"/>
67− <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
68− <constraints>
69− <constraint firstAttribute="height" constant="1" id="BNR-Cz-HJe"/>
70− </constraints>
71− </view>
72− </subviews>
73− <color key="backgroundColor" red="0.8901960784313725" green="0.8901960784313725" blue="0.8901960784313725" alpha="1" colorSpace="calibratedRGB"/>
74− <constraints>
75− <constraint firstItem="TgV-cB-bMd" firstAttribute="leading" secondItem="JpA-EH-PLI" secondAttribute="leading" id="3ZT-oY-Rzz"/>
76− <constraint firstAttribute="height" constant="85" id="7jH-zS-CoD"/>
77− <constraint firstAttribute="trailing" secondItem="nzW-L7-eY8" secondAttribute="trailing" id="HSn-Vn-8Kb"/>
78− <constraint firstItem="TgV-cB-bMd" firstAttribute="top" secondItem="JpA-EH-PLI" secondAttribute="top" id="K34-18-ZM8"/>
79− <constraint firstAttribute="bottom" secondItem="nzW-L7-eY8" secondAttribute="bottom" id="hKT-AB-KQS"/>
80− <constraint firstItem="nzW-L7-eY8" firstAttribute="leading" secondItem="JpA-EH-PLI" secondAttribute="leading" id="lqp-3j-OoO"/>
81− <constraint firstAttribute="trailing" secondItem="TgV-cB-bMd" secondAttribute="trailing" id="r1u-XE-GXS"/>
82− </constraints>
83− </view>
84− <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gQW-4g-8T5">
85− <rect key="frame" x="0.0" y="0.0" width="414" height="106"/>
86− <subviews>
87− <stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Gfj-mL-wQq">
88− <rect key="frame" x="0.0" y="0.0" width="414" height="106"/>
89− </stackView>
90− </subviews>
91− <constraints>
92− <constraint firstItem="Gfj-mL-wQq" firstAttribute="width" secondItem="gQW-4g-8T5" secondAttribute="width" priority="250" id="DhE-CT-MGo"/>
93− <constraint firstItem="Gfj-mL-wQq" firstAttribute="height" secondItem="gQW-4g-8T5" secondAttribute="height" id="JdJ-xb-2kM"/>
94− <constraint firstAttribute="bottom" secondItem="Gfj-mL-wQq" secondAttribute="bottom" id="Pji-4z-R86"/>
95− <constraint firstItem="Gfj-mL-wQq" firstAttribute="top" secondItem="gQW-4g-8T5" secondAttribute="top" id="UBW-vr-VEu"/>
96− <constraint firstAttribute="trailing" secondItem="Gfj-mL-wQq" secondAttribute="trailing" id="gkv-lF-jaW"/>
97− <constraint firstItem="Gfj-mL-wQq" firstAttribute="leading" secondItem="gQW-4g-8T5" secondAttribute="leading" id="yZy-o3-tDY"/>
98− </constraints>
99− <viewLayoutGuide key="contentLayoutGuide" id="jEg-I8-hwu"/>
100− <viewLayoutGuide key="frameLayoutGuide" id="EFO-bp-t4s"/>
101− </scrollView>
102− </subviews>
103− <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
104− <constraints>
105− <constraint firstItem="JpA-EH-PLI" firstAttribute="leading" secondItem="ByV-f1-mVO" secondAttribute="leading" id="0Yf-vL-RSK"/>
106− <constraint firstAttribute="trailing" secondItem="JpA-EH-PLI" secondAttribute="trailing" id="N9T-dc-Auk"/>
107− <constraint firstAttribute="bottom" secondItem="JpA-EH-PLI" secondAttribute="bottom" id="QPT-JY-erJ"/>
108− <constraint firstItem="gQW-4g-8T5" firstAttribute="top" secondItem="ByV-f1-mVO" secondAttribute="top" id="Qz6-Bm-fcB"/>
109− <constraint firstAttribute="height" constant="106" id="UWZ-LN-h4r"/>
110− <constraint firstItem="gQW-4g-8T5" firstAttribute="leading" secondItem="ByV-f1-mVO" secondAttribute="leading" id="gZ2-dm-HGX"/>
111− <constraint firstAttribute="bottom" secondItem="gQW-4g-8T5" secondAttribute="bottom" id="idD-XC-tGe"/>
112− <constraint firstAttribute="trailing" secondItem="gQW-4g-8T5" secondAttribute="trailing" id="mWv-Uy-FiK"/>
113− </constraints>
114− </view>
115− </subviews>
116− <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
117− <constraints>
118− <constraint firstItem="ByV-f1-mVO" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="1g0-ab-erl"/>
119− <constraint firstItem="ByV-f1-mVO" firstAttribute="top" secondItem="0H2-jJ-gOj" secondAttribute="bottom" constant="30" id="F84-ZL-MWp"/>
120− <constraint firstItem="0H2-jJ-gOj" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="20" id="GR6-gI-ecm"/>
121− <constraint firstItem="ByV-f1-mVO" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="KKj-7n-eQf"/>
122− <constraint firstItem="0H2-jJ-gOj" firstAttribute="top" secondItem="DL4-0a-WxC" secondAttribute="bottom" constant="30" id="VbN-sb-Pko"/>
123− <constraint firstItem="DL4-0a-WxC" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="20" id="cm0-tz-ta4"/>
124− <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="0H2-jJ-gOj" secondAttribute="trailing" constant="20" id="i3D-sP-KlI"/>
125− <constraint firstAttribute="trailing" secondItem="DL4-0a-WxC" secondAttribute="trailing" constant="20" id="kHp-8n-OTp"/>
126− <constraint firstItem="DL4-0a-WxC" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="20" id="vOg-X1-y93"/>
127− </constraints>
128− <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
129− <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
130− <connections>
131− <outlet property="closeButton" destination="QjM-My-aZ0" id="Z3P-aG-bf1"/>
132− <outlet property="infoLabel" destination="7xJ-nJ-IFN" id="jlH-CO-a0K"/>
133− <outlet property="scrollView" destination="gQW-4g-8T5" id="lLC-JE-ZUm"/>
134− <outlet property="stackView" destination="Gfj-mL-wQq" id="k5A-hd-BiB"/>
135− <outlet property="timeInterval" destination="ByV-f1-mVO" id="oB4-jH-8Ot"/>
136− <outlet property="totalLabel" destination="xHF-9h-q9F" id="W94-2J-w0A"/>
137− </connections>
138− <point key="canvasLocation" x="137.59999999999999" y="365.21739130434787"/>
139− </view>
140− </objects>
141− <resources>
142− <image name="Tick" width="58" height="45"/>
143− </resources>
144−</document>
Hookah Tau/Controllers/Client/Reservations/Steps/Common/DateView.swift → Hookah Tau/Controllers/Client/Reservations/Steps/First/DateView.swiftrenamed

The content is the same.

Hookah Tau/Controllers/Client/Reservations/Steps/Common/DateView.xib → Hookah Tau/Controllers/Client/Reservations/Steps/First/DateView.xibrenamed+2−2
@@ -15,7 +15,7 @@
1515 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1616 <subviews>
1717 <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="29" width="21" height="20"/>
18+ <rect key="frame" x="5" y="19.5" width="21" height="20"/>
1919 <constraints>
2020 <constraint firstAttribute="width" constant="21" id="gdn-d6-auU"/>
2121 </constraints>
@@ -26,10 +26,10 @@
2626 </subviews>
2727 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
2828 <constraints>
29+ <constraint firstItem="hzu-lu-5Cc" firstAttribute="centerY" secondItem="vUN-kp-3ea" secondAttribute="centerY" id="Vwr-KU-m3O"/>
2930 <constraint firstItem="hzu-lu-5Cc" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="fhT-nh-ejJ"/>
3031 <constraint firstItem="hzu-lu-5Cc" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="5" id="mLo-I1-FSM"/>
3132 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="hzu-lu-5Cc" secondAttribute="trailing" constant="5" id="qSb-Ok-1MH"/>
32− <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="hzu-lu-5Cc" secondAttribute="bottom" constant="10" id="vtm-8d-jCM"/>
3333 </constraints>
3434 <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
3535 <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepView.swift → Hookah Tau/Controllers/Client/Reservations/Steps/First/FirstStepView.swiftrenamed+15−84
@@ -16,7 +16,7 @@ class FirstStepView: UIView {
1616
1717 weak var mapUpdater: MapUpdater?
1818
19− var chosenPoint: Int? {
19+ var chosenPoint: Int? = 0 {
2020 didSet {
2121 guard
2222 let periods = chosenPoint,
@@ -27,13 +27,9 @@ class FirstStepView: UIView {
2727 }
2828 }
2929
30− var fullDate: Date? {
30+ var fullDate: Date? = Date.getDateFromCurrent() {
3131 didSet {
3232 guard let date = fullDate, let _ = chosenPoint else { return }
33−
34− let (prev, curr, next) = date.getPrevCurrentNextMonth()
35− setupMonth(prev, curr, next)
36−
3733 mapUpdater?.update(date)
3834 }
3935 }
@@ -50,50 +46,29 @@ class FirstStepView: UIView {
5046 guard
5147 let date = fullDate?.getDMY()
5248 else { return }
53−
54− let bookings = HFunc.main.filterPeriodsInDate(bookingsForDates, date)
55− setUpBookingsForIntervals(reservations: bookings)
49+ setUpBookingsForIntervals(reservations: bookingsForDates[date] ?? [])
5650 }
5751 }
5852
59− var bookingsForDates: [ReservationPeriod] = [] {
53+ var bookingsForDates: [Date: [ReservationPeriod]] = [:] {
6054 didSet {
61− guard
62− let date = fullDate?.getDMY()
63− else { return }
64−
65− let bookings = HFunc.main.filterPeriodsInDate(bookingsForDates, date)
66−
67− setUpBookingsForIntervals(reservations: bookings)
55+ guard let date = fullDate?.getDMY(), let reservPeriods = bookingsForDates[date] else { return }
56+ setUpBookingsForIntervals(reservations: reservPeriods)
6857 }
6958 }
70−
71− // intervals
7259
7360 @IBOutlet weak var scrollViewIntervals: UIScrollView!
7461
7562 @IBOutlet weak var stackViewIntervals: UIStackView!
7663
77− // dates
78−
7964 @IBOutlet weak var datesStackView: UIStackView!
8065
8166 @IBOutlet weak var datesScrollView: UIScrollView!
8267
83− // note labels
84−
8568 @IBOutlet weak var earlierThan12Label: UILabel!
8669
8770 @IBOutlet weak var laterThan3Label: UILabel!
8871
89− // months
90−
91− @IBOutlet weak var previousMonthLabel: UILabel!
92−
93− @IBOutlet weak var currentMonthLabel: UILabel!
94−
95− @IBOutlet weak var nextMonthLabel: UILabel!
96−
9772
9873 var bookingsViewsForDate: [UIView] = []
9974
@@ -114,33 +89,12 @@ class FirstStepView: UIView {
11489 func setUpIntervalStackView() {
11590
11691 for period in 0...Constants.day10MinPeriods {
117−
11892 let timePointView = TimePointView.loadFromNib()
11993 timePointView?.setUp(withTimePoint: period)
12094 let view = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 92))
12195 view.addSubviewThatFills(timePointView)
12296 stackViewIntervals.addArrangedSubview(view)
12397 }
124−
125− setupClosingInterval()
126− }
127−
128− /// Вьюшка, обозначающая часы закрытия кальянки
129− func setupClosingInterval() {
130− let offset = CGFloat(Constants.startClosingTime * Constants.widthTimePoint + Constants.widthTimePoint / 2)
131− let width = CGFloat(Constants.closingDuration * Constants.widthTimePoint)
132− let height = CGFloat(Constants.heightIntervals)
133− let closingTimeView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: height))
134− closingTimeView.translatesAutoresizingMaskIntoConstraints = false
135− scrollViewIntervals.addSubview(closingTimeView)
136− closingTimeView.backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 0.5)
137−
138− NSLayoutConstraint.activate([
139− closingTimeView.leftAnchor.constraint(equalTo: scrollViewIntervals.leftAnchor, constant: offset),
140− closingTimeView.bottomAnchor.constraint(equalToSystemSpacingBelow: scrollViewIntervals.bottomAnchor, multiplier: 0),
141− closingTimeView.heightAnchor.constraint(equalToConstant: height),
142− closingTimeView.widthAnchor.constraint(equalToConstant: width)
143− ])
14498 }
14599
146100 func setUpBookingsForIntervals(reservations: [ReservationPeriod]) {
@@ -148,33 +102,21 @@ class FirstStepView: UIView {
148102 bookingsViewsForDate = []
149103
150104 for reservation in reservations {
151− let uiview = UIView(frame: CGRect(x: 0, y: 0, width: Constants.widthTimePoint * reservation.duration, height: Constants.heightIntervals))
152− uiview.backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 0.5)
153−
105+ let uiview = UIView(frame: CGRect(x: 0, y: 0, width: Constants.widthTimePoint * reservation.duration, height: 71))
106+ uiview.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 0.5)
154107
155108 uiview.translatesAutoresizingMaskIntoConstraints = false
156109 scrollViewIntervals.addSubview(uiview)
157110
158111 guard let date = date else { return }
159− let startDate = Date.getDateFromCurrent(days: date)!.set(hours: 0, minutes: 0, seconds: 0)!
160−
161− let s = reservation.startTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint
162− let d = reservation.duration * Constants.widthTimePoint
112+ let startDate = Date.getDateFromCurrent(days: date)!.set(hours: 12, minutes: 0, seconds: 0)!
163113
164− let startTime = s < 0 ? 0 : s
165− var duration = 0
166− if s < 0 {
167− duration = reservation.endTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint
168− } else {
169− duration = (s + d) > Constants.widthOfIntervals ? Constants.widthOfIntervals - s : d
170− }
171−
172114 NSLayoutConstraint.activate([
115+ uiview.topAnchor.constraint(equalToSystemSpacingBelow: scrollViewIntervals.topAnchor, multiplier: 0),
173116 uiview.bottomAnchor.constraint(equalToSystemSpacingBelow: scrollViewIntervals.bottomAnchor, multiplier: 0),
174117 uiview.leftAnchor.constraint(equalTo: scrollViewIntervals.leftAnchor,
175− constant: CGFloat(Constants.widthTimePoint / 2 + startTime)),
176− uiview.widthAnchor.constraint(equalToConstant: CGFloat(duration)),
177− uiview.heightAnchor.constraint(equalToConstant: CGFloat(Constants.heightIntervals))
118+ constant: CGFloat(Constants.widthTimePoint / 2 + Constants.widthTimePoint * reservation.startTime.getMinutesPeriods(fromStart: startDate))),
119+ uiview.widthAnchor.constraint(equalToConstant: CGFloat(Constants.widthTimePoint * reservation.duration))
178120 ])
179121
180122 bookingsViewsForDate.append(uiview)
@@ -193,14 +135,14 @@ class FirstStepView: UIView {
193135
194136 datesScrollView.setContentOffset(CGPoint(x: abs(Constants.widthDate * Constants.daysCount / 2 - Int(edges.left)) + 8, y: 0),
195137 animated: true)
196− scrollViewIntervals.setContentOffset(CGPoint(x: abs(Constants.widthTimePoint * Constants.day10MinPeriods / 2 - Int(edges.left)) + 7, y: 0),
138+ scrollViewIntervals.setContentOffset(CGPoint(x: abs(Constants.widthTimePoint * Constants.day10MinPeriods / 2 - Int(edges.left)) + 5, y: 0),
197139 animated: true)
198140 }
199141
200142
201143 /// Method for setting up `stackViewIntervals` with appropriate busy intervals of chosen table
202144 /// - Parameter data: Map of booked periods by key - date - is provided
203− func setUp(_ data: [ReservationPeriod]) {
145+ func setUp(_ data: [Date: [ReservationPeriod]]) {
204146 bookingsForDates = data
205147 }
206148
@@ -215,12 +157,6 @@ class FirstStepView: UIView {
215157 datesStackView.addArrangedSubview(view)
216158 }
217159 }
218−
219− func setupMonth(_ prev: String, _ curr: String, _ next: String) {
220− currentMonthLabel.text = curr
221− previousMonthLabel.text = prev
222− nextMonthLabel.text = next
223− }
224160}
225161
226162extension FirstStepView: UIScrollViewDelegate {
@@ -278,14 +214,9 @@ extension FirstStepView: UIScrollViewDelegate {
278214
279215extension FirstStepView {
280216 enum Constants {
281− /// 24 ч * 60 минут / 10 минут в периоде; [00:00 ... 23:50]
282− static let day10MinPeriods = 143
217+ static let day10MinPeriods = 90
283218 static let daysCount = 14
284219 static let widthTimePoint = 11
285220 static let widthDate = 31
286− static let heightIntervals = 70
287− static let closingDuration = 54
288− static let startClosingTime = 18
289− static let widthOfIntervals = 1573
290221 }
291222}
Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepView.xib → Hookah Tau/Controllers/Client/Reservations/Steps/First/FirstStepView.xibrenamed+21−56
@@ -1,9 +1,9 @@
11<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
3− <device id="retina5_5" orientation="portrait" appearance="light"/>
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"/>
44 <dependencies>
55 <deployment identifier="iOS"/>
6− <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
77 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
88 <capability name="Stack View standard spacing" minToolsVersion="9.0"/>
99 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -47,7 +47,7 @@
4747 <rect key="frame" x="0.0" y="97" width="414" height="91"/>
4848 <subviews>
4949 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dh5-kt-LFH">
50− <rect key="frame" x="0.0" y="21" width="414" height="70"/>
50+ <rect key="frame" x="0.0" y="20" width="414" height="71"/>
5151 <subviews>
5252 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nqq-Xp-Lig">
5353 <rect key="frame" x="0.0" y="0.0" width="414" height="1"/>
@@ -57,16 +57,16 @@
5757 </constraints>
5858 </view>
5959 <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="kS7-N4-kdg">
60− <rect key="frame" x="16" y="9" width="382" height="52"/>
60+ <rect key="frame" x="16" y="9" width="382" height="53"/>
6161 <subviews>
6262 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Для брони времени раньше 12:00 свяжитесь с администратором" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6DK-77-Npa">
63− <rect key="frame" x="0.0" y="0.0" width="187" height="52"/>
63+ <rect key="frame" x="0.0" y="0.0" width="187" height="53"/>
6464 <fontDescription key="fontDescription" type="system" pointSize="13"/>
6565 <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
6666 <nil key="highlightedColor"/>
6767 </label>
6868 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Для брони времени позже 3:00 свяжитесь с администратором" textAlignment="right" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qz5-ce-S3I">
69− <rect key="frame" x="195" y="0.0" width="187" height="52"/>
69+ <rect key="frame" x="195" y="0.0" width="187" height="53"/>
7070 <fontDescription key="fontDescription" type="system" pointSize="13"/>
7171 <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
7272 <nil key="highlightedColor"/>
@@ -74,7 +74,7 @@
7474 </subviews>
7575 </stackView>
7676 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zqK-OT-P26">
77− <rect key="frame" x="0.0" y="69" width="414" height="1"/>
77+ <rect key="frame" x="0.0" y="70" width="414" height="1"/>
7878 <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
7979 <constraints>
8080 <constraint firstAttribute="height" constant="1" id="iUR-sJ-1M1"/>
@@ -93,7 +93,7 @@
9393 <constraint firstItem="kS7-N4-kdg" firstAttribute="top" secondItem="nqq-Xp-Lig" secondAttribute="bottom" constant="8" id="o6k-wD-gGp"/>
9494 <constraint firstAttribute="trailing" secondItem="kS7-N4-kdg" secondAttribute="trailing" constant="16" id="qfN-XY-Uqq"/>
9595 <constraint firstItem="nqq-Xp-Lig" firstAttribute="leading" secondItem="dh5-kt-LFH" secondAttribute="leading" id="qr9-52-TNC"/>
96− <constraint firstAttribute="height" constant="70" id="tcS-2U-ecA"/>
96+ <constraint firstAttribute="height" constant="71" id="tcS-2U-ecA"/>
9797 <constraint firstItem="zqK-OT-P26" firstAttribute="leading" secondItem="dh5-kt-LFH" secondAttribute="leading" id="yUf-Cj-HmN"/>
9898 </constraints>
9999 </view>
@@ -106,14 +106,14 @@
106106 </constraints>
107107 </view>
108108 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="TriangleDown" translatesAutoresizingMaskIntoConstraints="NO" id="5dC-Lq-opV">
109− <rect key="frame" x="184.66666666666666" y="0.0" width="45" height="29"/>
109+ <rect key="frame" x="184.5" y="0.0" width="45" height="29"/>
110110 <constraints>
111111 <constraint firstAttribute="width" constant="45" id="Tsw-fS-8qs"/>
112112 <constraint firstAttribute="height" constant="29" id="YWD-ja-gD5"/>
113113 </constraints>
114114 </imageView>
115115 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="TriangleUp" translatesAutoresizingMaskIntoConstraints="NO" id="Igw-O9-W92">
116− <rect key="frame" x="184.66666666666666" y="196" width="45" height="29"/>
116+ <rect key="frame" x="184.5" y="196" width="45" height="29"/>
117117 <constraints>
118118 <constraint firstAttribute="height" constant="29" id="AdE-yJ-WLL"/>
119119 <constraint firstAttribute="width" constant="45" id="Eaa-P8-3mv"/>
@@ -157,42 +157,10 @@
157157 </scrollView>
158158 <view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fvt-zf-8tU" customClass="RadialGradientView" customModule="Hookah_Tau" customModuleProvider="target">
159159 <rect key="frame" x="0.0" y="29" width="414" height="59"/>
160− <subviews>
161− <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="OEF-Kc-d38">
162− <rect key="frame" x="8" y="5.0000000000000009" width="398" height="14.333333333333336"/>
163− <subviews>
164− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="November" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5Mn-Mn-qaI">
165− <rect key="frame" x="0.0" y="0.0" width="58.333333333333336" height="14.333333333333334"/>
166− <fontDescription key="fontDescription" type="system" pointSize="12"/>
167− <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
168− <nil key="highlightedColor"/>
169− </label>
170− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="January" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Rfg-Ts-DX0">
171− <rect key="frame" x="353" y="0.0" width="45" height="14.333333333333334"/>
172− <fontDescription key="fontDescription" type="system" pointSize="12"/>
173− <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
174− <nil key="highlightedColor"/>
175− </label>
176− </subviews>
177− </stackView>
178− <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="December" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Fbc-VX-43f">
179− <rect key="frame" x="176.66666666666666" y="5.0000000000000009" width="60.666666666666657" height="14.333333333333336"/>
180− <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="12"/>
181− <color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
182− <nil key="highlightedColor"/>
183− </label>
184− </subviews>
185160 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
186− <constraints>
187− <constraint firstAttribute="trailing" secondItem="OEF-Kc-d38" secondAttribute="trailing" constant="8" id="BKe-IX-uiY"/>
188− <constraint firstItem="OEF-Kc-d38" firstAttribute="leading" secondItem="fvt-zf-8tU" secondAttribute="leading" constant="8" id="Cc6-Iv-RT8"/>
189− <constraint firstItem="Fbc-VX-43f" firstAttribute="top" secondItem="fvt-zf-8tU" secondAttribute="top" constant="5" id="jj2-kv-wnF"/>
190− <constraint firstItem="OEF-Kc-d38" firstAttribute="top" secondItem="fvt-zf-8tU" secondAttribute="top" constant="5" id="pmQ-MG-28r"/>
191− <constraint firstItem="Fbc-VX-43f" firstAttribute="centerX" secondItem="fvt-zf-8tU" secondAttribute="centerX" id="wAj-Z8-AP0"/>
192− </constraints>
193161 <userDefinedRuntimeAttributes>
194162 <userDefinedRuntimeAttribute type="color" keyPath="outsideColor">
195− <color key="value" white="1" alpha="0.88409674657534243" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
163+ <color key="value" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
196164 </userDefinedRuntimeAttribute>
197165 <userDefinedRuntimeAttribute type="color" keyPath="insideColor">
198166 <color key="value" white="0.67000000000000004" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -204,39 +172,36 @@
204172 <constraints>
205173 <constraint firstItem="Y9G-UI-WV7" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="22z-Ck-vsZ"/>
206174 <constraint firstItem="a6N-9A-8y5" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="5c8-YB-dSB"/>
207− <constraint firstAttribute="bottom" secondItem="954-g3-FZD" secondAttribute="bottom" constant="37" id="C3k-Mb-wT4"/>
175+ <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="954-g3-FZD" secondAttribute="bottom" constant="37" id="C3k-Mb-wT4"/>
208176 <constraint firstItem="Y9G-UI-WV7" firstAttribute="top" secondItem="5dC-Lq-opV" secondAttribute="bottom" id="E97-Lg-K2s"/>
209177 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="fvt-zf-8tU" secondAttribute="trailing" id="Eeh-zB-KWe"/>
210178 <constraint firstItem="a6N-9A-8y5" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="F03-yv-41V"/>
211179 <constraint firstItem="pgz-8G-Kx4" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="G0y-2f-SkS"/>
212180 <constraint firstItem="5dC-Lq-opV" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="If5-v7-UAj"/>
213− <constraint firstAttribute="bottom" secondItem="pgz-8G-Kx4" secondAttribute="bottom" constant="137" id="Lgn-Nv-wjD"/>
181+ <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="pgz-8G-Kx4" secondAttribute="bottom" constant="137" id="Lgn-Nv-wjD"/>
214182 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="954-g3-FZD" secondAttribute="trailing" id="MGt-d4-Win"/>
215183 <constraint firstItem="fvt-zf-8tU" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="SaI-rP-2em"/>
216184 <constraint firstItem="Igw-O9-W92" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="TtM-Bc-V1U"/>
217− <constraint firstItem="Igw-O9-W92" firstAttribute="bottom" secondItem="iN0-l3-epB" secondAttribute="bottom" id="V9u-Eu-VME"/>
185+ <constraint firstItem="Igw-O9-W92" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="V9u-Eu-VME"/>
218186 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="pgz-8G-Kx4" secondAttribute="trailing" id="Z6D-PY-Jrh"/>
219187 <constraint firstItem="Igw-O9-W92" firstAttribute="top" secondItem="a6N-9A-8y5" secondAttribute="bottom" constant="8" id="f4D-nq-HMa"/>
220188 <constraint firstItem="Y9G-UI-WV7" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="gZw-8a-dTG"/>
221189 <constraint firstItem="954-g3-FZD" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="itw-0z-3i7"/>
222− <constraint firstAttribute="bottom" secondItem="fvt-zf-8tU" secondAttribute="bottom" constant="137" id="lOx-ke-O6a"/>
190+ <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="fvt-zf-8tU" secondAttribute="bottom" constant="137" id="lOx-ke-O6a"/>
223191 <constraint firstItem="z9p-OK-tL7" firstAttribute="top" secondItem="52e-LM-cF6" secondAttribute="bottom" constant="9" id="ldj-Qh-p0k"/>
224− <constraint firstItem="fvt-zf-8tU" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="29" id="pSg-dd-INI"/>
225− <constraint firstItem="pgz-8G-Kx4" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="29" id="vfO-LG-tqR"/>
226− <constraint firstItem="954-g3-FZD" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="97" id="vhK-2E-j3k"/>
227− <constraint firstItem="5dC-Lq-opV" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="xOt-l0-Vzy"/>
228− <constraint firstItem="a6N-9A-8y5" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="97" id="yyf-QB-vfF"/>
192+ <constraint firstItem="fvt-zf-8tU" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="29" id="pSg-dd-INI"/>
193+ <constraint firstItem="pgz-8G-Kx4" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="29" id="vfO-LG-tqR"/>
194+ <constraint firstItem="954-g3-FZD" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="97" id="vhK-2E-j3k"/>
195+ <constraint firstItem="5dC-Lq-opV" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="xOt-l0-Vzy"/>
196+ <constraint firstItem="a6N-9A-8y5" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="97" id="yyf-QB-vfF"/>
229197 </constraints>
230198 <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
231199 <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
232200 <connections>
233− <outlet property="currentMonthLabel" destination="Fbc-VX-43f" id="CJr-eH-QMp"/>
234201 <outlet property="datesScrollView" destination="Y9G-UI-WV7" id="dbT-BM-Ckq"/>
235202 <outlet property="datesStackView" destination="52e-LM-cF6" id="6Ni-IN-sm4"/>
236203 <outlet property="earlierThan12Label" destination="6DK-77-Npa" id="ftP-Jz-gzw"/>
237204 <outlet property="laterThan3Label" destination="qz5-ce-S3I" id="dzR-7k-uDq"/>
238− <outlet property="nextMonthLabel" destination="Rfg-Ts-DX0" id="rpk-ci-pzX"/>
239− <outlet property="previousMonthLabel" destination="5Mn-Mn-qaI" id="c0S-Yz-e83"/>
240205 <outlet property="scrollViewIntervals" destination="a6N-9A-8y5" id="uDW-QY-gNF"/>
241206 <outlet property="stackViewIntervals" destination="z9p-OK-tL7" id="0Mj-wX-kq7"/>
242207 </connections>
Hookah Tau/Controllers/Client/Reservations/Steps/Common/TimePointView.swift → Hookah Tau/Controllers/Client/Reservations/Steps/First/TimePointView.swiftrenamed+1−1
@@ -47,6 +47,6 @@ class TimePointView: UIView {
4747 // MARK: - Static
4848
4949 static func getTextTimeFromTimePoint(_ time: Int) -> String {
50− return "\(Int(time / 6) % 24):00"
50+ return "\((Int(time / 6) + 12) % 24):00"
5151 }
5252}
Hookah Tau/Controllers/Client/Reservations/Steps/Common/TimePointView.xib → Hookah Tau/Controllers/Client/Reservations/Steps/First/TimePointView.xibrenamed

The content is the same.

Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepReservationCoordinator.swift → Hookah Tau/Controllers/Client/Reservations/Steps/FirstStepReservationCoordinator.swiftrenamed+4−17
@@ -8,14 +8,12 @@
88
99import UIKit
1010
11−class FirstStepReservationCoordinator: BaseCoordinator, FirstStepReservationProtocol {
11+class FirstStepReservationCoordinator: BaseCoordinator {
1212
1313 // MARK: - Properties
1414
1515 var didFinish: (() -> Void)?
1616
17− var establishment: Int = 1
18−
1917 // MARK: - Lifecycle
2018
2119 override func start() {
@@ -23,18 +21,13 @@ class FirstStepReservationCoordinator: BaseCoordinator, FirstStepReservationProt
2321 let reservationVC = storyboard.instantiateViewController(withIdentifier: "ReservationViewController") as! FirstStepReservationViewController
2422
2523 reservationVC.coordinator = self
26− reservationVC.establishmentId = establishment
27−
2824 navigationController?.pushViewController(reservationVC, animated: true)
2925 }
3026
31− var user: UserType {
32− get {
33− return .client
34− }
27+ func callAdmin() {
28+
3529 }
3630
37−
3831 func makeReservation(model: SecondStepModel,
3932 mapView: MapImageScroll?) {
4033
@@ -46,13 +39,7 @@ class FirstStepReservationCoordinator: BaseCoordinator, FirstStepReservationProt
4639
4740 addDependency(reservationCoordinator)
4841
49− reservationCoordinator.didFinish = {
50− self.navigationController?.popViewController(animated: false)
51− self.removeDependency(reservationCoordinator)
52− self.didFinish?()
53− }
54−
55− reservationCoordinator.goBack = { [weak self] mapView in
42+ reservationCoordinator.didFinish = { [weak self] mapView in
5643
5744 self?.navigationController?.popViewController(animated: false)
5845 self?.removeDependency(reservationCoordinator)
Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepReservationViewController.swift → Hookah Tau/Controllers/Client/Reservations/Steps/FirstStepReservationViewController.swiftrenamed+14−51
@@ -13,13 +13,13 @@ class FirstStepReservationViewController: BaseViewController {
1313
1414 // MARK: - Properties
1515
16− weak var coordinator: FirstStepReservationProtocol?
16+ weak var coordinator: FirstStepReservationCoordinator?
1717
1818 @IBOutlet weak var childContentView: UIView!
1919
2020 var firstStepView: FirstStepView?
2121
22− var tableId: Int = 2
22+ var tableId: Int = 1
2323
2424 var reservationsService: ReservationsService?
2525
@@ -33,7 +33,6 @@ class FirstStepReservationViewController: BaseViewController {
3333 right: 0)
3434 map.isUserInteractionEnabled = true
3535 map.scrollViewParent.setZoomScale(0.5, animated: true)
36− map.scrollBack()
3736 view.sendSubviewToBack(map)
3837 }
3938 }
@@ -59,6 +58,7 @@ class FirstStepReservationViewController: BaseViewController {
5958 let button = Button()
6059 let style = BlackButtonStyle()
6160 style.apply(to: button, withTitle: "ПОЗВОНИТЬ")
61+ //button.addTarget(self, action: #selector(cancelChange), for: .touchUpInside)
6262 return button
6363 }()
6464
@@ -77,24 +77,12 @@ class FirstStepReservationViewController: BaseViewController {
7777 reservationsService = ReservationsService(apiClient: APIClient.shared)
7878
7979 performUpdate()
80−
81− navigationItem.title = TotalStorage.standard.getEstablishment(establishmentId)?.address
8280 }
8381
8482 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 {
92− addStackViewWithButtons(leftBtn: callButton,
93− rightBtn: continueButton,
94− constant: -childContentView.frame.height - 20)
95−
96− callButton.addTarget(self, action: #selector(call), for: .touchUpInside)
97− }
83+ addStackViewWithButtons(leftBtn: callButton,
84+ rightBtn: continueButton,
85+ constant: -childContentView.frame.height - 20)
9886
9987 continueButton.addTarget(self, action: #selector(continueBooking), for: .touchUpInside)
10088 }
@@ -125,10 +113,10 @@ class FirstStepReservationViewController: BaseViewController {
125113 func configureMap() {
126114 if establishmentId == 1 {
127115 mapView = MapView1.loadFromNib()
128− } else if establishmentId == 2 {
129− mapView = MapView2.loadFromNib()
116+ mapView?.handler = self
117+ } else {
118+ // mapView = MapView2.loadFromNib()
130119 }
131− mapView?.handler = self
132120 }
133121
134122 func setupChildContainer() {
@@ -138,7 +126,7 @@ class FirstStepReservationViewController: BaseViewController {
138126 }
139127
140128 func updateChildViewControllerWithChosenId(_ id: Int) {
141− let reservationsForTable = allReservations?.reservations[id] ?? []
129+ let reservationsForTable = allReservations?.reservations[id] ?? [:]
142130 firstStepView?.setUp(reservationsForTable)
143131 }
144132
@@ -147,31 +135,17 @@ class FirstStepReservationViewController: BaseViewController {
147135 @objc func continueBooking() {
148136 let map = mapView
149137
150− guard let startTime = firstStepView?.fullDate else { return }
151− let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
152−
153− let (start, end) = isAdmin ? startTime.getAdminStartingAndEndPoint() : startTime.getClientStartingAndEndPoint()
138+ guard let startTime = firstStepView?.fullDate else { return }
154139
155− let reservPeriods = HFunc.main.filterPeriodsStartEndDates(allReservations?.reservations[tableId] ?? [],
156− start,
157− end)
140+ let reservPeriods = allReservations?.reservations[tableId]?[startTime.getDMY()] ?? []
158141
159− let model = SecondStepModel(establishment: establishmentId,
160− table: tableId,
142+ let model = SecondStepModel(table: tableId,
161143 startTime: startTime,
162144 reservedintervals: reservPeriods)
163145
164146 coordinator?.makeReservation(model: model,
165147 mapView: map)
166148 }
167−
168− @objc func call() {
169− guard
170− let phone = TotalStorage.standard.getEstablishment(establishmentId)?.admin,
171− let urlPhone = URL(string: "tel://79\(phone)") else { return }
172−
173− UIApplication.shared.open(urlPhone)
174− }
175149}
176150
177151extension FirstStepReservationViewController: MapHandler {
@@ -182,19 +156,8 @@ extension FirstStepReservationViewController: MapHandler {
182156}
183157
184158extension FirstStepReservationViewController: MapUpdater {
185− ///
186159 func update(_ date: Date) {
187− let areBooked = allReservations?.intervals[date] ?? []
188−
189− let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
190− let closed = !isAdmin && date.isInClosingHours()
191−
192− if Set(areBooked).contains(tableId) || closed {
193− continueButton.availiable = false
194− } else {
195− continueButton.availiable = true
196− }
197−
160+ let areBooked = allReservations?.intervals[date.getDMY()]?[date] ?? []
198161 mapView?.performUpdate(inactive: areBooked)
199162 }
200163}
Hookah Tau/Controllers/Client/Reservations/Steps/Second/SecondStepView.swiftnew file+189
@@ -0,0 +1,189 @@
1+//
2+// SecondStepView.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 21/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+struct SecondStepModel {
12+ var table: Int
13+ var startTime: Date
14+ var reservedintervals: [ReservationPeriod]
15+}
16+
17+class SecondStepView: UIView {
18+
19+ // MARK: - Properties
20+
21+ @IBOutlet weak var totalBookingLabel: UILabel!
22+
23+ @IBOutlet weak var infoLabel: UILabel!
24+
25+ @IBOutlet weak var numberOfGuestsLabel: UILabel!
26+
27+ @IBOutlet weak var guestSlider: UISlider!
28+
29+ @IBOutlet weak var scrollView: UIScrollView!
30+
31+ @IBOutlet weak var intervalsStackView: UIStackView!
32+
33+ var model: SecondStepModel? {
34+ didSet {
35+ guard let model = model else { return }
36+ totalBookingLabel.text = "Забронировать \(model.table) столик на \(Int(guestSlider.value)) человека \(model.startTime)?"
37+
38+ setUpReservedIntervals(model.reservedintervals)
39+ setUpBookingPeriod(model.startTime)
40+ }
41+ }
42+
43+ var startLeadingConstraint: NSLayoutConstraint!
44+ var endLeadingConstraint: NSLayoutConstraint!
45+
46+ var startPoint: UIView = {
47+ var view = UIView()
48+ view.backgroundColor = .blue
49+ view.translatesAutoresizingMaskIntoConstraints = false
50+ return view
51+ }()
52+
53+ var endPoint: UIView = {
54+ var view = UIView()
55+ view.backgroundColor = .red
56+ view.translatesAutoresizingMaskIntoConstraints = false
57+ return view
58+ }()
59+
60+ var fillInterval: UIView = {
61+ var view = UIView()
62+ view.backgroundColor = #colorLiteral(red: 0.476841867, green: 0.5048075914, blue: 1, alpha: 0.604880137)
63+ view.translatesAutoresizingMaskIntoConstraints = false
64+ return view
65+ }()
66+
67+ var duration: Int? = 1
68+
69+ // MARK: - Lifecycle
70+
71+ override func awakeFromNib() {
72+ super.awakeFromNib()
73+
74+ scrollView.delegate = self
75+
76+ scrollView.showsHorizontalScrollIndicator = false
77+
78+ setUpIntervals()
79+ }
80+
81+ @IBAction func sliderValueChanged(_ sender: UISlider) {
82+ let value = Int(sender.value)
83+ numberOfGuestsLabel.text = "Количество гостей: \(value)"
84+ infoLabel.text = getNumberOfCalians(value)
85+ totalBookingLabel.text = "Забронировать \(model?.table ?? 0) столик на \(value) человека 29 марта с 3:00 до 5:30?"
86+ }
87+
88+ func getNumberOfCalians(_ sliderValue: Int) -> String {
89+ return "Минимальное количество кальянов: \(sliderValue > 6 ? 2 : 1)"
90+ }
91+
92+ // MARK: - Setup
93+
94+ func setUpIntervals() {
95+ for period in 0...Constants.day10MinPeriods {
96+ let timePointView = TimePointView.loadFromNib()
97+ timePointView?.setUp(withTimePoint: period)
98+ let view = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 106))
99+ view.addSubviewThatFills(timePointView)
100+ intervalsStackView.addArrangedSubview(view)
101+ }
102+ }
103+
104+ private func setUpBookingPeriod(_ startTime: Date) {
105+ self.scrollView.addSubview(startPoint)
106+ self.scrollView.addSubview(endPoint)
107+ self.scrollView.addSubview(fillInterval)
108+
109+ let startDate = startTime.set(hours: 12, minutes: 0, seconds: 0)!
110+
111+ let startConstr = CGFloat(startDate.getMinutesPeriods(fromStart: startTime) * Constants.timepointWidth)
112+
113+ scrollView.setContentOffset(CGPoint(x: startConstr, y: 0), animated: true)
114+
115+ startLeadingConstraint = startPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
116+ constant: startConstr)
117+ endLeadingConstraint = endPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
118+ constant:startConstr + CGFloat(10 * Constants.timepointWidth))
119+
120+ NSLayoutConstraint.activate([
121+ startPoint.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0),
122+ endPoint.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0),
123+
124+ startPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
125+ endPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
126+
127+ startPoint.widthAnchor.constraint(equalToConstant: 7),
128+ endPoint.widthAnchor.constraint(equalToConstant: 7),
129+
130+ startLeadingConstraint,
131+ endLeadingConstraint,
132+
133+ fillInterval.leftAnchor.constraint(equalTo: startPoint.rightAnchor, constant: 0),
134+ fillInterval.rightAnchor.constraint(equalTo: endPoint.leftAnchor, constant: 0),
135+
136+ fillInterval.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0),
137+ fillInterval.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0)
138+ ])
139+
140+ let scrollViewPanStartGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanStart(recognizer:)))
141+ startPoint.addGestureRecognizer(scrollViewPanStartGesture)
142+
143+ let scrollViewPanEndGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanEnd(recognizer:)))
144+ endPoint.addGestureRecognizer(scrollViewPanEndGesture)
145+ }
146+
147+ func setUpReservedIntervals(_ reservations: [ReservationPeriod]) {
148+
149+ }
150+
151+ func bind(model: SecondStepModel) {
152+ self.model = model
153+ }
154+
155+ // MARK: - Pan
156+
157+ @objc func handlePanStart(recognizer:UIPanGestureRecognizer) {
158+ let translation = recognizer.translation(in: self.intervalsStackView)
159+ if let view = recognizer.view {
160+ startLeadingConstraint.constant += translation.x
161+ view.setNeedsUpdateConstraints()
162+ }
163+
164+ recognizer.setTranslation(CGPoint.zero, in: self.intervalsStackView)
165+ }
166+
167+ @objc func handlePanEnd(recognizer:UIPanGestureRecognizer) {
168+ let translation = recognizer.translation(in: self.intervalsStackView)
169+ if let view = recognizer.view {
170+ endLeadingConstraint.constant += translation.x
171+ view.setNeedsUpdateConstraints()
172+ }
173+
174+ recognizer.setTranslation(CGPoint.zero, in: self.intervalsStackView)
175+ }
176+}
177+
178+extension SecondStepView: UIScrollViewDelegate {
179+
180+}
181+
182+// MARK: - Nested types
183+
184+extension SecondStepView {
185+ enum Constants {
186+ static let day10MinPeriods = 90
187+ static let timepointWidth = 11
188+ }
189+}
Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepView.xib → Hookah Tau/Controllers/Client/Reservations/Steps/Second/SecondStepView.xibrenamed+27−23
@@ -1,25 +1,24 @@
11<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
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">
33 <device id="retina4_7" orientation="portrait" appearance="light"/>
44 <dependencies>
55 <deployment identifier="iOS"/>
6− <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
77 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
8− <capability name="Stack View standard spacing" minToolsVersion="9.0"/>
98 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
109 </dependencies>
1110 <objects>
1211 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
1312 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
1413 <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="SecondStepView" customModule="Hookah_Tau" customModuleProvider="target">
15− <rect key="frame" x="0.0" y="0.0" width="414" height="352"/>
14+ <rect key="frame" x="0.0" y="0.0" width="414" height="394"/>
1615 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1716 <subviews>
1817 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="bJ1-1q-VXq">
19− <rect key="frame" x="20" y="20" width="374" height="80"/>
18+ <rect key="frame" x="20" y="20" width="374" height="121.5"/>
2019 <subviews>
21− <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="center" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="Dkh-B7-3Dl">
22− <rect key="frame" x="16.5" y="0.0" width="341.5" height="41"/>
20+ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="center" spacing="21" translatesAutoresizingMaskIntoConstraints="NO" id="Dkh-B7-3Dl">
21+ <rect key="frame" x="16.5" y="0.0" width="341.5" height="82.5"/>
2322 <subviews>
2423 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Забронировать 7 столик на 3 человека 29 марта с 3:00 до 5:30?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7M9-lI-egu">
2524 <rect key="frame" x="0.0" y="0.0" width="341.5" height="41"/>
@@ -27,20 +26,26 @@
2726 <nil key="textColor"/>
2827 <nil key="highlightedColor"/>
2928 </label>
29+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Минимальное количество кальянов: 2" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zMP-Wa-N6b">
30+ <rect key="frame" x="11" y="62" width="319" height="20.5"/>
31+ <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
32+ <nil key="textColor"/>
33+ <nil key="highlightedColor"/>
34+ </label>
3035 </subviews>
3136 </stackView>
32− <label opaque="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PHb-Nt-9I2">
33− <rect key="frame" x="47" y="51" width="280.5" height="29"/>
37+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PHb-Nt-9I2">
38+ <rect key="frame" x="47" y="92.5" width="280.5" height="29"/>
3439 <string key="text">Если Вам нужно что-то особенное, Вы можете
35−связаться с администратором. </string>
36− <fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="12"/>
40+связаться с администратором.</string>
41+ <fontDescription key="fontDescription" type="system" pointSize="12"/>
3742 <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
3843 <nil key="highlightedColor"/>
3944 </label>
4045 </subviews>
4146 </stackView>
4247 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="9c7-IZ-n2p">
43− <rect key="frame" x="20" y="120" width="373.5" height="70"/>
48+ <rect key="frame" x="20" y="171.5" width="373.5" height="60.5"/>
4449 <subviews>
4550 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Количество гостей: 3" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QuY-68-2ax">
4651 <rect key="frame" x="0.0" y="0.0" width="373.5" height="20.5"/>
@@ -49,7 +54,7 @@
4954 <nil key="highlightedColor"/>
5055 </label>
5156 <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="3" minValue="1" maxValue="10" translatesAutoresizingMaskIntoConstraints="NO" id="TrY-MC-Ty0">
52− <rect key="frame" x="-2" y="30.5" width="377.5" height="40.5"/>
57+ <rect key="frame" x="-2" y="30.5" width="377.5" height="31"/>
5358 <connections>
5459 <action selector="sliderValueChanged:" destination="iN0-l3-epB" eventType="valueChanged" id="ekZ-3h-EeB"/>
5560 </connections>
@@ -57,10 +62,10 @@
5762 </subviews>
5863 </stackView>
5964 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RJE-Hk-KNh">
60− <rect key="frame" x="0.0" y="210" width="414" height="106"/>
65+ <rect key="frame" x="0.0" y="268" width="414" height="106"/>
6166 <subviews>
6267 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dmc-2e-y3T">
63− <rect key="frame" x="0.0" y="21" width="414" height="85"/>
68+ <rect key="frame" x="0.0" y="20" width="414" height="86"/>
6469 <subviews>
6570 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lBc-2o-oni">
6671 <rect key="frame" x="0.0" y="0.0" width="414" height="1"/>
@@ -70,7 +75,7 @@
7075 </constraints>
7176 </view>
7277 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Du-Fg-z1t">
73− <rect key="frame" x="0.0" y="84" width="414" height="1"/>
78+ <rect key="frame" x="0.0" y="85" width="414" height="1"/>
7479 <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
7580 <constraints>
7681 <constraint firstAttribute="height" constant="1" id="hal-Zc-mvq"/>
@@ -85,7 +90,7 @@
8590 <constraint firstItem="lBc-2o-oni" firstAttribute="leading" secondItem="dmc-2e-y3T" secondAttribute="leading" id="CA6-4b-6ZK"/>
8691 <constraint firstItem="7Du-Fg-z1t" firstAttribute="leading" secondItem="dmc-2e-y3T" secondAttribute="leading" id="YwH-ns-ecE"/>
8792 <constraint firstItem="lBc-2o-oni" firstAttribute="top" secondItem="dmc-2e-y3T" secondAttribute="top" id="ja1-YQ-A2D"/>
88− <constraint firstAttribute="height" constant="85" id="rbN-al-oWi"/>
93+ <constraint firstAttribute="height" constant="86" id="rbN-al-oWi"/>
8994 <constraint firstAttribute="bottom" secondItem="7Du-Fg-z1t" secondAttribute="bottom" id="wa8-GY-qKm"/>
9095 </constraints>
9196 </view>
@@ -123,28 +128,27 @@
123128 </subviews>
124129 <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
125130 <constraints>
126− <constraint firstAttribute="bottom" secondItem="RJE-Hk-KNh" secondAttribute="bottom" constant="36" id="0W3-e2-hCU"/>
127131 <constraint firstItem="9c7-IZ-n2p" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="20" id="94y-7J-ksb"/>
128− <constraint firstItem="9c7-IZ-n2p" firstAttribute="top" secondItem="bJ1-1q-VXq" secondAttribute="bottom" constant="20" id="9TT-vO-7PZ"/>
132+ <constraint firstItem="9c7-IZ-n2p" firstAttribute="top" secondItem="bJ1-1q-VXq" secondAttribute="bottom" constant="30" id="9TT-vO-7PZ"/>
129133 <constraint firstItem="RJE-Hk-KNh" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="AgS-kP-UNE"/>
130− <constraint firstItem="RJE-Hk-KNh" firstAttribute="top" secondItem="9c7-IZ-n2p" secondAttribute="bottom" constant="20" id="FAI-xj-uWk"/>
134+ <constraint firstItem="RJE-Hk-KNh" firstAttribute="top" secondItem="9c7-IZ-n2p" secondAttribute="bottom" constant="36" id="FAI-xj-uWk"/>
131135 <constraint firstAttribute="trailing" secondItem="bJ1-1q-VXq" secondAttribute="trailing" constant="20" id="OCH-eC-kP5"/>
132136 <constraint firstItem="bJ1-1q-VXq" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="20" id="PCm-nY-M6p"/>
133137 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="9c7-IZ-n2p" secondAttribute="trailing" constant="20.5" id="Rh7-V2-v2u"/>
134− <constraint firstItem="bJ1-1q-VXq" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="20" id="SnG-Cy-hHq"/>
138+ <constraint firstItem="bJ1-1q-VXq" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="20" id="SnG-Cy-hHq"/>
135139 <constraint firstItem="RJE-Hk-KNh" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="fW0-Tt-MpN"/>
136140 </constraints>
137141 <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
138142 <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
139143 <connections>
140144 <outlet property="guestSlider" destination="TrY-MC-Ty0" id="mR0-wv-AM7"/>
145+ <outlet property="infoLabel" destination="zMP-Wa-N6b" id="htu-ql-T0O"/>
141146 <outlet property="intervalsStackView" destination="IIO-je-eBt" id="gaP-LX-Xed"/>
142147 <outlet property="numberOfGuestsLabel" destination="QuY-68-2ax" id="DvK-dr-c3J"/>
143148 <outlet property="scrollView" destination="zk1-3E-2kS" id="b8R-jY-2Q3"/>
144− <outlet property="specialLabel" destination="PHb-Nt-9I2" id="hXL-Je-dax"/>
145149 <outlet property="totalBookingLabel" destination="7M9-lI-egu" id="7YU-yI-Gm4"/>
146150 </connections>
147− <point key="canvasLocation" x="-8" y="88.15592203898052"/>
151+ <point key="canvasLocation" x="137.59999999999999" y="70.164917541229386"/>
148152 </view>
149153 </objects>
150154</document>
Hookah Tau/Controllers/Client/Reservations/Steps/SecondStepReservationCoordinator.swiftnew file+38
@@ -0,0 +1,38 @@
1+//
2+// SecondStepReservationCoordinator.swift
3+// Hookah Tau
4+//
5+// Created by cstore on 21/11/2019.
6+// Copyright © 2019 Daria Rednikina. All rights reserved.
7+//
8+
9+import UIKit
10+
11+
12+class SecondStepReservationCoordinator: BaseCoordinator {
13+
14+ // MARK: - Properties
15+
16+ var didFinish: ((MapImageScroll?) -> Void)?
17+
18+ var model: SecondStepModel?
19+
20+ var mapView: MapImageScroll?
21+
22+ // MARK: - Lifecycle
23+
24+ override func start() {
25+ let storyboard = UIStoryboard(name: "Reservation", bundle: nil)
26+ let reservationVC = storyboard.instantiateViewController(withIdentifier: "SecondStepReservationViewController") as! SecondStepReservationViewController
27+
28+ reservationVC.model = model
29+ reservationVC.mapView = mapView
30+ reservationVC.coordinator = self
31+
32+ navigationController?.pushViewController(reservationVC, animated: false)
33+ }
34+
35+ func cancel(_ mapView: MapImageScroll?) {
36+ didFinish?(mapView)
37+ }
38+}
Hookah Tau/Controllers/Client/Reservations/Steps/change /ChangeReservationCoordinator.swiftdeleted−36
@@ -1,36 +0,0 @@
1−//
2−// ChangeReservationCoordinator.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 02/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class ChangeReservationCoordinator: BaseCoordinator {
12−
13− // MARK: - Peoperties
14−
15− var reservation: Reservation?
16−
17− var didFinish: ((Reservation) -> Void)?
18−
19− // MARK: - Lifecycle
20−
21− override func start() {
22− let storyboard = UIStoryboard(name: "Reservation", bundle: nil)
23− let vc = storyboard.instantiateViewController(withIdentifier: "ChangeReservationViewController") as? ChangeReservationViewController
24−
25− guard let viewController = vc else { return }
26−
27− viewController.reservation = reservation
28− viewController.coordinator = self
29− navigationController?.pushViewController(viewController, animated: false)
30− }
31−
32− /// Закончили редактирование, все хорошо
33− func finish(_ r: Reservation) {
34− didFinish?(r)
35− }
36−}
Hookah Tau/Controllers/Client/Reservations/Steps/change /ChangeReservationViewController.swiftdeleted−152
@@ -1,152 +0,0 @@
1−//
2−// ChangeReservationViewController.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 02/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class ChangeReservationViewController: BaseViewController {
12−
13− // MARK: - IBAOutlets
14−
15− @IBOutlet weak var childContentView: UIView!
16−
17− @IBOutlet weak var mapContentView: UIView!
18−
19− // MARK: - Peoperties
20−
21− var reservation: Reservation?
22−
23− var secondStepView: SecondStepView?
24−
25− var mapView: MapImageScroll?
26−
27− /// Как только получили ответ на запросах о бронирвоаниях, сразу обновляем
28− var reservedIntervals: [ReservationPeriod] = [] {
29− didSet {
30− setupContainer(withReservedPeriods: reservedIntervals)
31− }
32− }
33−
34− var reservationService: ReservationsService?
35−
36− weak var coordinator: ChangeReservationCoordinator?
37−
38− // MARK: - Buttons
39−
40− var confirmButton: Button = {
41− var button = Button()
42− var 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− reservationService = ReservationsService(apiClient: APIClient.shared)
53− setupButtons()
54− setupMap()
55− getReservations()
56−
57− navigationItem.hidesBackButton = true
58− // Do any additional setup after loading the view.
59− }
60−
61− // MARK: - setup
62−
63− func setupButtons() {
64− addStackViewWithButtons( rightBtn: confirmButton,
65− constant: -childContentView.frame.height - 20)
66−
67− confirmButton.addTarget(self, action: #selector(changeReservation), for: .touchUpInside)
68− }
69−
70− func setupContainer(withReservedPeriods resPer: [ReservationPeriod]) {
71− secondStepView = SecondStepView.loadFromNib()
72− childContentView.addSubviewThatFills(secondStepView)
73−
74− guard let r = reservation else { return }
75−
76− secondStepView?.bind(model: SecondStepModel(establishment: r.establishment,
77− table: r.reservedTable,
78− startTime: r.startTime,
79− endTime: r.endTime,
80− reservedintervals: resPer))
81− }
82−
83− func getReservations() {
84− guard let r = reservation else { return }
85− reservationService?.getAllReservations(establishmentID: r.establishment, completion: { (res) in
86− switch res {
87− case .failure(let err):
88− self.displayAlert(forError: err, with: "Прости, не смогли загрузить доступные периоды для брони этого столика. Попробуй, пожалуйста, еще раз!")
89− case .success(let allReservations):
90− let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
91− let (start, end) = isAdmin ? r.startTime.getAdminStartingAndEndPoint() : r.startTime.getClientStartingAndEndPoint()
92− let reservPeriods = HFunc.main.filterPeriodsStartEndDates(allReservations.reservations[r.reservedTable] ?? [],
93− start,
94− end)
95−
96− self.reservedIntervals = reservPeriods
97− }
98− })
99− }
100−
101− func setupMap() {
102− guard let reservation = reservation else {
103− return
104− }
105−
106− let width = view.frame.width
107− if reservation.establishment == 1 {
108− mapView = MapView1.loadFromNib()
109− mapView?.scrollViewParent.contentInset = UIEdgeInsets(top: 0,
110− left: width / 2,
111− bottom: 200,
112− right: width / 2)
113−
114− mapView?.scrollViewParent.setContentOffset(CGPoint(x: 0, y: 50), animated: false)
115− } else {
116− mapView = MapView2.loadFromNib()
117− mapView?.scrollViewParent.setContentOffset(CGPoint(x: 0, y: -100), animated: false)
118− mapView?.scrollViewParent.contentInset = UIEdgeInsets(top: 100,
119− left: width / 2,
120− bottom: 100,
121− right: width / 2)
122− }
123−
124− mapContentView.addSubviewThatFills(mapView)
125−
126− mapView?.isUserInteractionEnabled = false
127− mapView?.scrollToTable(table: reservation.reservedTable)
128− }
129−
130− // MARK: - Handlers
131−
132− @objc func changeReservation() {
133− guard let r = secondStepView?.data, let uuid = reservation?.uuid else { return }
134− confirmButton.loading = true
135−
136− reservationService?.updateReservation(startTime: r.startTime,
137− numberOfGuests: r.numberOfGuests,
138− endTime: r.endTime,
139− uuid: uuid,
140− isAdmin: false,
141− completion: { [weak self] (res) in
142− if res {
143− self?.coordinator?.finish(Reservation(uuid: uuid, reservationData: r))
144− } else {
145− self?.displayAlert(with: "Что-то пошло не так! Попробуешь еще раз?")
146− }
147−
148− self?.confirmButton.loading = false
149− })
150− }
151−
152−}
Hookah Tau/Controllers/Client/Tab bar/Client.storyboard+6−10
@@ -1,14 +1,14 @@
11<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
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">
33 <device id="retina6_1" orientation="portrait" appearance="light"/>
44 <dependencies>
55 <deployment identifier="iOS"/>
6− <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
6+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
77 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
88 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
99 </dependencies>
1010 <scenes>
11− <!--Профиль-->
11+ <!--Navigation Controller-->
1212 <scene sceneID="b0t-Wu-VhQ">
1313 <objects>
1414 <viewController id="qqN-qg-VJ7" customClass="UINavigationController" sceneMemberID="viewController">
@@ -18,13 +18,13 @@
1818 <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
1919 <viewLayoutGuide key="safeArea" id="WgY-fu-N23"/>
2020 </view>
21− <tabBarItem key="tabBarItem" title="Профиль" image="person" id="vPo-1j-5WO"/>
21+ <tabBarItem key="tabBarItem" systemItem="contacts" id="vPo-1j-5WO"/>
2222 </viewController>
2323 <placeholder placeholderIdentifier="IBFirstResponder" id="zv0-gE-V7c" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
2424 </objects>
2525 <point key="canvasLocation" x="-166" y="195"/>
2626 </scene>
27− <!--Брони-->
27+ <!--Navigation Controller-->
2828 <scene sceneID="nQv-Ks-RjM">
2929 <objects>
3030 <viewController id="MGt-zZ-AbL" customClass="UINavigationController" sceneMemberID="viewController">
@@ -34,7 +34,7 @@
3434 <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
3535 <viewLayoutGuide key="safeArea" id="vjZ-Ji-o7T"/>
3636 </view>
37− <tabBarItem key="tabBarItem" title="Брони" image="stack" id="B7T-zH-VfU"/>
37+ <tabBarItem key="tabBarItem" systemItem="mostViewed" id="B7T-zH-VfU"/>
3838 </viewController>
3939 <placeholder placeholderIdentifier="IBFirstResponder" id="W83-e1-iNk" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
4040 </objects>
@@ -59,8 +59,4 @@
5959 <point key="canvasLocation" x="-1081" y="-130"/>
6060 </scene>
6161 </scenes>
62− <resources>
63− <image name="person" width="25" height="24"/>
64− <image name="stack" width="25" height="24"/>
65− </resources>
6662</document>
Hookah Tau/Controllers/Client/Tab bar/ClientTabbarController.swift+6−6
@@ -10,18 +10,18 @@ import Foundation
1010import UIKit
1111
1212protocol TabbarView: class {
13− var onReservationFlowSelect: TabbarClosure? { get set }
14− var onProfileFlowSelect: TabbarClosure? { get set }
15− var onViewDidLoad: TabbarClosure? { get set }
13+ var onReservationFlowSelect: ((UINavigationController) -> ())? { get set }
14+ var onProfileFlowSelect: ((UINavigationController) -> ())? { get set }
15+ var onViewDidLoad: ((UINavigationController) -> ())? { get set }
1616}
1717
1818final class ClientTabbarController: UITabBarController, UITabBarControllerDelegate, TabbarView {
1919
2020 // MARK: - Properties
2121
22− var onReservationFlowSelect: TabbarClosure?
23− var onProfileFlowSelect: TabbarClosure?
24− var onViewDidLoad: TabbarClosure?
22+ var onReservationFlowSelect: ((UINavigationController) -> ())?
23+ var onProfileFlowSelect: ((UINavigationController) -> ())?
24+ var onViewDidLoad: ((UINavigationController) -> ())?
2525
2626
2727 // MARK: - Lifecycle
Hookah Tau/Controllers/Client/Tab bar/ClientTabbarCoordinator.swift+3−3
@@ -8,10 +8,10 @@
88
99import UIKit
1010
11−typealias TabbarClosure = ((UINavigationController) -> ())
12−
1311class ClientTabbarCoordinator: BaseCoordinator {
1412
13+ typealias TabbarClosure = ((UINavigationController) -> ())
14+
1515 // MARK: - Lifecycle
1616
1717 override func start() {
@@ -37,7 +37,7 @@ class ClientTabbarCoordinator: BaseCoordinator {
3737 }
3838 }
3939
40− private func runProfileFlow() -> TabbarClosure {
40+ private func runProfileFlow() -> TabbarClosure{
4141 return { navigationController in
4242 if navigationController.viewControllers.isEmpty {
4343 let profileCoordinator = ProfileCoordinator(navigationController: navigationController)
Hookah Tau/Controllers/Picker view/IntervalPickerView.swiftdeleted−265
@@ -1,265 +0,0 @@
1−//
2−// IntervalPickerView.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 19/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−struct IntervalPickerModel {
12− var startTime: Date
13− var endTime: Date
14−}
15−
16−protocol PickerViewUpdater: class {
17− func update(withModel model: IntervalPickerModel)
18−}
19−
20−class IntervalPickerView: UIView {
21−
22− // MARK: - IBAOutlets
23−
24− @IBOutlet weak var scrollView: UIScrollView!
25−
26− @IBOutlet weak var intervalsStackView: UIStackView!
27−
28− // MARK: - Properties
29−
30− // констрейнты начала и конца интервала
31− var startLeadingConstraint: NSLayoutConstraint!
32− var endLeadingConstraint: NSLayoutConstraint!
33−
34− var startPoint: UIImageView = {
35− var view = UIImageView()
36− view.isUserInteractionEnabled = true
37− view.image = #imageLiteral(resourceName: "handle_left")
38− view.translatesAutoresizingMaskIntoConstraints = false
39− return view
40− }()
41−
42− var endPoint: UIImageView = {
43− var view = UIImageView()
44− view.isUserInteractionEnabled = true
45− view.image = #imageLiteral(resourceName: "Group")
46− view.translatesAutoresizingMaskIntoConstraints = false
47− return view
48− }()
49−
50− /// Интервал
51− var fillInterval: UIView = {
52− var view = UIView()
53− view.backgroundColor = #colorLiteral(red: 0, green: 0.5921568627, blue: 1, alpha: 0.3426262843)
54− view.translatesAutoresizingMaskIntoConstraints = false
55− return view
56− }()
57−
58− /// Время начала вертелки.
59− /// Для клиента это 12:00 смены (надо вызвать метод для получения текущей смены).
60− /// Для администратора это `t` - 24h
61− var startDate: Date?
62−
63− /// Моделька для смены промежутков
64− var model: IntervalPickerModel? {
65− didSet {
66− guard let model = model else { return }
67− updater?.update(withModel: model)
68− }
69− }
70−
71− weak var updater: PickerViewUpdater?
72−
73− // MARK: - bind
74−
75− func bind(withModel model: ReservationData, user isAdmin: Bool, intervals: [ReservationPeriod]) {
76− // isAdmin
77− let isAdmin = DataStorage.standard.getUserModel()?.isAdmin ?? false
78−
79− let (start, _) = isAdmin ? model.startTime.getAdminStartingAndEndPoint() : model.startTime.getClientStartingAndEndPoint()
80−
81− startDate = start
82−
83− setUpIntervals(isAdmin)
84− setUpReservedIntervals(intervals, isAdmin)
85− setUpBookingPeriod(model.startTime, model.endTime)
86− }
87−
88− /// Тут происходит установка интервалов. Разное для клиента и админа
89− func setUpIntervals(_ isAdmin: Bool) {
90− guard let startPoint = startDate else { return }
91−
92− let startingPoint = isAdmin ? startPoint.getAdminsStartingPoint() : Constants.clientStartingPoint
93− let endingPoint = startingPoint + (isAdmin ? Constants.adminDuration : Constants.clientDuration)
94−
95− for period in startingPoint...endingPoint {
96− let timePointView = TimePointView.loadFromNib()
97− timePointView?.setUp(withTimePoint: period)
98− let view = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 106))
99− view.addSubviewThatFills(timePointView)
100− intervalsStackView.addArrangedSubview(view)
101− }
102− }
103−
104− private func setUpBookingPeriod(_ startTime: Date, _ endTime: Date? = nil) {
105− self.scrollView.addSubview(startPoint)
106− self.scrollView.addSubview(endPoint)
107− self.scrollView.addSubview(fillInterval)
108−
109− guard let startDate = startDate else { return }
110−
111− let startConstr = CGFloat(startTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint)
112−
113− scrollView.setContentOffset(CGPoint(x: startConstr - 50, y: 0), animated: true)
114−
115− startLeadingConstraint = startPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
116− constant: startConstr)
117−
118− if let end = endTime {
119− let endConstr = CGFloat(end.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint)
120− endLeadingConstraint = endPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
121− constant: endConstr)
122− } else {
123− endLeadingConstraint = endPoint.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
124− constant:startConstr + Constants.minBookingLength)
125− }
126−
127− NSLayoutConstraint.activate([
128−
129− startPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
130− endPoint.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0),
131−
132− startPoint.widthAnchor.constraint(equalToConstant: Constants.pointWidth),
133− endPoint.widthAnchor.constraint(equalToConstant: Constants.pointWidth),
134−
135− startPoint.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
136− endPoint.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
137−
138− startLeadingConstraint,
139− endLeadingConstraint,
140−
141− fillInterval.leftAnchor.constraint(equalTo: startPoint.rightAnchor, constant: 0),
142− fillInterval.rightAnchor.constraint(equalTo: endPoint.leftAnchor, constant: 0),
143−
144− fillInterval.heightAnchor.constraint(equalToConstant: Constants.pointHeight),
145− fillInterval.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0)
146− ])
147−
148− let scrollViewPanStartGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanStart(recognizer:)))
149− startPoint.addGestureRecognizer(scrollViewPanStartGesture)
150−
151− let scrollViewPanEndGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanEnd(recognizer:)))
152− endPoint.addGestureRecognizer(scrollViewPanEndGesture)
153− }
154−
155− func setUpReservedIntervals(_ reservations: [ReservationPeriod], _ isAdmin: Bool) {
156−
157− for reservation in reservations {
158− let uiview = UIView(frame: CGRect(x: 0, y: 0, width: Constants.widthTimePoint * reservation.duration, height: Constants.heightIntervals))
159− uiview.backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 0.5)
160−
161−
162− uiview.translatesAutoresizingMaskIntoConstraints = false
163− scrollView.addSubview(uiview)
164−
165− guard let startDate = startDate else { return }
166−
167− let s = reservation.startTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint
168− let d = reservation.duration * Constants.widthTimePoint
169−
170− let startTime = s < 0 ? 0 : s
171−
172− let total = (isAdmin ? Constants.adminDuration : Constants.clientDuration) * Constants.widthTimePoint
173− var duration = 0
174− if s < 0 {
175− duration = reservation.endTime.getMinutesPeriods(fromStart: startDate) * Constants.widthTimePoint
176− } else {
177− duration = (s + d) > total ? total - s : d
178− }
179−
180− NSLayoutConstraint.activate([
181− uiview.bottomAnchor.constraint(equalToSystemSpacingBelow: scrollView.bottomAnchor, multiplier: 0),
182− uiview.leftAnchor.constraint(equalTo: scrollView.leftAnchor,
183− constant: CGFloat(Constants.widthTimePoint / 2 + startTime)),
184− uiview.widthAnchor.constraint(equalToConstant: CGFloat(duration)),
185− uiview.heightAnchor.constraint(equalToConstant: CGFloat(Constants.heightIntervals))
186− ])
187− }
188− }
189−
190− // MARK: - Pan
191−
192− @objc func handlePanStart(recognizer:UIPanGestureRecognizer) {
193−
194− let translation = recognizer.translation(in: self.intervalsStackView)
195− let duration = abs(startLeadingConstraint.constant + translation.x - endLeadingConstraint.constant)
196−
197− if let view = recognizer.view, duration >= Constants.minBookingLength {
198− startLeadingConstraint.constant += translation.x
199−
200− changeTime(startLeadingConstraint, .start)
201−
202− view.setNeedsUpdateConstraints()
203− }
204−
205− recognizer.setTranslation(CGPoint.zero, in: self.intervalsStackView)
206− }
207−
208− @objc func handlePanEnd(recognizer:UIPanGestureRecognizer) {
209−
210− let translation = recognizer.translation(in: self.intervalsStackView)
211− let duration = abs(startLeadingConstraint.constant - (endLeadingConstraint.constant + translation.x))
212−
213− if let view = recognizer.view, duration >= Constants.minBookingLength {
214− endLeadingConstraint.constant += translation.x
215−
216− changeTime(endLeadingConstraint, .end)
217− view.setNeedsUpdateConstraints()
218− }
219−
220− recognizer.setTranslation(CGPoint.zero, in: self.intervalsStackView)
221− }
222−
223− func changeTime(_ constraint: NSLayoutConstraint, _ period: Period) {
224− guard let startDate = startDate, let m = model else { return }
225−
226− let offset = Int(constraint.constant) % Constants.widthTimePoint
227−
228− if offset == 0 {
229− let p = Int(constraint.constant) / Constants.widthTimePoint
230− let time = startDate.addPeriods(p)
231−
232− switch period {
233− case .start:
234− model = IntervalPickerModel(startTime: time,
235− endTime: m.endTime)
236− case .end:
237− model = IntervalPickerModel(startTime: m.startTime,
238− endTime: time)
239− }
240− }
241− }
242−}
243−
244−extension IntervalPickerView {
245− enum Constants {
246− static let widthTimePoint = 11
247−
248− static let adminDuration = 288
249− static let clientDuration = 90
250− // 12:00 = 12 * 6
251− static let clientStartingPoint = 72
252−
253− static let pointWidth: CGFloat = 19
254− static let pointHeight: CGFloat = 85
255−
256− static let minBookingLength: CGFloat = 132
257−
258− static let heightIntervals = 85
259− }
260−
261− enum Period {
262− case start
263− case end
264− }
265−}
Hookah Tau/Controllers/Picker view/IntervalPickerView.xibdeleted−84
@@ -1,84 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
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="IntervalPickerView" customModule="Hookah_Tau" customModuleProvider="target">
14− <rect key="frame" x="0.0" y="0.0" width="414" height="106"/>
15− <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16− <subviews>
17− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QgM-NY-puV">
18− <rect key="frame" x="0.0" y="21" width="414" height="85"/>
19− <subviews>
20− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0TX-kl-OPO">
21− <rect key="frame" x="0.0" y="84" width="414" height="1"/>
22− <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
23− <constraints>
24− <constraint firstAttribute="height" constant="1" id="Sf4-dJ-qsD"/>
25− </constraints>
26− </view>
27− <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wcb-MB-8F8">
28− <rect key="frame" x="0.0" y="0.0" 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="DCx-L0-09t"/>
32− </constraints>
33− </view>
34− </subviews>
35− <color key="backgroundColor" red="0.89019607840000003" green="0.89019607840000003" blue="0.89019607840000003" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
36− <constraints>
37− <constraint firstAttribute="height" constant="85" id="1jc-QZ-f8e"/>
38− <constraint firstItem="Wcb-MB-8F8" firstAttribute="top" secondItem="QgM-NY-puV" secondAttribute="top" id="2tI-Or-OAH"/>
39− <constraint firstItem="0TX-kl-OPO" firstAttribute="leading" secondItem="QgM-NY-puV" secondAttribute="leading" id="ZM5-CV-OL9"/>
40− <constraint firstItem="Wcb-MB-8F8" firstAttribute="leading" secondItem="QgM-NY-puV" secondAttribute="leading" id="adB-mX-tf3"/>
41− <constraint firstAttribute="bottom" secondItem="0TX-kl-OPO" secondAttribute="bottom" id="iji-xK-gU8"/>
42− <constraint firstAttribute="trailing" secondItem="Wcb-MB-8F8" secondAttribute="trailing" id="kK5-X5-zT5"/>
43− <constraint firstAttribute="trailing" secondItem="0TX-kl-OPO" secondAttribute="trailing" id="x2r-sO-Npw"/>
44− </constraints>
45− </view>
46− <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e97-Yk-hHi">
47− <rect key="frame" x="0.0" y="0.0" width="414" height="106"/>
48− <subviews>
49− <stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4n8-V3-m5t">
50− <rect key="frame" x="0.0" y="0.0" width="414" height="106"/>
51− </stackView>
52− </subviews>
53− <constraints>
54− <constraint firstItem="4n8-V3-m5t" firstAttribute="height" secondItem="e97-Yk-hHi" secondAttribute="height" id="8p9-v6-iaH"/>
55− <constraint firstAttribute="bottom" secondItem="4n8-V3-m5t" secondAttribute="bottom" id="ajS-3D-lcm"/>
56− <constraint firstItem="4n8-V3-m5t" firstAttribute="top" secondItem="e97-Yk-hHi" secondAttribute="top" id="eN5-bZ-4Wt"/>
57− <constraint firstItem="4n8-V3-m5t" firstAttribute="width" secondItem="e97-Yk-hHi" secondAttribute="width" id="enn-uv-GR2"/>
58− <constraint firstAttribute="trailing" secondItem="4n8-V3-m5t" secondAttribute="trailing" id="fIk-7A-mrL"/>
59− <constraint firstItem="4n8-V3-m5t" firstAttribute="leading" secondItem="e97-Yk-hHi" secondAttribute="leading" id="fcr-TD-pYK"/>
60− </constraints>
61− <viewLayoutGuide key="contentLayoutGuide" id="sxJ-gI-ilG"/>
62− <viewLayoutGuide key="frameLayoutGuide" id="yj8-fL-J9D"/>
63− </scrollView>
64− </subviews>
65− <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
66− <constraints>
67− <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="QgM-NY-puV" secondAttribute="bottom" id="JdC-xm-YdY"/>
68− <constraint firstItem="e97-Yk-hHi" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="Oqv-Y6-Qp3"/>
69− <constraint firstItem="e97-Yk-hHi" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="YH5-He-gHk"/>
70− <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="QgM-NY-puV" secondAttribute="trailing" id="ewc-Nf-fIZ"/>
71− <constraint firstItem="QgM-NY-puV" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="jGH-FL-IC0"/>
72− <constraint firstItem="e97-Yk-hHi" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="lOW-0Q-pvW"/>
73− <constraint firstItem="e97-Yk-hHi" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" symbolic="YES" id="x39-q5-hdD"/>
74− </constraints>
75− <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
76− <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
77− <connections>
78− <outlet property="intervalsStackView" destination="4n8-V3-m5t" id="239-zR-iS1"/>
79− <outlet property="scrollView" destination="e97-Yk-hHi" id="eED-qd-4Yw"/>
80− </connections>
81− <point key="canvasLocation" x="137.68115942028987" y="360.26785714285711"/>
82− </view>
83− </objects>
84−</document>
Hookah Tau/DB/DataStorage.swiftdeleted−115
@@ -1,115 +0,0 @@
1−//
2−// DataStorage.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 01/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−/// Класс для хранения промежуточного состояния регистрации,
12−/// данных пользователя, ...
13−class DataStorage {
14−
15− enum Keys: String {
16− case name
17− case phone
18− case isAdmin
19− case loggedIn
20− case cookies
21− case chosenEstablishment // only for admin
22− }
23−
24− private init() {}
25−
26− static let standard = DataStorage()
27−
28− /// Номер телефона для процесса регистрации/авторизации
29− var phone: String?
30− /// Имя введенное при регистрации
31− var name: String?
32−
33− /// Метод для сохранения данных пользователя в приложении,
34− /// используется для сохранения объекта, полученного после успешной
35− /// авторизации, регистрации
36− func saveUserModel(_ user: User) {
37− let name = user.name
38− let phone = user.phoneNumber
39− let isAdmin = user.isAdmin
40−
41− UserDefaults.standard.setValue(name, forKey: Keys.name.rawValue)
42− UserDefaults.standard.setValue(phone, forKey: Keys.phone.rawValue)
43− UserDefaults.standard.setValue(isAdmin, forKey: Keys.isAdmin.rawValue)
44− }
45−
46− /// Сохраняем выбранный администратором establishmentId
47− func setupEstablishmentChoice(id: Int) {
48− UserDefaults.standard.setValue(id, forKey: Keys.chosenEstablishment.rawValue)
49− }
50−
51− func getEstablishmentChoice() -> Int? {
52− let val = UserDefaults.standard.integer(forKey: Keys.chosenEstablishment.rawValue)
53− return val == 0 ? nil : val
54− }
55−
56− /// Метод для установки куков в хранилище
57− /// - Parameter cookies: куки
58− /// - Parameter url: url для куков
59− func setCookies(_ cookies: [HTTPCookie], forURL url: URL) {
60− let cookiesStorage = HTTPCookieStorage.shared
61− let userDefaults = UserDefaults.standard
62−
63− var cookieDict = [String: AnyObject]()
64−
65− for cookie in cookiesStorage.cookies(for: url)! {
66− cookieDict[cookie.name] = cookie.properties as AnyObject?
67− }
68−
69− userDefaults.set(cookieDict, forKey: Keys.cookies.rawValue)
70− }
71−
72−
73− /// Достаем из хранилища и устанавливаем куки
74− /// Если не выходит, то вовзращаем false
75− func getCookies() -> Bool {
76− let cookiesStorage = HTTPCookieStorage.shared
77− let userDefaults = UserDefaults.standard
78−
79− if let cookieDictionary = userDefaults.dictionary(forKey: Keys.cookies.rawValue) {
80−
81− for (_, cookieProperties) in cookieDictionary {
82− if let cookie = HTTPCookie(properties: cookieProperties as! [HTTPCookiePropertyKey : Any] ) {
83− cookiesStorage.setCookie(cookie)
84− }
85− }
86− return true
87− }
88−
89− return false
90− }
91−
92− func getUserModel() -> User? {
93− guard
94− let name = UserDefaults.standard.string(forKey: Keys.name.rawValue),
95− let phone = UserDefaults.standard.string(forKey: Keys.phone.rawValue)
96− else { return nil }
97−
98− let isAdmin = UserDefaults.standard.bool(forKey: Keys.isAdmin.rawValue)
99−
100− return User(name: name, phoneNumber: phone, isAdmin: isAdmin)
101− }
102−
103− func isLoggedIn() -> Bool {
104− return UserDefaults.standard.bool(forKey: Keys.loggedIn.rawValue) && getCookies()
105− }
106−
107− func setLoggedInState(_ value: Bool) {
108− if !value {
109− UserDefaults.standard.removeObject(forKey: Keys.name.rawValue)
110− UserDefaults.standard.removeObject(forKey: Keys.phone.rawValue)
111− UserDefaults.standard.removeObject(forKey: Keys.cookies.rawValue)
112− }
113− UserDefaults.standard.set(value, forKey: Keys.loggedIn.rawValue)
114− }
115−}
Hookah Tau/DB/TotalStorage.swiftdeleted−124
@@ -1,124 +0,0 @@
1−//
2−// TotalStorage.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 28/11/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import UIKit
10−
11−/// Класс для хранения `establishments`,
12−class TotalStorage {
13−
14− // MARK: - properties
15−
16− static let standard = TotalStorage()
17−
18− // MARK: - Init
19−
20− private init() {
21− service = EstablishmentSevice(apiClient: APIClient.shared)
22− setEstablishments()
23− }
24−
25− // MARK: - getters
26−
27− func getEstablishment(_ id: Int) -> EstablishmentData? {
28− return establishments[id]
29− }
30−
31− func getTable(establishment eId: Int, table tId: Int) -> Table? {
32− return imagesForTables[eId]?[tId]
33− }
34−
35− // MARK: - Setters
36−
37− private func setEstablishments() {
38− service.loadAdmins { (result) in
39− switch result {
40− case .success(let phones):
41− self.phones = phones
42− default:
43− break
44− }
45− }
46− }
47−
48− // MARK: - Private
49−
50− private let service: EstablishmentSevice
51−
52− private var establishments: [Int: EstablishmentData] = [
53− 1: EstablishmentData(id: 1,
54− image: #imageLiteral(resourceName: "1"),
55− admin: "",
56− address: "Гороховский пер. 12с5, 205",
57− maxTableNumber: 8),
58−
59− 2: EstablishmentData(id: 2,
60− image: #imageLiteral(resourceName: "2"),
61− admin: "",
62− address: "ул. Рыбинская 7, кв. 2",
63− maxTableNumber: 7)
64− ]
65−
66− private var imagesForTables: [Int: [Int: Table]] = [
67− 1 :[
68− 1: Table(image: #imageLiteral(resourceName: "1_1"), maxGuestNumber: 6),
69− 2: Table(image: #imageLiteral(resourceName: "1_2"), maxGuestNumber: 8),
70− 3: Table(image: #imageLiteral(resourceName: "1_3"), maxGuestNumber: 8),
71− 4: Table(image: #imageLiteral(resourceName: "1_4"), maxGuestNumber: 6),
72− 5: Table(image: #imageLiteral(resourceName: "1_5"), maxGuestNumber: 6),
73− 6: Table(image: #imageLiteral(resourceName: "1_6"), maxGuestNumber: 6),
74− 7: Table(image: #imageLiteral(resourceName: "1_7"), maxGuestNumber: 6),
75− 8: Table(image: #imageLiteral(resourceName: "1_8"), maxGuestNumber: 2)
76− ],
77− 2 :[
78− 2: Table(image: #imageLiteral(resourceName: "2_2"), maxGuestNumber: 9),
79− 3: Table(image: #imageLiteral(resourceName: "2_3"), maxGuestNumber: 6),
80− 4: Table(image: #imageLiteral(resourceName: "2_4"), maxGuestNumber: 2),
81− 5: Table(image: #imageLiteral(resourceName: "2_5"), maxGuestNumber: 5),
82− 6: Table(image: #imageLiteral(resourceName: "2_6"), maxGuestNumber: 5),
83− 7: Table(image: #imageLiteral(resourceName: "2_7"), maxGuestNumber: 5),
84− 8: Table(image: #imageLiteral(resourceName: "2_8"), maxGuestNumber: 2)
85− ]
86− ]
87−
88− private var phones: [Int: String] = [:] {
89− didSet {
90− let newEstablishments = phones.compactMap { el -> (Int, EstablishmentData)? in
91− if let es = establishments[el.key] {
92−
93− return (el.key, EstablishmentData(id: es.id,
94− image: es.image,
95− admin: el.value,
96− address: es.address,
97− maxTableNumber: es.maxTableNumber))
98− } else {
99− return nil
100− }
101− }
102−
103− establishments = Dictionary(uniqueKeysWithValues: newEstablishments)
104− }
105− }
106−}
107−
108−// MARK: - Nested types
109−
110−extension TotalStorage {
111−
112− struct EstablishmentData {
113− var id: Int
114− var image: UIImage
115− var admin: String
116− var address: String
117− var maxTableNumber: Int
118− }
119−
120− struct Table {
121− var image: UIImage
122− var maxGuestNumber: Int
123− }
124−}
Hookah Tau/Extensions+Date.swift+23−134
@@ -53,41 +53,46 @@ extension Date {
5353
5454 static func getDateFromCurrent(days: Int = 0, periods: Int? = nil) -> Date? {
5555 let date = Date()
56+ let calendar = Calendar.current
57+
58+ let day = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
59+
60+ var dateCalendars = DateComponents()
61+ dateCalendars.hour = day.hour!
62+ dateCalendars.minute = day.minute!
63+ dateCalendars.day = day.day!
64+ dateCalendars.month = day.month!
65+ dateCalendars.year = day.year!
66+ dateCalendars.timeZone = TimeZone(abbreviation: "GMT")
5667
57− let utcDate = date.getUTCDate()
68+ let utcDate = Calendar.current.date(from: dateCalendars)!
5869
59− let newDate = Calendar.current.date(byAdding: .day, value: days, to: utcDate)
70+ let newDate = calendar.date(byAdding: .day, value: days, to: utcDate)
6071
6172 // case if periods are important
6273 if let minutes = periods, let date = newDate {
6374 return date.changeTime(periods: minutes)
6475 }
6576
77+
6678 return newDate
6779 }
6880
69− /// Get UTC format of date
70− func getUTCDate() -> Date {
71− let calendar = Calendar.current
81+ func changeTime(periods: Int) -> Date? {
82+ let hours = (periods * 10 / 60 + 12) % 24
83+ let min = (periods * 10) % 60
84+
85+ let day = Calendar.current.dateComponents([.year, .month, .day], from: self)
7286
73− let day = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: self)
74−
7587 var dateCalendars = DateComponents()
76− dateCalendars.hour = day.hour!
77− dateCalendars.minute = day.minute!
88+ dateCalendars.hour = hours
89+ dateCalendars.minute = min
7890 dateCalendars.day = day.day!
7991 dateCalendars.month = day.month!
8092 dateCalendars.year = day.year!
8193 dateCalendars.timeZone = TimeZone(abbreviation: "GMT")
82−
83− return Calendar.current.date(from: dateCalendars)!
84− }
8594
86− func changeTime(periods: Int) -> Date? {
87− let hours = (periods * 10 / 60) % 24
88− let min = (periods * 10) % 60
89−
90− return self.set(hours: hours, minutes: min, seconds: 0)
95+ return Calendar.current.date(from: dateCalendars)
9196 }
9297
9398 func getDay() -> Int {
@@ -99,17 +104,6 @@ extension Date {
99104 return set(hours: 0, minutes: 0, seconds: 0)!
100105 }
101106
102− func addHours(_ h: Int) -> Date {
103− return self.addingTimeInterval(Double(h) * 60.0 * 60.0)
104− }
105−
106− func addPeriods(_ p: Int) -> Date {
107− let h = (p * 10 / 60) % 24
108− let m = (p * 10) % 60
109−
110− return self.addingTimeInterval(Double(h) * 60.0 * 60.0 + Double(m) * 60.0)
111− }
112−
113107 func set(hours: Int, minutes: Int, seconds: Int) -> Date? {
114108
115109 let dateFormatter = DateFormatter()
@@ -125,113 +119,8 @@ extension Date {
125119 }
126120
127121 func getMinutesPeriods(fromStart startDate: Date) -> Int {
128− let diffInMins = Calendar.current.dateComponents([.minute], from: startDate, to: self).minute!
122+ let diffInMins = Calendar.current.dateComponents([.minute], from: self, to: startDate).minute!
129123 let periods = diffInMins / 10
130124 return periods
131125 }
132−
133− func getPrevCurrentNextMonth() -> (String, String, String) {
134− let dateFormatter = DateFormatter()
135− dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
136− dateFormatter.dateFormat = "LLLL"
137− let current = dateFormatter.string(from: self)
138−
139− let nextDate = Calendar.current.date(byAdding: .month, value: 1, to: self)!
140− let next = dateFormatter.string(from: nextDate)
141−
142− let prevDate = Calendar.current.date(byAdding: .month, value: -1, to: self)!
143− let prev = dateFormatter.string(from: prevDate)
144−
145− print("\(prevDate) \(self) \(nextDate)")
146− return (prev, current, next)
147− }
148−}
149−
150−// MARK: - Admin vs Client
151−
152−extension Date {
153−
154− /// Идем на день назад, чтобы найти точку начала с которой может забронировать администратор
155− func getAdminStartingAndEndPoint() -> (Date, Date) {
156− let utcDate = self.getUTCDate()
157−
158− let startDate = Calendar.current.date(byAdding: .day, value: -1, to: utcDate)!
159− let endDate = Calendar.current.date(byAdding: .day, value: 1, to: utcDate)!
160−
161− return (startDate, endDate)
162− }
163−
164− func getAdminsStartingPoint() -> Int {
165− var calendar = Calendar.current
166− calendar.timeZone = TimeZone(abbreviation: "UTC")!
167−
168− let comp = calendar.dateComponents([.hour, .minute], from: self)
169− return (comp.hour! * 6 + comp.minute! / 10)
170− }
171−
172− func getClientStartingAndEndPoint() -> (Date, Date) {
173− // час
174− var calendar = Calendar.current
175− calendar.timeZone = TimeZone(abbreviation: "UTC")!
176−
177− let hour = calendar.dateComponents([.hour], from: self).hour!
178−
179− if hour >= 0 && hour <= 3 { // [ 00:00 ... 3:00 ]
180− let endDate = self.set(hours: 3, minutes: 0, seconds: 0)! // 3 00
181− let start = calendar.date(byAdding: .day, value: -1, to: self)!
182− let startDate = start.set(hours: 12, minutes: 0, seconds: 0)! // 12 00
183−
184− return (startDate, endDate)
185− } else { // [12:00 ... 23:50]
186− let startDate = self.set(hours: 12, minutes: 0, seconds: 0)! // 12 00
187− let end = calendar.date(byAdding: .day, value: 1, to: self)!
188− let endDate = end.set(hours: 3, minutes: 0, seconds: 0)! // 3 00
189−
190− return (startDate, endDate)
191− }
192− }
193−
194− /// Определяем попадает ли в промежуток между [3:00, 12:00)
195− func isInClosingHours() -> Bool {
196− var calendar = Calendar.current
197− calendar.timeZone = TimeZone(abbreviation: "UTC")!
198−
199− let day = calendar.dateComponents([.hour, .day, .month, .year, .minute], from: self)
200−
201− var dateCalendars = DateComponents()
202− dateCalendars.hour = 3
203− dateCalendars.minute = 0
204− dateCalendars.day = day.day!
205− dateCalendars.month = day.month!
206− dateCalendars.year = day.year!
207− dateCalendars.timeZone = TimeZone(abbreviation: "GMT")
208−
209− let startClosing = calendar.date(from: dateCalendars)!
210−
211− dateCalendars.hour = 11
212− dateCalendars.minute = 50
213−
214− let endClosing = calendar.date(from: dateCalendars)!
215−
216− let intervalClosing = DateInterval(start: startClosing, end: endClosing)
217−
218− return intervalClosing.contains(self)
219− }
220−}
221−
222−extension Date {
223− static func format(_ startDate: Date, _ endDate: Date) -> (date: String, time: String) {
224− let dateFormatter = DateFormatter()
225− dateFormatter.calendar = Calendar.current
226− dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
227− dateFormatter.dateFormat = "d MMMM"
228− dateFormatter.locale = Locale(identifier: "ru_RU")
229−
230− let dateStr = "\(dateFormatter.string(from: startDate))"
231−
232− dateFormatter.dateFormat = "HH:mm"
233− let timeStr = "\(dateFormatter.string(from: startDate)) — \(dateFormatter.string(from: endDate))"
234−
235− return (dateStr, timeStr)
236− }
237126}
Hookah Tau/Extensions+String.swiftdeleted−36
@@ -1,36 +0,0 @@
1−//
2−// Extensions+String.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 10/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−
12−extension String {
13−
14− /// Only works with 9-length strings, for ex 01 733 01 79: (2 3 2 2)
15− func formattedNumber() -> String {
16− let cleanPhoneNumber = self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
17−
18− var result = ""
19− let phoneMask = "+7 (9XX) XXX-XX-XX"
20− var index = cleanPhoneNumber.startIndex
21− for ch in phoneMask where index < cleanPhoneNumber.endIndex {
22− if ch == "X" {
23− result.append(cleanPhoneNumber[index])
24− index = cleanPhoneNumber.index(after: index)
25− } else {
26− result.append(ch)
27− }
28− }
29− return result
30− }
31−
32− /// Gets +7 9(XX) XXX-XX-XX returns XXXXXXXXX
33− func toApiPhoneNumberFormat() -> String {
34− return String(self.filter{ $0.isNumber }.dropFirst(2))
35− }
36−}
Hookah Tau/HFunc.swiftdeleted−68
@@ -1,68 +0,0 @@
1−//
2−// HFunc.swift
3−// Hookah Tau
4−//
5−// Created by cstore on 02/12/2019.
6−// Copyright © 2019 Daria Rednikina. All rights reserved.
7−//
8−
9−import Foundation
10−
11−
12−class HFunc {
13−
14− private init() {}
15−
16− static let main = HFunc()
17−
18− func exportClientsToCSV(_ arr: [Client]) -> String {
19− return arr.reduce(Client.csvHeading) { return funcToMapClientsIntoString($0, $1) }
20− }
21−
22− /// Filtering function to get every periods which intersects with given date
23− /// - Parameter periods: all periods of bookings (for a particular table)
24− /// - Parameter today: date
25− func filterPeriodsInDate(_ periods: [ReservationPeriod], _ today: Date) -> [ReservationPeriod] {
26− return periods.filter(filterPeriod(today))
27− }
28−
29−
30− /// Filtering func to get every intersecting period for the table. Useful for 2nd booning screen
31− /// - Parameter periods: Periods for the table
32− /// - Parameter start: for client 12:00, for admin t - 24h
33− /// - Parameter end: for client 3:00, for admin t + 24h
34− func filterPeriodsStartEndDates(_ periods: [ReservationPeriod], _ start: Date, _ end: Date) -> [ReservationPeriod] {
35− return periods.filter(filterInInterval(start, end))
36− }
37−
38− private func filterPeriod(_ today: Date) -> ((ReservationPeriod) -> Bool) {
39−
40− func datePredicate(_ start: Date, _ end: Date, _ current: Date) -> Bool {
41− var calendar = Calendar.current
42− calendar.timeZone = TimeZone(identifier: "GMT")!
43−
44− let result = calendar.isDate(start, equalTo: current, toGranularity: .day)
45− || calendar.isDate(end, equalTo: current, toGranularity: .day)
46−
47− return result
48− }
49−
50− return { (period: ReservationPeriod) in datePredicate(period.startTime, period.endTime, today) }
51− }
52−
53− private func filterInInterval(_ start: Date, _ end: Date) -> ((ReservationPeriod) -> Bool) {
54−
55− let dateInterval = DateInterval(start: start, end: end)
56− func intervalChecking(_ sp: Date, _ ep: Date) -> Bool {
57− let innerInterval = DateInterval(start: sp, end: ep)
58−
59− return dateInterval.intersects(innerInterval)
60− }
61−
62− return { (period: ReservationPeriod) in intervalChecking(period.startTime, period.endTime) }
63− }
64−
65− private func funcToMapClientsIntoString(_ acc: String, _ el: Client) -> String {
66− return acc + el.toString + "\n"
67− }
68−}
Hookah Tau/Info.plist+3−5
@@ -2,6 +2,8 @@
22<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33<plist version="1.0">
44<dict>
5+ <key>UIUserInterfaceStyle</key>
6+ <string>Ligth</string>
57 <key>CFBundleDevelopmentRegion</key>
68 <string>$(DEVELOPMENT_LANGUAGE)</string>
79 <key>CFBundleExecutable</key>
@@ -17,9 +19,7 @@
1719 <key>CFBundleShortVersionString</key>
1820 <string>1.0</string>
1921 <key>CFBundleVersion</key>
20− <string>$(CURRENT_PROJECT_VERSION)</string>
21− <key>ITSAppUsesNonExemptEncryption</key>
22− <false/>
22+ <string>1</string>
2323 <key>LSRequiresIPhoneOS</key>
2424 <true/>
2525 <key>UILaunchStoryboardName</key>
@@ -39,7 +39,5 @@
3939 <string>UIInterfaceOrientationLandscapeLeft</string>
4040 <string>UIInterfaceOrientationLandscapeRight</string>
4141 </array>
42− <key>UIUserInterfaceStyle</key>
43− <string>Light</string>
4442</dict>
4543</plist>
Hookah Tau/Models/AllReservations.swift+17−8
@@ -9,8 +9,8 @@
99import Foundation
1010
1111struct AllReservations: MyCodable {
12− var reservations: [Int: [ReservationPeriod]]
13− var intervals: [Date: [Int]]
12+ var reservations: [Int: [Date: [ReservationPeriod]]]
13+ var intervals: [Date: [Date: [Int]]]
1414
1515 enum CodingKeys: CodingKey {
1616 case reservations
@@ -20,20 +20,29 @@ struct AllReservations: MyCodable {
2020 init(from decoder: Decoder) throws {
2121 let container = try decoder.container(keyedBy: CodingKeys.self)
2222
23− let intervalsWithStr = try container.decode([String: [Int]].self, forKey: .intervals)
24− reservations = try container.decode([Int: [ReservationPeriod]].self, forKey: .reservations)
23+ let intervalsWithStr = try container.decode([String: [String: [Int]]].self, forKey: .intervals)
24+ let reservationWithStr = try container.decode([String: [String: [ReservationPeriod]]].self, forKey: .reservations)
2525
26− let intervArray = intervalsWithStr.map { (element) -> (Date, [Int]) in
27− let key = DateFormatter.iso8601Full.date(from: element.key)!
28− return (key, element.value)
26+ let resArray = reservationWithStr.map { (element) -> (Int, [Date: [ReservationPeriod]]) in
27+ let key = Int(element.key) ?? 0
28+ let valArr = element.value.compactMap { (DateFormatter.dmy.date(from: $0.0)!, $0.1) }
29+ let val = Dictionary(uniqueKeysWithValues: valArr)
30+ return (key, val)
31+ }
32+
33+ let intervArray = intervalsWithStr.map { (element) -> (Date, [Date: [Int]]) in
34+ let key = DateFormatter.dmy.date(from: element.key)!
35+ let arr = element.value.compactMap { (DateFormatter.iso8601Full.date(from: $0.0)!, $0.1) }
36+ let val = Dictionary(uniqueKeysWithValues: arr)
37+ return (key, val)
2938 }
3039
3140 intervals = Dictionary(uniqueKeysWithValues: intervArray)
41+ reservations = Dictionary(uniqueKeysWithValues: resArray)
3242 }
3343}
3444
3545struct ReservationPeriod: MyCodable {
3646 var startTime: Date
3747 var duration: Int
38− var endTime: Date
3948}
Hookah Tau/Models/Reservation.swift+3−69
@@ -11,77 +11,11 @@ import Foundation
1111
1212struct Reservation: MyCodable {
1313
14− var uuid: String
14+ var uuid: UUID
1515 var establishment: Int
16− var startTime: Date
17− var endTime: Date
16+ var startTime: String
17+ var endTime: String
1818 var numberOfGuests: Int
1919 var reservedTable: Int
2020
21− init(uuid: String, reservationData: ReservationData) {
22− self.uuid = uuid
23− self.establishment = reservationData.establishment
24− self.startTime = reservationData.startTime
25− self.endTime = reservationData.endTime
26− self.numberOfGuests = reservationData.numberOfGuests
27− self.reservedTable = reservationData.reservedTable
28− }
29−
30− init(uuid: String, establishment: Int, startTime: Date, endTime: Date, numberOfGuests: Int, reservedTable: Int) {
31− self.uuid = uuid
32− self.establishment = establishment
33− self.startTime = startTime
34− self.endTime = endTime
35− self.numberOfGuests = numberOfGuests
36− self.reservedTable = reservedTable
37− }
38−}
39−
40−/// `Reservation` without `uuid`
41−struct ReservationData: MyCodable {
42−
43− var establishment: Int
44− var startTime: Date
45− var endTime: Date
46− var numberOfGuests: Int
47− var reservedTable: Int
48−
49−}
50−
51−/// Структура для получения респонса на `GET /admin/reservations/{establishment id}`
52−struct ReservationWithUser: MyCodable {
53−
54− var uuid: String?
55− var establishment: Int
56− var startTime: Date
57− var endTime: Date
58− var numberOfGuests: Int
59− var reservedTable: Int
60− var owner: FullUser
61−
62− init(reservation: Reservation, user: FullUser) {
63− self.uuid = reservation.uuid
64− self.establishment = reservation.establishment
65− self.startTime = reservation.startTime
66− self.endTime = reservation.endTime
67− self.numberOfGuests = reservation.numberOfGuests
68− self.reservedTable = reservation.reservedTable
69− self.owner = user
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− }
81−}
82−
83−struct AdminCreateReservation: MyCodable {
84− var reservation: ReservationData
85− var user: String
8621}
87−
Hookah Tau/Models/User.swift−27
@@ -8,35 +8,8 @@
88
99import Foundation
1010
11−/// Используется в запросах при регистрации пользователя
1211struct User: MyCodable {
1312 var name: String
1413 var phoneNumber: String
1514 var isAdmin: Bool
1615}
17−
18−/// При запросах на список пользователей в аккаунте администратора.
19−struct FullUser: MyCodable {
20− var uuid: String?
21− var name: String?
22− var phoneNumber: String
23− var isAdmin: Bool
24−}
25−
26−/// `GET /admin/clients`
27−struct Client: MyCodable {
28− var uuid: String
29− var name: String?
30− var phoneNumber: String
31− var isAdmin: Bool
32− var reservationCount: Int
33− var isBlocked: Bool
34−
35− static var csvHeading: String {
36− return "uuid, имя, телефон, админ, количество активных бронирований, в черном списке\n"
37− }
38−
39− var toString: String {
40− return "\(uuid), \(name ?? "❔"), +79\(phoneNumber), \(isAdmin), \(reservationCount), \(isBlocked)"
41− }
42−}
Hookah Tau/Supporting Files/Assets.xcassets/1.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "place 1.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/1.imageset/place 1.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/1_1.imageset/1_1.pdfdeleted

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/1_8.imageset/Contents.jsondeleted−12
@@ -1,12 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "1_8.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− }
12−}
Hookah Tau/Supporting Files/Assets.xcassets/2.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "place 2.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/2.imageset/place 2.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/2_2.imageset/2_2.pdfdeleted

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/2_8.imageset/Contents.jsondeleted−12
@@ -1,12 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "2_8.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− }
12−}
Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/1024.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/120-1.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/120.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/152.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/167.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/180.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/20.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/29.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/40-1.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/40-2.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/40.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/58-1.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/58.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/60.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/76.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/80-1.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/80.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/87.pngdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json+18−36
@@ -1,111 +1,93 @@
11{
22 "images" : [
33 {
4− "size" : "20x20",
54 "idiom" : "iphone",
6− "filename" : "40-1.png",
5+ "size" : "20x20",
76 "scale" : "2x"
87 },
98 {
10− "size" : "20x20",
119 "idiom" : "iphone",
12− "filename" : "60.png",
10+ "size" : "20x20",
1311 "scale" : "3x"
1412 },
1513 {
16− "size" : "29x29",
1714 "idiom" : "iphone",
18− "filename" : "58-1.png",
15+ "size" : "29x29",
1916 "scale" : "2x"
2017 },
2118 {
22− "size" : "29x29",
2319 "idiom" : "iphone",
24− "filename" : "87.png",
20+ "size" : "29x29",
2521 "scale" : "3x"
2622 },
2723 {
28− "size" : "40x40",
2924 "idiom" : "iphone",
30− "filename" : "80.png",
25+ "size" : "40x40",
3126 "scale" : "2x"
3227 },
3328 {
34− "size" : "40x40",
3529 "idiom" : "iphone",
36− "filename" : "120.png",
30+ "size" : "40x40",
3731 "scale" : "3x"
3832 },
3933 {
40− "size" : "60x60",
4134 "idiom" : "iphone",
42− "filename" : "120-1.png",
35+ "size" : "60x60",
4336 "scale" : "2x"
4437 },
4538 {
46− "size" : "60x60",
4739 "idiom" : "iphone",
48− "filename" : "180.png",
40+ "size" : "60x60",
4941 "scale" : "3x"
5042 },
5143 {
52− "size" : "20x20",
5344 "idiom" : "ipad",
54− "filename" : "20.png",
45+ "size" : "20x20",
5546 "scale" : "1x"
5647 },
5748 {
58− "size" : "20x20",
5949 "idiom" : "ipad",
60− "filename" : "40.png",
50+ "size" : "20x20",
6151 "scale" : "2x"
6252 },
6353 {
64− "size" : "29x29",
6554 "idiom" : "ipad",
66− "filename" : "29.png",
55+ "size" : "29x29",
6756 "scale" : "1x"
6857 },
6958 {
70− "size" : "29x29",
7159 "idiom" : "ipad",
72− "filename" : "58.png",
60+ "size" : "29x29",
7361 "scale" : "2x"
7462 },
7563 {
76− "size" : "40x40",
7764 "idiom" : "ipad",
78− "filename" : "40-2.png",
65+ "size" : "40x40",
7966 "scale" : "1x"
8067 },
8168 {
82− "size" : "40x40",
8369 "idiom" : "ipad",
84− "filename" : "80-1.png",
70+ "size" : "40x40",
8571 "scale" : "2x"
8672 },
8773 {
88− "size" : "76x76",
8974 "idiom" : "ipad",
90− "filename" : "76.png",
75+ "size" : "76x76",
9176 "scale" : "1x"
9277 },
9378 {
94− "size" : "76x76",
9579 "idiom" : "ipad",
96− "filename" : "152.png",
80+ "size" : "76x76",
9781 "scale" : "2x"
9882 },
9983 {
100− "size" : "83.5x83.5",
10184 "idiom" : "ipad",
102− "filename" : "167.png",
85+ "size" : "83.5x83.5",
10386 "scale" : "2x"
10487 },
10588 {
106− "size" : "1024x1024",
10789 "idiom" : "ios-marketing",
108− "filename" : "1024.png",
90+ "size" : "1024x1024",
10991 "scale" : "1x"
11092 }
11193 ],
Hookah Tau/Supporting Files/Assets.xcassets/Group.imageset/Group.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/Group.imageset/Contents.json → Hookah Tau/Supporting Files/Assets.xcassets/Map.imageset/Contents.jsonrenamed+1−1
@@ -2,7 +2,7 @@
22 "images" : [
33 {
44 "idiom" : "universal",
5− "filename" : "Group.pdf"
5+ "filename" : "Map.pdf"
66 }
77 ],
88 "info" : {
Hookah Tau/Supporting Files/Assets.xcassets/Map.imageset/Map.pdfnew file

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/arrow.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "arrow.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/arrow.imageset/arrow.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/blacklist.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "blacklist.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/blacklist.imageset/blacklist.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/handle_left.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "handle.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/handle_left.imageset/handle.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/map_1.imageset/Contents.json−3
@@ -8,8 +8,5 @@
88 "info" : {
99 "version" : 1,
1010 "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
1411 }
1512}
Hookah Tau/Supporting Files/Assets.xcassets/map_2.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "place 2.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/map_2.imageset/place 2.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/peoplee.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "peoplee.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "template-rendering-intent" : "template"
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/peoplee.imageset/peoplee.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/person.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "person.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "template-rendering-intent" : "template"
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/person.imageset/person.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/phone.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "Medium-M.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/phone.imageset/Medium-M.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/stack.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "Light-S.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "template-rendering-intent" : "template"
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/stack.imageset/Light-S.pdfdeleted

Binary file not shown.

Hookah Tau/Supporting Files/Assets.xcassets/stack2.imageset/Contents.jsondeleted−15
@@ -1,15 +0,0 @@
1−{
2− "images" : [
3− {
4− "idiom" : "universal",
5− "filename" : "stack2.pdf"
6− }
7− ],
8− "info" : {
9− "version" : 1,
10− "author" : "xcode"
11− },
12− "properties" : {
13− "preserves-vector-representation" : true
14− }
15−}
Hookah Tau/Supporting Files/Assets.xcassets/stack2.imageset/stack2.pdfdeleted

Binary file not shown.

Hookah Tau/Views/Phone/PhoneView.swift+2−1
@@ -24,8 +24,9 @@ class PhoneView: UIView {
2424 phone?.attributedPlaceholder = NSAttributedString(string:"+ 7 (901) 733 01 79", attributes: [NSAttributedString.Key.foregroundColor: UIColor.lightGray])
2525 }
2626
27+ // TODO: - change in future
2728 func bind(withModel model: String) {
28− phone?.text = model.formattedNumber()
29+ phone?.text = model
2930 }
3031}
3132