parent
a4ac2b8c8f
commit
d131eae629
@ -0,0 +1,33 @@ |
|||||||
|
// |
||||||
|
// Color+Extensions.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by Razmig Sarkissian on 27/03/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import SwiftUI |
||||||
|
|
||||||
|
extension Color { |
||||||
|
func variation(withHueOffset hueOffset: Double = 0, saturationFactor: Double = 0.4, brightnessFactor: Double = 0.8, opacity: Double = 0.5) -> Color { |
||||||
|
var hue: CGFloat = 0 |
||||||
|
var saturation: CGFloat = 0 |
||||||
|
var brightness: CGFloat = 0 |
||||||
|
var alpha: CGFloat = 0 |
||||||
|
|
||||||
|
UIColor(self).getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) |
||||||
|
|
||||||
|
// Apply adjustments |
||||||
|
hue += CGFloat(hueOffset) |
||||||
|
saturation *= CGFloat(saturationFactor) |
||||||
|
brightness *= CGFloat(brightnessFactor) |
||||||
|
alpha *= CGFloat(opacity) |
||||||
|
|
||||||
|
// Clamp values |
||||||
|
hue = max(0, min(hue, 1)) |
||||||
|
saturation = max(0, min(saturation, 1)) |
||||||
|
brightness = max(0, min(brightness, 1)) |
||||||
|
alpha = max(0, min(alpha, 1)) |
||||||
|
|
||||||
|
return Color(hue: Double(hue), saturation: Double(saturation), brightness: Double(brightness), opacity: Double(alpha)) |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,191 @@ |
|||||||
|
// |
||||||
|
// InscriptionInfoView.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by Razmig Sarkissian on 27/03/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import SwiftUI |
||||||
|
|
||||||
|
struct InscriptionInfoView: View { |
||||||
|
@Environment(Tournament.self) var tournament |
||||||
|
@State private var duplicates = [PlayerRegistration]() |
||||||
|
@State private var problematicPlayers = [PlayerRegistration]() |
||||||
|
@State private var inadequatePlayers = [PlayerRegistration]() |
||||||
|
@State private var playersWithoutValidLicense = [PlayerRegistration]() |
||||||
|
@State private var entriesNotFromBeachPadel = [TeamRegistration]() |
||||||
|
@State private var playersMissing = [TeamRegistration]() |
||||||
|
@State private var waitingList = [TeamRegistration]() |
||||||
|
@State private var selectedTeams = [TeamRegistration]() |
||||||
|
|
||||||
|
var body: some View { |
||||||
|
List { |
||||||
|
let waitingListInBracket = waitingList.filter({ $0.bracketPosition != nil }) |
||||||
|
let waitingListInGroupStage = waitingList.filter({ $0.groupStage != nil }) |
||||||
|
|
||||||
|
Section { |
||||||
|
DisclosureGroup { |
||||||
|
ForEach(waitingListInBracket) { team in |
||||||
|
TeamRowView(team: team) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
LabeledContent { |
||||||
|
Text(waitingListInBracket.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("Dans le tableau") |
||||||
|
} |
||||||
|
} |
||||||
|
.listRowView(color: .red) |
||||||
|
|
||||||
|
DisclosureGroup { |
||||||
|
ForEach(waitingListInGroupStage) { team in |
||||||
|
TeamRowView(team: team) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
LabeledContent { |
||||||
|
Text(waitingListInGroupStage.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("En poule") |
||||||
|
} |
||||||
|
} |
||||||
|
.listRowView(color: .red) |
||||||
|
} header: { |
||||||
|
Text("Équipes non sélectionnées") |
||||||
|
} footer: { |
||||||
|
Text("Il s'agit des équipes déjà placé en poule ou tableau qui sont actuellement en attente à cause de l'arrivée d'une nouvelle équipe ou une modification de classement.") |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
DisclosureGroup { |
||||||
|
ForEach(duplicates) { player in |
||||||
|
ImportedPlayerView(player: player) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
LabeledContent { |
||||||
|
Text(duplicates.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("Doublons") |
||||||
|
} |
||||||
|
} |
||||||
|
.listRowView(color: .red) |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
DisclosureGroup { |
||||||
|
ForEach(problematicPlayers) { player in |
||||||
|
PlayerSexPickerView(player: player) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
LabeledContent { |
||||||
|
Text(problematicPlayers.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("Joueurs problématiques") |
||||||
|
} |
||||||
|
} |
||||||
|
.listRowView(color: .purple) |
||||||
|
} footer: { |
||||||
|
Text("Il s'agit des joueurs ou joueuses dont le sexe n'a pas pu être déterminé") |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
DisclosureGroup { |
||||||
|
ForEach(inadequatePlayers) { player in |
||||||
|
ImportedPlayerView(player: player) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
LabeledContent { |
||||||
|
Text(inadequatePlayers.count.formatted()) |
||||||
|
} label: { |
||||||
|
let playerLabel : String = tournament.tournamentCategory == .women ? "joueuse" : "joueur" |
||||||
|
let grammarSuffix : String = tournament.tournamentCategory == .women ? "e" + inadequatePlayers.count.pluralSuffix : inadequatePlayers.count.pluralSuffix |
||||||
|
Text(playerLabel.capitalized + inadequatePlayers.count.pluralSuffix + " trop bien classé" + grammarSuffix) |
||||||
|
} |
||||||
|
} |
||||||
|
.listRowView(color: .red) |
||||||
|
} footer: { |
||||||
|
Text("Il s'agit des joueurs ou joueuses dont le rang est inférieur à la limite fédérale.") |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
DisclosureGroup { |
||||||
|
ForEach(playersWithoutValidLicense) { |
||||||
|
ImportedPlayerView(player: $0) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
LabeledContent { |
||||||
|
Text(playersWithoutValidLicense.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("Joueurs sans licence valide") |
||||||
|
} |
||||||
|
} |
||||||
|
.listRowView(color: .orange) |
||||||
|
} footer: { |
||||||
|
Text("importé du fichier beach-padel sans licence valide ou créé sans licence") |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
DisclosureGroup { |
||||||
|
ForEach(playersMissing) { |
||||||
|
TeamRowView(team: $0) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
LabeledContent { |
||||||
|
Text(playersMissing.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("Paires incomplètes") |
||||||
|
} |
||||||
|
} |
||||||
|
.listRowView(color: .pink) |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
LabeledContent { |
||||||
|
Text(entriesNotFromBeachPadel.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("Paires importées") |
||||||
|
Text(SourceFileManager.beachPadel.absoluteString) |
||||||
|
} |
||||||
|
.listRowView(color: .indigo) |
||||||
|
|
||||||
|
LabeledContent { |
||||||
|
Text(selectedTeams.filter { $0.called() }.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("Paires convoquées") |
||||||
|
Text("Vous avez envoyé une convocation par sms ou email") |
||||||
|
} |
||||||
|
.listRowView(color: .cyan) |
||||||
|
|
||||||
|
LabeledContent { |
||||||
|
Text(selectedTeams.filter { $0.confirmed() }.count.formatted()) |
||||||
|
} label: { |
||||||
|
Text("Paires ayant confirmées") |
||||||
|
Text("Vous avez noté la confirmation de l'équipe") |
||||||
|
} |
||||||
|
.listRowView(color: .green) |
||||||
|
} |
||||||
|
} |
||||||
|
.navigationTitle("Synthèse") |
||||||
|
.navigationBarTitleDisplayMode(.inline) |
||||||
|
.toolbarBackground(.visible, for: .navigationBar) |
||||||
|
.onAppear { |
||||||
|
_initData() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private func _initData() { |
||||||
|
let players = tournament.unsortedPlayers() |
||||||
|
selectedTeams = tournament.selectedSortedTeams() |
||||||
|
waitingList = tournament.waitingListTeams(in: selectedTeams) |
||||||
|
duplicates = tournament.duplicates(in: players) |
||||||
|
problematicPlayers = players.filter({ $0.sex == -1 }) |
||||||
|
inadequatePlayers = tournament.inadequatePlayers(in: players) |
||||||
|
playersWithoutValidLicense = tournament.playersWithoutValidLicense(in: players) |
||||||
|
entriesNotFromBeachPadel = selectedTeams.filter({ $0.isImported() }) |
||||||
|
playersMissing = selectedTeams.filter({ $0.unsortedPlayers().count < 2 }) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#Preview { |
||||||
|
InscriptionInfoView() |
||||||
|
.environment(Tournament.mock()) |
||||||
|
} |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
// |
||||||
|
// ListRowViewModifier.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by Razmig Sarkissian on 27/03/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import SwiftUI |
||||||
|
|
||||||
|
struct ListRowViewModifier: ViewModifier { |
||||||
|
@State private var isActived = true |
||||||
|
let color: Color |
||||||
|
|
||||||
|
func body(content: Content) -> some View { |
||||||
|
if isActived { |
||||||
|
content |
||||||
|
.listRowBackground( |
||||||
|
color.variation() |
||||||
|
.overlay(alignment: .leading, content: { |
||||||
|
color.frame(width: 8) |
||||||
|
}) |
||||||
|
) |
||||||
|
} else { |
||||||
|
content |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
extension View { |
||||||
|
func listRowView(color: Color) -> some View { |
||||||
|
modifier(ListRowViewModifier(color: color)) |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue