Merge branch 'main'

sync3
Razmig Sarkissian 1 month ago
commit ea13b13101
  1. 20
      PadelClub.xcodeproj/project.pbxproj
  2. 22
      PadelClub/Extensions/View+Extensions.swift
  3. 15
      PadelClub/Utils/Tips.swift
  4. 31
      PadelClub/Views/Cashier/Event/EventTournamentsView.swift
  5. 91
      PadelClub/Views/Cashier/Event/TournamentPickerView.swift
  6. 25
      PadelClub/Views/Components/BarButtonView.swift
  7. 5
      PadelClub/Views/GroupStage/GroupStagesView.swift
  8. 8
      PadelClub/Views/Match/MatchDetailView.swift
  9. 14
      PadelClub/Views/Navigation/Agenda/TournamentSubscriptionView.swift
  10. 10
      PadelClub/Views/Planning/CourtAvailabilitySettingsView.swift
  11. 7
      PadelClub/Views/Round/LoserRoundsView.swift
  12. 6
      PadelClub/Views/Round/RoundsView.swift
  13. 7
      PadelClub/Views/Score/EditScoreView.swift
  14. 7
      PadelClub/Views/Score/FollowUpMatchView.swift
  15. 55
      PadelClub/Views/Tournament/Screen/BroadcastView.swift
  16. 5
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
  17. 5
      PadelClub/Views/Tournament/Screen/PrintSettingsView.swift
  18. 5
      PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift
  19. 6
      PadelClub/Views/Tournament/Screen/TableStructureView.swift
  20. 5
      PadelClub/Views/Tournament/Screen/TournamentCallView.swift
  21. 5
      PadelClub/Views/Tournament/Screen/TournamentCashierView.swift
  22. 5
      PadelClub/Views/Tournament/Screen/TournamentRankView.swift
  23. 6
      PadelClub/Views/Tournament/Screen/TournamentScheduleView.swift
  24. 6
      PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift
  25. 25
      PadelClub/Views/Tournament/TournamentView.swift

