multistore
Razmig Sarkissian 2 years ago
parent e9ec8111b8
commit 3e1c8ae636
  1. 12
      PadelClub.xcodeproj/project.pbxproj
  2. 2
      PadelClub/Data/DataStore.swift
  3. 4
      PadelClub/Data/User.swift
  4. 7
      PadelClub/Utils/LocationManager.swift
  5. 0
      PadelClub/ViewModel/PresentationContext.swift
  6. 0
      PadelClub/ViewModel/Screen.swift
  7. 15
      PadelClub/Views/Club/ClubDetailView.swift
  8. 14
      PadelClub/Views/Club/ClubSearchView.swift
  9. 21
      PadelClub/Views/Navigation/Agenda/ActivityView.swift
  10. 40
      PadelClub/Views/Navigation/Agenda/EmptyActivityView.swift
  11. 24
      PadelClub/Views/Navigation/Agenda/WelcomeView.swift
  12. 2
      PadelClub/Views/Navigation/MainView.swift
  13. 30
      PadelClub/Views/Navigation/PadelClubView.swift
  14. 33
      PadelClub/Views/Navigation/Umpire/UmpireView.swift

@ -248,8 +248,6 @@
FFCFC01A2BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0192BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift */; };
FFCFC01C2BBC5AAA00B82851 /* SetDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC01B2BBC5AAA00B82851 /* SetDescriptor.swift */; };
FFD783FF2B91BA42000F62A6 /* PadelClubView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFD783FE2B91BA42000F62A6 /* PadelClubView.swift */; };
FFD784022B91C1B4000F62A6 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFD784012B91C1B4000F62A6 /* WelcomeView.swift */; };
FFD784042B91C280000F62A6 /* EmptyActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFD784032B91C280000F62A6 /* EmptyActivityView.swift */; };
FFDB1C6D2BB2A02000F1E467 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFDB1C6C2BB2A02000F1E467 /* AppSettings.swift */; };
FFDB1C732BB2CFE900F1E467 /* MySortDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFDB1C722BB2CFE900F1E467 /* MySortDescriptor.swift */; };
FFDDD40C2B93B2BB00C91A49 /* DeferredViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFDDD40B2B93B2BB00C91A49 /* DeferredViewModifier.swift */; };
@ -546,8 +544,6 @@
FFCFC01B2BBC5AAA00B82851 /* SetDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetDescriptor.swift; sourceTree = "<group>"; };
FFD783FE2B91BA42000F62A6 /* PadelClubView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PadelClubView.swift; sourceTree = "<group>"; };
FFD784002B91BF79000F62A6 /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
FFD784012B91C1B4000F62A6 /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = "<group>"; };
FFD784032B91C280000F62A6 /* EmptyActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyActivityView.swift; sourceTree = "<group>"; };
FFDB1C6C2BB2A02000F1E467 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = "<group>"; };
FFDB1C722BB2CFE900F1E467 /* MySortDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySortDescriptor.swift; sourceTree = "<group>"; };
FFDDD40B2B93B2BB00C91A49 /* DeferredViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeferredViewModifier.swift; sourceTree = "<group>"; };
@ -936,8 +932,6 @@
FF3F74F92B91A018004CFE0E /* Screen */ = {
isa = PBXGroup;
children = (
FF6EC8FD2B94792300EA7F5A /* Screen.swift */,
FF6EC8FF2B94794700EA7F5A /* PresentationContext.swift */,
FF70916D2B9108C600AB08DA /* InscriptionManagerView.swift */,
FF8F26422BADFE5B00650388 /* TournamentSettingsView.swift */,
FF8F26532BAE1E4400650388 /* TableStructureView.swift */,
@ -984,6 +978,8 @@
FF3F74FD2B91A087004CFE0E /* ViewModel */ = {
isa = PBXGroup;
children = (
FF6EC8FD2B94792300EA7F5A /* Screen.swift */,
FF6EC8FF2B94794700EA7F5A /* PresentationContext.swift */,
FF7091652B90F0B000AB08DA /* TabDestination.swift */,
FF025AEC2BD1513700A86CF8 /* AppScreen.swift */,
FF3F74FE2B91A2D4004CFE0E /* AgendaDestination.swift */,
@ -1176,8 +1172,6 @@
isa = PBXGroup;
children = (
FF82CFC82B9132AF00B0CAF2 /* ActivityView.swift */,
FFD784032B91C280000F62A6 /* EmptyActivityView.swift */,
FFD784012B91C1B4000F62A6 /* WelcomeView.swift */,
FF59FFB22B90EFAC0061EFF9 /* EventListView.swift */,
FF5D0D8A2BB4D1E3005CB568 /* CalendarView.swift */,
);
@ -1596,7 +1590,6 @@
FF9AC3952BE3627B00C2E883 /* GroupStageTeamReplacementView.swift in Sources */,
FF4C7F022BBBD7150031B6A3 /* TabItemModifier.swift in Sources */,
FFDDD40C2B93B2BB00C91A49 /* DeferredViewModifier.swift in Sources */,
FFD784042B91C280000F62A6 /* EmptyActivityView.swift in Sources */,
FF0E0B6D2BC254C6005F00A9 /* TournamentScheduleView.swift in Sources */,
FF025AF12BD1AEBD00A86CF8 /* MatchFormatStorageView.swift in Sources */,
FF3F74F62B919E45004CFE0E /* UmpireView.swift in Sources */,
@ -1618,7 +1611,6 @@
FFF964532BC262B000EEF017 /* PlanningSettingsView.swift in Sources */,
FFF527D62BC6DDD000FF4EF2 /* MatchScheduleEditorView.swift in Sources */,
FFC91AF92BD6A09100B29808 /* FortuneWheelView.swift in Sources */,
FFD784022B91C1B4000F62A6 /* WelcomeView.swift in Sources */,
FFF8ACD62B923960008466FA /* URL+Extensions.swift in Sources */,
FF089EBD2BB0287D00F0AEC7 /* PlayerView.swift in Sources */,
FF967D032BAEF0C000A9A3BD /* MatchDetailView.swift in Sources */,

@ -105,7 +105,7 @@ class DataStore: ObservableObject {
if let _ = Guard.main.currentPlan {
return .creation
}
if let user = self.user, user.club != nil {
if let user = self.user, user.clubs != nil {
if user.umpireCode != nil {
return .creation
} else {

@ -24,7 +24,7 @@ class User: UserBase, Storable {
public var id: String = Store.randomId()
public var username: String
public var email: String
var club: String?
var clubs: [String]?
var umpireCode: String?
var licenceId: String?
var firstName: String
@ -61,7 +61,7 @@ class User: UserBase, Storable {
case _id = "id"
case _username = "username"
case _email = "email"
case _club = "club"
case _clubs = "clubs"
case _umpireCode = "umpireCode"
case _licenceId = "licenceId"
case _firstName = "firstName"

@ -17,7 +17,6 @@ class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
@Published var requestStarted: Bool = false
@Published var userReadableCityOrZipcode: String = ""
@Published var lastError: Error? = nil
var shouldRequestLocation: Bool = false
override init() {
super.init()
@ -41,10 +40,8 @@ class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if manager.authorizationStatus == .authorizedWhenInUse || manager.authorizationStatus == .authorizedAlways {
if requestStarted == false && shouldRequestLocation {
DispatchQueue.main.async {
self.requestLocation()
}
DispatchQueue.main.async {
self.requestLocation()
}
}
}

@ -6,6 +6,7 @@
//
import SwiftUI
import LeStorage
struct ClubDetailView: View {
@Bindable var club: Club
@ -138,6 +139,20 @@ struct ClubDetailView: View {
.navigationBarTitleDisplayMode(.inline)
.toolbar(.visible, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
do {
dataStore.user?.clubs?.removeAll(where: { $0.id == club.id })
try dataStore.userStorage.update()
} catch {
Logger.error(error)
}
} label: {
LabelDelete()
}
}
}
.onDisappear {
if displayContext == .edition {
try? dataStore.clubs.addOrUpdate(instance: club)

@ -25,6 +25,8 @@ struct ClubSearchView: View {
@State private var getForwardCityList: [CLPlacemark] = []
@State private var searchPresented: Bool = false
@State private var showingSettingsAlert = false
@State private var presentClubCreationView: Bool = false
var displayContext: DisplayContext = .edition
var club: Club?
@ -141,7 +143,7 @@ struct ClubSearchView: View {
if searchAttempted {
Label("Aucun club trouvé", systemImage: "mappin.slash")
} else {
Text("Recherche de club")
Label("Recherche de club", systemImage: "location.circle")
}
} description: {
Text("Padel Club peut rechercher un club autour de vous, d'une ville ou d'un code postal, facilitant ainsi la saisie d'information.")
@ -160,12 +162,22 @@ struct ClubSearchView: View {
RowButtonView("Chercher une ville ou un code postal") {
searchPresented = true
}
if searchAttempted {
RowButtonView("Créer un club manuellement") {
presentClubCreationView = true
}
}
}
}
} else {
ContentUnavailableView("recherche en cours", systemImage: "mappin.and.ellipse", description: Text("recherche des clubs autour de vous"))
}
}
.sheet(isPresented: $presentClubCreationView) {
CreateClubView()
.tint(.master)
}
.alert(isPresented: $showingSettingsAlert) {
Alert(
title: Text("Réglages"),

@ -20,7 +20,8 @@ struct ActivityView: View {
@State private var isGatheringFederalTournaments: Bool = false
@State private var error: Error?
@State private var uuid: UUID = UUID()
@State private var presentClubSearchView: Bool = false
var runningTournaments: [FederalTournamentHolder] {
dataStore.tournaments.filter({ $0.endDate == nil })
.filter({ federalDataViewModel.isTournamentValidForFilters($0) })
@ -199,6 +200,10 @@ struct ActivityView: View {
.environment(navigation)
.tint(.master)
}
.sheet(isPresented: $presentClubSearchView) {
ClubImportView()
.tint(.master)
}
}
}
}
@ -245,8 +250,14 @@ struct ActivityView: View {
RowButtonView("Créer un nouvel événement") {
newTournament = Tournament.newEmptyInstance()
}
RowButtonView("Importer via Tenup") {
navigation.agendaDestination = .tenup
if dataStore.clubs.isEmpty {
RowButtonView("Chercher l'un de vos clubs") {
presentClubSearchView = true
}
} else {
RowButtonView("Importer via Tenup") {
navigation.agendaDestination = .tenup
}
}
}
}
@ -264,9 +275,9 @@ struct ActivityView: View {
ContentUnavailableView {
Label("Aucun tournoi", systemImage: "shield.slash")
} description: {
Text("Pour voir vos tournois tenup ici, indiquez vos clubs préférés.")
Text("Pour voir vos tournois tenup ici, choisissez vos clubs.")
} actions: {
RowButtonView("Choisir mes clubs préférés") {
RowButtonView("Choisir mes clubs") {
navigation.selectedTab = .umpire
}
}

@ -1,40 +0,0 @@
//
// EmptyActivityView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 01/03/2024.
//
import SwiftUI
struct EmptyActivityView: View {
@State private var newTournament: Tournament?
var body: some View {
NavigationStack {
List {
WelcomeView()
Section {
RowButtonView("Créer votre premier événement", action: {
newTournament = Tournament.newEmptyInstance()
})
}
Section {
RowButtonView("Importer vos tournois Tenup", action: {
})
}
}
.sheet(item: $newTournament) { tournament in
EventCreationView(tournaments: [tournament])
.tint(.master)
}
}
}
}
#Preview {
EmptyActivityView()
}

@ -1,24 +0,0 @@
//
// WelcomeView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 01/03/2024.
//
import SwiftUI
struct WelcomeView: View {
var body: some View {
Image(.padelClubLogoFondfonce)
.resizable()
.scaledToFit()
.buttonStyle(.borderedProminent)
.tint(.logoBackground)
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(.zero))
}
}
#Preview {
WelcomeView()
}

@ -101,7 +101,7 @@ struct MainView: View {
checkingFiles = false
if let mostRecentDateAvailable = SourceFileManager.shared.mostRecentDateAvailable, mostRecentDateAvailable > SourceFileManager.shared.lastDataSourceDate() ?? .distantPast {
_startImporting()
//_startImporting()
}
}

@ -11,8 +11,8 @@ import SwiftData
struct PadelClubView: View {
@State private var checkingFilesAttempt: Int = 0
@State private var checkingFiles: Bool = false
@State private var importingFiles: Bool = false
@AppStorage("importingFiles") var importingFiles: Bool = false
@EnvironmentObject var dataStore: DataStore
var lastDataSource: String? {
@ -72,18 +72,20 @@ struct PadelClubView: View {
Text(monthData.monthKey)
}
}
//
// if players.isEmpty {
// ContentUnavailableView {
// Label("Aucun joueur importé", systemImage: "person.slash")
// } description: {
// Text("Padel peut importer toutes les données publique de la FFT concernant tous les compétiteurs et compétitrices.")
// } actions: {
// RowButtonView("Démarrer l'importation") {
// _startImporting()
// }
// }
// }
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) {
ContentUnavailableView {
Label("Aucun joueur importé", systemImage: "person.slash")
} description: {
Text("Padel Club peut importer toutes les données publiques de la FFT concernant tous les compétiteurs et compétitrices.")
} actions: {
RowButtonView("Démarrer l'importation") {
_startImporting()
}
}
}
}
.task {
await self._checkSourceFileAvailability()

@ -59,7 +59,11 @@ struct UmpireView: View {
user.licenceId = player.license
let club = dataStore.clubs.first(where: { $0.code == player.clubCode }) ?? Club(name: player.clubName!, code: player.clubCode!)
try? dataStore.clubs.addOrUpdate(instance: club)
user.club = club.id
if user.clubs == nil {
user.clubs = [club.id]
} else {
user.clubs!.insert(club.id, at: 0)
}
dataStore.setUser(user)
}
})
@ -82,22 +86,19 @@ struct UmpireView: View {
}
}
if let clubId = user.club {
if let club = dataStore.clubs.findById(clubId) {
Section {
NavigationLink {
ClubDetailView(club: club, displayContext: .edition)
} label: {
ClubRowView(club: club)
}
} header: {
Text("Mon club")
} footer: {
Button("supprimer", role: .destructive) {
user.club = nil
dataStore.setUser(user)
if let clubs = user.clubs {
Section {
ForEach(clubs) { clubId in
if let club = dataStore.clubs.findById(clubId) {
NavigationLink {
ClubDetailView(club: club, displayContext: .edition)
} label: {
ClubRowView(club: club)
}
}
}
} header: {
Text("Mes clubs")
}
}
}
@ -109,7 +110,7 @@ struct UmpireView: View {
LabeledContent {
Text(dataStore.clubs.count.formatted())
} label: {
Label("Mes clubs favoris", systemImage: "house.and.flag.circle.fill")
Label("Mes clubs", systemImage: "house.and.flag.circle.fill")
}
}
}

Loading…
Cancel
Save