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