multistore
Razmig Sarkissian 1 year ago
parent 92b5b91c77
commit 1fc17d1992
  1. 4
      PadelClub/Data/Round.swift
  2. 5
      PadelClub/Data/Tournament.swift
  3. 12
      PadelClub/Utils/HtmlService.swift
  4. 4
      PadelClub/Utils/SourceFileManager.swift
  5. 109
      PadelClub/Utils/Tips.swift
  6. 2
      PadelClub/Views/Navigation/MainView.swift
  7. 6
      PadelClub/Views/Navigation/Organizer/OrganizedTournamentView.swift
  8. 2
      PadelClub/Views/Navigation/Organizer/TournamentOrganizerView.swift
  9. 11
      PadelClub/Views/Navigation/Umpire/PadelClubView.swift
  10. 41
      PadelClub/Views/Round/RoundView.swift
  11. 29
      PadelClub/Views/Tournament/Screen/BroadcastView.swift

@ -39,6 +39,10 @@ class Round: ModelObject, Storable {
Store.main.filter { $0.round == self.id }
}
func getDisabledMatches() -> [Match] {
Store.main.filter { $0.round == self.id && $0.disabled == true }
}
// MARK: -
var matchFormat: MatchFormat {

@ -446,6 +446,11 @@ class Tournament : ModelObject, Storable {
}
func shareURL(_ pageLink: PageLink = .matches) -> URL? {
// if pageLink == .broadcast {
// if let club = club(), let broadcastCode = club.broadcastCode {
//
// }
// }
return URLs.main.url.appending(path: "tournament/\(id)").appending(path: pageLink.path)
}

@ -88,6 +88,9 @@ enum HtmlService {
} else {
template = template.replacingOccurrences(of: "{{weightOne}}", with: "")
}
} else {
template = template.replacingOccurrences(of: "{{playerOne}}", with: "--")
template = template.replacingOccurrences(of: "{{weightOne}}", with: "")
}
if let playerTwo = entrant.players()[safe: 1] {
@ -97,6 +100,9 @@ enum HtmlService {
} else {
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "")
}
} else {
template = template.replacingOccurrences(of: "{{playerTwo}}", with: "--")
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "")
}
return template
case .groupstageRow(let entrant, let teamsPerBracket):
@ -139,6 +145,9 @@ enum HtmlService {
} else {
template = template.replacingOccurrences(of: "{{weightOne}}", with: "")
}
} else {
template = template.replacingOccurrences(of: "{{playerOne}}", with: "--")
template = template.replacingOccurrences(of: "{{weightOne}}", with: "")
}
if let playerTwo = entrant.players()[safe: 1] {
@ -148,6 +157,9 @@ enum HtmlService {
} else {
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "")
}
} else {
template = template.replacingOccurrences(of: "{{playerTwo}}", with: "--")
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "")
}
return template
case .hiddenPlayer:

