multistore
Razmig Sarkissian 1 year ago
parent a7bd190313
commit 6ea9676a64
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 2
      PadelClub/Data/GroupStage.swift
  3. 4
      PadelClub/Data/PlayerRegistration.swift
  4. 4
      PadelClub/Data/TeamRegistration.swift
  5. 9
      PadelClub/Data/Tournament.swift
  6. 4
      PadelClub/HTML Templates/tournament-template.html
  7. 1
      PadelClub/Utils/HtmlGenerator.swift
  8. 8
      PadelClub/Utils/HtmlService.swift
  9. 33
      PadelClub/Utils/URLs.swift
  10. 48
      PadelClub/Views/Calling/SendToAllView.swift
  11. 60
      PadelClub/Views/Cashier/Event/EventLinksView.swift
  12. 9
      PadelClub/Views/Cashier/Event/EventView.swift
  13. 49
      PadelClub/Views/GroupStage/GroupStageSettingsView.swift
  14. 16
      PadelClub/Views/Tournament/Screen/BroadcastView.swift
  15. 4
      PadelClub/Views/Tournament/Screen/Components/TournamentStatusView.swift

@ -141,6 +141,7 @@
FF1F4B8A2BFA02A4000B4573 /* groupstage-template.html in Resources */ = {isa = PBXBuildFile; fileRef = FF1F4B772BFA0105000B4573 /* groupstage-template.html */; }; FF1F4B8A2BFA02A4000B4573 /* groupstage-template.html in Resources */ = {isa = PBXBuildFile; fileRef = FF1F4B772BFA0105000B4573 /* groupstage-template.html */; };
FF1F4B8B2BFA02A4000B4573 /* groupstageentrant-template.html in Resources */ = {isa = PBXBuildFile; fileRef = FF1F4B792BFA0105000B4573 /* groupstageentrant-template.html */; }; FF1F4B8B2BFA02A4000B4573 /* groupstageentrant-template.html in Resources */ = {isa = PBXBuildFile; fileRef = FF1F4B792BFA0105000B4573 /* groupstageentrant-template.html */; };
FF1F4B8C2BFA02A4000B4573 /* match-template.html in Resources */ = {isa = PBXBuildFile; fileRef = FF1F4B7D2BFA0105000B4573 /* match-template.html */; }; FF1F4B8C2BFA02A4000B4573 /* match-template.html in Resources */ = {isa = PBXBuildFile; fileRef = FF1F4B7D2BFA0105000B4573 /* match-template.html */; };
FF2B6F5E2C036A1500835EE7 /* EventLinksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF2B6F5D2C036A1400835EE7 /* EventLinksView.swift */; };
FF2EFBF02BDE295E0049CE3B /* SendToAllView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF2EFBEF2BDE295E0049CE3B /* SendToAllView.swift */; }; FF2EFBF02BDE295E0049CE3B /* SendToAllView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF2EFBEF2BDE295E0049CE3B /* SendToAllView.swift */; };
FF3795622B9396D0004EA093 /* PadelClubApp.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = FF3795602B9396D0004EA093 /* PadelClubApp.xcdatamodeld */; }; FF3795622B9396D0004EA093 /* PadelClubApp.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = FF3795602B9396D0004EA093 /* PadelClubApp.xcdatamodeld */; };
FF3795662B9399AA004EA093 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3795652B9399AA004EA093 /* Persistence.swift */; }; FF3795662B9399AA004EA093 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3795652B9399AA004EA093 /* Persistence.swift */; };
@ -460,6 +461,7 @@
FF1F4B7E2BFA0105000B4573 /* player-template.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "player-template.html"; sourceTree = "<group>"; }; FF1F4B7E2BFA0105000B4573 /* player-template.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "player-template.html"; sourceTree = "<group>"; };
FF1F4B7F2BFA0105000B4573 /* tournament-template.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "tournament-template.html"; sourceTree = "<group>"; }; FF1F4B7F2BFA0105000B4573 /* tournament-template.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "tournament-template.html"; sourceTree = "<group>"; };
FF1F4B812BFA0124000B4573 /* PrintSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrintSettingsView.swift; sourceTree = "<group>"; }; FF1F4B812BFA0124000B4573 /* PrintSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrintSettingsView.swift; sourceTree = "<group>"; };
FF2B6F5D2C036A1400835EE7 /* EventLinksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventLinksView.swift; sourceTree = "<group>"; };
FF2EFBEF2BDE295E0049CE3B /* SendToAllView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToAllView.swift; sourceTree = "<group>"; }; FF2EFBEF2BDE295E0049CE3B /* SendToAllView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToAllView.swift; sourceTree = "<group>"; };
FF3795612B9396D0004EA093 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; }; FF3795612B9396D0004EA093 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
FF3795652B9399AA004EA093 /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; }; FF3795652B9399AA004EA093 /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
@ -1209,6 +1211,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FFBF41812BF73EB3001B24CB /* EventView.swift */, FFBF41812BF73EB3001B24CB /* EventView.swift */,
FF2B6F5D2C036A1400835EE7 /* EventLinksView.swift */,
FFBF41832BF75ED7001B24CB /* EventTournamentsView.swift */, FFBF41832BF75ED7001B24CB /* EventTournamentsView.swift */,
FFBF41852BF75FDA001B24CB /* EventSettingsView.swift */, FFBF41852BF75FDA001B24CB /* EventSettingsView.swift */,
FF8F263A2BAD528600650388 /* EventCreationView.swift */, FF8F263A2BAD528600650388 /* EventCreationView.swift */,
@ -1550,6 +1553,7 @@
FF8F264F2BAE0B9600650388 /* MatchTypeSelectionView.swift in Sources */, FF8F264F2BAE0B9600650388 /* MatchTypeSelectionView.swift in Sources */,
FF967D062BAF3C4200A9A3BD /* MatchSetupView.swift in Sources */, FF967D062BAF3C4200A9A3BD /* MatchSetupView.swift in Sources */,
FF4AB6B52B9248200002987F /* NetworkManager.swift in Sources */, FF4AB6B52B9248200002987F /* NetworkManager.swift in Sources */,
FF2B6F5E2C036A1500835EE7 /* EventLinksView.swift in Sources */,
FFB9C8752BBADDF700A0EF4F /* SeedInterval.swift in Sources */, FFB9C8752BBADDF700A0EF4F /* SeedInterval.swift in Sources */,
FF025AE12BD0EB9000A86CF8 /* TournamentClubSettingsView.swift in Sources */, FF025AE12BD0EB9000A86CF8 /* TournamentClubSettingsView.swift in Sources */,
FFBF065C2BBD2657009D6715 /* GroupStageTeamView.swift in Sources */, FFBF065C2BBD2657009D6715 /* GroupStageTeamView.swift in Sources */,

