diff --git a/SportApp.xcodeproj/project.xcworkspace/xcuserdata/user.xcuserdatad/UserInterfaceState.xcuserstate b/SportApp.xcodeproj/project.xcworkspace/xcuserdata/user.xcuserdatad/UserInterfaceState.xcuserstate index 780f8e5..1685eb2 100644 Binary files a/SportApp.xcodeproj/project.xcworkspace/xcuserdata/user.xcuserdatad/UserInterfaceState.xcuserstate and b/SportApp.xcodeproj/project.xcworkspace/xcuserdata/user.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/SportApp/HomeView.swift b/SportApp/HomeView.swift index d06152d..7d67a6c 100644 --- a/SportApp/HomeView.swift +++ b/SportApp/HomeView.swift @@ -64,6 +64,14 @@ struct HomeView: View { Label("Главная", systemImage: "house.fill") } .tag(0) // исправить потом + + NavigationStack() { + EmptyView() + } + .tabItem { + Label("Мои матчи", systemImage: "pawprint.circle.fill") + } + .tag(1) NavigationStack() { ProfileView(isActive: $isAuthenticated) @@ -73,7 +81,8 @@ struct HomeView: View { .tabItem { Label("Профиль", systemImage: "person.crop.circle") } - .tag(1) + + .tag(2) } } diff --git a/SportApp/NetworkService/Data/APIRoutes.swift b/SportApp/NetworkService/Data/APIRoutes.swift index 86aae18..0573510 100644 --- a/SportApp/NetworkService/Data/APIRoutes.swift +++ b/SportApp/NetworkService/Data/APIRoutes.swift @@ -14,4 +14,5 @@ struct APIRoutes { let login: String = "/api/v1/auth/login" let register: String = "/api/v1/auth/register" let getUserInfo: String = "/api/v1/users/" + let getParticipants: String = "/api/v1/tournaments/{id}/participants" } diff --git a/SportApp/Statistics/View/StatisticsView.swift b/SportApp/Statistics/View/StatisticsView.swift new file mode 100644 index 0000000..0c79298 --- /dev/null +++ b/SportApp/Statistics/View/StatisticsView.swift @@ -0,0 +1,7 @@ +// +// StatisticsView.swift +// SportApp +// +// Created by user on 11.07.2025. +// + diff --git a/SportApp/Tournirs/Model/DTO/.DS_Store b/SportApp/Tournirs/Model/DTO/.DS_Store new file mode 100644 index 0000000..fbf6254 Binary files /dev/null and b/SportApp/Tournirs/Model/DTO/.DS_Store differ diff --git a/SportApp/Tournirs/Model/Participant.swift b/SportApp/Tournirs/Model/Participant.swift new file mode 100644 index 0000000..5b50cbe --- /dev/null +++ b/SportApp/Tournirs/Model/Participant.swift @@ -0,0 +1,19 @@ +// +// Participant.swift +// SportApp +// +// Created by user on 10.07.2025. +// + +import Foundation + +struct Participant: Identifiable, Hashable, Codable { + var id: UUID + var phio: String + var phone_number: String? + var email: String + var age: Int? + var sex: Bool? + var weight: Double? + var height: Double? +} diff --git a/SportApp/Tournirs/Model/Participant/ParticipantDTO.swift b/SportApp/Tournirs/Model/Participant/ParticipantDTO.swift new file mode 100644 index 0000000..a77a0e7 --- /dev/null +++ b/SportApp/Tournirs/Model/Participant/ParticipantDTO.swift @@ -0,0 +1,24 @@ +// +// Participants.swift +// SportApp +// +// Created by user on 09.07.2025. +// + +import Foundation + +struct ParticipantDTO: Identifiable, Hashable, Codable { + var id: String + var name: String + var surname: String + var patronymic: String + var phone_number: String? + var email: String + var date_of_birth: String? + var sex: String? + var weight: Double? + var height: Double? + var bio: String? + var avatar_url: String? + +} diff --git a/SportApp/Tournirs/Model/Participant/ParticipantEndpoint.swift b/SportApp/Tournirs/Model/Participant/ParticipantEndpoint.swift new file mode 100644 index 0000000..4a95898 --- /dev/null +++ b/SportApp/Tournirs/Model/Participant/ParticipantEndpoint.swift @@ -0,0 +1,27 @@ +// +// ParticipantsEndpoint.swift +// SportApp +// +// Created by user on 09.07.2025. +// + +import Foundation + +struct ParticipantEndpoint: Endpoint { + var baseURL = APIRoutes().baseURL + var tournamentID: String + + var path: String { + return APIRoutes().getParticipants.replacingOccurrences(of: "{id}", with: "\(tournamentID)") + } + + var method = HTTPMethod.get + var headers: [String: String]? = ["Content-Type": "application/json"] + var loginString: String? = "Admin:hashedpassword" + var isTokenRequired: Bool = true + + init(tournamentID: String) { + self.tournamentID = tournamentID + } +} + diff --git a/SportApp/Tournirs/Model/Participant/ParticipantPostEndpoint.swift b/SportApp/Tournirs/Model/Participant/ParticipantPostEndpoint.swift new file mode 100644 index 0000000..7328898 --- /dev/null +++ b/SportApp/Tournirs/Model/Participant/ParticipantPostEndpoint.swift @@ -0,0 +1,22 @@ +// +// ParticipantsPostEndpoint.swift +// SportApp +// +// Created by user on 09.07.2025. +// + +import Foundation + +struct ParticipantPostEndpoint: Endpoint { + var baseURL = APIRoutes().baseURL + + var path = APIRoutes().getParticipants + + var method = HTTPMethod.post + + var headers: [String: String]? + + var loginString: String? + + var isTokenRequired: Bool = true +} diff --git a/SportApp/Tournirs/Model/Participant/ParticipantPostRequest.swift b/SportApp/Tournirs/Model/Participant/ParticipantPostRequest.swift new file mode 100644 index 0000000..cb116e1 --- /dev/null +++ b/SportApp/Tournirs/Model/Participant/ParticipantPostRequest.swift @@ -0,0 +1,21 @@ +// +// ParticipantPostRequest.swift +// SportApp +// +// Created by user on 09.07.2025. +// + +import Foundation + +struct ParticipantPostRequest: Encodable { + var id: String + var phio: String + var email: String + +/* + init(participant: Participant) { + id = participant.id + + } +*/ +} diff --git a/SportApp/Tournirs/Model/Participant/ParticipantRequest.swift b/SportApp/Tournirs/Model/Participant/ParticipantRequest.swift new file mode 100644 index 0000000..7d31b49 --- /dev/null +++ b/SportApp/Tournirs/Model/Participant/ParticipantRequest.swift @@ -0,0 +1,10 @@ +// +// ParticipantRequest.swift +// SportApp +// +// Created by user on 09.07.2025. +// + +import Foundation + +struct ParticipantRequest: RequestDTO {} diff --git a/SportApp/Tournirs/Model/Tournir.swift b/SportApp/Tournirs/Model/Tournir.swift index 0851235..6f7ebc0 100644 --- a/SportApp/Tournirs/Model/Tournir.swift +++ b/SportApp/Tournirs/Model/Tournir.swift @@ -8,7 +8,7 @@ import Foundation struct Tournir: Codable, Identifiable, Hashable { - var id = UUID() + var id: UUID var title: String var description: String var sport: String @@ -43,8 +43,8 @@ struct Requirements: Codable, Hashable { heightMax = 200 weightMin = 0 weightMax = 100 - mmrMin = 0 - mmrMax = 10000 + mmrMin = 500 + mmrMax = 3000 } } diff --git a/SportApp/Tournirs/View/TournirMaker.swift b/SportApp/Tournirs/View/TournirMaker.swift index b18eb97..94c95e2 100644 --- a/SportApp/Tournirs/View/TournirMaker.swift +++ b/SportApp/Tournirs/View/TournirMaker.swift @@ -177,7 +177,7 @@ struct TournirMaker: View { Spacer() Button(action: { - let tourinr: Tournir = Tournir(title: name, description: description, sport: Sport.toStringEng(Sport.allSports[selectedSport]), type_group: .olympic, type_tournir: .solo, start_time: combinedDateTime, created_at: Date(), entry_cost: Double(cost) ?? 0, is_team_based: true, place: "", max_participants: 10, organizer_id: UUID(), requirements: Requirements()) + let tourinr: Tournir = Tournir(id: UUID(), title: name, description: description, sport: Sport.toStringEng(Sport.allSports[selectedSport]), type_group: .olympic, type_tournir: .solo, start_time: combinedDateTime, created_at: Date(), entry_cost: Double(cost) ?? 0, is_team_based: true, place: "", max_participants: 10, organizer_id: UUID(), requirements: Requirements()) viewModel.tournirs.append(tourinr) viewModel.giveTournir(tournir: tourinr) coordinator.dismissSheet() diff --git a/SportApp/Tournirs/View/TournirsDetail.swift b/SportApp/Tournirs/View/TournirsDetail.swift index cb6548a..e97c4f0 100644 --- a/SportApp/Tournirs/View/TournirsDetail.swift +++ b/SportApp/Tournirs/View/TournirsDetail.swift @@ -9,6 +9,7 @@ import SwiftUI struct TournirsDetail: View { @EnvironmentObject var coordinator: Coordinator + @StateObject var viewModel = ParticipantsViewModel() var body: some View { VStack { @@ -68,7 +69,6 @@ struct TournirsDetail: View { .frame(height: 1) .padding(.horizontal, 12) - Text("Участники") List { HStack { @@ -76,20 +76,11 @@ struct TournirsDetail: View { .padding(.leading) Spacer() - - Text("MMR") - .padding(.trailing) } - - ForEach(coordinator.currentTournir!.users, id: \.id) { user in - HStack { - Text(user.phio) - .padding(.leading) - - Spacer() - - Text(String(Int(user.mmr ?? 0))) - .padding(.trailing) + ScrollView { + ForEach(viewModel.participants, id: \.id) { participant in + Text(participant.name) + .padding() } } } @@ -110,6 +101,9 @@ struct TournirsDetail: View { Spacer() } .navigationTitle("О соревновании") + .onAppear() { + viewModel.loadParticipants(for: coordinator.currentTournir!.id.uuidString) + } } } diff --git a/SportApp/Tournirs/ViewModel/ParticipantsViewModel.swift b/SportApp/Tournirs/ViewModel/ParticipantsViewModel.swift new file mode 100644 index 0000000..e24efb9 --- /dev/null +++ b/SportApp/Tournirs/ViewModel/ParticipantsViewModel.swift @@ -0,0 +1,58 @@ +// +// ParticipantsViewModel.swift +// SportApp +// +// Created by user on 09.07.2025. +// + +import Foundation +import Combine + +@MainActor +class ParticipantsViewModel: ObservableObject { + @Published var participants: [UserDTO] = [] + + func loadParticipants(for tournamentID: String) { + Task { + do { + participants = try await fetchParticipants(tournamentID: tournamentID) + print(participants) + } catch { + print(error) + } + } + } + + func fetchParticipants(tournamentID: String) async throws -> [UserDTO] { + let participantEndpoint = ParticipantEndpoint(tournamentID: tournamentID) + let participantRequest = ParticipantRequest() + + var participantResponses = [UserDTO]() + participantResponses = try await NetworkService.shared.request( + endpoint: participantEndpoint, + requestDTO: participantRequest + ) + + return participantResponses + } +/* + func giveParticipant(participant: Participant) { + Task { + let participantEndpoint = ParticipantPostEndpoint() + let participantRequest = ParticipantPostRequest(participant: participant) + + do { + let respone: ParticipantDTO = try await NetworkService.shared.request( + endpoint: participantEndpoint, + requestDTO: participantRequest + ) + print(син) + } catch { + print(error) + } + } + + */ + +} + diff --git a/SportApp/Tournirs/ViewModel/TournirsViewModel.swift b/SportApp/Tournirs/ViewModel/TournirsViewModel.swift index aaceef7..8e92e52 100644 --- a/SportApp/Tournirs/ViewModel/TournirsViewModel.swift +++ b/SportApp/Tournirs/ViewModel/TournirsViewModel.swift @@ -22,7 +22,7 @@ class TournirsViewModel: ObservableObject { do { tournirs = try await fetchTournirs() } catch { - tournirs = loadMockTournirs() + tournirs = [] } } } @@ -42,7 +42,7 @@ class TournirsViewModel: ObservableObject { } let mappedEvents = tournirResponses.map { dto -> Tournir in - Tournir(title: dto.title ?? "Unnamed", description: dto.description ?? "", sport: dto.sport ?? "Chess", type_group: TypeTournir.fromString(dto.typeGroup ?? ""), type_tournir: TypeIsTeam.fromString(dto.typeTournament ?? ""), start_time: Date(), created_at: Date(), entry_cost: Double(dto.entryCost ?? 0), is_team_based: true, place: dto.place ?? "", max_participants: Int(dto.maxParticipants ?? 0), organizer_id: UUID(), requirements: Requirements()) + Tournir(id: UUID(uuidString: dto.id) ?? UUID(), title: dto.title ?? "Unnamed", description: dto.description ?? "", sport: dto.sport ?? "Chess", type_group: TypeTournir.fromString(dto.typeGroup ?? ""), type_tournir: TypeIsTeam.fromString(dto.typeTournament ?? ""), start_time: Date(), created_at: Date(), entry_cost: Double(dto.entryCost ?? 0), is_team_based: true, place: dto.place ?? "", max_participants: Int(dto.maxParticipants ?? 0), organizer_id: UUID(), requirements: Requirements()) } return mappedEvents } @@ -63,7 +63,7 @@ class TournirsViewModel: ObservableObject { } } } - + /* func loadMockTournirs() -> [Tournir] { let x = [ Tournir( @@ -144,4 +144,5 @@ class TournirsViewModel: ObservableObject { ] return x } + */ }