diff --git a/Club_portal/Club Portal/Club Portal.xcodeproj/project.pbxproj b/Club_portal/Club Portal/Club Portal.xcodeproj/project.pbxproj index 19e74b6..27240df 100644 --- a/Club_portal/Club Portal/Club Portal.xcodeproj/project.pbxproj +++ b/Club_portal/Club Portal/Club Portal.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + AC136A092DB96847009D478F /* ObjectMapper in Frameworks */ = {isa = PBXBuildFile; productRef = AC136A082DB96847009D478F /* ObjectMapper */; }; + AC53DEAA2DB9476D003445AD /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = AC53DEA92DB9476D003445AD /* Alamofire */; }; ACAC2DEB2D9F2C1900869E5C /* CalendarKit in Frameworks */ = {isa = PBXBuildFile; productRef = ACAC2DEA2D9F2C1900869E5C /* CalendarKit */; }; /* End PBXBuildFile section */ @@ -27,7 +29,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + AC136A092DB96847009D478F /* ObjectMapper in Frameworks */, ACAC2DEB2D9F2C1900869E5C /* CalendarKit in Frameworks */, + AC53DEAA2DB9476D003445AD /* Alamofire in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -71,6 +75,8 @@ name = "Club Portal"; packageProductDependencies = ( ACAC2DEA2D9F2C1900869E5C /* CalendarKit */, + AC53DEA92DB9476D003445AD /* Alamofire */, + AC136A082DB96847009D478F /* ObjectMapper */, ); productName = "Club Portal"; productReference = ACAC2DCF2D9F271300869E5C /* Club Portal.app */; @@ -102,6 +108,8 @@ minimizedProjectReferenceProxies = 1; packageReferences = ( ACAC2DE92D9F2C1900869E5C /* XCRemoteSwiftPackageReference "CalendarKit" */, + AC53DEA82DB9476D003445AD /* XCRemoteSwiftPackageReference "Alamofire" */, + AC136A072DB96847009D478F /* XCRemoteSwiftPackageReference "ObjectMapper" */, ); preferredProjectObjectVersion = 77; productRefGroup = ACAC2DD02D9F271300869E5C /* Products */; @@ -343,6 +351,22 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + AC136A072DB96847009D478F /* XCRemoteSwiftPackageReference "ObjectMapper" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/tristanhimmelman/ObjectMapper.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 4.4.3; + }; + }; + AC53DEA82DB9476D003445AD /* XCRemoteSwiftPackageReference "Alamofire" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Alamofire/Alamofire.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.10.2; + }; + }; ACAC2DE92D9F2C1900869E5C /* XCRemoteSwiftPackageReference "CalendarKit" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/richardtop/CalendarKit"; @@ -354,6 +378,16 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + AC136A082DB96847009D478F /* ObjectMapper */ = { + isa = XCSwiftPackageProductDependency; + package = AC136A072DB96847009D478F /* XCRemoteSwiftPackageReference "ObjectMapper" */; + productName = ObjectMapper; + }; + AC53DEA92DB9476D003445AD /* Alamofire */ = { + isa = XCSwiftPackageProductDependency; + package = AC53DEA82DB9476D003445AD /* XCRemoteSwiftPackageReference "Alamofire" */; + productName = Alamofire; + }; ACAC2DEA2D9F2C1900869E5C /* CalendarKit */ = { isa = XCSwiftPackageProductDependency; package = ACAC2DE92D9F2C1900869E5C /* XCRemoteSwiftPackageReference "CalendarKit" */; diff --git a/Club_portal/Club Portal/Club Portal.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Club_portal/Club Portal/Club Portal.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 45d1f78..b6006bc 100644 --- a/Club_portal/Club Portal/Club Portal.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Club_portal/Club Portal/Club Portal.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,15 @@ { - "originHash" : "67a1c5e835fc1360427d7e9a548368960eed766e429f7c9f11a95a0e99d682d9", + "originHash" : "60390f3252b346980a2b0f96582e92fec2c37e9487d7b684f3d58a001c214046", "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "513364f870f6bfc468f9d2ff0a95caccc10044c5", + "version" : "5.10.2" + } + }, { "identity" : "calendarkit", "kind" : "remoteSourceControl", @@ -9,6 +18,15 @@ "revision" : "89e02a1472e9ad815ae72b62fd15430144fd1c4c", "version" : "1.1.11" } + }, + { + "identity" : "objectmapper", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tristanhimmelman/ObjectMapper.git", + "state" : { + "revision" : "6021c6035e83a306047348666f6400dc61445d3b", + "version" : "4.4.3" + } } ], "version" : 3 diff --git a/Club_portal/Club Portal/Club Portal.xcodeproj/xcuserdata/umertahir.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Club_portal/Club Portal/Club Portal.xcodeproj/xcuserdata/umertahir.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 19e5bda..7f0b0e8 100644 --- a/Club_portal/Club Portal/Club Portal.xcodeproj/xcuserdata/umertahir.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/Club_portal/Club Portal/Club Portal.xcodeproj/xcuserdata/umertahir.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -8,7 +8,7 @@ BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/APIError.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/APIError.swift index 7f5e094..823afa4 100644 --- a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/APIError.swift +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/APIError.swift @@ -1,6 +1,7 @@ import Foundation import SwiftUI +import Alamofire enum APIError: Error, CustomStringConvertible { case invalidURL @@ -55,6 +56,8 @@ final class APIService { if let responseString = String(data: data, encoding: .utf8) { print("Response: \(responseString)") +// let resp = ProfileDetailResponse(JSONString: responseString) +// print(resp) } else { print("Failed to convert response data to string") } @@ -77,6 +80,99 @@ final class APIService { throw APIError.decodingError(error) } } + + func requestReservation(_ endpoint: Endpoint, responseType: T.Type) async throws -> ReservationResponse? { + guard let request = endpoint.urlRequest else { + throw APIError.invalidURL + } + + print("Request URL: \(request.url?.absoluteString ?? "Invalid URL")") + + let (data, response) = try await URLSession.shared.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + throw APIError.invalidResponse(0, "No HTTP response received") + } + + print("HTTP Status Code: \(httpResponse.statusCode)") + + + + if !(200..<300).contains(httpResponse.statusCode) { + if let errorResponse = try? JSONDecoder().decode(ErrorResponse.self, from: data) { + if errorResponse.message == "TOKEN_EXPIRED" { + // Perform logout + throw APIError.logout + } + throw APIError.serverError(errorResponse.message) + } else { + throw APIError.invalidResponse(httpResponse.statusCode, "Unknown server error") + } + } + + do { + if let responseString = String(data: data, encoding: .utf8) { + print("Response: \(responseString)") + if let resp = ReservationResponse(JSONString: responseString) { + print(resp) + return resp + } + } + + return nil + + + } catch { + throw APIError.decodingError(error) + } + } + + + func requestProfile(_ endpoint: Endpoint, responseType: T.Type) async throws -> ProfileDetailResponse? { + guard let request = endpoint.urlRequest else { + throw APIError.invalidURL + } + + print("Request URL: \(request.url?.absoluteString ?? "Invalid URL")") + + let (data, response) = try await URLSession.shared.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + throw APIError.invalidResponse(0, "No HTTP response received") + } + + print("HTTP Status Code: \(httpResponse.statusCode)") + + + + if !(200..<300).contains(httpResponse.statusCode) { + if let errorResponse = try? JSONDecoder().decode(ErrorResponse.self, from: data) { + if errorResponse.message == "TOKEN_EXPIRED" { + // Perform logout + throw APIError.logout + } + throw APIError.serverError(errorResponse.message) + } else { + throw APIError.invalidResponse(httpResponse.statusCode, "Unknown server error") + } + } + + do { + if let responseString = String(data: data, encoding: .utf8) { + print("Response: \(responseString)") + if let resp = ProfileDetailResponse(JSONString: responseString) { + print(resp) + return resp + } + } + + return nil + + + } catch { + throw APIError.decodingError(error) + } + } private func uploadMultipart(endpoint: Endpoint, responseType: T.Type) async throws -> T { guard var request = endpoint.urlRequest else { throw APIError.invalidURL } @@ -115,6 +211,72 @@ final class APIService { } +// func requestWithAlamofire(_ endpoint: Endpoint, responseType: T.Type) async throws -> T { +// guard let urlRequest = endpoint.urlRequest else { +// throw APIError.invalidURL +// } +// +// let response = await AF.request(urlRequest, interceptor: .retryPolicy) +// .validate() +// .serializingDecodable(T.self) +// .response +// +// debugPrint(response) +// +// switch response.result { +// case .success(let value): +// return value +// case .failure(let error): +// if let data = response.data { +// +// if let responseString = String(data: data, encoding: .utf8) { +// print("Response: \(responseString)") +// // let resp = ProfileDetailResponse(map: responseString) +// } else { +// print("Failed to convert response data to string") +// } +// +// } else { +// throw APIError.invalidResponse(response.response?.statusCode ?? 0, error.localizedDescription) +// } +// } +// } + + // MARK: - Alamofire Multipart Upload with Swift Concurrency + func uploadMultipartWithAlamofire(_ endpoint: Endpoint, responseType: T.Type) async throws -> T { + guard let url = endpoint.urlRequest?.url else { + throw APIError.invalidURL + } + + let response = await AF.upload(multipartFormData: { multipartFormData in + // Append your multipart form data here + // Example: + // multipartFormData.append(data, withName: "file", fileName: "file.jpg", mimeType: "image/jpeg") + }, to: url) + .validate() + .serializingDecodable(T.self) + .response + + debugPrint(response) + + switch response.result { + case .success(let value): + return value + case .failure(let error): + if let data = response.data, + let errorResponse = try? JSONDecoder().decode(ErrorResponse.self, from: data) { + if errorResponse.message == "TOKEN_EXPIRED" { + throw APIError.logout + } else { + throw APIError.serverError(errorResponse.message) + } + } else { + throw APIError.invalidResponse(response.response?.statusCode ?? 0, error.localizedDescription) + } + } + } + + } struct ErrorResponse: Codable { diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/EndPoints/ClubStatisticsEndpoint.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/EndPoints/ClubStatisticsEndpoint.swift index 8382931..78dd919 100644 --- a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/EndPoints/ClubStatisticsEndpoint.swift +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/EndPoints/ClubStatisticsEndpoint.swift @@ -33,6 +33,8 @@ struct ClubStatisticsEndpoint: Endpoint { var isMultipart: Bool { false } } + + struct GetClubEndpoint: Endpoint { var path: String { "/v3/api/custom/courtmatchup/user/club/\(clubId)" diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/EndPoints/ReservationListEndpoint.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/EndPoints/ReservationListEndpoint.swift index 108887a..1a22caa 100644 --- a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/EndPoints/ReservationListEndpoint.swift +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/EndPoints/ReservationListEndpoint.swift @@ -8,9 +8,8 @@ import SwiftUI struct ReservationListEndpoint: Endpoint { var urlQueryItems: [URLQueryItem] = [] - var path: String { - "/v4/api/records/reservation?join=booking|booking_id&join=user|user_id&join=buddy|buddy_id&join=clubs|club_id&order=id,desc&filter=courtmatchup_booking.date,cs,\(clubID)" + "/v4/api/records/reservation?join=booking|booking_id&join=user|user_id&join=buddy|buddy_id&join=clubs|club_id&order=id,desc&filter=courtmatchup_booking.court_id,eq,163" } var method: HTTPMethod { .get } diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ClubDetailsResponse.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ClubDetailsResponse.swift index 625aa0c..11d62a0 100644 --- a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ClubDetailsResponse.swift +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ClubDetailsResponse.swift @@ -17,7 +17,7 @@ struct ClubDetailsResponse: Codable { // MARK: - Club Details Model struct ClubDetailsModel: Codable { let user: ClubUser - let club: Club + let club: ClubSport let courts: [Court] let sports: [Sport] let pricing: [Pricing] diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ClubResponse.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ClubResponse.swift index 148558d..f8e5a3d 100644 --- a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ClubResponse.swift +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ClubResponse.swift @@ -9,7 +9,7 @@ import Foundation struct ClubDetail: Codable { let error: Bool? let model: Model? - let sports: [Club]? + let sports: [Club1]? let courts: [Court]? let pricing: [Pricing]? } diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Club.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Club.swift new file mode 100644 index 0000000..c94099a --- /dev/null +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Club.swift @@ -0,0 +1,95 @@ + + +import Foundation +import ObjectMapper + +class ClubMap : Mappable { + var id : Int? + var name : String? + var slug : String? + var title : String? + var description : String? + var user_id : Int? + var completed : Int? + var bio : String? + var opening_time : String? + var closing_time : String? + var times : String? + var splash_screen : String? + var show_clinic : Int? + var show_notification : Int? + var club_logo : String? + var fee_settings : String? + var custom_fields : String? + var home_image : String? + var show_buddy : Int? + var exceptions : String? + var club_location : String? + var show_coach : Int? + var show_groups : Int? + var show_court : Int? + var buddy_description : String? + var court_description : String? + var coach_description : String? + var clinic_description : String? + var lesson_description : String? + var custom_request_threshold : Int? + var club_fee : Int? + var service_fee : Int? + var max_players : Int? + var account_details : String? + var account_settings : String? + var membership_settings : String? + var daily_breaks : String? + var days_off : String? + var create_at : String? + var update_at : String? + + required init?(map: Map) { + } + + func mapping(map: Map) { + + id <- map["id"] + name <- map["name"] + slug <- map["slug"] + title <- map["title"] + description <- map["description"] + user_id <- map["user_id"] + completed <- map["completed"] + bio <- map["bio"] + opening_time <- map["opening_time"] + closing_time <- map["closing_time"] + times <- map["times"] + splash_screen <- map["splash_screen"] + show_clinic <- map["show_clinic"] + show_notification <- map["show_notification"] + club_logo <- map["club_logo"] + fee_settings <- map["fee_settings"] + custom_fields <- map["custom_fields"] + home_image <- map["home_image"] + show_buddy <- map["show_buddy"] + exceptions <- map["exceptions"] + club_location <- map["club_location"] + show_coach <- map["show_coach"] + show_groups <- map["show_groups"] + show_court <- map["show_court"] + buddy_description <- map["buddy_description"] + court_description <- map["court_description"] + coach_description <- map["coach_description"] + clinic_description <- map["clinic_description"] + lesson_description <- map["lesson_description"] + custom_request_threshold <- map["custom_request_threshold"] + club_fee <- map["club_fee"] + service_fee <- map["service_fee"] + max_players <- map["max_players"] + account_details <- map["account_details"] + account_settings <- map["account_settings"] + membership_settings <- map["membership_settings"] + daily_breaks <- map["daily_breaks"] + days_off <- map["days_off"] + create_at <- map["create_at"] + update_at <- map["update_at"] + } + +} diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Courts.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Courts.swift new file mode 100644 index 0000000..ad7688d --- /dev/null +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Courts.swift @@ -0,0 +1,41 @@ + + +import Foundation +import ObjectMapper + +class CourtsMap: Mappable, Identifiable, Hashable { + var id: Int? + var club_id: Int? + var name: String? + var sport_id: Int? + var type: String? + var surface_id: Int? + var sub_type: String? + var availability: String? + var create_at: String? + var update_at: String? + + required init?(map: Map) {} + + func mapping(map: Map) { + id <- map["id"] + club_id <- map["club_id"] + name <- map["name"] + sport_id <- map["sport_id"] + type <- map["type"] + surface_id <- map["surface_id"] + sub_type <- map["sub_type"] + availability <- map["availability"] + create_at <- map["create_at"] + update_at <- map["update_at"] + } + + // MARK: - Hashable + static func == (lhs: CourtsMap, rhs: CourtsMap) -> Bool { + return lhs.id == rhs.id + } + + func hash(into hasher: inout Hasher) { + hasher.combine(id) + } +} diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Model.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Model.swift new file mode 100644 index 0000000..4f55f27 --- /dev/null +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Model.swift @@ -0,0 +1,25 @@ + +import Foundation +import ObjectMapper + +class ModelMap : Mappable { + var user : UserMap? + var club : ClubMap? + var courts : [CourtsMap]? + var sports : [SportsMap]? + var pricing : [PricingMap]? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + user <- map["user"] + club <- map["club"] + courts <- map["courts"] + sports <- map["sports"] + pricing <- map["pricing"] + } + +} diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Pricing.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Pricing.swift new file mode 100644 index 0000000..1a4a7ab --- /dev/null +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Pricing.swift @@ -0,0 +1,39 @@ + +import Foundation +import ObjectMapper + +class PricingMap : Mappable { + var id : Int? + var surface_id : String? + var club_id : Int? + var type : String? + var subtype : String? + var sport_id : Int? + var status : Int? + var is_general : Int? + var general_rate : Int? + var price_by_hours : String? + var create_at : String? + var update_at : String? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + id <- map["id"] + surface_id <- map["surface_id"] + club_id <- map["club_id"] + type <- map["type"] + subtype <- map["subtype"] + sport_id <- map["sport_id"] + status <- map["status"] + is_general <- map["is_general"] + general_rate <- map["general_rate"] + price_by_hours <- map["price_by_hours"] + create_at <- map["create_at"] + update_at <- map["update_at"] + } + +} diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/ProfileDetailResponse.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/ProfileDetailResponse.swift new file mode 100644 index 0000000..e472834 --- /dev/null +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/ProfileDetailResponse.swift @@ -0,0 +1,19 @@ + +import Foundation +import ObjectMapper + +class ProfileDetailResponse : Mappable { + var error : Bool? + var model : ModelMap? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + error <- map["error"] + model <- map["model"] + } + +} diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Sport_types.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Sport_types.swift new file mode 100644 index 0000000..e1f12b3 --- /dev/null +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Sport_types.swift @@ -0,0 +1,22 @@ + + +import Foundation +import ObjectMapper + +class Sport_types : Mappable { + var type : String? + var subtype : [String]? + var club_sport_type_id : String? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + type <- map["type"] + subtype <- map["subtype"] + club_sport_type_id <- map["club_sport_type_id"] + } + +} diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Sports.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Sports.swift new file mode 100644 index 0000000..57edd97 --- /dev/null +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/Sports.swift @@ -0,0 +1,25 @@ + +import Foundation +import ObjectMapper + +class SportsMap : Mappable { + var id : Int? + var status : Int? + var name : String? + var club_id : Int? + var sport_types : [Sport_types]? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + id <- map["id"] + status <- map["status"] + name <- map["name"] + club_id <- map["club_id"] + sport_types <- map["sport_types"] + } + +} diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/User.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/User.swift new file mode 100644 index 0000000..6199d4d --- /dev/null +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/Model/User.swift @@ -0,0 +1,67 @@ + +import Foundation +import ObjectMapper + +class UserMap : Mappable { + var id : Int? + var oauth : String? + var role : String? + var first_name : String? + var last_name : String? + var email : String? + var password : String? + var type : Int? + var alternative_phone : String? + var age_group : String? + var family_role : String? + var default_payment_method : String? + var guardian : Int? + var password_login : Int? + var verify : Int? + var club_id : String? + var phone : String? + var photo : String? + var bio : String? + var refer : String? + var stripe_uid : String? + var paypal_uid : String? + var two_factor_authentication : String? + var status : Int? + var create_at : String? + var update_at : String? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + id <- map["id"] + oauth <- map["oauth"] + role <- map["role"] + first_name <- map["first_name"] + last_name <- map["last_name"] + email <- map["email"] + password <- map["password"] + type <- map["type"] + alternative_phone <- map["alternative_phone"] + age_group <- map["age_group"] + family_role <- map["family_role"] + default_payment_method <- map["default_payment_method"] + guardian <- map["guardian"] + password_login <- map["password_login"] + verify <- map["verify"] + club_id <- map["club_id"] + phone <- map["phone"] + photo <- map["photo"] + bio <- map["bio"] + refer <- map["refer"] + stripe_uid <- map["stripe_uid"] + paypal_uid <- map["paypal_uid"] + two_factor_authentication <- map["two_factor_authentication"] + status <- map["status"] + create_at <- map["create_at"] + update_at <- map["update_at"] + } + +} diff --git a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ReservationResponse.swift b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ReservationResponse.swift index f60f7ac..13ef3a5 100644 --- a/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ReservationResponse.swift +++ b/Club_portal/Club Portal/Club Portal/Network/Api_Stuff/Response/ReservationResponse.swift @@ -1,146 +1,360 @@ + import Foundation +import ObjectMapper + +class ReservationResponse : Mappable { + var list : [ReservationList]? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + list <- map["list"] + } -// MARK: - Root -struct ReservationRsp: Codable { - let list: [Reservation] } -// MARK: - Reservation -struct Reservation: Codable { - let id: Int - let bookingID: Int - let buddyID: Int? - let spaceAssigned: String - let userID: Int - let clubID: Int - let reservationType: Int? - let status: Int - let checkIn: Int - let recurring: Int - let notes: String - let createAt: String - let updateAt: String - let booking: Booking - let user: User - let buddy: [String?] - let clubs: Club + +class ReservationList : Mappable, Identifiable { + var id : Int? + var booking_id : Int? + var buddy_id : String? + var space_assigned : String? + var user_id : Int? + var club_id : Int? + var reservation_type : String? + var status : Int? + var check_in : Int? + var recurring : Int? + var notes : String? + var create_at : String? + var update_at : String? + var booking : Booking? + var user : ObjUser? + var buddy : Buddy? + var clubs : Clubs? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + id <- map["id"] + booking_id <- map["booking_id"] + buddy_id <- map["buddy_id"] + space_assigned <- map["space_assigned"] + user_id <- map["user_id"] + club_id <- map["club_id"] + reservation_type <- map["reservation_type"] + status <- map["status"] + check_in <- map["check_in"] + recurring <- map["recurring"] + notes <- map["notes"] + create_at <- map["create_at"] + update_at <- map["update_at"] + booking <- map["booking"] + user <- map["user"] + buddy <- map["buddy"] + clubs <- map["clubs"] + } + } -// MARK: - Booking -struct Booking: Codable { - let id: Int - let userID: Int - let sportID: Int - let type: String - let receiptID: String - let subtype: String - let status: Int - let clinicID: Int? - let minNtrp: Int - let maxNtrp: Int - let coachID: Int? - let reservationType: Int - let courtID: Int - let courtIDs: String - let customRequest: Int - let price: Double - let clubFee: Double - let serviceFee: Double - let clinicFee: Double - let last4: Int - let clubID: Int? - let coachFee: Double - let lessonID: Int? - let duration: Int - let paymentIntent: String? - let notes: String? - let spaceAssigned: String? - let playerIDs: String - let courtFee: Double? - let playerID: Int? - let date: String - let startTime: String - let endTime: String - let createAt: String - let updateAt: String - let coachIDs: String + +class Booking : Mappable, Identifiable { + var id : Int? + var user_id : Int? + var sport_id : Int? + var type : String? + var receipt_id : String? + var subtype : String? + var status : Int? + var clinic_id : String? + var min_ntrp : Int? + var max_ntrp : Int? + var coach_id : String? + var reservation_type : Int? + var court_id : Int? + var court_ids : String? + var custom_request : Int? + var price : Int? + var club_fee : Int? + var service_fee : Int? + var clinic_fee : Int? + var last_4 : Int? + var club_id : Int? + var coach_fee : Int? + var lesson_id : String? + var duration : Int? + var payment_intent : String? + var notes : String? + var space_assigned : String? + var player_ids : String? + var court_fee : String? + var player_id : Int? + var date : String? + var start_time : String? + var end_time : String? + var create_at : String? + var update_at : String? + var coach_ids : String? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + id <- map["id"] + user_id <- map["user_id"] + sport_id <- map["sport_id"] + type <- map["type"] + receipt_id <- map["receipt_id"] + subtype <- map["subtype"] + status <- map["status"] + clinic_id <- map["clinic_id"] + min_ntrp <- map["min_ntrp"] + max_ntrp <- map["max_ntrp"] + coach_id <- map["coach_id"] + reservation_type <- map["reservation_type"] + court_id <- map["court_id"] + court_ids <- map["court_ids"] + custom_request <- map["custom_request"] + price <- map["price"] + club_fee <- map["club_fee"] + service_fee <- map["service_fee"] + clinic_fee <- map["clinic_fee"] + last_4 <- map["last_4"] + club_id <- map["club_id"] + coach_fee <- map["coach_fee"] + lesson_id <- map["lesson_id"] + duration <- map["duration"] + payment_intent <- map["payment_intent"] + notes <- map["notes"] + space_assigned <- map["space_assigned"] + player_ids <- map["player_ids"] + court_fee <- map["court_fee"] + player_id <- map["player_id"] + date <- map["date"] + start_time <- map["start_time"] + end_time <- map["end_time"] + create_at <- map["create_at"] + update_at <- map["update_at"] + coach_ids <- map["coach_ids"] + } + } -// MARK: - User -struct User: Codable { - let id: Int - let oauth: String? - let role: String - let firstName: String - let lastName: String - let email: String - let password: String - let type: Int - let alternativePhone: String? - let ageGroup: String? - let familyRole: String? - let defaultPaymentMethod: String? - let guardian: Int - let passwordLogin: String - let verify: Int - let clubID: Int? - let phone: String? - let photo: String? - let bio: String? - let refer: String? - let stripeUID: String? - let paypalUID: String? - let twoFactorAuthentication: String? - let status: Int - let createAt: String - let updateAt: String + +class Buddy : Mappable { + var id : String? + var sport_id : String? + var type : String? + var sub_type : String? + var ntrp : String? + var surface_id : String? + var reservation_id : String? + var num_players : String? + var max_ntrp : String? + var slots : String? + var num_needed : String? + var need_coach : String? + var notes : String? + var player_ids : String? + var date : String? + var start_time : String? + var end_time : String? + var create_at : String? + var update_at : String? + var user_id : String? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + id <- map["id"] + sport_id <- map["sport_id"] + type <- map["type"] + sub_type <- map["sub_type"] + ntrp <- map["ntrp"] + surface_id <- map["surface_id"] + reservation_id <- map["reservation_id"] + num_players <- map["num_players"] + max_ntrp <- map["max_ntrp"] + slots <- map["slots"] + num_needed <- map["num_needed"] + need_coach <- map["need_coach"] + notes <- map["notes"] + player_ids <- map["player_ids"] + date <- map["date"] + start_time <- map["start_time"] + end_time <- map["end_time"] + create_at <- map["create_at"] + update_at <- map["update_at"] + user_id <- map["user_id"] + } + } -// MARK: - Buddy -struct Buddy: Codable { - // Add properties if needed + +class Clubs : Mappable { + var id : Int? + var name : String? + var slug : String? + var title : String? + var description : String? + var user_id : Int? + var completed : Int? + var bio : String? + var opening_time : String? + var closing_time : String? + var times : String? + var splash_screen : String? + var show_clinic : Int? + var show_notification : Int? + var club_logo : String? + var fee_settings : String? + var custom_fields : String? + var home_image : String? + var show_buddy : Int? + var exceptions : String? + var club_location : String? + var show_coach : Int? + var show_groups : Int? + var show_court : Int? + var buddy_description : String? + var court_description : String? + var coach_description : String? + var clinic_description : String? + var lesson_description : String? + var custom_request_threshold : Int? + var club_fee : Int? + var service_fee : Int? + var max_players : Int? + var account_details : String? + var account_settings : String? + var membership_settings : String? + var daily_breaks : String? + var days_off : String? + var create_at : String? + var update_at : String? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + id <- map["id"] + name <- map["name"] + slug <- map["slug"] + title <- map["title"] + description <- map["description"] + user_id <- map["user_id"] + completed <- map["completed"] + bio <- map["bio"] + opening_time <- map["opening_time"] + closing_time <- map["closing_time"] + times <- map["times"] + splash_screen <- map["splash_screen"] + show_clinic <- map["show_clinic"] + show_notification <- map["show_notification"] + club_logo <- map["club_logo"] + fee_settings <- map["fee_settings"] + custom_fields <- map["custom_fields"] + home_image <- map["home_image"] + show_buddy <- map["show_buddy"] + exceptions <- map["exceptions"] + club_location <- map["club_location"] + show_coach <- map["show_coach"] + show_groups <- map["show_groups"] + show_court <- map["show_court"] + buddy_description <- map["buddy_description"] + court_description <- map["court_description"] + coach_description <- map["coach_description"] + clinic_description <- map["clinic_description"] + lesson_description <- map["lesson_description"] + custom_request_threshold <- map["custom_request_threshold"] + club_fee <- map["club_fee"] + service_fee <- map["service_fee"] + max_players <- map["max_players"] + account_details <- map["account_details"] + account_settings <- map["account_settings"] + membership_settings <- map["membership_settings"] + daily_breaks <- map["daily_breaks"] + days_off <- map["days_off"] + create_at <- map["create_at"] + update_at <- map["update_at"] + } + } -// MARK: - Club -struct Club: Codable { - let id: Int - let name: String - let slug: String - let title: String - let description: String - let userID: Int - let completed: Int - let bio: String? - let openingTime: String - let closingTime: String - let times: String - let splashScreen: String - let showClinic: Int - let showNotification: Int - let clubLogo: String - let feeSettings: String - let customFields: String - let homeImage: String - let showBuddy: Int - let exceptions: String - let clubLocation: String - let showCoach: Int - let showGroups: Int - let showCourt: Int - let buddyDescription: String - let courtDescription: String - let coachDescription: String - let clinicDescription: String - let lessonDescription: String - let customRequestThreshold: Int - let clubFee: Double - let serviceFee: Double - let maxPlayers: Int - let accountDetails: String - let accountSettings: String - let membershipSettings: String - let dailyBreaks: String - let daysOff: String - let createAt: String - let updateAt: String + +class ObjUser : Mappable { + var id : Int? + var oauth : String? + var role : String? + var first_name : String? + var last_name : String? + var email : String? + var password : String? + var type : Int? + var alternative_phone : String? + var age_group : String? + var family_role : String? + var default_payment_method : String? + var guardian : Int? + var password_login : String? + var verify : Int? + var club_id : String? + var phone : String? + var photo : String? + var bio : String? + var refer : String? + var stripe_uid : String? + var paypal_uid : String? + var two_factor_authentication : String? + var status : Int? + var create_at : String? + var update_at : String? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + + id <- map["id"] + oauth <- map["oauth"] + role <- map["role"] + first_name <- map["first_name"] + last_name <- map["last_name"] + email <- map["email"] + password <- map["password"] + type <- map["type"] + alternative_phone <- map["alternative_phone"] + age_group <- map["age_group"] + family_role <- map["family_role"] + default_payment_method <- map["default_payment_method"] + guardian <- map["guardian"] + password_login <- map["password_login"] + verify <- map["verify"] + club_id <- map["club_id"] + phone <- map["phone"] + photo <- map["photo"] + bio <- map["bio"] + refer <- map["refer"] + stripe_uid <- map["stripe_uid"] + paypal_uid <- map["paypal_uid"] + two_factor_authentication <- map["two_factor_authentication"] + status <- map["status"] + create_at <- map["create_at"] + update_at <- map["update_at"] + } + } diff --git a/Club_portal/Club Portal/Club Portal/UI/DailySecheduler/FilterView1.swift b/Club_portal/Club Portal/Club Portal/UI/DailySecheduler/FilterView1.swift index 705da9b..4856164 100644 --- a/Club_portal/Club Portal/Club Portal/UI/DailySecheduler/FilterView1.swift +++ b/Club_portal/Club Portal/Club Portal/UI/DailySecheduler/FilterView1.swift @@ -9,15 +9,16 @@ import SwiftUI +import SwiftUI struct ScheduleFilterView: View { @Environment(\.dismiss) var dismiss @Binding var navigationPaths: [String] @State private var isClubExpanded = true - @State private var selectedClubs: Set = [] // For storing selected clubs + @State private var selectedClub: String? = nil // Single selection - @State var filterBlock: ((Int) -> Void)? + @State var filterBlock: ((CourtsMap) -> Void)? @EnvironmentObject var dasModel: DashViewModel var body: some View { @@ -27,15 +28,14 @@ struct ScheduleFilterView: View { // Club Filter Section DisclosureGroup(isExpanded: $isClubExpanded) { VStack(spacing: 10) { - if let clubs = dasModel.club?.courts { + if let clubs = dasModel.profile?.model?.courts { ForEach(clubs, id: \.self) { court in if let clubName = court.name { - ClubCheckboxRow(clubName: clubName, isSelected: selectedClubs.contains(clubName)) { - if selectedClubs.contains(clubName) { - selectedClubs.remove(clubName) - } else { - selectedClubs.insert(clubName) - } + ClubCheckboxRow( + clubName: clubName, + isSelected: selectedClub == clubName + ) { + selectedClub = (selectedClub == clubName) ? nil : clubName } } } @@ -60,7 +60,11 @@ struct ScheduleFilterView: View { Spacer() Button(action: { - // Handle apply logic + if let selectedClub = selectedClub, + let court = dasModel.profile?.model?.courts?.first(where: { $0.name == selectedClub }), + let id = court.id { + filterBlock?(court) + } self.navigationPaths.removeLast() }) { Text("Apply and close") @@ -72,35 +76,33 @@ struct ScheduleFilterView: View { .cornerRadius(10) .padding(.horizontal) } - .padding(.vertical, 10) - .background(Color.white) + .navigationTitle("Filter") + .navigationBarTitleDisplayMode(.inline) + .background(Color(.systemGray6).ignoresSafeArea()) } - .navigationTitle("Filter") - .navigationBarTitleDisplayMode(.inline) - .background(Color(.systemGray6).ignoresSafeArea()) } -} - -// MARK: - Club Checkbox Row -struct ClubCheckboxRow: View { - let clubName: String - let isSelected: Bool - let onTap: () -> Void - var body: some View { - Button(action: onTap) { - HStack { - Text(clubName) - .foregroundColor(.primary) - Spacer() - Image(systemName: isSelected ? "checkmark.square.fill" : "square") - .foregroundColor(isSelected ? Colorr.themeBlueColor : .gray) + // MARK: - Club Checkbox Row + struct ClubCheckboxRow: View { + let clubName: String + let isSelected: Bool + let onTap: () -> Void + + var body: some View { + Button(action: onTap) { + HStack { + Text(clubName) + .foregroundColor(.primary) + Spacer() + Image(systemName: isSelected ? "checkmark.square.fill" : "square") + .foregroundColor(isSelected ? Colorr.themeBlueColor : .gray) + } + .padding() + .background( + RoundedRectangle(cornerRadius: 8) + .stroke(isSelected ? Colorr.themeBlueColor : Color.gray.opacity(0.3), lineWidth: 1) + ) } - .padding() - .background( - RoundedRectangle(cornerRadius: 8) - .stroke(isSelected ? Colorr.themeBlueColor : Color.gray.opacity(0.3), lineWidth: 1) - ) } } } diff --git a/Club_portal/Club Portal/Club Portal/UI/DailySecheduler/ScheduleView.swift b/Club_portal/Club Portal/Club Portal/UI/DailySecheduler/ScheduleView.swift index 0ad0fa5..3e89262 100644 --- a/Club_portal/Club Portal/Club Portal/UI/DailySecheduler/ScheduleView.swift +++ b/Club_portal/Club Portal/Club Portal/UI/DailySecheduler/ScheduleView.swift @@ -1,21 +1,15 @@ import SwiftUI -struct Event: Identifiable { - let id = UUID() - let title: String - let startTime: Date - let endTime: Date - let color: Color -} + struct ScheduleView: View { @State var navigationPaths: [String] = [] @State private var selectedDate = Date() @State private var displayedMonth = Date() - @State private var events: [Event] = [] + // @State private var events: [ReservationList] = [] @Binding var presentSideMenu: Bool // Optional for side menu - - let hours = Array(8...20) + @State var courtName = "" + let hours = Array(4...20) let calendar = Calendar.current @EnvironmentObject var viewModel : DashViewModel @@ -47,11 +41,17 @@ struct ScheduleView: View { Divider() + HStack { + Spacer() + Text(courtName) + Spacer() + } // Time Slots with Events ScrollView { VStack(spacing: 0) { ForEach(hours, id: \.self) { hour in timeSlotRow(hour: hour) + } } .padding(.horizontal) @@ -62,18 +62,20 @@ struct ScheduleView: View { } .onAppear { // loadDummyEvents() - viewModel.getDailySched(clubId: 10) - if let club = self.viewModel.club { - print(club.courts?.count) + if let club = self.viewModel.profile { + print(club.model?.courts?.count) + // viewModel.getDailySched(clubId: club.model?.courts?.first?.id ?? 0) + }else { - viewModel.getClubProfile() + viewModel.getProfile() } } .navigationDestination(for: String.self) { value in if value == "DailyFilterView" { ScheduleFilterView(navigationPaths: $navigationPaths) { filter in - viewModel.getDailySched(clubId: filter) + self.courtName = filter.name ?? "" + viewModel.getDailySched(clubId: filter.id ?? 0) } }else if value == "ReservationDetailsView" { ReservationDetailsView() @@ -201,6 +203,7 @@ struct ScheduleView: View { Text(timeLabel(for: hour)) .font(.caption) .frame(width: 50, alignment: .leading) + .padding(.top) ZStack(alignment: .topLeading) { Rectangle() @@ -216,21 +219,40 @@ struct ScheduleView: View { func eventOverlay(for hour: Int) -> some View { VStack(spacing: 4) { - ForEach(events.filter { - calendar.isDate($0.startTime, inSameDayAs: selectedDate) - && calendar.component(.hour, from: $0.startTime) == hour - }) { event in + ForEach( + viewModel.dailyReservations.filter({ event in + guard let eventDateString = event.booking?.date, + let startTimeString = event.booking?.start_time, + let _ = event.booking?.end_time else { + return false + } + + // Format selectedDate as "yyyy-MM-dd" + let selectedDateStr = DateFormatter.bookingDateFormatter.string(from: selectedDate) + + // Debug print + print("Event Date: \(eventDateString), Selected: \(selectedDateStr), StartTime: \(startTimeString)") + + // Match event date to selected date string + guard eventDateString == selectedDateStr else { return false } + // Compare the 12-hour formatted string labels + let startTimeLabel = startTimeString.to12HourFormat() + let currentHourLabel = timeLabel(for: hour) + return startTimeLabel == currentHourLabel + }), + id: \.id + ) { event in VStack(alignment: .leading, spacing: 2) { - Text(event.title) + Text(event.booking?.type ?? "- -") .font(.subheadline) .bold() - Text("\(timeOnly(event.startTime)) - \(timeOnly(event.endTime))") + Text("\(event.booking!.start_time!.to12HourFormat()) - \(event.booking!.end_time!.to12HourFormat())") .font(.caption) .foregroundColor(.gray) } .padding(8) - .background(event.color.opacity(0.2)) - .foregroundColor(event.color) + .background(Colorr.greenColor.opacity(0.2)) + .foregroundColor(Colorr.greenColor.opacity(0.8)) .cornerRadius(12) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) .background(Color.clear) @@ -245,23 +267,23 @@ struct ScheduleView: View { // MARK: - Utility - func loadDummyEvents() { - let baseDate = calendar.startOfDay(for: Date()) - events = [ - Event( - title: "Court reserved", - startTime: calendar.date(bySettingHour: 9, minute: 0, second: 0, of: baseDate)!, - endTime: calendar.date(bySettingHour: 10, minute: 0, second: 0, of: baseDate)!, - color: .green - ), - Event( - title: "Clinic", - startTime: calendar.date(bySettingHour: 11, minute: 30, second: 0, of: baseDate)!, - endTime: calendar.date(bySettingHour: 13, minute: 0, second: 0, of: baseDate)!, - color: .purple - ) - ] - } +// func loadDummyEvents() { +// let baseDate = calendar.startOfDay(for: Date()) +// events = [ +// Event( +// title: "Court reserved", +// startTime: calendar.date(bySettingHour: 9, minute: 0, second: 0, of: baseDate)!, +// endTime: calendar.date(bySettingHour: 10, minute: 0, second: 0, of: baseDate)!, +// color: .green +// ), +// Event( +// title: "Clinic", +// startTime: calendar.date(bySettingHour: 11, minute: 30, second: 0, of: baseDate)!, +// endTime: calendar.date(bySettingHour: 13, minute: 0, second: 0, of: baseDate)!, +// color: .purple +// ) +// ] +// } func getDatesForMonth(from date: Date) -> [Date] { let range = calendar.range(of: .day, in: .month, for: date)! @@ -296,7 +318,7 @@ struct ScheduleView: View { func timeLabel(for hour: Int) -> String { let date = calendar.date(bySettingHour: hour, minute: 0, second: 0, of: Date())! let formatter = DateFormatter() - formatter.dateFormat = "h a" + formatter.dateFormat = "h:mm a" return formatter.string(from: date) } @@ -304,3 +326,39 @@ struct ScheduleView: View { calendar.isDate(a, inSameDayAs: b) } } + +extension DateFormatter { + static var isoFormatter: DateFormatter { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + formatter.locale = Locale(identifier: "en_US_POSIX") + return formatter + } +} + +extension DateFormatter { + static var bookingDateFormatter: DateFormatter { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd" + // formatter.locale = Locale(identifier: "en_US_POSIX") + return formatter + } +} + +extension String { + func to12HourFormat() -> String { + let inputFormatter = DateFormatter() + inputFormatter.dateFormat = "HH:mm:ss" + // inputFormatter.locale = Locale(identifier: "en_US_POSIX") + + let outputFormatter = DateFormatter() + outputFormatter.dateFormat = "h:mm a" + // outputFormatter.locale = Locale(identifier: "en_US_POSIX") + + if let date = inputFormatter.date(from: self) { + return outputFormatter.string(from: date) + } else { + return self // Return original if parsing fails + } + } +} diff --git a/Club_portal/Club Portal/Club Portal/UI/Dashboard/DashboardView.swift b/Club_portal/Club Portal/Club Portal/UI/Dashboard/DashboardView.swift index 5fa6771..d1c3876 100644 --- a/Club_portal/Club Portal/Club Portal/UI/Dashboard/DashboardView.swift +++ b/Club_portal/Club Portal/Club Portal/UI/Dashboard/DashboardView.swift @@ -68,7 +68,7 @@ struct SummaryView: View { } } // viewModel.getClubProfile() - // viewModel.getProfile() + viewModel.getProfile() } diff --git a/Club_portal/Club Portal/Club Portal/Utliz/Extensions.swift b/Club_portal/Club Portal/Club Portal/Utliz/Extensions.swift index 1611911..9a89438 100644 --- a/Club_portal/Club Portal/Club Portal/Utliz/Extensions.swift +++ b/Club_portal/Club Portal/Club Portal/Utliz/Extensions.swift @@ -167,33 +167,33 @@ extension String { } } - func to12HourFormat() -> String? { - let inputDateFormatter = DateFormatter() - inputDateFormatter.dateFormat = "HH:mm:ss" // Input format (24-hour) - - let outputDateFormatter = DateFormatter() - outputDateFormatter.dateFormat = "hh:mm a" // Output format (12-hour with AM/PM) - - // Split the range into start and end times - let timeComponents = self.components(separatedBy: "-") - - if timeComponents.count == 2 { - let startTime = inputDateFormatter.date(from: timeComponents[0]) - let endTime = inputDateFormatter.date(from: timeComponents[1]) - - let start12Hour = outputDateFormatter.string(from: startTime!) - let end12Hour = outputDateFormatter.string(from: endTime!) - - return "\(start12Hour) - \(end12Hour)" - }else { - let startTime = inputDateFormatter.date(from: self) - let start12Hour = outputDateFormatter.string(from: startTime!) - - return start12Hour - } - - // Return nil if conversion fails - } +// func to12HourFormat() -> String? { +// let inputDateFormatter = DateFormatter() +// inputDateFormatter.dateFormat = "HH:mm:ss" // Input format (24-hour) +// +// let outputDateFormatter = DateFormatter() +// outputDateFormatter.dateFormat = "hh:mm a" // Output format (12-hour with AM/PM) +// +// // Split the range into start and end times +// let timeComponents = self.components(separatedBy: "-") +// +// if timeComponents.count == 2 { +// let startTime = inputDateFormatter.date(from: timeComponents[0]) +// let endTime = inputDateFormatter.date(from: timeComponents[1]) +// +// let start12Hour = outputDateFormatter.string(from: startTime!) +// let end12Hour = outputDateFormatter.string(from: endTime!) +// +// return "\(start12Hour) - \(end12Hour)" +// }else { +// let startTime = inputDateFormatter.date(from: self) +// let start12Hour = outputDateFormatter.string(from: startTime!) +// +// return start12Hour +// } +// +// // Return nil if conversion fails +// } diff --git a/Club_portal/Club Portal/Club Portal/ViewModels/DashViewModel.swift b/Club_portal/Club Portal/Club Portal/ViewModels/DashViewModel.swift index de63924..73e63f3 100644 --- a/Club_portal/Club Portal/Club Portal/ViewModels/DashViewModel.swift +++ b/Club_portal/Club Portal/Club Portal/ViewModels/DashViewModel.swift @@ -12,11 +12,11 @@ class DashViewModel: ObservableObject { @Published var dashboardfilters = "" @Published var statResponse : ClubStatisticsModel? - @Published var dailyReservations : [Reservation]? + @Published var dailyReservations : [ReservationList] = [] @Published var availRsp : AvailabliltyRsp? @Published var club : ClubDetail? @Published var clubDetail : ClubDetailsResponse? - @Published var profile : ProfileRsp? + @Published var profile : ProfileDetailResponse? @Published var sessionExpired = false func getStats(completion: @escaping () -> ()) { @@ -51,9 +51,9 @@ class DashViewModel: ObservableObject { let endpoint = ReservationListEndpoint(clubID: clubId) Task { do { - let result = try await APIService.shared.request(endpoint, responseType: ReservationRsp.self) - dailyReservations = result.list - print("Reservations:", result.list) + let result = try await APIService.shared.requestReservation(endpoint, responseType: ProfileRsp.self) + dailyReservations = result?.list ?? [] + print("Reservations:", result?.list) } catch { print("Error fetching reservations:", error) } @@ -78,11 +78,11 @@ class DashViewModel: ObservableObject { Task { do { - let result = try await APIService.shared.request(endpoint, responseType: ProfileRsp.self) + let result = try await APIService.shared.requestProfile(endpoint, responseType: ProfileRsp.self) profile = result - AppSettings.clubId = result.model?.club?.id ?? 0 - AppSettings.clubName = result.model?.club?.name ?? "" - AppSettings.clubName = result.model?.user?.email ?? "" + AppSettings.clubId = result?.model?.club?.id ?? 0 + AppSettings.clubName = result?.model?.club?.name ?? "" + AppSettings.clubName = result?.model?.user?.email ?? "" } catch { print("Error fetching reservations:", error) @@ -91,7 +91,7 @@ class DashViewModel: ObservableObject { } func getClubProfile(){ - let endpoint = GetClubEndpoint(clubId: "10") + let endpoint = GetClubEndpoint(clubId: "\(AppSettings.clubId)") Task { do { let result = try await APIService.shared.request(endpoint, responseType: ClubDetail.self)