git.iko.soy/dashared/hookah-tau
on develop help sign in
Добавила фильтрацию на даты, подстроилась под новую структуру с reservations/all

куча всего в общем

commitf964fc98b51012f07ccd40d59f9c9361344b8ca1 authorDarya Rednikina <rednikina.com@yandex.ru> dateMon 2 Dec 2019, 21:16 (7 years ago) parente8a990c
20 files changed+320−84
Hookah Tau.xcodeproj/project.pbxproj+20 Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsCoordinator.swift+14 Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsViewController.swift+23−2 Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationView.swift+19−1 Hookah Tau/Controllers/Client/Reservations/Maps/MapView.swift+1 Hookah Tau/Controllers/Client/Reservations/Reservation.storyboard+3−3 Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepReservationViewController.swift+5−4 Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepView.swift+15−6 Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepReservationCoordinator.swift+4−8 Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepReservationViewController.swift+8−1 Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepReservationCoordinator.swift+14−8 Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepReservationViewController.swift+80−10 Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepView.swift+23−2 Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepView.xib+6−6 Hookah Tau/Controllers/Client/Reservations/Steps/change /ChangeReservationCoordinator.swift+13 Hookah Tau/Controllers/Client/Reservations/Steps/change /ChangeReservationViewController.swift+19 Hookah Tau/Extensions+Date.swift+2−12 Hookah Tau/HFunc.swift+39 Hookah Tau/Models/AllReservations.swift+8−17 Hookah Tau/Models/Reservation.swift+4−4
Hookah Tau.xcodeproj/project.pbxproj+20
@@ -36,6 +36,9 @@
3636 124D007C23721FD400AE76B9 /* Reservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007B23721FD400AE76B9 /* Reservation.swift */; };
3737 124D007F237222B200AE76B9 /* ReservationsResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D007E237222B200AE76B9 /* ReservationsResolver.swift */; };
3838 124D0081237222C900AE76B9 /* ReservationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124D0080237222C900AE76B9 /* ReservationsService.swift */; };
39+ 125AE51D2395583E00F847BD /* ChangeReservationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */; };
40+ 125AE51F2395585300F847BD /* ChangeReservationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */; };
41+ 125AE5212395753400F847BD /* HFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125AE5202395753400F847BD /* HFunc.swift */; };
3942 12838EA9236764A600CEF108 /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EA8236764A600CEF108 /* APIClient.swift */; };
4043 12838EAC2367689600CEF108 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 12838EAB2367689600CEF108 /* Alamofire */; };
4144 12838EAE2367701300CEF108 /* AuthorizationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12838EAD2367701300CEF108 /* AuthorizationService.swift */; };
@@ -156,6 +159,9 @@
156159 124D007B23721FD400AE76B9 /* Reservation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reservation.swift; sourceTree = "<group>"; };
157160 124D007E237222B200AE76B9 /* ReservationsResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsResolver.swift; sourceTree = "<group>"; };
158161 124D0080237222C900AE76B9 /* ReservationsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservationsService.swift; sourceTree = "<group>"; };
162+ 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationCoordinator.swift; sourceTree = "<group>"; };
163+ 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeReservationViewController.swift; sourceTree = "<group>"; };
164+ 125AE5202395753400F847BD /* HFunc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HFunc.swift; sourceTree = "<group>"; };
159165 12838EA8236764A600CEF108 /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = "<group>"; };
160166 12838EAD2367701300CEF108 /* AuthorizationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorizationService.swift; sourceTree = "<group>"; };
161167 12838EAF236777D400CEF108 /* ServerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerError.swift; sourceTree = "<group>"; };
@@ -420,6 +426,15 @@
420426 path = Resolvers;
421427 sourceTree = "<group>";
422428 };
429+ 125AE51B2395582900F847BD /* change */ = {
430+ isa = PBXGroup;
431+ children = (
432+ 125AE51C2395583E00F847BD /* ChangeReservationCoordinator.swift */,
433+ 125AE51E2395585300F847BD /* ChangeReservationViewController.swift */,
434+ );
435+ path = "change ";
436+ sourceTree = "<group>";
437+ };
423438 12838EB923679AEB00CEF108 /* API */ = {
424439 isa = PBXGroup;
425440 children = (
@@ -448,6 +463,7 @@
448463 12BD95B3237EC231009614D8 /* Steps */ = {
449464 isa = PBXGroup;
450465 children = (
466+ 125AE51B2395582900F847BD /* change */,
451467 12230AEF239008F8004A01E5 /* Common */,
452468 12BD95B4237EC23A009614D8 /* 1 */,
453469 12F9652823868E4900FCA696 /* 2 */,
@@ -702,6 +718,7 @@
702718 F31E20C62348DDB900BEA215 /* Extensions+UIView.swift */,
703719 12050568238048CE00801618 /* Extensions+Date.swift */,
704720 1205056A2380588C00801618 /* Extenstions+IBDesignable.swift */,
721+ 125AE5202395753400F847BD /* HFunc.swift */,
705722 12838EB923679AEB00CEF108 /* API */,
706723 F30369BC2336861100A8EA84 /* Models */,
707724 F3199E59233FD7F700F3C17A /* Views */,
@@ -895,6 +912,7 @@
895912 123615D12355141600D1122A /* ProfileView.swift in Sources */,
896913 12F73B022357AD7B007D4476 /* ProfileChangeViewController.swift in Sources */,
897914 F3851B2E2340A444009EE0B6 /* TitleTextView.swift in Sources */,
915+ 125AE51F2395585300F847BD /* ChangeReservationViewController.swift in Sources */,
898916 12EA99462362B674005D9FE9 /* AddressCoordinator.swift in Sources */,
899917 12B6A613235B9B4300898B31 /* BaseViewController.swift in Sources */,
900918 12230AFA23901029004A01E5 /* DataStorage.swift in Sources */,
@@ -910,6 +928,7 @@
910928 12219CEF2353A63F0057DDEE /* ReservationsCoordinator.swift in Sources */,
911929 12230AF423900BCB004A01E5 /* EstablishmentService.swift in Sources */,
912930 12A07601237359BB00D749BB /* MapView1.swift in Sources */,
931+ 125AE5212395753400F847BD /* HFunc.swift in Sources */,
913932 12BD95B8237EDB01009614D8 /* TimePointView.swift in Sources */,
914933 12838EB2236779A000CEF108 /* AuthResolver.swift in Sources */,
915934 12A075F72373535C00D749BB /* FirstStepReservationViewController.swift in Sources */,
@@ -962,6 +981,7 @@
962981 12FC40382382C93D00AB593B /* TableButtonStyle.swift in Sources */,
963982 12D8FA31237F08C700305F57 /* AllReservations.swift in Sources */,
964983 12838EB0236777D400CEF108 /* ServerError.swift in Sources */,
984+ 125AE51D2395583E00F847BD /* ChangeReservationCoordinator.swift in Sources */,
965985 );
966986 runOnlyForDeploymentPostprocessing = 0;
967987 };
Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsCoordinator.swift+14
@@ -29,4 +29,18 @@ 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] map in
40+ self?.removeDependency(thirdStepRCoordinator)
41+ self?.navigationController?.popViewController(animated: true)
42+ }
43+
44+ thirdStepRCoordinator.start()
45+ }
3246}
Hookah Tau/Controllers/Client/Reservations/Active Reservations/ReservationsViewController.swift+23−2
@@ -19,8 +19,10 @@ class ReservationsViewController: BaseViewController {
1919 guard let empty = noReservationsView else { return }
2020 if activeReservations.isEmpty {
2121 contentView.bringSubviewToFront(empty)
22+ empty.alpha = 1
2223 } else {
2324 contentView.sendSubviewToBack(empty)
25+ tableView?.alpha = 1
2426 }
2527
2628 tableView?.reloadData()
@@ -54,11 +56,21 @@ class ReservationsViewController: BaseViewController {
5456
5557 reservationsService = ReservationsService(apiClient: APIClient.shared)
5658
57− performUpdate()
58−
5959 setUpContentView()
6060 }
6161
62+ override func viewWillAppear(_ animated: Bool) {
63+ super.viewWillAppear(animated)
64+
65+ tabBarController?.tabBar.isHidden = false
66+ }
67+
68+ override func viewDidAppear(_ animated: Bool) {
69+ super.viewDidAppear(animated)
70+
71+ performUpdate()
72+ }
73+
6274 // MARK: - Setup
6375
6476 func setUpContentView() {
@@ -68,6 +80,8 @@ class ReservationsViewController: BaseViewController {
6880 noReservationsView = NoReservationsView.loadFromNib()
6981 contentView.addSubviewThatFills(noReservationsView)
7082 noReservationsView?.makeReservationButton?.addTarget(self, action: #selector(tapToMakeReservation), for: .touchUpInside)
83+
84+ noReservationsView?.alpha = 0
7185
7286 // table
7387 contentView.addSubviewThatFills(tableView)
@@ -79,6 +93,8 @@ class ReservationsViewController: BaseViewController {
7993 tableView?.delegate = self
8094 tableView?.dataSource = self
8195
96+ tableView?.alpha = 0
97+
8298 tableView?.register(ReservationCell.self, forCellReuseIdentifier: reservationCell)
8399 }
84100
@@ -135,6 +151,11 @@ extension ReservationsViewController: UITableViewDelegate, UITableViewDataSource
135151 return cell
136152 }
137153
154+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
155+ let reservation = activeReservations[indexPath.row]
156+ coordinator?.viewReservation(reservation)
157+ }
158+
138159 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
139160 return UITableView.automaticDimension
140161 }
Hookah Tau/Controllers/Client/Reservations/Cells/Reservation/ReservationView.swift+19−1
@@ -29,7 +29,25 @@ class ReservationView: UIView {
2929
3030 tableImageView?.image = table.image
3131 adressLabel?.text = establishment.address
32− maxPeopleLabel?.text = "\(model.numberOfGuests) человека"
32+ maxPeopleLabel?.text = "\(model.numberOfGuests) " + (2...4 ~= model.numberOfGuests ? "человека" : "человек")
33+
34+ let (date, time) = format(model.startTime, model.endTime)
35+ dateLabel?.text = date
36+ timeLabel?.text = time
3337 }
3438
39+ private func format(_ startDate: Date, _ endDate: Date) -> (date: String, time: String) {
40+ let dateFormatter = DateFormatter()
41+ dateFormatter.calendar = Calendar.current
42+ dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
43+ dateFormatter.dateFormat = "d MMMM"
44+ dateFormatter.locale = Locale(identifier: "ru_RU")
45+
46+ let dateStr = "\(dateFormatter.string(from: startDate))"
47+
48+ dateFormatter.dateFormat = "HH:mm"
49+ let timeStr = "\(dateFormatter.string(from: startDate)) — \(dateFormatter.string(from: endDate))"
50+
51+ return (dateStr, timeStr)
52+ }
3553}
Hookah Tau/Controllers/Client/Reservations/Maps/MapView.swift+1
@@ -26,6 +26,7 @@ class MapImageScroll: UIView {
2626 func scrollToTable(table: Int) {
2727 guard let tableButton = tables[table] else { return }
2828
29+ tableButton.select()
2930 img.bringSubviewToFront(shadowView)
3031 img.bringSubviewToFront(tableButton)
3132
Hookah Tau/Controllers/Client/Reservations/Reservation.storyboard+3−3
@@ -81,14 +81,14 @@
8181 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
8282 <subviews>
8383 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e2X-iN-FVj">
84− <rect key="frame" x="0.0" y="502" width="414" height="394"/>
84+ <rect key="frame" x="0.0" y="556" width="414" height="340"/>
8585 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
8686 <constraints>
87− <constraint firstAttribute="height" constant="394" id="5U9-DA-Asv"/>
87+ <constraint firstAttribute="height" constant="340" id="5U9-DA-Asv"/>
8888 </constraints>
8989 </view>
9090 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lUx-gC-C8T">
91− <rect key="frame" x="0.0" y="44" width="414" height="458"/>
91+ <rect key="frame" x="0.0" y="44" width="414" height="512"/>
9292 <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
9393 </view>
9494 </subviews>
Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepReservationViewController.swift+5−4
@@ -129,7 +129,7 @@ class FirstStepReservationViewController: BaseViewController {
129129 }
130130
131131 func updateChildViewControllerWithChosenId(_ id: Int) {
132− let reservationsForTable = allReservations?.reservations[id] ?? [:]
132+ let reservationsForTable = allReservations?.reservations[id] ?? []
133133 firstStepView?.setUp(reservationsForTable)
134134 }
135135
@@ -138,9 +138,10 @@ class FirstStepReservationViewController: BaseViewController {
138138 @objc func continueBooking() {
139139 let map = mapView
140140
141− guard let startTime = firstStepView?.fullDate else { return }
141+ guard let startTime = firstStepView?.fullDate else { return }
142142
143− let reservPeriods = allReservations?.reservations[tableId]?[startTime.getDMY()] ?? []
143+ let reservPeriods = HFunc.main.filterPeriodsInDate(allReservations?.reservations[tableId] ?? [],
144+ startTime)
144145
145146 let model = SecondStepModel(establishment: establishmentId,
146147 table: tableId,
@@ -169,7 +170,7 @@ extension FirstStepReservationViewController: MapHandler {
169170
170171extension FirstStepReservationViewController: MapUpdater {
171172 func update(_ date: Date) {
172− let areBooked = allReservations?.intervals[date.getDMY()]?[date] ?? []
173+ let areBooked = allReservations?.intervals[date] ?? []
173174
174175 if Set(areBooked).contains(tableId) {
175176 continueButton.availiable = false
Hookah Tau/Controllers/Client/Reservations/Steps/1/FirstStepView.swift+15−6
@@ -50,17 +50,21 @@ class FirstStepView: UIView {
5050 guard
5151 let date = fullDate?.getDMY()
5252 else { return }
53− setUpBookingsForIntervals(reservations: bookingsForDates[date] ?? [])
53+
54+ let bookings = HFunc.main.filterPeriodsInDate(bookingsForDates, date)
55+ setUpBookingsForIntervals(reservations: bookings)
5456 }
5557 }
5658
57− var bookingsForDates: [Date: [ReservationPeriod]] = [:] {
59+ var bookingsForDates: [ReservationPeriod] = [] {
5860 didSet {
5961 guard
6062 let date = fullDate?.getDMY()
6163 else { return }
6264
63− setUpBookingsForIntervals(reservations: bookingsForDates[date] ?? [])
65+ let bookings = HFunc.main.filterPeriodsInDate(bookingsForDates, date)
66+
67+ setUpBookingsForIntervals(reservations: bookings)
6468 }
6569 }
6670
@@ -158,7 +162,12 @@ class FirstStepView: UIView {
158162 let d = reservation.duration * Constants.widthTimePoint
159163
160164 let startTime = s < 0 ? 0 : s
161− let duration = (s + d) > Constants.widthOfIntervals ? Constants.widthOfIntervals - s : d
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+ }
162171
163172 NSLayoutConstraint.activate([
164173 uiview.bottomAnchor.constraint(equalToSystemSpacingBelow: scrollViewIntervals.bottomAnchor, multiplier: 0),
@@ -184,14 +193,14 @@ class FirstStepView: UIView {
184193
185194 datesScrollView.setContentOffset(CGPoint(x: abs(Constants.widthDate * Constants.daysCount / 2 - Int(edges.left)) + 8, y: 0),
186195 animated: true)
187− scrollViewIntervals.setContentOffset(CGPoint(x: abs(Constants.widthTimePoint * Constants.day10MinPeriods / 2 - Int(edges.left)) + 5, y: 0),
196+ scrollViewIntervals.setContentOffset(CGPoint(x: abs(Constants.widthTimePoint * Constants.day10MinPeriods / 2 - Int(edges.left)) + 7, y: 0),
188197 animated: true)
189198 }
190199
191200
192201 /// Method for setting up `stackViewIntervals` with appropriate busy intervals of chosen table
193202 /// - Parameter data: Map of booked periods by key - date - is provided
194− func setUp(_ data: [Date: [ReservationPeriod]]) {
203+ func setUp(_ data: [ReservationPeriod]) {
195204 bookingsForDates = data
196205 }
197206
Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepReservationCoordinator.swift+4−8
@@ -19,6 +19,8 @@ class SecondStepReservationCoordinator: BaseCoordinator {
1919
2020 var mapView: MapImageScroll?
2121
22+ var onBooking: ((MapImageScroll, Reservation) -> Void)?
23+
2224 var vc: SecondStepReservationViewController?
2325
2426 // MARK: - Lifecycle
@@ -40,7 +42,7 @@ class SecondStepReservationCoordinator: BaseCoordinator {
4042 didFinish?(mapView)
4143 }
4244
43− func book() {
45+ func book(_ mapView: MapImageScroll?) {
4446 let coordinator = ThirdStepReservationCoordinator(navigationController: navigationController)
4547 addDependency(coordinator)
4648
@@ -52,13 +54,7 @@ class SecondStepReservationCoordinator: BaseCoordinator {
5254 }
5355 }
5456
55− coordinator.wantsToBeChanged = { [weak self] reservation in
56− self?.navigationController?.popViewController(animated: false)
57− self?.removeDependency(coordinator)
58−
59−
60− }
61−
57+ coordinator.mapView = mapView
6258 coordinator.start()
6359 }
6460}
Hookah Tau/Controllers/Client/Reservations/Steps/2/SecondStepReservationViewController.swift+8−1
@@ -65,6 +65,13 @@ class SecondStepReservationViewController: BaseViewController {
6565
6666 }
6767
68+ override func viewWillAppear(_ animated: Bool) {
69+ super.viewWillAppear(animated)
70+
71+ tabBarController?.tabBar.isHidden = true
72+ }
73+
74+
6875 // MARK: - Setup
6976
7077 func setupNavBar() {
@@ -122,6 +129,6 @@ class SecondStepReservationViewController: BaseViewController {
122129 }
123130
124131 @objc func book() {
125− coordinator?.book()
132+ coordinator?.book(mapView)
126133 }
127134}
Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepReservationCoordinator.swift+14−8
@@ -12,12 +12,12 @@ class ThirdStepReservationCoordinator: BaseCoordinator {
1212
1313 // MARK: - Properties
1414
15− var didFinish: ((MapImageScroll) -> Void)?
15+ var didFinish: ((MapImageScroll?) -> Void)?
1616
17− /// callback to change created booking
18− var wantsToBeChanged: ((Reservation) -> Void)?
17+ var mapView: MapImageScroll?
1918
20− var mapView: UIView?
19+ /// Объект регистрации, созданной или существующей
20+ var resrvation: Reservation?
2121
2222 // MARK: - Lifecycle
2323
@@ -26,13 +26,19 @@ class ThirdStepReservationCoordinator: BaseCoordinator {
2626 let reservationVC = storyboard.instantiateViewController(withIdentifier: "ThirdStepReservationViewController") as! ThirdStepReservationViewController
2727
2828 reservationVC.coordinator = self
29−
29+ reservationVC.mapView = mapView
30+ reservationVC.reservation = resrvation
3031
3132 navigationController?.pushViewController(reservationVC, animated: false)
3233 }
3334
34− /// You need to pass `uuid` of the booking to be changed
35− func change(_ reservation: Reservation) {
36− wantsToBeChanged?(reservation)
35+ /// You need to pass reservation object and map describing booked table
36+ func change(_ reservation: Reservation, _ map: MapImageScroll) {
37+ //
38+ }
39+
40+ /// Goes back to `allReservations` screen
41+ func close() {
42+ didFinish?(nil)
3743 }
3844}
Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepReservationViewController.swift+80−10
@@ -9,27 +9,42 @@
99import UIKit
1010
1111class ThirdStepReservationViewController: BaseViewController {
12+
13+ // MARK: - IBAOutlets
1214
1315 @IBOutlet weak var containerView: UIView!
1416
17+ @IBOutlet weak var contentForMap: UIView!
18+
19+ // MARK: - Properties
20+
21+ var mapView: MapImageScroll?
22+
1523 weak var coordinator: ThirdStepReservationCoordinator?
1624
1725 var thirdStepView: ThirdStepView?
1826
19− @IBOutlet weak var contentForMap: UIView!
20−
21− var mapView: MapImageScroll?
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+ }
2236
23− var reservation: Reservation?
37+ var reservationService: ReservationsService?
2438
39+ /// "Отменить бронь"
2540 let cancelButton: Button = {
2641 let button = Button()
2742 let style = BlackButtonStyle()
2843 style.apply(to: button, withTitle: "ОТМЕНИТЬ БРОНЬ")
29− //button.addTarget(self, action: #selector(doneChanging), for: .touchUpInside)
3044 return button
3145 }()
3246
47+ /// "Изменить бронь"
3348 let changeButton: Button = {
3449 let button = Button()
3550 let style = BlackButtonStyle()
@@ -37,6 +52,8 @@ class ThirdStepReservationViewController: BaseViewController {
3752 return button
3853 }()
3954
55+ // MARK: - Lifecycle
56+
4057 override func viewDidLoad() {
4158 super.viewDidLoad()
4259
@@ -44,17 +61,49 @@ class ThirdStepReservationViewController: BaseViewController {
4461 setupContainer()
4562 setupButtons()
4663 setupMap()
64+
65+ reservationService = ReservationsService(apiClient: APIClient.shared)
66+ }
67+
68+ override func viewWillAppear(_ animated: Bool) {
69+ super.viewWillAppear(animated)
70+
71+ tabBarController?.tabBar.isHidden = true
4772 }
73+
74+ // MARK: - Setup
4875
4976 func setupMap() {
77+ guard let reservation = reservation else {
78+ return
79+ }
80+
81+ if reservation.establishment == 1 {
82+ mapView = MapView1.loadFromNib()
83+ } else {
84+ mapView = MapView2.loadFromNib()
85+ }
86+
5087 contentForMap.addSubviewThatFills(mapView)
88+
89+ let width = view.frame.width
90+ mapView?.scrollViewParent.contentInset = UIEdgeInsets(top: 0,
91+ left: width / 2,
92+ bottom: 300,
93+ right: width / 2)
94+
95+ mapView?.scrollViewParent.setContentOffset(CGPoint(x: 0, y: -100), animated: false)
96+
97+ mapView?.isUserInteractionEnabled = false
98+ mapView?.scrollToTable(table: reservation.reservedTable)
5199 }
52100
53101 func setupContainer() {
54102 thirdStepView = ThirdStepView.loadFromNib()
55103 containerView.addSubviewThatFills(thirdStepView)
56−// guard let model = model else { return }
57−// thirdStepView?.bind(withModel: model)
104+
105+ guard let res = reservation else { return }
106+ thirdStepView?.bind(withModel: res)
58107 }
59108
60109 func setupButtons() {
@@ -63,17 +112,38 @@ class ThirdStepReservationViewController: BaseViewController {
63112 constant: -containerView.frame.height - 20)
64113
65114 changeButton.addTarget(self, action: #selector(change), for: .touchUpInside)
115+ cancelButton.addTarget(self, action: #selector(cancelBooking), for: .touchUpInside)
116+ thirdStepView?.closeButton.addTarget(self, action: #selector(close), for: .touchUpInside)
66117 }
67118
68119
69120 // MARK: - handlers for buttons
70121
71122 @objc func change() {
72− guard let res = reservation else { return }
73− coordinator?.change(res)
123+ guard
124+ let res = reservation,
125+ let map = mapView
126+ else { return }
127+
128+ coordinator?.change(res, map)
74129 }
75130
76− @objc func cancel() {
131+ @objc func cancelBooking() {
132+ guard let res = reservation else { return }
77133
134+ cancelButton.loading = true
135+ reservationService?.deleteReservation(uuid: res.uuid, completion: { [weak self] (result) in
136+ self?.cancelButton.loading = false
137+
138+ if result {
139+ self?.close()
140+ } else {
141+ self?.displayAlert(with: "Не удалось отменить бронь, попробуйте еще раз!")
142+ }
143+ })
144+ }
145+
146+ @objc func close() {
147+ coordinator?.close()
78148 }
79149}
Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepView.swift+23−2
@@ -25,11 +25,32 @@ class ThirdStepView: UIView {
2525 }
2626 }
2727
28−
2928 @IBOutlet weak var timeInterval: UIView!
3029
30+ func bind(withModel model: Reservation) {
31+ let date = format(model.startTime, model.endTime)
32+
33+ totalLabel.text = "Забронирован \(model.reservedTable) столик на \(model.numberOfGuests)-х\n \(date)"
34+
35+ infoLabel.text = "Минимальное количество кальянов: \(countTotalNumber(model.numberOfGuests))"
36+ }
37+
38+ private func format(_ startDate: Date, _ endDate: Date) -> String {
39+ let dateFormatter = DateFormatter()
40+ dateFormatter.calendar = Calendar.current
41+ dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
42+ dateFormatter.dateFormat = "MM.dd, с HH:mm по"
3143
32− func bind(withModel model: ThirdStepViewModel) {
44+ var newDateString = "\(dateFormatter.string(from: startDate))"
45+
46+ dateFormatter.dateFormat = "HH:mm"
47+ newDateString += " \(dateFormatter.string(from: endDate))"
3348
49+ return newDateString
50+ }
51+
52+ private func countTotalNumber(_ people: Int) -> Int {
53+ let num = people > 6 ? 2 : 1
54+ return num
3455 }
3556}
Hookah Tau/Controllers/Client/Reservations/Steps/3/ThirdStepView.xib+6−6
@@ -12,7 +12,7 @@
1212 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
1313 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
1414 <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="394"/>
15+ <rect key="frame" x="0.0" y="0.0" width="414" height="340"/>
1616 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1717 <subviews>
1818 <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="center" spacing="21" translatesAutoresizingMaskIntoConstraints="NO" id="DL4-0a-WxC">
@@ -33,7 +33,7 @@
3333 </subviews>
3434 </stackView>
3535 <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="0H2-jJ-gOj">
36− <rect key="frame" x="20" y="152.5" width="374" height="45"/>
36+ <rect key="frame" x="20" y="132.5" width="374" height="45"/>
3737 <subviews>
3838 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Tick" translatesAutoresizingMaskIntoConstraints="NO" id="lcW-xm-Gb7">
3939 <rect key="frame" x="0.0" y="0.0" width="230" height="45"/>
@@ -50,7 +50,7 @@
5050 </subviews>
5151 </stackView>
5252 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ByV-f1-mVO">
53− <rect key="frame" x="0.0" y="247.5" width="414" height="106"/>
53+ <rect key="frame" x="0.0" y="207.5" width="414" height="106"/>
5454 <color key="backgroundColor" systemColor="systemBlueColor" red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
5555 <constraints>
5656 <constraint firstAttribute="height" constant="106" id="UWZ-LN-h4r"/>
@@ -60,10 +60,10 @@
6060 <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
6161 <constraints>
6262 <constraint firstItem="ByV-f1-mVO" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="1g0-ab-erl"/>
63− <constraint firstItem="ByV-f1-mVO" firstAttribute="top" secondItem="0H2-jJ-gOj" secondAttribute="bottom" constant="50" id="F84-ZL-MWp"/>
63+ <constraint firstItem="ByV-f1-mVO" firstAttribute="top" secondItem="0H2-jJ-gOj" secondAttribute="bottom" constant="30" id="F84-ZL-MWp"/>
6464 <constraint firstItem="0H2-jJ-gOj" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="20" id="GR6-gI-ecm"/>
6565 <constraint firstItem="ByV-f1-mVO" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="KKj-7n-eQf"/>
66− <constraint firstItem="0H2-jJ-gOj" firstAttribute="top" secondItem="DL4-0a-WxC" secondAttribute="bottom" constant="50" id="VbN-sb-Pko"/>
66+ <constraint firstItem="0H2-jJ-gOj" firstAttribute="top" secondItem="DL4-0a-WxC" secondAttribute="bottom" constant="30" id="VbN-sb-Pko"/>
6767 <constraint firstItem="DL4-0a-WxC" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="20" id="cm0-tz-ta4"/>
6868 <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="0H2-jJ-gOj" secondAttribute="trailing" constant="20" id="i3D-sP-KlI"/>
6969 <constraint firstAttribute="trailing" secondItem="DL4-0a-WxC" secondAttribute="trailing" constant="20" id="kHp-8n-OTp"/>
@@ -77,7 +77,7 @@
7777 <outlet property="timeInterval" destination="ByV-f1-mVO" id="oB4-jH-8Ot"/>
7878 <outlet property="totalLabel" destination="xHF-9h-q9F" id="W94-2J-w0A"/>
7979 </connections>
80− <point key="canvasLocation" x="137.59999999999999" y="391.304347826087"/>
80+ <point key="canvasLocation" x="137.59999999999999" y="365.21739130434787"/>
8181 </view>
8282 </objects>
8383 <resources>
Hookah Tau/Controllers/Client/Reservations/Steps/change /ChangeReservationCoordinator.swiftnew file+13
@@ -0,0 +1,13 @@
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 Foundation
10+
11+class ChangeReservationCoordinator: BaseCoordinator {
12+
13+}
Hookah Tau/Controllers/Client/Reservations/Steps/change /ChangeReservationViewController.swiftnew file+19
@@ -0,0 +1,19 @@
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+ override func viewDidLoad() {
14+ super.viewDidLoad()
15+
16+ // Do any additional setup after loading the view.
17+ }
18+
19+}
Hookah Tau/Extensions+Date.swift+2−12
@@ -84,20 +84,10 @@ extension Date {
8484 }
8585
8686 func changeTime(periods: Int) -> Date? {
87− let hours = (periods * 10 / 60 + 12) % 24
87+ let hours = (periods * 10 / 60) % 24
8888 let min = (periods * 10) % 60
8989
90− let day = Calendar.current.dateComponents([.year, .month, .day], from: self)
91−
92− var dateCalendars = DateComponents()
93− dateCalendars.hour = hours
94− dateCalendars.minute = min
95− dateCalendars.day = day.day!
96− dateCalendars.month = day.month!
97− dateCalendars.year = day.year!
98− dateCalendars.timeZone = TimeZone(abbreviation: "GMT")
99−
100− return Calendar.current.date(from: dateCalendars)
90+ return self.set(hours: hours, minutes: min, seconds: 0)
10191 }
10292
10393 func getDay() -> Int {
Hookah Tau/HFunc.swiftnew file+39
@@ -0,0 +1,39 @@
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+ private func filterPeriod(_ today: Date) -> ((ReservationPeriod) -> Bool) {
19+ func datePredicate(_ start: Date, _ end: Date, _ current: Date) -> Bool {
20+ var calendar = Calendar.current
21+ calendar.timeZone = TimeZone(identifier: "GMT")!
22+
23+ let result = calendar.isDate(start, equalTo: current, toGranularity: .day)
24+ || calendar.isDate(end, equalTo: current, toGranularity: .day)
25+
26+ return result
27+ }
28+
29+ return { (period: ReservationPeriod) in datePredicate(period.startTime, period.endTime, today) }
30+ }
31+
32+
33+ /// Filtering function to get every periods which intersects with given date
34+ /// - Parameter periods: all periods of bookings (for a particular table)
35+ /// - Parameter today: date
36+ func filterPeriodsInDate(_ periods: [ReservationPeriod], _ today: Date) -> [ReservationPeriod] {
37+ return periods.filter(filterPeriod(today))
38+ }
39+}
Hookah Tau/Models/AllReservations.swift+8−17
@@ -9,8 +9,8 @@
99import Foundation
1010
1111struct AllReservations: MyCodable {
12− var reservations: [Int: [Date: [ReservationPeriod]]]
13− var intervals: [Date: [Date: [Int]]]
12+ var reservations: [Int: [ReservationPeriod]]
13+ var intervals: [Date: [Int]]
1414
1515 enum CodingKeys: CodingKey {
1616 case reservations
@@ -20,29 +20,20 @@ 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: [String: [Int]]].self, forKey: .intervals)
24− let reservationWithStr = try container.decode([String: [String: [ReservationPeriod]]].self, forKey: .reservations)
23+ let intervalsWithStr = try container.decode([String: [Int]].self, forKey: .intervals)
24+ reservations = try container.decode([Int: [ReservationPeriod]].self, forKey: .reservations)
2525
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)
26+ let intervArray = intervalsWithStr.map { (element) -> (Date, [Int]) in
27+ let key = DateFormatter.iso8601Full.date(from: element.key)!
28+ return (key, element.value)
3829 }
3930
4031 intervals = Dictionary(uniqueKeysWithValues: intervArray)
41− reservations = Dictionary(uniqueKeysWithValues: resArray)
4232 }
4333}
4434
4535struct ReservationPeriod: MyCodable {
4636 var startTime: Date
4737 var duration: Int
38+ var endTime: Date
4839}
Hookah Tau/Models/Reservation.swift+4−4
@@ -13,8 +13,8 @@ struct Reservation: MyCodable {
1313
1414 var uuid: String
1515 var establishment: Int
16− var startTime: String
17− var endTime: String
16+ var startTime: Date
17+ var endTime: Date
1818 var numberOfGuests: Int
1919 var reservedTable: Int
2020
@@ -24,8 +24,8 @@ struct Reservation: MyCodable {
2424struct ReservationData: MyCodable {
2525
2626 var establishment: Int
27− var startTime: String
28− var endTime: String
27+ var startTime: Date
28+ var endTime: Date
2929 var numberOfGuests: Int
3030 var reservedTable: Int
3131