@ -711,6 +711,12 @@
FFA252B62CDD2C6C0074E63F /* OngoingDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA252B42CDD2C630074E63F /* OngoingDestination.swift */; };
FFA252B72CDD2C6C0074E63F /* OngoingDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA252B42CDD2C630074E63F /* OngoingDestination.swift */; };
FFA6D7852BB0B795003A31F3 /* FileImportManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA6D7842BB0B795003A31F3 /* FileImportManager.swift */; };
FFA97C8D2E8A59D00089EA22 /* TournamentPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA97C8C2E8A59D00089EA22 /* TournamentPickerView.swift */; };
FFA97C8E2E8A59D00089EA22 /* TournamentPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA97C8C2E8A59D00089EA22 /* TournamentPickerView.swift */; };
FFA97C8F2E8A59D00089EA22 /* TournamentPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA97C8C2E8A59D00089EA22 /* TournamentPickerView.swift */; };
FFA97C9E2E8A7C080089EA22 /* View+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA97C9D2E8A7C080089EA22 /* View+Extensions.swift */; };
FFA97C9F2E8A7C080089EA22 /* View+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA97C9D2E8A7C080089EA22 /* View+Extensions.swift */; };
FFA97CA02E8A7C080089EA22 /* View+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA97C9D2E8A7C080089EA22 /* View+Extensions.swift */; };
FFB0FF672E81B671009EDEAC /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFB0FF662E81B671009EDEAC /* OnboardingView.swift */; };
FFB0FF682E81B671009EDEAC /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFB0FF662E81B671009EDEAC /* OnboardingView.swift */; };
FFB0FF692E81B671009EDEAC /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFB0FF662E81B671009EDEAC /* OnboardingView.swift */; };
@ -1118,6 +1124,8 @@
FFA252B42CDD2C630074E63F /* OngoingDestination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OngoingDestination.swift; sourceTree = "<group>"; };
FFA6D7842BB0B795003A31F3 /* FileImportManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileImportManager.swift; sourceTree = "<group>"; };
FFA6D78A2BB0BEB3003A31F3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
FFA97C8C2E8A59D00089EA22 /* TournamentPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentPickerView.swift; sourceTree = "<group>"; };
FFA97C9D2E8A7C080089EA22 /* View+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extensions.swift"; sourceTree = "<group>"; };
FFB0FF662E81B671009EDEAC /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = "<group>"; };
FFB0FF722E841042009EDEAC /* WeekdaySelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeekdaySelectionView.swift; sourceTree = "<group>"; };
FFB1C98A2C10255100B154A7 /* TournamentBroadcastRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentBroadcastRowView.swift; sourceTree = "<group>"; };
@ -1341,6 +1349,7 @@
C49771DE2DC25F04005CD239 /* Badge+Extensions.swift */,
C49771DF2DC25F04005CD239 /* SpinDrawable+Extensions.swift */,
C49772022DC260D3005CD239 /* Round+Extensions.swift */,
FFA97C9D2E8A7C080089EA22 /* View+Extensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -1866,6 +1875,7 @@
FFE103072C353B7600684FC9 /* EventClubSettingsView.swift */,
FF8F263C2BAD627A00650388 /* TournamentConfiguratorView.swift */,
FF8E52332DF01D6100099B75 /* EventStatusView.swift */,
FFA97C8C2E8A59D00089EA22 /* TournamentPickerView.swift */,
);
name = Event;
path = Cashier/Event;
@ -2345,6 +2355,7 @@
FF5BAF6E2BE0B3C8008B4B7E /* FederalDataViewModel.swift in Sources */,
FF3F74FF2B91A2D4004CFE0E /* AgendaDestination.swift in Sources */,
FF3795622B9396D0004EA093 /* PadelClubApp.xcdatamodeld in Sources */,
FFA97CA02E8A7C080089EA22 /* View+Extensions.swift in Sources */,
FFCFC0162BBC5A4C00B82851 /* SetInputView.swift in Sources */,
FFF03C942BD91D0C00B516FC /* ButtonValidateView.swift in Sources */,
FF5D0D892BB4935C005CB568 /* ClubRowView.swift in Sources */,
@ -2433,6 +2444,7 @@
FFF527D62BC6DDD000FF4EF2 /* MatchScheduleEditorView.swift in Sources */,
FFC91AF92BD6A09100B29808 /* FortuneWheelView.swift in Sources */,
FFE8B5C82DAA390900BDE966 /* StripeValidationService.swift in Sources */,
FFA97C8D2E8A59D00089EA22 /* TournamentPickerView.swift in Sources */,
C493B37E2C10AD3600862481 /* LoadingViewModifier.swift in Sources */,
FF089EBD2BB0287D00F0AEC7 /* PlayerView.swift in Sources */,
FF967D032BAEF0C000A9A3BD /* MatchDetailView.swift in Sources */,
@ -2612,6 +2624,7 @@
FF4CBFBF2C996C0600151637 /* SetInputView.swift in Sources */,
FF4CBFC02C996C0600151637 /* ButtonValidateView.swift in Sources */,
FF4CBFC12C996C0600151637 /* ClubRowView.swift in Sources */,
FFA97C9E2E8A7C080089EA22 /* View+Extensions.swift in Sources */,
FF4CBFC22C996C0600151637 /* ClubDetailView.swift in Sources */,
FF4CBFC32C996C0600151637 /* GroupStageCallingView.swift in Sources */,
FF4CBFC52C996C0600151637 /* CashierSettingsView.swift in Sources */,
@ -2700,6 +2713,7 @@
FF4CC0102C996C0600151637 /* LoadingViewModifier.swift in Sources */,
FF4CC0112C996C0600151637 /* PlayerView.swift in Sources */,
FF4CC0122C996C0600151637 /* MatchDetailView.swift in Sources */,
FFA97C8F2E8A59D00089EA22 /* TournamentPickerView.swift in Sources */,
FF4CC0142C996C0600151637 /* PlayerBlockView.swift in Sources */,
FF4CC0172C996C0600151637 /* PointView.swift in Sources */,
FF4CC0182C996C0600151637 /* ClubHolder.swift in Sources */,
@ -2857,6 +2871,7 @@
FF70FB3E2C90584900129CC2 /* SetInputView.swift in Sources */,
FF70FB3F2C90584900129CC2 /* ButtonValidateView.swift in Sources */,
FF70FB402C90584900129CC2 /* ClubRowView.swift in Sources */,
FFA97C9F2E8A7C080089EA22 /* View+Extensions.swift in Sources */,
FF70FB412C90584900129CC2 /* ClubDetailView.swift in Sources */,
FF70FB422C90584900129CC2 /* GroupStageCallingView.swift in Sources */,
FF70FB442C90584900129CC2 /* CashierSettingsView.swift in Sources */,
@ -2945,6 +2960,7 @@
FF70FB8F2C90584900129CC2 /* LoadingViewModifier.swift in Sources */,
FF70FB902C90584900129CC2 /* PlayerView.swift in Sources */,
FF70FB912C90584900129CC2 /* MatchDetailView.swift in Sources */,
FFA97C8E2E8A59D00089EA22 /* TournamentPickerView.swift in Sources */,
FF70FB932C90584900129CC2 /* PlayerBlockView.swift in Sources */,
FF70FB962C90584900129CC2 /* PointView.swift in Sources */,
FF70FB972C90584900129CC2 /* ClubHolder.swift in Sources */,
@ -3160,7 +3176,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.52;
MARKETING_VERSION = 1.2.53;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -3207,7 +3223,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.52;
MARKETING_VERSION = 1.2.53;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

