working on calendar slot issue
This commit is contained in:
@@ -7,6 +7,8 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* 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 */; };
|
ACAC2DEB2D9F2C1900869E5C /* CalendarKit in Frameworks */ = {isa = PBXBuildFile; productRef = ACAC2DEA2D9F2C1900869E5C /* CalendarKit */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@@ -27,7 +29,9 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
AC136A092DB96847009D478F /* ObjectMapper in Frameworks */,
|
||||||
ACAC2DEB2D9F2C1900869E5C /* CalendarKit in Frameworks */,
|
ACAC2DEB2D9F2C1900869E5C /* CalendarKit in Frameworks */,
|
||||||
|
AC53DEAA2DB9476D003445AD /* Alamofire in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -71,6 +75,8 @@
|
|||||||
name = "Club Portal";
|
name = "Club Portal";
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
ACAC2DEA2D9F2C1900869E5C /* CalendarKit */,
|
ACAC2DEA2D9F2C1900869E5C /* CalendarKit */,
|
||||||
|
AC53DEA92DB9476D003445AD /* Alamofire */,
|
||||||
|
AC136A082DB96847009D478F /* ObjectMapper */,
|
||||||
);
|
);
|
||||||
productName = "Club Portal";
|
productName = "Club Portal";
|
||||||
productReference = ACAC2DCF2D9F271300869E5C /* Club Portal.app */;
|
productReference = ACAC2DCF2D9F271300869E5C /* Club Portal.app */;
|
||||||
@@ -102,6 +108,8 @@
|
|||||||
minimizedProjectReferenceProxies = 1;
|
minimizedProjectReferenceProxies = 1;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
ACAC2DE92D9F2C1900869E5C /* XCRemoteSwiftPackageReference "CalendarKit" */,
|
ACAC2DE92D9F2C1900869E5C /* XCRemoteSwiftPackageReference "CalendarKit" */,
|
||||||
|
AC53DEA82DB9476D003445AD /* XCRemoteSwiftPackageReference "Alamofire" */,
|
||||||
|
AC136A072DB96847009D478F /* XCRemoteSwiftPackageReference "ObjectMapper" */,
|
||||||
);
|
);
|
||||||
preferredProjectObjectVersion = 77;
|
preferredProjectObjectVersion = 77;
|
||||||
productRefGroup = ACAC2DD02D9F271300869E5C /* Products */;
|
productRefGroup = ACAC2DD02D9F271300869E5C /* Products */;
|
||||||
@@ -343,6 +351,22 @@
|
|||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference 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" */ = {
|
ACAC2DE92D9F2C1900869E5C /* XCRemoteSwiftPackageReference "CalendarKit" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/richardtop/CalendarKit";
|
repositoryURL = "https://github.com/richardtop/CalendarKit";
|
||||||
@@ -354,6 +378,16 @@
|
|||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency 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 */ = {
|
ACAC2DEA2D9F2C1900869E5C /* CalendarKit */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = ACAC2DE92D9F2C1900869E5C /* XCRemoteSwiftPackageReference "CalendarKit" */;
|
package = ACAC2DE92D9F2C1900869E5C /* XCRemoteSwiftPackageReference "CalendarKit" */;
|
||||||
|
|||||||
+19
-1
@@ -1,6 +1,15 @@
|
|||||||
{
|
{
|
||||||
"originHash" : "67a1c5e835fc1360427d7e9a548368960eed766e429f7c9f11a95a0e99d682d9",
|
"originHash" : "60390f3252b346980a2b0f96582e92fec2c37e9487d7b684f3d58a001c214046",
|
||||||
"pins" : [
|
"pins" : [
|
||||||
|
{
|
||||||
|
"identity" : "alamofire",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/Alamofire/Alamofire.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "513364f870f6bfc468f9d2ff0a95caccc10044c5",
|
||||||
|
"version" : "5.10.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "calendarkit",
|
"identity" : "calendarkit",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
@@ -9,6 +18,15 @@
|
|||||||
"revision" : "89e02a1472e9ad815ae72b62fd15430144fd1c4c",
|
"revision" : "89e02a1472e9ad815ae72b62fd15430144fd1c4c",
|
||||||
"version" : "1.1.11"
|
"version" : "1.1.11"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "objectmapper",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/tristanhimmelman/ObjectMapper.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "6021c6035e83a306047348666f6400dc61445d3b",
|
||||||
|
"version" : "4.4.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 3
|
"version" : 3
|
||||||
|
|||||||
+85
-21
@@ -8,7 +8,7 @@
|
|||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
uuid = "D5681314-32C1-4998-BEBF-D4691C886BC2"
|
uuid = "D5681314-32C1-4998-BEBF-D4691C886BC2"
|
||||||
shouldBeEnabled = "Yes"
|
shouldBeEnabled = "No"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No"
|
continueAfterRunningActions = "No"
|
||||||
filePath = "Club Portal/ViewModels/DashViewModel.swift"
|
filePath = "Club Portal/ViewModels/DashViewModel.swift"
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
uuid = "9DDEE31F-4183-4E3A-8568-5DBD8C04570A"
|
uuid = "9DDEE31F-4183-4E3A-8568-5DBD8C04570A"
|
||||||
shouldBeEnabled = "Yes"
|
shouldBeEnabled = "No"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No"
|
continueAfterRunningActions = "No"
|
||||||
filePath = "Club Portal/ViewModels/DashViewModel.swift"
|
filePath = "Club Portal/ViewModels/DashViewModel.swift"
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
uuid = "002CCE4B-DBB4-4BE0-82C0-03D8524CC2DA"
|
uuid = "002CCE4B-DBB4-4BE0-82C0-03D8524CC2DA"
|
||||||
shouldBeEnabled = "Yes"
|
shouldBeEnabled = "No"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No"
|
continueAfterRunningActions = "No"
|
||||||
filePath = "Club Portal/ViewModels/DashViewModel.swift"
|
filePath = "Club Portal/ViewModels/DashViewModel.swift"
|
||||||
@@ -196,22 +196,6 @@
|
|||||||
landmarkType = "7">
|
landmarkType = "7">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "E284DADA-1EA8-4DBD-89DA-714E86264DCF"
|
|
||||||
shouldBeEnabled = "Yes"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "Club Portal/UI/DailySecheduler/ScheduleView.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "76"
|
|
||||||
endingLineNumber = "76"
|
|
||||||
landmarkName = "body"
|
|
||||||
landmarkType = "24">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
<BreakpointProxy
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
@@ -232,7 +216,7 @@
|
|||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
uuid = "1D973B51-0BF4-4CAE-9D3D-08BB2000E001"
|
uuid = "1D973B51-0BF4-4CAE-9D3D-08BB2000E001"
|
||||||
shouldBeEnabled = "Yes"
|
shouldBeEnabled = "No"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No"
|
continueAfterRunningActions = "No"
|
||||||
filePath = "Club Portal/UI/Dashboard/DashboardView.swift"
|
filePath = "Club Portal/UI/Dashboard/DashboardView.swift"
|
||||||
@@ -264,7 +248,7 @@
|
|||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
uuid = "692D9FC1-2C27-4BD9-BF6C-1817B389E36A"
|
uuid = "692D9FC1-2C27-4BD9-BF6C-1817B389E36A"
|
||||||
shouldBeEnabled = "Yes"
|
shouldBeEnabled = "No"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No"
|
continueAfterRunningActions = "No"
|
||||||
filePath = "Club Portal/ViewModels/AuthViewModel1.swift"
|
filePath = "Club Portal/ViewModels/AuthViewModel1.swift"
|
||||||
@@ -276,5 +260,85 @@
|
|||||||
landmarkType = "7">
|
landmarkType = "7">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
uuid = "9F0229B2-427C-4F86-BB4B-02C7B32822AA"
|
||||||
|
shouldBeEnabled = "No"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Club Portal/Network/Api_Stuff/APIError.swift"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "60"
|
||||||
|
endingLineNumber = "60"
|
||||||
|
landmarkName = "request(_:responseType:)"
|
||||||
|
landmarkType = "7">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
uuid = "D4FFED32-06EF-4269-A4CC-2E38B7C48467"
|
||||||
|
shouldBeEnabled = "No"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Club Portal/Network/Api_Stuff/APIError.swift"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "57"
|
||||||
|
endingLineNumber = "57"
|
||||||
|
landmarkName = "request(_:responseType:)"
|
||||||
|
landmarkType = "7">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
uuid = "D6562595-44F2-4161-B839-AB9E5F01BC4A"
|
||||||
|
shouldBeEnabled = "No"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Club Portal/UI/DailySecheduler/FilterView1.swift"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "65"
|
||||||
|
endingLineNumber = "65"
|
||||||
|
landmarkName = "body"
|
||||||
|
landmarkType = "24">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
uuid = "2F83466D-D868-4502-8601-E4770581F3EB"
|
||||||
|
shouldBeEnabled = "Yes"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Club Portal/UI/DailySecheduler/ScheduleView.swift"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "241"
|
||||||
|
endingLineNumber = "241"
|
||||||
|
landmarkName = "eventOverlay(for:)"
|
||||||
|
landmarkType = "7">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
uuid = "EDD74E11-A7AD-4B5F-919B-B2DEB378DD99"
|
||||||
|
shouldBeEnabled = "Yes"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Club Portal/UI/DailySecheduler/ScheduleView.swift"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "239"
|
||||||
|
endingLineNumber = "239"
|
||||||
|
landmarkName = "eventOverlay(for:)"
|
||||||
|
landmarkType = "7">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
</Breakpoints>
|
</Breakpoints>
|
||||||
</Bucket>
|
</Bucket>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
enum APIError: Error, CustomStringConvertible {
|
enum APIError: Error, CustomStringConvertible {
|
||||||
case invalidURL
|
case invalidURL
|
||||||
@@ -55,6 +56,8 @@ final class APIService {
|
|||||||
|
|
||||||
if let responseString = String(data: data, encoding: .utf8) {
|
if let responseString = String(data: data, encoding: .utf8) {
|
||||||
print("Response: \(responseString)")
|
print("Response: \(responseString)")
|
||||||
|
// let resp = ProfileDetailResponse(JSONString: responseString)
|
||||||
|
// print(resp)
|
||||||
} else {
|
} else {
|
||||||
print("Failed to convert response data to string")
|
print("Failed to convert response data to string")
|
||||||
}
|
}
|
||||||
@@ -78,6 +81,99 @@ final class APIService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func requestReservation<T: Decodable>(_ 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<T: Decodable>(_ 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<T: Decodable>(endpoint: Endpoint, responseType: T.Type) async throws -> T {
|
private func uploadMultipart<T: Decodable>(endpoint: Endpoint, responseType: T.Type) async throws -> T {
|
||||||
guard var request = endpoint.urlRequest else { throw APIError.invalidURL }
|
guard var request = endpoint.urlRequest else { throw APIError.invalidURL }
|
||||||
|
|
||||||
@@ -115,6 +211,72 @@ final class APIService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// func requestWithAlamofire<T: Decodable>(_ 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<T: Decodable>(_ 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 {
|
struct ErrorResponse: Codable {
|
||||||
|
|||||||
+2
@@ -33,6 +33,8 @@ struct ClubStatisticsEndpoint: Endpoint {
|
|||||||
|
|
||||||
var isMultipart: Bool { false }
|
var isMultipart: Bool { false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct GetClubEndpoint: Endpoint {
|
struct GetClubEndpoint: Endpoint {
|
||||||
var path: String {
|
var path: String {
|
||||||
"/v3/api/custom/courtmatchup/user/club/\(clubId)"
|
"/v3/api/custom/courtmatchup/user/club/\(clubId)"
|
||||||
|
|||||||
+1
-2
@@ -8,9 +8,8 @@ import SwiftUI
|
|||||||
|
|
||||||
struct ReservationListEndpoint: Endpoint {
|
struct ReservationListEndpoint: Endpoint {
|
||||||
var urlQueryItems: [URLQueryItem] = []
|
var urlQueryItems: [URLQueryItem] = []
|
||||||
|
|
||||||
var path: String {
|
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 }
|
var method: HTTPMethod { .get }
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ struct ClubDetailsResponse: Codable {
|
|||||||
// MARK: - Club Details Model
|
// MARK: - Club Details Model
|
||||||
struct ClubDetailsModel: Codable {
|
struct ClubDetailsModel: Codable {
|
||||||
let user: ClubUser
|
let user: ClubUser
|
||||||
let club: Club
|
let club: ClubSport
|
||||||
let courts: [Court]
|
let courts: [Court]
|
||||||
let sports: [Sport]
|
let sports: [Sport]
|
||||||
let pricing: [Pricing]
|
let pricing: [Pricing]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import Foundation
|
|||||||
struct ClubDetail: Codable {
|
struct ClubDetail: Codable {
|
||||||
let error: Bool?
|
let error: Bool?
|
||||||
let model: Model?
|
let model: Model?
|
||||||
let sports: [Club]?
|
let sports: [Club1]?
|
||||||
let courts: [Court]?
|
let courts: [Court]?
|
||||||
let pricing: [Pricing]?
|
let pricing: [Pricing]?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+19
@@ -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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+22
@@ -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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+347
-133
@@ -1,146 +1,360 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import ObjectMapper
|
||||||
|
|
||||||
|
class ReservationResponse : Mappable {
|
||||||
|
var list : [ReservationList]?
|
||||||
|
|
||||||
|
required init?(map: Map) {
|
||||||
|
|
||||||
// MARK: - Root
|
|
||||||
struct ReservationRsp: Codable {
|
|
||||||
let list: [Reservation]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Reservation
|
func mapping(map: Map) {
|
||||||
struct Reservation: Codable {
|
|
||||||
let id: Int
|
list <- map["list"]
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - User
|
|
||||||
struct User: Codable {
|
class ReservationList : Mappable, Identifiable {
|
||||||
let id: Int
|
var id : Int?
|
||||||
let oauth: String?
|
var booking_id : Int?
|
||||||
let role: String
|
var buddy_id : String?
|
||||||
let firstName: String
|
var space_assigned : String?
|
||||||
let lastName: String
|
var user_id : Int?
|
||||||
let email: String
|
var club_id : Int?
|
||||||
let password: String
|
var reservation_type : String?
|
||||||
let type: Int
|
var status : Int?
|
||||||
let alternativePhone: String?
|
var check_in : Int?
|
||||||
let ageGroup: String?
|
var recurring : Int?
|
||||||
let familyRole: String?
|
var notes : String?
|
||||||
let defaultPaymentMethod: String?
|
var create_at : String?
|
||||||
let guardian: Int
|
var update_at : String?
|
||||||
let passwordLogin: String
|
var booking : Booking?
|
||||||
let verify: Int
|
var user : ObjUser?
|
||||||
let clubID: Int?
|
var buddy : Buddy?
|
||||||
let phone: String?
|
var clubs : Clubs?
|
||||||
let photo: String?
|
|
||||||
let bio: String?
|
required init?(map: Map) {
|
||||||
let refer: String?
|
|
||||||
let stripeUID: String?
|
|
||||||
let paypalUID: String?
|
|
||||||
let twoFactorAuthentication: String?
|
|
||||||
let status: Int
|
|
||||||
let createAt: String
|
|
||||||
let updateAt: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Buddy
|
func mapping(map: Map) {
|
||||||
struct Buddy: Codable {
|
|
||||||
// Add properties if needed
|
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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,16 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
struct ScheduleFilterView: View {
|
struct ScheduleFilterView: View {
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
@Binding var navigationPaths: [String]
|
@Binding var navigationPaths: [String]
|
||||||
|
|
||||||
@State private var isClubExpanded = true
|
@State private var isClubExpanded = true
|
||||||
@State private var selectedClubs: Set<String> = [] // 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
|
@EnvironmentObject var dasModel: DashViewModel
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -27,15 +28,14 @@ struct ScheduleFilterView: View {
|
|||||||
// Club Filter Section
|
// Club Filter Section
|
||||||
DisclosureGroup(isExpanded: $isClubExpanded) {
|
DisclosureGroup(isExpanded: $isClubExpanded) {
|
||||||
VStack(spacing: 10) {
|
VStack(spacing: 10) {
|
||||||
if let clubs = dasModel.club?.courts {
|
if let clubs = dasModel.profile?.model?.courts {
|
||||||
ForEach(clubs, id: \.self) { court in
|
ForEach(clubs, id: \.self) { court in
|
||||||
if let clubName = court.name {
|
if let clubName = court.name {
|
||||||
ClubCheckboxRow(clubName: clubName, isSelected: selectedClubs.contains(clubName)) {
|
ClubCheckboxRow(
|
||||||
if selectedClubs.contains(clubName) {
|
clubName: clubName,
|
||||||
selectedClubs.remove(clubName)
|
isSelected: selectedClub == clubName
|
||||||
} else {
|
) {
|
||||||
selectedClubs.insert(clubName)
|
selectedClub = (selectedClub == clubName) ? nil : clubName
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,11 @@ struct ScheduleFilterView: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Button(action: {
|
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()
|
self.navigationPaths.removeLast()
|
||||||
}) {
|
}) {
|
||||||
Text("Apply and close")
|
Text("Apply and close")
|
||||||
@@ -72,9 +76,6 @@ struct ScheduleFilterView: View {
|
|||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
.padding(.vertical, 10)
|
|
||||||
.background(Color.white)
|
|
||||||
}
|
|
||||||
.navigationTitle("Filter")
|
.navigationTitle("Filter")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.background(Color(.systemGray6).ignoresSafeArea())
|
.background(Color(.systemGray6).ignoresSafeArea())
|
||||||
@@ -104,3 +105,4 @@ struct ClubCheckboxRow: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct Event: Identifiable {
|
|
||||||
let id = UUID()
|
|
||||||
let title: String
|
|
||||||
let startTime: Date
|
|
||||||
let endTime: Date
|
|
||||||
let color: Color
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ScheduleView: View {
|
struct ScheduleView: View {
|
||||||
@State var navigationPaths: [String] = []
|
@State var navigationPaths: [String] = []
|
||||||
@State private var selectedDate = Date()
|
@State private var selectedDate = Date()
|
||||||
@State private var displayedMonth = Date()
|
@State private var displayedMonth = Date()
|
||||||
@State private var events: [Event] = []
|
// @State private var events: [ReservationList] = []
|
||||||
@Binding var presentSideMenu: Bool // Optional for side menu
|
@Binding var presentSideMenu: Bool // Optional for side menu
|
||||||
|
@State var courtName = ""
|
||||||
let hours = Array(8...20)
|
let hours = Array(4...20)
|
||||||
let calendar = Calendar.current
|
let calendar = Calendar.current
|
||||||
|
|
||||||
@EnvironmentObject var viewModel : DashViewModel
|
@EnvironmentObject var viewModel : DashViewModel
|
||||||
@@ -47,11 +41,17 @@ struct ScheduleView: View {
|
|||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
Text(courtName)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
// Time Slots with Events
|
// Time Slots with Events
|
||||||
ScrollView {
|
ScrollView {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
ForEach(hours, id: \.self) { hour in
|
ForEach(hours, id: \.self) { hour in
|
||||||
timeSlotRow(hour: hour)
|
timeSlotRow(hour: hour)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
@@ -62,18 +62,20 @@ struct ScheduleView: View {
|
|||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
// loadDummyEvents()
|
// loadDummyEvents()
|
||||||
viewModel.getDailySched(clubId: 10)
|
|
||||||
|
|
||||||
if let club = self.viewModel.club {
|
if let club = self.viewModel.profile {
|
||||||
print(club.courts?.count)
|
print(club.model?.courts?.count)
|
||||||
|
// viewModel.getDailySched(clubId: club.model?.courts?.first?.id ?? 0)
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
viewModel.getClubProfile()
|
viewModel.getProfile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationDestination(for: String.self) { value in
|
.navigationDestination(for: String.self) { value in
|
||||||
if value == "DailyFilterView" {
|
if value == "DailyFilterView" {
|
||||||
ScheduleFilterView(navigationPaths: $navigationPaths) { filter in
|
ScheduleFilterView(navigationPaths: $navigationPaths) { filter in
|
||||||
viewModel.getDailySched(clubId: filter)
|
self.courtName = filter.name ?? ""
|
||||||
|
viewModel.getDailySched(clubId: filter.id ?? 0)
|
||||||
}
|
}
|
||||||
}else if value == "ReservationDetailsView" {
|
}else if value == "ReservationDetailsView" {
|
||||||
ReservationDetailsView()
|
ReservationDetailsView()
|
||||||
@@ -201,6 +203,7 @@ struct ScheduleView: View {
|
|||||||
Text(timeLabel(for: hour))
|
Text(timeLabel(for: hour))
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.frame(width: 50, alignment: .leading)
|
.frame(width: 50, alignment: .leading)
|
||||||
|
.padding(.top)
|
||||||
|
|
||||||
ZStack(alignment: .topLeading) {
|
ZStack(alignment: .topLeading) {
|
||||||
Rectangle()
|
Rectangle()
|
||||||
@@ -216,21 +219,40 @@ struct ScheduleView: View {
|
|||||||
|
|
||||||
func eventOverlay(for hour: Int) -> some View {
|
func eventOverlay(for hour: Int) -> some View {
|
||||||
VStack(spacing: 4) {
|
VStack(spacing: 4) {
|
||||||
ForEach(events.filter {
|
ForEach(
|
||||||
calendar.isDate($0.startTime, inSameDayAs: selectedDate)
|
viewModel.dailyReservations.filter({ event in
|
||||||
&& calendar.component(.hour, from: $0.startTime) == hour
|
guard let eventDateString = event.booking?.date,
|
||||||
}) { event in
|
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) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
Text(event.title)
|
Text(event.booking?.type ?? "- -")
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.bold()
|
.bold()
|
||||||
Text("\(timeOnly(event.startTime)) - \(timeOnly(event.endTime))")
|
Text("\(event.booking!.start_time!.to12HourFormat()) - \(event.booking!.end_time!.to12HourFormat())")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
}
|
}
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.background(event.color.opacity(0.2))
|
.background(Colorr.greenColor.opacity(0.2))
|
||||||
.foregroundColor(event.color)
|
.foregroundColor(Colorr.greenColor.opacity(0.8))
|
||||||
.cornerRadius(12)
|
.cornerRadius(12)
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
||||||
.background(Color.clear)
|
.background(Color.clear)
|
||||||
@@ -245,23 +267,23 @@ struct ScheduleView: View {
|
|||||||
|
|
||||||
// MARK: - Utility
|
// MARK: - Utility
|
||||||
|
|
||||||
func loadDummyEvents() {
|
// func loadDummyEvents() {
|
||||||
let baseDate = calendar.startOfDay(for: Date())
|
// let baseDate = calendar.startOfDay(for: Date())
|
||||||
events = [
|
// events = [
|
||||||
Event(
|
// Event(
|
||||||
title: "Court reserved",
|
// title: "Court reserved",
|
||||||
startTime: calendar.date(bySettingHour: 9, minute: 0, second: 0, of: baseDate)!,
|
// startTime: calendar.date(bySettingHour: 9, minute: 0, second: 0, of: baseDate)!,
|
||||||
endTime: calendar.date(bySettingHour: 10, minute: 0, second: 0, of: baseDate)!,
|
// endTime: calendar.date(bySettingHour: 10, minute: 0, second: 0, of: baseDate)!,
|
||||||
color: .green
|
// color: .green
|
||||||
),
|
// ),
|
||||||
Event(
|
// Event(
|
||||||
title: "Clinic",
|
// title: "Clinic",
|
||||||
startTime: calendar.date(bySettingHour: 11, minute: 30, second: 0, of: baseDate)!,
|
// startTime: calendar.date(bySettingHour: 11, minute: 30, second: 0, of: baseDate)!,
|
||||||
endTime: calendar.date(bySettingHour: 13, minute: 0, second: 0, of: baseDate)!,
|
// endTime: calendar.date(bySettingHour: 13, minute: 0, second: 0, of: baseDate)!,
|
||||||
color: .purple
|
// color: .purple
|
||||||
)
|
// )
|
||||||
]
|
// ]
|
||||||
}
|
// }
|
||||||
|
|
||||||
func getDatesForMonth(from date: Date) -> [Date] {
|
func getDatesForMonth(from date: Date) -> [Date] {
|
||||||
let range = calendar.range(of: .day, in: .month, for: date)!
|
let range = calendar.range(of: .day, in: .month, for: date)!
|
||||||
@@ -296,7 +318,7 @@ struct ScheduleView: View {
|
|||||||
func timeLabel(for hour: Int) -> String {
|
func timeLabel(for hour: Int) -> String {
|
||||||
let date = calendar.date(bySettingHour: hour, minute: 0, second: 0, of: Date())!
|
let date = calendar.date(bySettingHour: hour, minute: 0, second: 0, of: Date())!
|
||||||
let formatter = DateFormatter()
|
let formatter = DateFormatter()
|
||||||
formatter.dateFormat = "h a"
|
formatter.dateFormat = "h:mm a"
|
||||||
return formatter.string(from: date)
|
return formatter.string(from: date)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,3 +326,39 @@ struct ScheduleView: View {
|
|||||||
calendar.isDate(a, inSameDayAs: b)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ struct SummaryView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// viewModel.getClubProfile()
|
// viewModel.getClubProfile()
|
||||||
// viewModel.getProfile()
|
viewModel.getProfile()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,33 +167,33 @@ extension String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func to12HourFormat() -> String? {
|
// func to12HourFormat() -> String? {
|
||||||
let inputDateFormatter = DateFormatter()
|
// let inputDateFormatter = DateFormatter()
|
||||||
inputDateFormatter.dateFormat = "HH:mm:ss" // Input format (24-hour)
|
// inputDateFormatter.dateFormat = "HH:mm:ss" // Input format (24-hour)
|
||||||
|
//
|
||||||
let outputDateFormatter = DateFormatter()
|
// let outputDateFormatter = DateFormatter()
|
||||||
outputDateFormatter.dateFormat = "hh:mm a" // Output format (12-hour with AM/PM)
|
// outputDateFormatter.dateFormat = "hh:mm a" // Output format (12-hour with AM/PM)
|
||||||
|
//
|
||||||
// Split the range into start and end times
|
// // Split the range into start and end times
|
||||||
let timeComponents = self.components(separatedBy: "-")
|
// let timeComponents = self.components(separatedBy: "-")
|
||||||
|
//
|
||||||
if timeComponents.count == 2 {
|
// if timeComponents.count == 2 {
|
||||||
let startTime = inputDateFormatter.date(from: timeComponents[0])
|
// let startTime = inputDateFormatter.date(from: timeComponents[0])
|
||||||
let endTime = inputDateFormatter.date(from: timeComponents[1])
|
// let endTime = inputDateFormatter.date(from: timeComponents[1])
|
||||||
|
//
|
||||||
let start12Hour = outputDateFormatter.string(from: startTime!)
|
// let start12Hour = outputDateFormatter.string(from: startTime!)
|
||||||
let end12Hour = outputDateFormatter.string(from: endTime!)
|
// let end12Hour = outputDateFormatter.string(from: endTime!)
|
||||||
|
//
|
||||||
return "\(start12Hour) - \(end12Hour)"
|
// return "\(start12Hour) - \(end12Hour)"
|
||||||
}else {
|
// }else {
|
||||||
let startTime = inputDateFormatter.date(from: self)
|
// let startTime = inputDateFormatter.date(from: self)
|
||||||
let start12Hour = outputDateFormatter.string(from: startTime!)
|
// let start12Hour = outputDateFormatter.string(from: startTime!)
|
||||||
|
//
|
||||||
return start12Hour
|
// return start12Hour
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Return nil if conversion fails
|
// // Return nil if conversion fails
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ class DashViewModel: ObservableObject {
|
|||||||
|
|
||||||
@Published var dashboardfilters = ""
|
@Published var dashboardfilters = ""
|
||||||
@Published var statResponse : ClubStatisticsModel?
|
@Published var statResponse : ClubStatisticsModel?
|
||||||
@Published var dailyReservations : [Reservation]?
|
@Published var dailyReservations : [ReservationList] = []
|
||||||
@Published var availRsp : AvailabliltyRsp?
|
@Published var availRsp : AvailabliltyRsp?
|
||||||
@Published var club : ClubDetail?
|
@Published var club : ClubDetail?
|
||||||
@Published var clubDetail : ClubDetailsResponse?
|
@Published var clubDetail : ClubDetailsResponse?
|
||||||
@Published var profile : ProfileRsp?
|
@Published var profile : ProfileDetailResponse?
|
||||||
@Published var sessionExpired = false
|
@Published var sessionExpired = false
|
||||||
|
|
||||||
func getStats(completion: @escaping () -> ()) {
|
func getStats(completion: @escaping () -> ()) {
|
||||||
@@ -51,9 +51,9 @@ class DashViewModel: ObservableObject {
|
|||||||
let endpoint = ReservationListEndpoint(clubID: clubId)
|
let endpoint = ReservationListEndpoint(clubID: clubId)
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let result = try await APIService.shared.request(endpoint, responseType: ReservationRsp.self)
|
let result = try await APIService.shared.requestReservation(endpoint, responseType: ProfileRsp.self)
|
||||||
dailyReservations = result.list
|
dailyReservations = result?.list ?? []
|
||||||
print("Reservations:", result.list)
|
print("Reservations:", result?.list)
|
||||||
} catch {
|
} catch {
|
||||||
print("Error fetching reservations:", error)
|
print("Error fetching reservations:", error)
|
||||||
}
|
}
|
||||||
@@ -78,11 +78,11 @@ class DashViewModel: ObservableObject {
|
|||||||
Task {
|
Task {
|
||||||
do {
|
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
|
profile = result
|
||||||
AppSettings.clubId = result.model?.club?.id ?? 0
|
AppSettings.clubId = result?.model?.club?.id ?? 0
|
||||||
AppSettings.clubName = result.model?.club?.name ?? ""
|
AppSettings.clubName = result?.model?.club?.name ?? ""
|
||||||
AppSettings.clubName = result.model?.user?.email ?? ""
|
AppSettings.clubName = result?.model?.user?.email ?? ""
|
||||||
|
|
||||||
} catch {
|
} catch {
|
||||||
print("Error fetching reservations:", error)
|
print("Error fetching reservations:", error)
|
||||||
@@ -91,7 +91,7 @@ class DashViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getClubProfile(){
|
func getClubProfile(){
|
||||||
let endpoint = GetClubEndpoint(clubId: "10")
|
let endpoint = GetClubEndpoint(clubId: "\(AppSettings.clubId)")
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let result = try await APIService.shared.request(endpoint, responseType: ClubDetail.self)
|
let result = try await APIService.shared.request(endpoint, responseType: ClubDetail.self)
|
||||||
|
|||||||
Reference in New Issue
Block a user