@ -50,7 +50,7 @@ class GroupStage: ModelObject, Storable {
} }
func groupStageTitle(_ displayStyle: DisplayStyle = .wide) -> String { func groupStageTitle(_ displayStyle: DisplayStyle = .wide) -> String {
if let name { return "Poule " + name } if let name { return name }
switch displayStyle { switch displayStyle {
case .wide: case .wide:
return "Poule \(index + 1)" return "Poule \(index + 1)"

@ -74,8 +74,8 @@ class PlayerRegistration: ModelObject, Storable {
} }
internal init(federalData: [String], sex: Int, sexUnknown: Bool) { internal init(federalData: [String], sex: Int, sexUnknown: Bool) {
lastName = federalData[0].trimmed.capitalized lastName = federalData[0].trimmed.uppercased()
firstName = federalData[1].trimmed.uppercased() firstName = federalData[1].trimmed.capitalized
birthdate = federalData[2] birthdate = federalData[2]
licenceId = federalData[3] licenceId = federalData[3]
clubName = federalData[4] clubName = federalData[4]

@ -228,8 +228,10 @@ class TeamRegistration: ModelObject, Storable {
func updatePlayers(_ players: Set<PlayerRegistration>, inTournamentCategory tournamentCategory: TournamentCategory) { func updatePlayers(_ players: Set<PlayerRegistration>, inTournamentCategory tournamentCategory: TournamentCategory) {
let previousPlayers = Set(unsortedPlayers())
let playersToRemove = previousPlayers.subtracting(players)
do { do {
try DataStore.shared.playerRegistrations.delete(contentOfs: unsortedPlayers()) try DataStore.shared.playerRegistrations.delete(contentOfs: playersToRemove)
} catch { } catch {
Logger.error(error) Logger.error(error)
} }

@ -405,13 +405,8 @@ class Tournament : ModelObject, Storable {
} }
} }
func shareURL(_ pageLink: PageLink = .matches) -> URL? {
func shareURL() -> URL? { return URLs.main.url.appending(path: "tournament/\(id)").appending(path: pageLink.path)
return URLs.main.url.appending(path: "tournament/\(id)")
}
func broadcastURL() -> URL? {
return URLs.main.url.appending(path: "tournament/\(id)/broadcast")
} }
func courtUsed() -> [Int] { func courtUsed() -> [Int] {

@ -80,13 +80,13 @@
} }
.player { .player {
font-size:28px; font-size:26px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.hiddenPlayer { .hiddenPlayer {
font-size:28px; font-size:26px;
white-space: pre; white-space: pre;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;

@ -103,6 +103,7 @@ class HtmlGenerator: ObservableObject {
groupStageDone = 0 groupStageDone = 0
groupStageIsReady = false groupStageIsReady = false
pdfDocument = PDFDocument() pdfDocument = PDFDocument()
rects.removeAll()
try? FileManager.default.removeItem(at: pdfURL!) try? FileManager.default.removeItem(at: pdfURL!)
print("buildPDF", width, height, zoomLevel ?? 0) print("buildPDF", width, height, zoomLevel ?? 0)
if let zoomLevel { if let zoomLevel {

@ -66,7 +66,7 @@ enum HtmlService {
} else { } else {
template = template.replacingOccurrences(of: "{{bracketStartDate}}", with: "") template = template.replacingOccurrences(of: "{{bracketStartDate}}", with: "")
} }
template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: bracket.tournamentObject()!.tournamentTitle()) template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: bracket.tournamentObject()!.tournamentTitle(.short))
template = template.replacingOccurrences(of: "{{bracketTitle}}", with: bracket.groupStageTitle()) template = template.replacingOccurrences(of: "{{bracketTitle}}", with: bracket.groupStageTitle())
var col = "" var col = ""
@ -133,7 +133,7 @@ enum HtmlService {
case .player(let entrant): case .player(let entrant):
var template = html var template = html
if let playerOne = entrant.players()[safe: 0] { if let playerOne = entrant.players()[safe: 0] {
template = template.replacingOccurrences(of: "{{playerOne}}", with: playerOne.playerLabel(.short)) template = template.replacingOccurrences(of: "{{playerOne}}", with: playerOne.playerLabel())
if withRank { if withRank {
template = template.replacingOccurrences(of: "{{weightOne}}", with: "(\(playerOne.formattedRank()))") template = template.replacingOccurrences(of: "{{weightOne}}", with: "(\(playerOne.formattedRank()))")
} else { } else {
@ -142,7 +142,7 @@ enum HtmlService {
} }
if let playerTwo = entrant.players()[safe: 1] { if let playerTwo = entrant.players()[safe: 1] {
template = template.replacingOccurrences(of: "{{playerTwo}}", with: playerTwo.playerLabel(.short)) template = template.replacingOccurrences(of: "{{playerTwo}}", with: playerTwo.playerLabel())
if withRank { if withRank {
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "(\(playerTwo.formattedRank()))") template = template.replacingOccurrences(of: "{{weightTwo}}", with: "(\(playerTwo.formattedRank()))")
} else { } else {
@ -192,7 +192,7 @@ enum HtmlService {
return bracket return bracket
case .template(let tournament): case .template(let tournament):
var template = html var template = html
template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: tournament.tournamentTitle()) template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: tournament.tournamentTitle(.short))
var brackets = "" var brackets = ""
for round in tournament.rounds() { for round in tournament.rounds() {
brackets = brackets.appending(HtmlService.bracket(tournament: tournament, roundIndex: round.index).html(headName: headName, withRank: withRank, withScore: withScore)) brackets = brackets.appending(HtmlService.bracket(tournament: tournament, roundIndex: round.index).html(headName: headName, withRank: withRank, withScore: withScore))

@ -21,3 +21,36 @@ enum URLs: String, Identifiable {
} }
} }
enum PageLink: String, Identifiable, CaseIterable {
case teams = "Équipes"
case summons = "Convocations"
case groupStages = "Poules"
case matches = "Matchs"
case rankings = "Classement"
case broadcast = "Broadcast"
var id: String { self.rawValue }
func localizedLabel() -> String {
rawValue
}
var path: String {
switch self {
case .matches:
return ""
case .teams:
return "teams"
case .summons:
return "summons"
case .rankings:
return "rankings"
case .groupStages:
return "group-stages"
case .broadcast:
return "broadcast"
}
}
}

@ -9,6 +9,8 @@ import SwiftUI
import LeStorage import LeStorage
struct SendToAllView: View { struct SendToAllView: View {
@Environment(\.dismiss) var dismiss
@EnvironmentObject var dataStore: DataStore
@Environment(Tournament.self) var tournament: Tournament @Environment(Tournament.self) var tournament: Tournament
@EnvironmentObject var networkMonitor: NetworkMonitor @EnvironmentObject var networkMonitor: NetworkMonitor
@ -18,6 +20,7 @@ struct SendToAllView: View {
@State private var sentError: ContactManagerError? = nil @State private var sentError: ContactManagerError? = nil
let addLink: Bool let addLink: Bool
@State var cannotPayForTournament: Bool = false @State var cannotPayForTournament: Bool = false
@State private var pageLink: PageLink = .teams
var messageSentFailed: Binding<Bool> { var messageSentFailed: Binding<Bool> {
Binding { Binding {
@ -69,12 +72,34 @@ struct SendToAllView: View {
} }
} }
if addLink {
Section {
let links : [PageLink] = [.teams, .summons, .groupStages, .matches, .rankings]
Picker(selection: $pageLink) {
ForEach(links) { pageLink in
Text(pageLink.localizedLabel())
}
} label: {
Text("Choisir une page du tournoi en particulier")
}
.pickerStyle(.menu)
}
}
Section { Section {
RowButtonView("Contacter \(_totalString())") { RowButtonView("Contacter \(_totalString())") {
self._contactAndPay() self._contactAndPay()
} }
} }
} }
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("Annuler", role: .cancel) {
dismiss()
}
}
}
.environment(\.editMode, Binding.constant(EditMode.active)) .environment(\.editMode, Binding.constant(EditMode.active))
.headerProminence(.increased) .headerProminence(.increased)
.navigationTitle("Préparation") .navigationTitle("Préparation")
@ -141,7 +166,10 @@ struct SendToAllView: View {
} }
func _teams() -> [TeamRegistration] { func _teams() -> [TeamRegistration] {
_roundTeams() + _groupStagesTeams() if _roundTeams().isEmpty && _groupStagesTeams().isEmpty {
return tournament.selectedSortedTeams()
}
return _roundTeams() + _groupStagesTeams()
} }
func _roundTeams() -> [TeamRegistration] { func _roundTeams() -> [TeamRegistration] {
@ -172,11 +200,25 @@ struct SendToAllView: View {
} }
} }
func finalMessage() -> String {
var message = [String?]()
message.append("\n\n")
if addLink {
message.append(tournament.shareURL(pageLink)?.absoluteString)
}
let signature = dataStore.user.summonsMessageSignature ?? dataStore.user.defaultSignature()
message.append(signature)
return message.compactMap { $0 }.joined(separator: "\n\n")
}
fileprivate func _contact() { fileprivate func _contact() {
if contactMethod == 0 { if contactMethod == 0 {
contactType = .message(date: nil, recipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.phoneNumber }, body: addLink ? tournament.shareURL()?.absoluteString : nil, tournamentBuild: nil) contactType = .message(date: nil, recipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.phoneNumber }, body: finalMessage(), tournamentBuild: nil)
} else { } else {
contactType = .mail(date: nil, recipients: tournament.umpireMail(), bccRecipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.email }, body: addLink ? tournament.shareURL()?.absoluteString : nil, subject: tournament.tournamentTitle(), tournamentBuild: nil) contactType = .mail(date: nil, recipients: tournament.umpireMail(), bccRecipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.email }, body: finalMessage(), subject: tournament.tournamentTitle(), tournamentBuild: nil)
} }
} }

@ -0,0 +1,60 @@
//
// EventLinksView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 26/05/2024.
//
import SwiftUI
struct EventLinksView: View {
let event: Event
@State private var pageLink: PageLink = .teams
func eventLinksPasteData() -> String {
var link = [String]()
link.append(event.eventTitle())
event.tournaments.forEach({ tournament in
if let url = tournament.shareURL(pageLink) {
var tournamentLink = [String]()
tournamentLink.append(tournament.tournamentTitle())
tournamentLink.append(url.absoluteString)
link.append(tournamentLink.joined(separator: "\n"))
}
})
return link.joined(separator: "\n\n")
}
var body: some View {
List {
Section {
let links : [PageLink] = [.teams, .summons, .groupStages, .matches, .rankings]
Picker(selection: $pageLink) {
ForEach(links) { pageLink in
Text(pageLink.localizedLabel())
}
} label: {
Text("Choisir une page du tournoi en particulier")
}
.pickerStyle(.menu)
}
let eventLinksPasteData = eventLinksPasteData()
Section {
Text(eventLinksPasteData)
.italic()
.multilineTextAlignment(.leading)
ShareLink("Partagez ce message", item: eventLinksPasteData)
}
}
}
}
#Preview {
EventLinksView(event: Event.mock())
}

@ -9,6 +9,7 @@ import SwiftUI
import LeStorage import LeStorage
enum EventDestination: Identifiable, Selectable { enum EventDestination: Identifiable, Selectable {
case links
case tournaments(Event) case tournaments(Event)
case cashier case cashier
@ -18,6 +19,8 @@ enum EventDestination: Identifiable, Selectable {
func selectionLabel() -> String { func selectionLabel() -> String {
switch self { switch self {
case .links:
return "Liens"
case .tournaments: case .tournaments:
return "Épreuves" return "Épreuves"
case .cashier: case .cashier:
@ -27,6 +30,8 @@ enum EventDestination: Identifiable, Selectable {
func badgeValue() -> Int? { func badgeValue() -> Int? {
switch self { switch self {
case .links:
return nil
case .tournaments(let event): case .tournaments(let event):
return event.tournaments.count return event.tournaments.count
case .cashier: case .cashier:
@ -49,7 +54,7 @@ struct EventView: View {
@State private var selectedDestination: EventDestination? @State private var selectedDestination: EventDestination?
func allDestinations() -> [EventDestination] { func allDestinations() -> [EventDestination] {
[.tournaments(event), .cashier] [.links, .tournaments(event), .cashier]
} }
var body: some View { var body: some View {
@ -60,6 +65,8 @@ struct EventView: View {
EventSettingsView(event: event) EventSettingsView(event: event)
case .some(let selectedEventDestination): case .some(let selectedEventDestination):
switch selectedEventDestination { switch selectedEventDestination {
case .links:
EventLinksView(event: event)
case .tournaments(let event): case .tournaments(let event):
EventTournamentsView(event: event) EventTournamentsView(event: event)
case .cashier: case .cashier:

@ -11,7 +11,6 @@ import LeStorage
struct GroupStageSettingsView: View { struct GroupStageSettingsView: View {
@EnvironmentObject var dataStore: DataStore @EnvironmentObject var dataStore: DataStore
@Environment(Tournament.self) var tournament: Tournament @Environment(Tournament.self) var tournament: Tournament
@State private var nameAlphabetical: Bool = false
@State private var generationDone: Bool = false @State private var generationDone: Bool = false
var body: some View { var body: some View {
@ -60,9 +59,36 @@ struct GroupStageSettingsView: View {
Text("Redistribue les équipes par la méthode du serpentin") Text("Redistribue les équipes par la méthode du serpentin")
} }
Toggle(isOn: $nameAlphabetical) { Section {
Text("Nommer les poules alphabétiquement") RowButtonView("Nommer les poules alphabétiquement", role: .destructive) {
let groupStages = tournament.groupStages()
groupStages.forEach { groupStage in
if let letter = Alphabet.letterForIndex(index: groupStage.index) {
groupStage.name = "Poule " + letter
}
}
do {
try dataStore.groupStages.addOrUpdate(contentOfs: groupStages)
} catch {
Logger.error(error)
}
}
} }
Section {
RowButtonView("Supprimer les noms des poules", role: .destructive) {
let groupStages = tournament.groupStages()
groupStages.forEach { groupStage in
groupStage.name = nil
}
do {
try dataStore.groupStages.addOrUpdate(contentOfs: groupStages)
} catch {
Logger.error(error)
}
}
}
} }
.overlay(alignment: .bottom) { .overlay(alignment: .bottom) {
if generationDone { if generationDone {
@ -71,23 +97,6 @@ struct GroupStageSettingsView: View {
.deferredRendering(for: .seconds(2)) .deferredRendering(for: .seconds(2))
} }
} }
.onChange(of: nameAlphabetical) {
let groupStages = tournament.groupStages()
if nameAlphabetical {
groupStages.forEach { groupStage in
groupStage.name = Alphabet.letterForIndex(index: groupStage.index)
}
} else {
groupStages.forEach { groupStage in
groupStage.name = nil
}
}
do {
try dataStore.groupStages.addOrUpdate(contentOfs: groupStages)
} catch {
Logger.error(error)
}
}
} }

@ -21,6 +21,7 @@ struct BroadcastView: View {
let filter = CIFilter.qrCodeGenerator() let filter = CIFilter.qrCodeGenerator()
@State private var urlToShow: String? @State private var urlToShow: String?
@State private var tvMode: Bool = false @State private var tvMode: Bool = false
@State private var pageLink: PageLink = .teams
let tournamentPublishingTip = TournamentPublishingTip() let tournamentPublishingTip = TournamentPublishingTip()
let tournamentTVBroadcastTip = TournamentTVBroadcastTip() let tournamentTVBroadcastTip = TournamentTVBroadcastTip()
@ -180,15 +181,26 @@ struct BroadcastView: View {
} }
} }
if let url = tournament.shareURL() { if let url = tournament.shareURL(pageLink) {
LabeledContent { LabeledContent {
actionForURL(url) actionForURL(url)
} label: { } label: {
Text("Tournoi") Text("Tournoi")
Text(pageLink.localizedLabel())
} }
} }
if let url = tournament.broadcastURL() { let links : [PageLink] = [.teams, .summons, .groupStages, .matches, .rankings]
Picker(selection: $pageLink) {
ForEach(links) { pageLink in
Text(pageLink.localizedLabel()).tag(pageLink)
}
} label: {
Text("Modifier la page du tournoi à partager")
}
.pickerStyle(.menu)
if let url = tournament.shareURL(.broadcast) {
LabeledContent { LabeledContent {
actionForURL(url) actionForURL(url)
} label: { } label: {

@ -81,7 +81,7 @@ struct TournamentStatusView: View {
dismiss() dismiss()
} }
} footer: { } footer: {
Text(.init("Si votre tournoi n'a pas pu aboutir à cause de la météo ou autre, vous pouvez l'annuler et il ne sera pas comptabilisé. Toutes les données du tournoi seront conservées. Le tournoi visible sur [Padel Club](\(URLs.main)")) Text(.init("Si votre tournoi n'a pas pu aboutir à cause de la météo ou autre, vous pouvez l'annuler et il ne sera pas comptabilisé. Toutes les données du tournoi seront conservées. Le tournoi visible sur [Padel Club](\(URLs.main.rawValue))"))
} }
} }
@ -90,7 +90,7 @@ struct TournamentStatusView: View {
Text("Tournoi privé") Text("Tournoi privé")
} }
} footer: { } footer: {
Text(.init("Le tournoi sera masqué sur le site [Padel Club](\(URLs.main)")) Text(.init("Le tournoi sera masqué sur le site [Padel Club](\(URLs.main.rawValue))"))
} }
} }
.toolbarBackground(.visible, for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar)

Loading…
Cancel
Save