@ -0,0 +1,22 @@
//
// View+Extensions.swift
// PadelClub
//
// Created by Razmig Sarkissian on 29/09/2025.
//
import SwiftUI
extension View {
/// Runs a transform only on iOS 26+, otherwise returns self
@ViewBuilder
func ifAvailableiOS26<Content: View>(
@ViewBuilder transform: (Self) -> Content
) -> some View {
if #available(iOS 26.0, *) {
transform(self)
} else {
self
}
}
}

@ -660,6 +660,21 @@ struct UpdatePlannedDatesTip: Tip {
}
}
struct MergeTournamentTip: Tip {
var title: Text {
Text("Transfert de tournois")
}
var message: Text? {
Text("Vous pouvez transferer des tournois d'un autre événement dans celui-ci.")
}
var image: Image? {
Image(systemName: "square.and.arrow.down")
}
}
struct TipStyleModifier: ViewModifier {
@Environment(\.colorScheme) var colorScheme
var tint: Color?

@ -15,7 +15,8 @@ struct EventTournamentsView: View {
let event: Event
@State private var newTournament: Tournament?
@State private var mainTournament: Tournament?
@State private var showTournamentPicker: Bool = false
var presentTournamentCreationView: Binding<Bool> { Binding(
get: { newTournament != nil },
set: { isPresented in
@ -122,13 +123,35 @@ struct EventTournamentsView: View {
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
BarButtonView("Ajouter un tournoi", icon: "plus.circle.fill") {
let tournament = Tournament.newEmptyInstance()
newTournament = tournament
BarButtonView("Importer un tournoi", icon: "square.and.arrow.down") {
showTournamentPicker = true
}
}
if #available(iOS 26.0, *) {
ToolbarSpacer(placement: .topBarTrailing)
}
ToolbarItem(placement: .topBarTrailing) {
if #available(iOS 26.0, *) {
BarButtonView("Ajouter une indisponibilité", icon: "plus") {
let tournament = Tournament.newEmptyInstance()
newTournament = tournament
}
} else {
BarButtonView("Ajouter une indisponibilité", icon: "plus.circle.fill") {
let tournament = Tournament.newEmptyInstance()
newTournament = tournament
}
}
}
}
.headerProminence(.increased)
.sheet(isPresented: $showTournamentPicker, content: {
NavigationStack {
TournamentPickerView(event: event)
.environmentObject(dataStore)
}
})
.sheet(isPresented: presentTournamentCreationView) {
if let newTournament {
NavigationStack {

@ -0,0 +1,91 @@
//
// TournamentPickerView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 29/09/2025.
//
import SwiftUI
import LeStorage
import PadelClubData
import TipKit
struct TournamentPickerView: View {
@EnvironmentObject var dataStore: DataStore
@Environment(\.dismiss) private var dismiss
let mergeTournamentTip = MergeTournamentTip()
let event: Event
@State private var selectedTournamentIds: Set<String> = Set()
@State private var shouldEraseEmptyEvents: Bool = false
var tournaments: [Tournament] {
dataStore.tournaments.filter({ $0.isDeleted == false && $0.event?.id != event.id }).sorted(by: \.startDate, order: .descending)
}
var body: some View {
List(selection: $selectedTournamentIds) {
Section {
TipView(mergeTournamentTip)
.tipStyle(tint: .green)
}
Section {
Toggle(isOn: $shouldEraseEmptyEvents) {
Text("Effacer les événements vides")
Text("Les événements qui n'ont plus de tournois seront effacés automatiquement.")
}
}
ForEach(tournaments) { tournament in
TournamentCellView(tournament: tournament).tag(tournament.id)
}
}
.environment(\.editMode, Binding.constant(EditMode.active))
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("Annuler") {
dismiss()
}
}
ToolbarItem(placement: .topBarTrailing) {
ButtonValidateView {
_transferTournaments()
dismiss()
}
.disabled(selectedTournamentIds.isEmpty)
}
}
.navigationTitle("Transfert de tournois")
}
private func _transferTournaments() {
let tournaments = tournaments
var eventIdsToCheck = Set<String>()
var tournamentsToSave = [Tournament]()
selectedTournamentIds.forEach { id in
if let tournament = tournaments.first(where: { $0.id == id }) {
if let eventId = tournament.event{
eventIdsToCheck.insert(eventId)
}
tournament.event = event.id
tournamentsToSave.append(tournament)
}
}
dataStore.tournaments.addOrUpdate(contentOfs: tournamentsToSave)
if shouldEraseEmptyEvents {
var eventsToDelete = [Event]()
eventIdsToCheck.forEach { eventId in
if let eventToCheck = dataStore.events.first(where: { $0.id == eventId }) {
if eventToCheck.tournaments.isEmpty && shouldEraseEmptyEvents {
eventsToDelete.append(eventToCheck)
}
}
}
dataStore.events.delete(contentOfs: eventsToDelete)
}
}
}

@ -22,23 +22,14 @@ struct BarButtonView: View {
Button(action: {
action()
}) {
Image(systemName: icon)
.resizable()
.scaledToFit()
.frame(minHeight: 28)
/*
Label {
Text(accessibilityLabel)
} icon: {
Image(systemName: icon)
.resizable()
.scaledToFit()
.frame(minHeight: 36)
}
.labelStyle(.iconOnly)
//todo: resizing not working when label used
*/
if #available(iOS 26.0, *) {
Label(accessibilityLabel, systemImage: icon)
} else {
Image(systemName: icon)
.resizable()
.scaledToFit()
.frame(minHeight: 32)
}
}
}
}

@ -256,5 +256,10 @@ struct GroupStagesView: View {
.environment(tournament)
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
}
}

@ -427,7 +427,13 @@ struct MatchDetailView: View {
.navigationTitle(match.matchTitle())
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
if let tournament = match.currentTournament() {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
}
}
var quickLookHeader: some View {

@ -383,17 +383,3 @@ struct TournamentSubscriptionView: View {
}
}
extension View {
/// Runs a transform only on iOS 26+, otherwise returns self
@ViewBuilder
func ifAvailableiOS26<Content: View>(
@ViewBuilder transform: (Self) -> Content
) -> some View {
if #available(iOS 26.0, *) {
transform(self)
} else {
self
}
}
}

