quick enhance tip

online_reg
Raz 11 months ago
parent 7b06c8cefc
commit 906172d9e2
  1. 2
      PadelClub/PadelClubApp.swift
  2. 95
      PadelClub/Utils/Tips.swift
  3. 3
      PadelClub/Views/Navigation/Agenda/EventListView.swift
  4. 20
      PadelClub/Views/Tournament/Shared/TournamentCellView.swift
  5. 35
      PadelClub/Views/Tournament/TournamentView.swift

@ -99,7 +99,7 @@ print("Running in Release mode")
} }
.task { .task {
//try? Tips.resetDatastore() try? Tips.resetDatastore()
try? Tips.configure([ try? Tips.configure([
.displayFrequency(.immediate), .displayFrequency(.immediate),

@ -21,7 +21,7 @@ struct PadelBeachExportTip: Tip {
var image: Image? { var image: Image? {
Image(systemName: "square.and.arrow.up") Image(systemName: "square.and.arrow.up")
} }
var actions: [Action] { var actions: [Action] {
Action(id: "more-info-export", title: "En savoir plus") Action(id: "more-info-export", title: "En savoir plus")
Action(id: "beach-padel", title: "beach-padel.app.fft.fr") Action(id: "beach-padel", title: "beach-padel.app.fft.fr")
@ -42,7 +42,7 @@ struct PadelBeachImportTip: Tip {
var image: Image? { var image: Image? {
Image(systemName: "square.and.arrow.down") Image(systemName: "square.and.arrow.down")
} }
var actions: [Action] { var actions: [Action] {
Action(id: "more-info-import", title: "Importer le fichier excel beach-padel") Action(id: "more-info-import", title: "Importer le fichier excel beach-padel")
} }
@ -61,8 +61,8 @@ struct GenerateLoserBracketTip: Tip {
var image: Image? { var image: Image? {
nil nil
} }
var actions: [Action] { var actions: [Action] {
Action(id: "generate-loser-bracket", title: "Générer les matchs de classements") Action(id: "generate-loser-bracket", title: "Générer les matchs de classements")
} }
@ -83,7 +83,7 @@ struct TeamChampionshipTip: Tip {
var image: Image? { var image: Image? {
Image(systemName: "person.3") Image(systemName: "person.3")
} }
var actions: [Action] { var actions: [Action] {
Action(id: "list-manager", title: "Ouvrir le gestionnaire d'équipe") Action(id: "list-manager", title: "Ouvrir le gestionnaire d'équipe")
} }
@ -104,7 +104,7 @@ struct TeamChampionshipMainScreenTip: Tip {
var image: Image? { var image: Image? {
Image(systemName: "arrow.uturn.backward") Image(systemName: "arrow.uturn.backward")
} }
var actions: [Action] { var actions: [Action] {
Action(id: "set-list-manager-main", title: "Afficher sur l'écran principal") Action(id: "set-list-manager-main", title: "Afficher sur l'écran principal")
} }
@ -193,7 +193,7 @@ struct InscriptionManagerWomanRankTip: Tip {
var image: Image? { var image: Image? {
Image(systemName: "figure.dress.line.vertical.figure") Image(systemName: "figure.dress.line.vertical.figure")
} }
var title: Text { var title: Text {
Text("Rang d'une joueuse dans un tournoi messieurs") Text("Rang d'une joueuse dans un tournoi messieurs")
} }
@ -213,7 +213,7 @@ struct InscriptionManagerRankUpdateTip: Tip {
var message: Text? { var message: Text? {
Text("Padel Club vous permet de mettre à jour le classement des équipes inscrites. Si vous avez clôturé les inscriptions, la mise à jour du classement ne modifie pas la phase d'intégration de l'équipe, poule ou tableau final. Vous pouvez manuellement mettre à jour cette option.") Text("Padel Club vous permet de mettre à jour le classement des équipes inscrites. Si vous avez clôturé les inscriptions, la mise à jour du classement ne modifie pas la phase d'intégration de l'équipe, poule ou tableau final. Vous pouvez manuellement mettre à jour cette option.")
} }
var image: Image? { var image: Image? {
Image(systemName: "list.number") Image(systemName: "list.number")
} }
@ -232,7 +232,7 @@ struct SharePictureTip: Tip {
var message: Text? { var message: Text? {
Text("Lors d'un partage d'une photo, le texte est disponible dans le presse-papier du téléphone") Text("Lors d'un partage d'une photo, le texte est disponible dans le presse-papier du téléphone")
} }
var image: Image? { var image: Image? {
Image(systemName: "photo.badge.checkmark.fill") Image(systemName: "photo.badge.checkmark.fill")
} }
@ -246,7 +246,7 @@ struct NewRankDataAvailableTip: Tip {
var message: Text? { var message: Text? {
Text("Padel Club récupère toutes les données publique provenant de la FFT. L'importation de ce nouveau classement peut prendre plusieurs dizaines de secondes.") Text("Padel Club récupère toutes les données publique provenant de la FFT. L'importation de ce nouveau classement peut prendre plusieurs dizaines de secondes.")
} }
var image: Image? { var image: Image? {
Image(systemName: "exclamationmark.icloud") Image(systemName: "exclamationmark.icloud")
} }
@ -266,7 +266,7 @@ struct ClubSearchTip: Tip {
var message: Text? { var message: Text? {
Text("Padel Club peut rechercher un club autour de vous, d'une ville ou d'un code postal, facilitant ainsi la saisie d'information.") Text("Padel Club peut rechercher un club autour de vous, d'une ville ou d'un code postal, facilitant ainsi la saisie d'information.")
} }
var image: Image? { var image: Image? {
Image(systemName: "house.and.flag.fill") Image(systemName: "house.and.flag.fill")
} }
@ -275,7 +275,7 @@ struct ClubSearchTip: Tip {
Action(id: ActionKey.searchAroundMe.rawValue, title: "Chercher autour de moi") Action(id: ActionKey.searchAroundMe.rawValue, title: "Chercher autour de moi")
Action(id: ActionKey.searchCity.rawValue, title: "Chercher une ville") Action(id: ActionKey.searchCity.rawValue, title: "Chercher une ville")
} }
enum ActionKey: String { enum ActionKey: String {
case searchAroundMe = "search-around-me" case searchAroundMe = "search-around-me"
case searchCity = "search-city" case searchCity = "search-city"
@ -291,7 +291,7 @@ struct SlideToDeleteTip: Tip {
var message: Text? { var message: Text? {
Text("Vous pouvez effacer un club en glissant votre doigt vers la gauche") Text("Vous pouvez effacer un club en glissant votre doigt vers la gauche")
} }
var image: Image? { var image: Image? {
Image(systemName: "trash") Image(systemName: "trash")
} }
@ -306,7 +306,7 @@ struct MultiTournamentsEventTip: Tip {
var message: Text? { var message: Text? {
Text("Padel Club permet de gérer plusieurs tournois ayant lieu en même temps. Un P100 homme et dame le même week-end par exemple.") Text("Padel Club permet de gérer plusieurs tournois ayant lieu en même temps. Un P100 homme et dame le même week-end par exemple.")
} }
var image: Image? { var image: Image? {
Image(systemName: "trophy.circle") Image(systemName: "trophy.circle")
} }
@ -320,7 +320,7 @@ struct NotFoundAreWalkOutTip: Tip {
var message: Text? { var message: Text? {
Text("Si une équipe déjà présente dans votre liste d'attente n'est pas dans le fichier, elle sera mise WO") Text("Si une équipe déjà présente dans votre liste d'attente n'est pas dans le fichier, elle sera mise WO")
} }
var image: Image? { var image: Image? {
Image(systemName: "person.2.slash.fill") Image(systemName: "person.2.slash.fill")
} }
@ -338,7 +338,7 @@ struct TournamentPublishingTip: Tip {
var message: Text? { var message: Text? {
Text("Padel Club vous permet de publier votre tournoi et rendre accessible à tous les résultats des matchs et l'évolution de l'événement. Les informations seront accessibles sur le site Padel Club.") Text("Padel Club vous permet de publier votre tournoi et rendre accessible à tous les résultats des matchs et l'évolution de l'événement. Les informations seront accessibles sur le site Padel Club.")
} }
var image: Image? { var image: Image? {
Image("PadelClub_logo_fondclair_transparent") Image("PadelClub_logo_fondclair_transparent")
} }
@ -352,7 +352,7 @@ struct TournamentTVBroadcastTip: Tip {
var message: Text? { var message: Text? {
return Text("Padel Club vous propose un site spéficique à utiliser sur les écrans de votre club, présentant de manière intelligente l'évolution de votre tournoi.") return Text("Padel Club vous propose un site spéficique à utiliser sur les écrans de votre club, présentant de manière intelligente l'évolution de votre tournoi.")
} }
var image: Image? { var image: Image? {
Image(systemName: "sparkles.tv") Image(systemName: "sparkles.tv")
} }
@ -361,7 +361,7 @@ struct TournamentTVBroadcastTip: Tip {
struct TournamentSelectionTip: Tip { struct TournamentSelectionTip: Tip {
@Parameter @Parameter
static var tournamentCount: Int? = nil static var tournamentCount: Int? = nil
var rules: [Rule] { var rules: [Rule] {
[ [
// Define a rule based on the app state. // Define a rule based on the app state.
@ -379,7 +379,7 @@ struct TournamentSelectionTip: Tip {
var message: Text? { var message: Text? {
return Text("Vous pouvez appuyer sur la barre de navigation pour accéder à un tournoi de votre événement.") return Text("Vous pouvez appuyer sur la barre de navigation pour accéder à un tournoi de votre événement.")
} }
var image: Image? { var image: Image? {
Image(systemName: "filemenu.and.selection") Image(systemName: "filemenu.and.selection")
} }
@ -388,7 +388,7 @@ struct TournamentSelectionTip: Tip {
struct TournamentRunningTip: Tip { struct TournamentRunningTip: Tip {
@Parameter @Parameter
static var isRunning: Bool = false static var isRunning: Bool = false
var rules: [Rule] { var rules: [Rule] {
[ [
// Define a rule based on the app state. // Define a rule based on the app state.
@ -406,7 +406,7 @@ struct TournamentRunningTip: Tip {
var message: Text? { var message: Text? {
return Text("Le tournoi a commencé, les options utiles surtout à sa préparation sont maintenant accessibles dans le menu en haut à droite.") return Text("Le tournoi a commencé, les options utiles surtout à sa préparation sont maintenant accessibles dans le menu en haut à droite.")
} }
var image: Image? { var image: Image? {
Image(systemName: "ellipsis.circle") Image(systemName: "ellipsis.circle")
} }
@ -421,18 +421,18 @@ struct CreateAccountTip: Tip {
let message = "Un compte est nécessaire pour publier le tournoi sur [Padel Club](\(URLs.main.rawValue)) et profiter de toutes les pages du site, comme le mode TV pour transformer l'expérience de vos tournois !" let message = "Un compte est nécessaire pour publier le tournoi sur [Padel Club](\(URLs.main.rawValue)) et profiter de toutes les pages du site, comme le mode TV pour transformer l'expérience de vos tournois !"
return Text(.init(message)) return Text(.init(message))
} }
var image: Image? { var image: Image? {
Image(systemName: "person.crop.circle") Image(systemName: "person.crop.circle")
} }
var actions: [Action] { var actions: [Action] {
Action(id: ActionKey.createAccount.rawValue, title: "Créer votre compte") Action(id: ActionKey.createAccount.rawValue, title: "Créer votre compte")
//todo //todo
//Action(id: ActionKey.learnMore.rawValue, title: "En savoir plus") //Action(id: ActionKey.learnMore.rawValue, title: "En savoir plus")
Action(id: ActionKey.accessPadelClubWebPage.rawValue, title: "Voir le site Padel Club") Action(id: ActionKey.accessPadelClubWebPage.rawValue, title: "Voir le site Padel Club")
} }
enum ActionKey: String { enum ActionKey: String {
case createAccount = "createAccount" case createAccount = "createAccount"
case learnMore = "learnMore" case learnMore = "learnMore"
@ -443,7 +443,7 @@ struct CreateAccountTip: Tip {
struct SlideToDeleteSeedTip: Tip { struct SlideToDeleteSeedTip: Tip {
@Parameter @Parameter
static var seeds: Int = 0 static var seeds: Int = 0
var rules: [Rule] { var rules: [Rule] {
[ [
// Define a rule based on the app state. // Define a rule based on the app state.
@ -461,7 +461,7 @@ struct SlideToDeleteSeedTip: Tip {
var message: Text? { var message: Text? {
Text("Vous pouvez retirer une tête de série de sa position en glissant votre doigt vers la gauche") Text("Vous pouvez retirer une tête de série de sa position en glissant votre doigt vers la gauche")
} }
var image: Image? { var image: Image? {
Image(systemName: "person.fill.xmark") Image(systemName: "person.fill.xmark")
} }
@ -470,7 +470,7 @@ struct SlideToDeleteSeedTip: Tip {
struct PrintTip: Tip { struct PrintTip: Tip {
@Parameter @Parameter
static var seeds: Int = 0 static var seeds: Int = 0
var rules: [Rule] { var rules: [Rule] {
[ [
// Define a rule based on the app state. // Define a rule based on the app state.
@ -480,7 +480,7 @@ struct PrintTip: Tip {
} }
] ]
} }
var title: Text { var title: Text {
Text("Coup d'oeil de votre tableau") Text("Coup d'oeil de votre tableau")
} }
@ -488,7 +488,7 @@ struct PrintTip: Tip {
var message: Text? { var message: Text? {
Text("Vous pouvez avoir un aperçu de votre tableau ou l'imprimer.") Text("Vous pouvez avoir un aperçu de votre tableau ou l'imprimer.")
} }
var image: Image? { var image: Image? {
Image(systemName: "printer") Image(systemName: "printer")
} }
@ -505,9 +505,9 @@ struct PrintTip: Tip {
struct BracketEditTip: Tip { struct BracketEditTip: Tip {
@Parameter @Parameter
static var matchesHidden: Int = 0 static var matchesHidden: Int = 0
var nextRoundName: String? var nextRoundName: String?
var rules: [Rule] { var rules: [Rule] {
[ [
// Define a rule based on the app state. // Define a rule based on the app state.
@ -528,14 +528,14 @@ struct BracketEditTip: Tip {
let wording = nextRoundName != nil ? "en \(nextRoundName!)" : "dans la manche suivante" let wording = nextRoundName != nil ? "en \(nextRoundName!)" : "dans la manche suivante"
return Text("Padel Club a bien pris en compte \(article) tête\(Self.matchesHidden.pluralSuffix) de série positionnée\(Self.matchesHidden.pluralSuffix) \(wording). Le\(Self.matchesHidden.pluralSuffix) \(Self.matchesHidden) match\(Self.matchesHidden.pluralSuffix) inutile\(Self.matchesHidden.pluralSuffix) \(grammar) été désactivé automatiquement.") return Text("Padel Club a bien pris en compte \(article) tête\(Self.matchesHidden.pluralSuffix) de série positionnée\(Self.matchesHidden.pluralSuffix) \(wording). Le\(Self.matchesHidden.pluralSuffix) \(Self.matchesHidden) match\(Self.matchesHidden.pluralSuffix) inutile\(Self.matchesHidden.pluralSuffix) \(grammar) été désactivé automatiquement.")
} }
var image: Image? { var image: Image? {
Image(systemName: "rectangle.slash") Image(systemName: "rectangle.slash")
} }
} }
struct TeamsExportTip: Tip { struct TeamsExportTip: Tip {
var title: Text { var title: Text {
Text("Exporter les paires") Text("Exporter les paires")
} }
@ -543,7 +543,7 @@ struct TeamsExportTip: Tip {
var message: Text? { var message: Text? {
Text("Partager les paires comme indiqué dans le guide de la compétition à J-6 avant midi.") Text("Partager les paires comme indiqué dans le guide de la compétition à J-6 avant midi.")
} }
var image: Image? { var image: Image? {
Image(systemName: "square.and.arrow.up") Image(systemName: "square.and.arrow.up")
} }
@ -557,7 +557,7 @@ struct PlayerTournamentSearchTip: Tip {
var message: Text? { var message: Text? {
Text("Padel Club facilite la recherche de tournois et l'inscription !") Text("Padel Club facilite la recherche de tournois et l'inscription !")
} }
var image: Image? { var image: Image? {
Image(systemName: "trophy.circle") Image(systemName: "trophy.circle")
} }
@ -580,7 +580,7 @@ struct OnlineRegistrationTip: Tip {
var message: Text? { var message: Text? {
Text("Facilitez les inscriptions à votre tournoi en activant l'inscription en ligne. Les joueurs pourront s'inscrire directement depuis l'application ou le site Padel Club.") Text("Facilitez les inscriptions à votre tournoi en activant l'inscription en ligne. Les joueurs pourront s'inscrire directement depuis l'application ou le site Padel Club.")
} }
var image: Image? { var image: Image? {
Image(systemName: "person.2.crop.square.stack") Image(systemName: "person.2.crop.square.stack")
} }
@ -588,19 +588,36 @@ struct OnlineRegistrationTip: Tip {
var actions: [Action] { var actions: [Action] {
Action(id: ActionKey.enableOnlineRegistration.rawValue, title: "Activer dans les réglages du tournoi") Action(id: ActionKey.enableOnlineRegistration.rawValue, title: "Activer dans les réglages du tournoi")
} }
enum ActionKey: String { enum ActionKey: String {
case enableOnlineRegistration = "enableOnlineRegistration" case enableOnlineRegistration = "enableOnlineRegistration"
} }
} }
struct ShouldTournamentBeOverTip: Tip {
var title: Text {
Text("Clôturer le tournoi ?")
}
var message: Text? {
Text("Le dernier match est terminé depuis plus de 2 heures. Si le tournoi a été annulé pour cause de météo vous pouvez l'indiquer comme 'Annulé' dans le menu 􀍡, si ce n'est pas le cas, saisissez les scores manquants pour clôturer automatiquement le tournoi et publier le classement final.")
}
var image: Image? {
Image(systemName: "clock.badge.questionmark")
}
var actions: [Action] {
Action(id: "tournament-status", title: "Gérer le statut du tournoi")
}
}
struct TipStyleModifier: ViewModifier { struct TipStyleModifier: ViewModifier {
@Environment(\.colorScheme) var colorScheme @Environment(\.colorScheme) var colorScheme
var tint: Color? var tint: Color?
var background: Color? var background: Color?
var asSection: Bool var asSection: Bool
func body(content: Content) -> some View { func body(content: Content) -> some View {
if asSection { if asSection {
Section { Section {
@ -610,7 +627,7 @@ struct TipStyleModifier: ViewModifier {
preparedContent(content: content) preparedContent(content: content)
} }
} }
@ViewBuilder @ViewBuilder
func preparedContent(content: Content) -> some View { func preparedContent(content: Content) -> some View {
if let background { if let background {

@ -116,9 +116,8 @@ struct EventListView: View {
private func _tournamentView(_ tournament: Tournament) -> some View { private func _tournamentView(_ tournament: Tournament) -> some View {
NavigationLink(value: tournament) { NavigationLink(value: tournament) {
TournamentCellView(tournament: tournament) TournamentCellView(tournament: tournament, shouldTournamentBeOver: tournament.shouldTournamentBeOver())
} }
.listRowView(isActive: tournament.shouldTournamentBeOver(), color: .red, hideColorVariation: true, alignment: .leading)
.contextMenu { .contextMenu {
if tournament.hasEnded() == false { if tournament.hasEnded() == false {
Button { Button {

@ -15,6 +15,7 @@ struct TournamentCellView: View {
let tournament: FederalTournamentHolder let tournament: FederalTournamentHolder
// let color: Color = .black // let color: Color = .black
var displayStyle: DisplayStyle = .wide var displayStyle: DisplayStyle = .wide
var shouldTournamentBeOver: Bool = false
var event: Event? { var event: Event? {
guard let federalTournament = tournament as? FederalTournament else { return nil } guard let federalTournament = tournament as? FederalTournament else { return nil }
@ -115,8 +116,9 @@ struct TournamentCellView: View {
if let tournament = tournament as? Tournament, displayStyle == .wide { if let tournament = tournament as? Tournament, displayStyle == .wide {
if tournament.isCanceled { if tournament.isCanceled {
Text("Annulé".uppercased()) Text("Annulé".uppercased())
.capsule(foreground: .white, background: .red) .capsule(foreground: .white, background: .logoRed)
} else if shouldTournamentBeOver {
Image(systemName: "clock.badge.questionmark").foregroundStyle(.logoRed)
} else if let teamCount { } else if let teamCount {
Text(teamCount.formatted()) Text(teamCount.formatted())
} }
@ -147,10 +149,15 @@ struct TournamentCellView: View {
Text(tournament.durationLabel()) Text(tournament.durationLabel())
} }
Spacer() Spacer()
if let tournament = tournament as? Tournament, tournament.isCanceled == false, let teamCount { if let tournament = tournament as? Tournament, tournament.isCanceled == false {
let hasStarted = tournament.inscriptionClosed() || tournament.hasStarted() if shouldTournamentBeOver {
let word = hasStarted ? "équipe" : "inscription" Text("à clôturer ?")
Text(word + teamCount.pluralSuffix) .foregroundStyle(.logoRed)
} else if let teamCount {
let hasStarted = tournament.inscriptionClosed() || tournament.hasStarted()
let word = hasStarted ? "équipe" : "inscription"
Text(word + teamCount.pluralSuffix)
}
} }
} }
} else { } else {
@ -160,7 +167,6 @@ struct TournamentCellView: View {
} }
} }
.font(.caption) .font(.caption)
.listRowView(isActive: existingTournament != nil, color: .green, hideColorVariation: true, alignment: .leading)
} }
private func _createOrShow(federalTournament: FederalTournament, existingTournament: Tournament?, build: any TournamentBuildHolder) { private func _createOrShow(federalTournament: FederalTournament, existingTournament: Tournament?, build: any TournamentBuildHolder) {

@ -19,7 +19,8 @@ struct TournamentView: View {
let tournamentSelectionTip: TournamentSelectionTip = TournamentSelectionTip() let tournamentSelectionTip: TournamentSelectionTip = TournamentSelectionTip()
let tournamentRunningTip: TournamentRunningTip = TournamentRunningTip() let tournamentRunningTip: TournamentRunningTip = TournamentRunningTip()
let onlineRegistrationTip: OnlineRegistrationTip = OnlineRegistrationTip() let onlineRegistrationTip: OnlineRegistrationTip = OnlineRegistrationTip()
let shouldTournamentBeOverTip: ShouldTournamentBeOverTip = ShouldTournamentBeOverTip()
var selectedTournamentId: Binding<String> { Binding( var selectedTournamentId: Binding<String> { Binding(
get: { tournament.id }, get: { tournament.id },
set: { id in set: { id in
@ -76,7 +77,7 @@ struct TournamentView: View {
TipView(onlineRegistrationTip) { actions in TipView(onlineRegistrationTip) { actions in
navigation.path.append(Screen.settings) navigation.path.append(Screen.settings)
} }
.tipStyle(tint: .master, asSection: true) .tipStyle(tint: .green, asSection: true)
} }
Section { Section {
@ -87,34 +88,10 @@ struct TournamentView: View {
case .running: case .running:
if tournament.shouldTournamentBeOver() { if tournament.shouldTournamentBeOver() {
Section { Section {
Menu { TipView(shouldTournamentBeOverTip) { actions in
navigation.path.append(Screen.stateSettings)
Button("Scores manquants") {
if let activeRound = tournament.getActiveRound() {
navigation.path.append(Screen.round)
} else if let activeGroupStage = tournament.getActiveGroupStage() {
navigation.path.append(Screen.groupStage)
}
}
Button {
navigation.path.append(Screen.stateSettings)
} label: {
Text("Annuler le tournoi")
}
} label: {
Label("Actions rapides", systemImage: "bolt.circle")
.foregroundColor(.white)
.frame(height: 32)
.font(.headline)
.frame(maxWidth: .infinity)
} }
.menuStyle(.button) .tipStyle(tint: .logoRed, asSection: true)
.buttonStyle(.borderedProminent)
.tint(.logoYellow)
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(.zero))
} }
} }
TournamentBuildView(tournament: tournament) TournamentBuildView(tournament: tournament)

Loading…
Cancel
Save