Laurent 1 year ago
commit a84ddc539f
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 6
      PadelClub/Data/Club.swift
  3. 2
      PadelClub/Data/Federal/FederalTournament.swift
  4. 5
      PadelClub/Data/GroupStage.swift
  5. 7
      PadelClub/Data/MatchScheduler.swift
  6. 2
      PadelClub/Data/Tournament.swift
  7. 5
      PadelClub/Views/Calling/GroupStageCallingView.swift
  8. 16
      PadelClub/Views/Cashier/Event/EventCreationView.swift
  9. 28
      PadelClub/Views/Club/ClubDetailView.swift
  10. 7
      PadelClub/Views/Club/ClubRowView.swift
  11. 14
      PadelClub/Views/Club/ClubSearchView.swift
  12. 14
      PadelClub/Views/Club/ClubsView.swift
  13. 30
      PadelClub/Views/Club/CreateClubView.swift
  14. 21
      PadelClub/Views/Navigation/MainView.swift
  15. 12
      PadelClub/Views/Navigation/Umpire/UmpireView.swift
  16. 2
      PadelClub/Views/Subscription/Guard.swift

@ -1908,7 +1908,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 61;
CURRENT_PROJECT_VERSION = 66;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -1949,7 +1949,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 61;
CURRENT_PROJECT_VERSION = 66;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;