@ -113,8 +113,8 @@ class SourceFileManager {
}
func getAllFiles() async {
let dates = monthsBetweenDates(startDateString: "08-2022", endDateString: Date().monthYearFormatted)
func getAllFiles(initialDate: String = "08-2022") async {
let dates = monthsBetweenDates(startDateString: initialDate, endDateString: Date().monthYearFormatted)
.compactMap {
URL.importDateFormatter.date(from: $0)
}

@ -440,13 +440,118 @@ struct CreateAccountTip: Tip {
}
}
struct SlideToDeleteSeedTip: Tip {
@Parameter
static var seeds: Int = 0
var rules: [Rule] {
[
// Define a rule based on the app state.
#Rule(Self.$seeds) {
// Set the conditions for when the tip displays.
return $0 > 0
}
]
}
var title: Text {
Text("Glisser pour effacer")
}
var message: Text? {
Text("Vous pouvez retirer une tête de série de sa position en glissant votre doigt vers la gauche")
}
var image: Image? {
Image(systemName: "person.fill.xmark")
}
}
struct PrintTip: Tip {
@Parameter
static var seeds: Int = 0
var rules: [Rule] {
[
// Define a rule based on the app state.
#Rule(Self.$seeds) {
// Set the conditions for when the tip displays.
return $0 > 0
}
]
}
var title: Text {
Text("Coup d'oeil de votre tableau")
}
var message: Text? {
Text("Vous pouvez avoir un aperçu de votre tableau ou l'imprimer.")
}
var image: Image? {
Image(systemName: "printer")
}
var actions: [Action] {
Action(id: ActionKey.printAction.rawValue, title: "Aperçu du tableau et option d'impression")
}
enum ActionKey: String {
case printAction = "printAction"
}
}
struct BracketEditTip: Tip {
@Parameter
static var matchesHidden: Int = 0
var nextRoundName: String?
var rules: [Rule] {
[
// Define a rule based on the app state.
#Rule(Self.$matchesHidden) {
// Set the conditions for when the tip displays.
return $0 > 0
}
]
}
var title: Text {
Text("Désactivation automatique des matchs")
}
var message: Text? {
let grammar = Self.matchesHidden == 1 ? "a" : "ont"
let article = Self.matchesHidden == 1 ? "la" : "les"
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.")
}
var image: Image? {
Image(systemName: "rectangle.slash")
}
}
struct TipStyleModifier: ViewModifier {
@Environment(\.colorScheme) var colorScheme
var tint: Color?
var background: Color?
var asSection: Bool
func body(content: Content) -> some View {
if asSection {
Section {
preparedContent(content: content)
}
} else {
preparedContent(content: content)
}
}
@ViewBuilder
func preparedContent(content: Content) -> some View {
if let background {
content
.tint(.white)
@ -477,7 +582,7 @@ struct TipStyleModifier: ViewModifier {
}
extension View {
func tipStyle(tint: Color?, background: Color? = nil) -> some View {
modifier(TipStyleModifier(tint: tint, background: background))
func tipStyle(tint: Color?, background: Color? = nil, asSection: Bool = false) -> some View {
modifier(TipStyleModifier(tint: tint, background: background, asSection: asSection))
}
}

@ -150,7 +150,7 @@ struct MainView: View {
}
private func _downloadPreviousDate() async {
await SourceFileManager.shared.getAllFiles()
await SourceFileManager.shared.getAllFiles(initialDate: "05-2024")
}
}

@ -8,14 +8,10 @@
import SwiftUI
struct OrganizedTournamentView: View {
let tournament: Tournament
@Bindable var tournament: Tournament
var body: some View {
@Bindable var tournament = tournament
NavigationStack(path: $tournament.navigationPath) {
TournamentView(tournament: tournament, presentationContext: .organizer)
// .onChange(of: navigationPath) {
// tournament.navigationPath = navigationPath
// }
}
}
}

@ -15,7 +15,7 @@ struct TournamentOrganizerView: View {
var body: some View {
VStack(spacing: 0) {
if let tournament = navigation.organizerTournament {
OrganizedTournamentView(tournament: tournament)
OrganizedTournamentView(tournament: tournament).id(tournament.id)
} else {
NavigationStack {
let userClubsEmpty = dataStore.user.clubs.isEmpty

@ -92,6 +92,11 @@ struct PadelClubView: View {
}
}
Section {
RowButtonView("Télécharger les données des mois précédents", role: .destructive) { _downloadPreviousDate()
}
}
if importingFiles {
ContentUnavailableView("Importation en cours", systemImage: "server.rack", description: Text("Une importation des données fédérales publiques est en cours, veuillez patienter."))
} else if (players.isEmpty || lastDataSource == nil) {
@ -226,6 +231,12 @@ struct PadelClubView: View {
viewContext.refreshAllObjects()
}
}
private func _downloadPreviousDate() {
Task {
await SourceFileManager.shared.getAllFiles(initialDate: "08-2022")
}
}
}
#Preview {

@ -7,16 +7,20 @@
import SwiftUI
import LeStorage
import TipKit
struct RoundView: View {
@Environment(\.isEditingTournamentSeed) private var isEditingTournamentSeed
@Environment(Tournament.self) var tournament: Tournament
@EnvironmentObject var dataStore: DataStore
@Environment(NavigationViewModel.self) private var navigation: NavigationViewModel
@State private var selectedSeedGroup: SeedInterval?
@State private var spaceLeft: [Match] = []
@State private var seedSpaceLeft: [Match] = []
@State private var availableSeedGroup: SeedInterval?
@State private var showPrintScreen: Bool = false
private func _getAvailableSeedGroup() async {
availableSeedGroup = tournament.seedGroupAvailable(atRoundIndex: round.index)
}
@ -55,6 +59,12 @@ struct RoundView: View {
}
} else if isEditingTournamentSeed.wrappedValue == false {
//(where: { $0.isDisabled() == false || isEditingTournamentSeed.wrappedValue })
let printTip = PrintTip()
TipView(printTip) { actions in
showPrintScreen = true
}
.tipStyle(tint: .master, asSection: true)
if loserRounds.isEmpty == false {
let correspondingLoserRoundTitle = round.correspondingLoserRoundTitle()
Section {
@ -68,6 +78,22 @@ struct RoundView: View {
}
}
} else {
let disabledMatchesCount = BracketEditTip.matchesHidden
if disabledMatchesCount > 0 {
let bracketTip = BracketEditTip(nextRoundName: round.nextRound()?.roundTitle())
TipView(bracketTip).tipStyle(tint: .green, asSection: true)
Section {
let leftToPlay = (RoundRule.numberOfMatches(forRoundIndex: round.index) - disabledMatchesCount)
LabeledContent {
Text(leftToPlay.formatted()).font(.largeTitle)
} label: {
Text("Match\(leftToPlay.pluralSuffix) à jouer \(round.roundTitle(.short))")
Text("\(disabledMatchesCount) match\(disabledMatchesCount.pluralSuffix) désactivé\(disabledMatchesCount.pluralSuffix) automatiquement")
}
}
}
let availableSeeds = tournament.availableSeeds()
let availableQualifiedTeams = tournament.availableQualifiedTeams()
@ -191,6 +217,12 @@ struct RoundView: View {
}
}
}
if isEditingTournamentSeed.wrappedValue == true {
let slideToDelete = SlideToDeleteSeedTip()
TipView(slideToDelete).tipStyle(tint: .logoRed, asSection: true)
}
ForEach(displayableMatches) { match in
Section {
MatchRowView(match: match, matchViewStyle: .sectionedStandardStyle)
@ -217,10 +249,17 @@ struct RoundView: View {
}
}
}
.navigationDestination(isPresented: $showPrintScreen) {
PrintSettingsView(tournament: tournament)
}
.onAppear {
Task {
await _prepareRound()
}
let seeds = round.seeds()
SlideToDeleteSeedTip.seeds = seeds.count
PrintTip.seeds = seeds.count
BracketEditTip.matchesHidden = round.getDisabledMatches().count
}
.fullScreenCover(isPresented: showVisualDrawView) {
if let availableSeedGroup = selectedSeedGroup {

@ -63,6 +63,26 @@ struct BroadcastView: View {
}
if tournament.isPrivate == false {
if let url = tournament.shareURL(.broadcast) {
Section {
Link(destination: url) {
Text(url.absoluteString).font(.largeTitle)
}
.contextMenu {
Button("Copier") {
let pasteboard = UIPasteboard.general
pasteboard.string = url.absoluteString
}
actionForURL(url)
}
} header: {
Text("Lien pour la diffusion TV")
} footer: {
Text("Lien à mettre sur une smart tv ou ordinateur dans le club house par exemple !")
}
}
Section {
LabeledContent {
if tournament.isTournamentPublished() {
@ -258,15 +278,6 @@ struct BroadcastView: View {
Text("Modifier la page du tournoi à partager")
}
.pickerStyle(.menu)
if let url = tournament.shareURL(.broadcast) {
LabeledContent {
actionForURL(url)
} label: {
Text("TV")
}
}
} header: {
Text("Liens à partager")
.textCase(nil)

Loading…
Cancel
Save