@ -111,8 +111,14 @@ struct CourtAvailabilitySettingsView: View {
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
BarButtonView("Ajouter une indisponibilité", icon: "plus.circle.fill") {
showingPopover = true
if #available(iOS 26.0, *) {
BarButtonView("Ajouter une indisponibilité", icon: "plus") {
showingPopover = true
}
} else {
BarButtonView("Ajouter une indisponibilité", icon: "plus.circle.fill") {
showingPopover = true
}
}
}
}

@ -297,5 +297,12 @@ struct LoserRoundsView: View {
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.navigationTitle(upperBracketRound.correspondingLoserRoundTitle)
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
if let tournament = upperBracketRound.round.tournamentObject() {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
}
}
}

@ -48,11 +48,17 @@ struct RoundsView: View {
case .some(let selectedRound):
RoundView(upperRound: selectedRound).id(selectedRound.id)
.navigationTitle(selectedRound.round.roundTitle())
}
}
.environment(\.isEditingTournamentSeed, $isEditingTournamentSeed)
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
}
}

@ -244,6 +244,13 @@ struct EditScoreView: View {
matchDescriptor.setDescriptors.removeAll()
matchDescriptor.addNewSet()
}
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
if let tournament = matchDescriptor.match?.currentTournament() {
$0.navigationBarTitle(tournament.tournamentTitle())
}
}
}
}
func save() {

@ -292,6 +292,13 @@ struct FollowUpMatchView: View {
}
}
}
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
if let tournament = match?.currentTournament() {
$0.navigationBarTitle(tournament.tournamentTitle())
}
}
}
.onChange(of: readyMatches) {
dismissWhenPresentFollowUpMatchIsDismissed = true
if autoDismiss {

@ -84,6 +84,24 @@ struct BroadcastView: View {
.tipStyle(tint: nil)
}
if let shareURL = tournament.shareURL(.info) {
Section {
Link(destination: shareURL) {
Text(shareURL.absoluteString)
}
} header: {
Text("Page d'information")
} footer: {
HStack {
CopyPasteButtonView(pasteValue: shareURL.absoluteString)
Spacer()
ShareLink(item: shareURL) {
Label("Partager", systemImage: "square.and.arrow.up")
}
}
}
}
if let url = tournament.shareURL(.clubBroadcast) {
Section {
Link(destination: url) {
@ -113,6 +131,21 @@ struct BroadcastView: View {
}
}
Section {
let links : [PageLink] = [.info, .teams, .summons, .groupStages, .matches, .rankings, .broadcast, .clubBroadcast]
Picker(selection: $pageLink) {
ForEach(links) { pageLink in
Text(pageLink.localizedLabel()).tag(pageLink)
}
} label: {
Text("Page à partager")
}
.pickerStyle(.menu)
actionForURL(title: "Partager la page '" + pageLink.localizedLabel() + "'", url: tournament.shareURL(pageLink))
} header: {
Text("Lien du tournoi à partager")
}
if tournament.isPrivate == false {
Section {
@ -300,24 +333,9 @@ struct BroadcastView: View {
}
}
.toolbar(content: {
if StoreCenter.main.userId != nil, tournament.isPrivate == false, tournament.club() != nil {
if StoreCenter.main.userId != nil, tournament.club() != nil {
ToolbarItem(placement: .topBarTrailing) {
Menu {
Section {
let links : [PageLink] = [.info, .teams, .summons, .groupStages, .matches, .rankings, .broadcast, .clubBroadcast]
Picker(selection: $pageLink) {
ForEach(links) { pageLink in
Text(pageLink.localizedLabel()).tag(pageLink)
}
} label: {
Text("Choisir la page à partager")
}
.pickerStyle(.menu)
actionForURL(title: "Partager la page '" + pageLink.localizedLabel() + "'", url: tournament.shareURL(pageLink))
} header: {
Text("Lien du tournoi à partager")
}
#if DEBUG
Section {
actionForURL(title: "La Boutique", url: URLs.main.url.appending(path: "shop"))
@ -344,6 +362,11 @@ struct BroadcastView: View {
})
.headerProminence(.increased)
.navigationTitle("Publication")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.sheet(item: $urlToShow) { urlToShow in

@ -485,6 +485,11 @@ struct InscriptionManagerView: View {
}
.toolbarBackground(.visible, for: .navigationBar)
.navigationTitle("Inscriptions")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
.navigationBarTitleDisplayMode(.inline)
.onChange(of: tournament.hideTeamsWeight) {
_save()

@ -169,6 +169,11 @@ struct PrintSettingsView: View {
}
}
.navigationTitle("Imprimer")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
.toolbarBackground(.visible, for: .navigationBar)
.navigationBarTitleDisplayMode(.inline)
.sheet(isPresented: $presentShareView) {

@ -358,6 +358,11 @@ struct RegistrationSetupView: View {
.toolbarRole(.editor)
.headerProminence(.increased)
.navigationTitle("Inscription en ligne")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.navigationBarBackButtonHidden(hasChanges)

@ -412,6 +412,12 @@ struct TableStructureView: View {
}
.navigationTitle("Structure")
.navigationBarTitleDisplayMode(.inline)
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
}

@ -137,6 +137,11 @@ struct TournamentCallView: View {
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.navigationTitle("Convocations")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
}
}

@ -166,6 +166,11 @@ struct TournamentCashierView: View {
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.navigationTitle(tournament.isFree() ? "Présence" : "Encaissement")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
} else {
Text("no store")
}

@ -158,6 +158,11 @@ struct TournamentRankView: View {
}
}
.navigationTitle("Classement")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.toolbar {

@ -101,6 +101,12 @@ struct TournamentScheduleView: View {
.toolbarRole(.editor)
.toolbarBackground(.visible, for: .navigationBar)
.navigationTitle("Horaires et formats")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
}
}

@ -81,6 +81,12 @@ struct TournamentSettingsView: View {
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.navigationTitle("Réglages du tournoi")
.ifAvailableiOS26 {
if #available(iOS 26.0, *) {
$0.navigationSubtitle(tournament.tournamentTitle())
}
}
}
}

@ -240,21 +240,38 @@ struct TournamentView: View {
}
Menu {
NavigationLink(value: Screen.event) {
Button {
navigation.path.append(Screen.event)
} label: {
Text("Événement")
if let tournamentCount = tournament.eventObject()?.confirmedTournaments().count {
Text(tournamentCount.formatted() + " tournoi" + tournamentCount.pluralSuffix)
.foregroundStyle(.secondary)
}
}
NavigationLink(value: Screen.settings) {
Button {
navigation.path.append(Screen.settings)
} label: {
Text("Tournoi")
Text("Inscription en ligne, pistes, formats")
.foregroundStyle(.secondary)
}
NavigationLink(value: Screen.structure) {
Button {
navigation.path.append(Screen.structure)
} label: {
LabelStructure()
Text("Poules, tableau, qualifiés sortants")
.foregroundStyle(.secondary)
}
Divider()
NavigationLink(value: Screen.stateSettings) {
Button {
navigation.path.append(Screen.stateSettings)
} label: {
Label("Gestion", systemImage: "trash")
Text("Annuler, supprimer ou terminer le tournoi")
}
.disabled((self.tournament.sharing != nil))

Loading…
Cancel
Save