@ -170,7 +170,7 @@ class Club : ModelObject, Storable, Hashable {
extension Club {
var isValid: Bool {
name.isEmpty == false && acronym.isEmpty == false
name.isEmpty == false && name.count > 3
}
func automaticShortName() -> String {
@ -216,7 +216,7 @@ extension Club {
}
func hasBeenCreated(by creatorId: String?) -> Bool {
return creatorId == creator
return creatorId == creator || creator == nil
}
func isFavorite() -> Bool {
@ -235,7 +235,7 @@ extension Club {
if clubs.isEmpty == false {
return clubs.first!
} else {
return Club(name: name, code: code, city: city, zipCode: zipCode)
return Club(creator: Store.main.userId, name: name, code: code, city: city, zipCode: zipCode)
}
}

@ -20,7 +20,7 @@ struct FederalTournament: Identifiable, Codable {
let club = DataStore.shared.user.clubsObjects().first(where: { $0.code == codeClub })
var event = DataStore.shared.events.first(where: { $0.tenupId == id.string })
if event == nil {
event = Event(creator: DataStore.shared.user.id, club: club?.id, name: libelle, tenupId: id.string)
event = Event(creator: Store.main.userId, club: club?.id, name: libelle, tenupId: id.string)
do {
try DataStore.shared.events.addOrUpdate(instance: event!)
} catch {

@ -166,6 +166,11 @@ class GroupStage: ModelObject, Storable {
return _matches().filter { matchIndexes.contains($0.index) }
}
func initialStartDate(forTeam team: TeamRegistration) -> Date? {
guard let groupStagePosition = team.groupStagePosition else { return nil }
return matches(forGroupStagePosition: groupStagePosition).compactMap({ $0.startDate }).sorted().first ?? startDate
}
func matchPlayed(by groupStagePosition: Int, againstPosition: Int) -> Match? {
if groupStagePosition == againstPosition { return nil }
let combos = Array((0..<size).combinations(ofCount: 2))

@ -85,7 +85,7 @@ class MatchScheduler : ModelObject, Storable {
@discardableResult
func updateGroupStageSchedule(tournament: Tournament) -> Date {
let computedGroupStageChunkCount = groupStageChunkCount ?? 1
let computedGroupStageChunkCount = groupStageChunkCount ?? tournament.getGroupStageChunkValue()
let groupStages: [GroupStage] = tournament.groupStages()
let numberOfCourtsAvailablePerRotation: Int = tournament.courtCount
@ -677,7 +677,10 @@ class MatchScheduler : ModelObject, Storable {
}
func updateSchedule(tournament: Tournament) -> Bool {
let lastDate = updateGroupStageSchedule(tournament: tournament)
var lastDate = tournament.startDate
if tournament.groupStageCount > 0 {
lastDate = updateGroupStageSchedule(tournament: tournament)
}
return updateBracketSchedule(tournament: tournament, fromRoundId: nil, fromMatchId: nil, startDate: lastDate)
}
}

@ -1762,7 +1762,7 @@ class Tournament : ModelObject, Storable {
}
func getGroupStageChunkValue() -> Int {
if teamsPerGroupStage >= 2 {
if groupStageCount > 0 && teamsPerGroupStage >= 2 {
let result = courtCount / (teamsPerGroupStage / 2)
let remainder = courtCount % (teamsPerGroupStage / 2)
let value = remainder == 0 ? result : result + 1

@ -70,8 +70,8 @@ struct GroupStageCallingView: View {
private func _groupStageView(groupStage: GroupStage) -> some View {
let teams = groupStage.teams()
List {
if let startDate = groupStage.startDate {
ForEach(teams) { team in
ForEach(teams) { team in
if let startDate = groupStage.initialStartDate(forTeam: team) {
Section {
CallView.TeamView(team: team)
} header: {
@ -80,7 +80,6 @@ struct GroupStageCallingView: View {
CallView(teams: [team], callDate: startDate, matchFormat: groupStage.matchFormat, roundLabel: "poule")
}
}
}
}
.overlay {

@ -130,10 +130,6 @@ struct EventCreationView: View {
private func _validate() {
let event = Event(creator: Store.main.userId, name: eventName)
event.club = selectedClub?.id
tournaments.forEach { tournament in
tournament.event = event.id
}
do {
try dataStore.events.addOrUpdate(instance: event)
@ -142,6 +138,7 @@ struct EventCreationView: View {
}
tournaments.forEach { tournament in
tournament.event = event.id
tournament.courtCount = selectedClub?.courtCount ?? 2
tournament.startDate = startingDate
tournament.dayDuration = duration
@ -154,6 +151,17 @@ struct EventCreationView: View {
Logger.error(error)
}
if let selectedClub, let verifiedSelectedClubId = dataStore.clubs.first(where: { selectedClub.id == $0.id })?.id {
event.club = verifiedSelectedClubId
do {
try dataStore.events.addOrUpdate(instance: event)
} catch {
Logger.error(error)
}
}
dismiss()
navigation.path.append(tournaments.first!)
}

@ -43,6 +43,7 @@ struct ClubDetailView: View {
dataStore.user.clubs.append(club.id)
}
self.dataStore.saveUser()
dismiss()
}
} footer: {
if displayContext == .lockedForEditing {
@ -52,7 +53,7 @@ struct ClubDetailView: View {
}
Section {
TextField("Nom du club", text: $club.name)
TextField("Nom du club (4 lettres mini)", text: $club.name)
.autocorrectionDisabled()
.keyboardType(.alphabet)
.frame(maxWidth: .infinity)
@ -186,31 +187,6 @@ struct ClubDetailView: View {
}
}
if displayContext == .addition {
Section {
} header: {
HStack {
VStack {
Divider()
}
Text("ou")
VStack {
Divider()
}
}
}
Section {
NavigationLink {
ClubSearchView(displayContext: .edition, club: club)
} label: {
Label("Chercher dans la base fédérale", systemImage: "magnifyingglass")
}
} footer: {
Text("Vous pouvez chercher un club dans la base fédérale et importer les informations directement.")
}
}
ClubCourtSetupView(club: club, displayContext: displayContext, selectedCourt: $selectedCourt, hideLockForEditingMessage: true)
if displayContext == .edition {

@ -19,7 +19,12 @@ struct ClubRowView: View {
// .foregroundStyle(club.isFavorite() ? .green : .logoRed)
// }
} label: {
Text(club.name)
HStack {
Text(club.name)
Spacer()
}
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
}
}

@ -303,7 +303,7 @@ struct ClubSearchView: View {
}
private func _importClub(clubToEdit: Club, clubMarker: ClubMarker) {
if clubToEdit.creator == dataStore.user.id {
if clubToEdit.hasBeenCreated(by: Store.main.userId) {
if clubToEdit.name.isEmpty {
clubToEdit.name = clubMarker.nom.capitalized
clubToEdit.acronym = clubToEdit.automaticShortName().capitalized
@ -314,17 +314,19 @@ struct ClubSearchView: View {
clubToEdit.city = clubMarker.ville
}
if displayContext == .addition {
if displayContext == .addition && clubToEdit.hasBeenCreated(by: Store.main.userId) {
do {
try dataStore.clubs.addOrUpdate(instance: clubToEdit)
if dataStore.user.clubs.contains(where: { $0 == clubToEdit.id }) == false {
dataStore.user.clubs.append(clubToEdit.id)
self.dataStore.saveUser()
}
} catch {
Logger.error(error)
}
}
if dataStore.user.clubs.contains(where: { $0 == clubToEdit.id }) == false {
dataStore.user.clubs.append(clubToEdit.id)
self.dataStore.saveUser()
}
dismiss()
selection?(clubToEdit)
}

@ -27,6 +27,20 @@ struct ClubsView: View {
var body: some View {
List {
#if DEBUG
Section {
RowButtonView("Delete unexisted clubs", action: {
var ids = dataStore.user.clubs
ids.forEach { clubId in
if dataStore.clubs.findById(clubId) == nil {
dataStore.user.clubs.removeAll(where: { $0 == clubId })
}
}
dataStore.saveUser()
})
}
#endif
let clubs : [Club] = dataStore.user.clubsObjects(includeCreated: false)
let onlyCreatedClubs : [Club] = dataStore.user.createdClubsObjectsNotFavorite()

@ -30,6 +30,10 @@ struct CreateClubView: View {
ProgressView()
} else {
ButtonValidateView {
if club.acronym.isEmpty {
club.acronym = club.name.canonicalVersion.replaceCharactersFromSet(characterSet: .whitespacesAndNewlines).acronym()
}
validationInProgress = true
}
.disabled(club.isValid == false)
@ -45,27 +49,25 @@ struct CreateClubView: View {
Logger.error(error)
}
let club = Club.findOrCreate(name: club.name, code: club.code, city: club.city, zipCode: club.zipCode)
club.creator = Store.main.userId
let newClub = Club.findOrCreate(name: club.name, code: club.code, city: club.city, zipCode: club.zipCode)
//update existing club if rights ok / freshly created club with data input from user
if club.hasBeenCreated(by: Store.main.userId) {
club.update(fromClub: club)
if newClub.hasBeenCreated(by: Store.main.userId) {
newClub.update(fromClub: club)
do {
try dataStore.clubs.addOrUpdate(instance: newClub)
} catch {
Logger.error(error)
}
}
do {
try dataStore.clubs.addOrUpdate(instance: club)
} catch {
Logger.error(error)
}
//save into user
if dataStore.user.clubs.contains(where: { $0 == club.id }) == false {
dataStore.user.clubs.append(club.id)
if dataStore.user.clubs.contains(where: { $0 == newClub.id }) == false {
dataStore.user.clubs.append(newClub.id)
self.dataStore.saveUser()
}
dismiss()
selection?(club)
selection?(newClub)
}
}
}

@ -92,6 +92,27 @@ struct MainView: View {
.environmentObject(dataStore)
.task {
await self._checkSourceFileAvailability()
if Store.main.hasToken() {
do {
try await dataStore.clubs.loadDataFromServerIfAllowed()
} catch {
Logger.error(error)
}
let ids = dataStore.user.clubs
var save = false
ids.forEach { clubId in
if dataStore.clubs.findById(clubId) == nil {
dataStore.user.clubs.removeAll(where: { $0 == clubId })
save = true
}
}
if save {
dataStore.saveUser()
}
}
}
// .refreshable {
// Task {

@ -193,12 +193,14 @@ struct UmpireView: View {
user.licenceId = player.license
if user.clubsObjects().contains(where: { $0.code == player.clubCode }) == false {
let userClub = Club.findOrCreate(name: player.clubName!, code: player.clubCode)
do {
try dataStore.clubs.addOrUpdate(instance: userClub)
user.setUserClub(userClub)
} catch {
Logger.error(error)
if userClub.hasBeenCreated(by: Store.main.userId) {
do {
try dataStore.clubs.addOrUpdate(instance: userClub)
} catch {
Logger.error(error)
}
}
user.setUserClub(userClub)
}
self.dataStore.saveUser()
}

@ -140,7 +140,7 @@ import LeStorage
}
var currentPlan: StoreItem? {
// return .monthlyUnlimited
return .monthlyUnlimited
// #if DEBUG
// return .monthlyUnlimited
// #else

Loading…
Cancel
Save