Provides a non-optional user in DataStore + cleanup

multistore
Laurent 2 years ago
parent 6996ed5e09
commit f8a34de73f
  1. 28
      PadelClub.xcodeproj/project.pbxproj
  2. 2
      PadelClub.xcodeproj/xcshareddata/xcschemes/PadelClub Raw.xcscheme
  3. 2
      PadelClub.xcodeproj/xcshareddata/xcschemes/PadelClub.xcscheme
  4. 315
      PadelClub/Assets.xcassets/logoBackground.colorset/Contents.json
  5. 4
      PadelClub/Data/Club.swift
  6. 85
      PadelClub/Data/DataStore.swift
  7. 2
      PadelClub/Data/Federal/FederalTournament.swift
  8. 39
      PadelClub/Data/Migration/ClubV1.swift
  9. 34
      PadelClub/Data/Migration/TournamentV1.swift
  10. 36
      PadelClub/Data/Migration/TournamentV2.swift
  11. 6
      PadelClub/Data/Tournament.swift
  12. 4
      PadelClub/Data/User.swift
  13. 2
      PadelClub/Views/Calling/CallMessageCustomizationView.swift
  14. 6
      PadelClub/Views/Club/ClubDetailView.swift
  15. 6
      PadelClub/Views/Club/ClubSearchView.swift
  16. 6
      PadelClub/Views/Club/ClubsView.swift
  17. 6
      PadelClub/Views/Club/CreateClubView.swift
  18. 2
      PadelClub/Views/Event/EventCreationView.swift
  19. 2
      PadelClub/Views/Match/MatchDetailView.swift
  20. 12
      PadelClub/Views/Navigation/Agenda/ActivityView.swift
  21. 4
      PadelClub/Views/Navigation/Agenda/EventListView.swift
  22. 98
      PadelClub/Views/Navigation/Umpire/UmpireView.swift
  23. 2
      PadelClub/Views/Shared/TournamentFilterView.swift
  24. 4
      PadelClub/Views/Subscription/Guard.swift
  25. 2
      PadelClub/Views/Subscription/StoreManager.swift
  26. 2
      PadelClub/Views/Tournament/Screen/Components/TournamentClubSettingsView.swift
  27. 2
      PadelClub/Views/User/LoginView.swift
  28. 6
      PadelClub/Views/User/MainUserView.swift
  29. 3
      PadelClub/Views/User/UserCreationView.swift

@ -27,9 +27,6 @@
C4A47D5A2B6D383C00ADC637 /* Tournament.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D592B6D383C00ADC637 /* Tournament.swift */; };
C4A47D5E2B6D38EC00ADC637 /* DataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D5D2B6D38EC00ADC637 /* DataStore.swift */; };
C4A47D632B6D3D6500ADC637 /* Club.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D622B6D3D6500ADC637 /* Club.swift */; };
C4A47D772B73789100ADC637 /* TournamentV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D762B73789100ADC637 /* TournamentV1.swift */; };
C4A47D7B2B73C0F900ADC637 /* TournamentV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D7A2B73C0F900ADC637 /* TournamentV2.swift */; };
C4A47D7D2B73CDC300ADC637 /* ClubV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D7C2B73CDC300ADC637 /* ClubV1.swift */; };
C4A47D872B7BA36D00ADC637 /* UserCreationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D862B7BA36D00ADC637 /* UserCreationView.swift */; };
C4A47D8A2B7BBB6500ADC637 /* SubscriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D892B7BBB6500ADC637 /* SubscriptionView.swift */; };
C4A47D902B7BBBEC00ADC637 /* StoreManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D8D2B7BBBEC00ADC637 /* StoreManager.swift */; };
@ -323,9 +320,6 @@
C4A47D592B6D383C00ADC637 /* Tournament.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tournament.swift; sourceTree = "<group>"; };
C4A47D5D2B6D38EC00ADC637 /* DataStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStore.swift; sourceTree = "<group>"; };
C4A47D622B6D3D6500ADC637 /* Club.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Club.swift; sourceTree = "<group>"; };
C4A47D762B73789100ADC637 /* TournamentV1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentV1.swift; sourceTree = "<group>"; };
C4A47D7A2B73C0F900ADC637 /* TournamentV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentV2.swift; sourceTree = "<group>"; };
C4A47D7C2B73CDC300ADC637 /* ClubV1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClubV1.swift; sourceTree = "<group>"; };
C4A47D862B7BA36D00ADC637 /* UserCreationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserCreationView.swift; sourceTree = "<group>"; };
C4A47D892B7BBB6500ADC637 /* SubscriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionView.swift; sourceTree = "<group>"; };
C4A47D8D2B7BBBEC00ADC637 /* StoreManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoreManager.swift; sourceTree = "<group>"; };
@ -670,7 +664,6 @@
C4A47D5F2B6D3B2D00ADC637 /* Data */ = {
isa = PBXGroup;
children = (
C4A47D752B73787D00ADC637 /* Migration */,
C4A47D5D2B6D38EC00ADC637 /* DataStore.swift */,
C4A47DAC2B85FCCD00ADC637 /* User.swift */,
C4A47D592B6D383C00ADC637 /* Tournament.swift */,
@ -718,16 +711,6 @@
path = Views;
sourceTree = "<group>";
};
C4A47D752B73787D00ADC637 /* Migration */ = {
isa = PBXGroup;
children = (
C4A47D762B73789100ADC637 /* TournamentV1.swift */,
C4A47D7A2B73C0F900ADC637 /* TournamentV2.swift */,
C4A47D7C2B73CDC300ADC637 /* ClubV1.swift */,
);
path = Migration;
sourceTree = "<group>";
};
C4A47D852B7BA33F00ADC637 /* User */ = {
isa = PBXGroup;
children = (
@ -1320,7 +1303,7 @@
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1520;
LastUpgradeCheck = 1520;
LastUpgradeCheck = 1530;
TargetAttributes = {
C425D3FC2B6D249D002A7B48 = {
CreatedOnToolsVersion = 15.2;
@ -1510,7 +1493,6 @@
FF1162872BD004AD000C4809 /* EditingTeamView.swift in Sources */,
FF6EC9062B947A1000EA7F5A /* NetworkManagerError.swift in Sources */,
C4A47D5A2B6D383C00ADC637 /* Tournament.swift in Sources */,
C4A47D7B2B73C0F900ADC637 /* TournamentV2.swift in Sources */,
FF3795662B9399AA004EA093 /* Persistence.swift in Sources */,
FF1DF49B2BD8D23900822FA0 /* BarButtonView.swift in Sources */,
FFF964502BC25E3700EEF017 /* PlanningView.swift in Sources */,
@ -1523,7 +1505,6 @@
FF82CFC52B911F5B00B0CAF2 /* OrganizedTournamentView.swift in Sources */,
FFF964572BC26B3400EEF017 /* RoundScheduleEditorView.swift in Sources */,
FF59FFB32B90EFAC0061EFF9 /* EventListView.swift in Sources */,
C4A47D7D2B73CDC300ADC637 /* ClubV1.swift in Sources */,
FF8F263D2BAD627A00650388 /* TournamentConfiguratorView.swift in Sources */,
FFC1E10C2BAC7FB0008D6F59 /* ClubImportView.swift in Sources */,
FF3B60A32BC49BBC008C2E66 /* MatchScheduler.swift in Sources */,
@ -1593,7 +1574,6 @@
FF0E0B6D2BC254C6005F00A9 /* TournamentScheduleView.swift in Sources */,
FF025AF12BD1AEBD00A86CF8 /* MatchFormatStorageView.swift in Sources */,
FF3F74F62B919E45004CFE0E /* UmpireView.swift in Sources */,
C4A47D772B73789100ADC637 /* TournamentV1.swift in Sources */,
C4A47DAD2B85FCCD00ADC637 /* User.swift in Sources */,
FF967D012BAEF0B400A9A3BD /* MatchSummaryView.swift in Sources */,
FF8F26452BAE0A3400650388 /* TournamentDurationManagerView.swift in Sources */,
@ -1806,6 +1786,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;
ENABLE_MODULE_VERIFIER = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PadelClub/Info.plist;
@ -1823,6 +1804,8 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.1;
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_SWIFT_FLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
@ -1841,6 +1824,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;
ENABLE_MODULE_VERIFIER = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PadelClub/Info.plist;
@ -1858,6 +1842,8 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.1;
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_SWIFT_FLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1520"
LastUpgradeVersion = "1530"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1520"
LastUpgradeVersion = "1530"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"

@ -12,24 +12,6 @@
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
@ -47,307 +29,10 @@
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
},
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
},
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal"
},
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "fr"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "fr"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "fr"
},
{
"appearances" : [
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "fr"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
},
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "fr"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
},
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "fr"
},
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "en"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "en"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "en"
},
{
"appearances" : [
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "en"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
},
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "en"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
},
{
"appearance" : "contrast",
"value" : "high"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "58",
"green" : "35",
"red" : "25"
}
},
"idiom" : "universal",
"locale" : "en"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"localizable" : true
}
}

@ -131,7 +131,7 @@ extension Club {
}
func isFavorite() -> Bool {
DataStore.shared.user?.clubs?.contains(where: { $0 == id }) == true
DataStore.shared.user.clubs?.contains(where: { $0 == id }) == true
}
static func findOrCreate(name: String, code: String?, city: String? = nil, zipCode: String? = nil) -> Club {
@ -146,7 +146,7 @@ extension Club {
if clubs.isEmpty == false {
return clubs.first!
} else {
return Club(creator: DataStore.shared.user?.id, name: name, code: code)
return Club(creator: DataStore.shared.user.id, name: name, code: code)
}
}
}

@ -14,6 +14,21 @@ class DataStore: ObservableObject {
// fileprivate var _store: Store
static let shared = DataStore()
@Published var user: User = User.placeHolder() {
didSet {
Store.main.collectionsCanSynchronize = (user.username.count > 0)
do {
if self.user.id != self.userStorage.item()?.id {
try self.userStorage.setItemNoSync(self.user)
if Store.main.collectionsCanSynchronize {
Store.main.loadCollectionFromServer()
}
}
} catch {
Logger.error(error)
}
}
}
fileprivate(set) var tournaments: StoredCollection<Tournament>
fileprivate(set) var clubs: StoredCollection<Club>
@ -28,7 +43,7 @@ class DataStore: ObservableObject {
fileprivate(set) var monthData: StoredCollection<MonthData>
fileprivate(set) var dateIntervals: StoredCollection<DateInterval>
fileprivate(set) var userStorage: StoredObject<User>
fileprivate(set) var userStorage: StoredSingleton<User>
// fileprivate var _userStorage: OptionalStorage<User> = OptionalStorage<User>(fileName: "user.json")
fileprivate var _appSettingsStorage: MicroStorage<AppSettings> = MicroStorage()
@ -52,22 +67,6 @@ class DataStore: ObservableObject {
}
}
var user: User? {
return self.userStorage.item()
// return self._userStorage.item
}
func setUser(_ user: User) {
do {
try self.userStorage.setItem(user)
Store.main.collectionsCanSynchronize = true
self._loadCollections()
} catch {
Logger.error(error)
}
// self._userStorage.item = user
}
init() {
let store = Store.main
store.synchronizationApiURL = "http://127.0.0.1:8000/api/"
@ -92,26 +91,58 @@ class DataStore: ObservableObject {
self.monthData = store.registerCollection(synchronized: false, indexed: indexed)
self.dateIntervals = store.registerCollection(synchronized: synchronized, indexed: indexed)
self.userStorage = store.registerObject(synchronized: false)
self.userStorage = store.registerObject(synchronized: synchronized)
NotificationCenter.default.addObserver(self, selector: #selector(collectionDidLoad), name: NSNotification.Name.CollectionDidLoad, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(collectionDidUpdate), name: NSNotification.Name.CollectionDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(collectionWasUpdated), name: NSNotification.Name.CollectionDidLoad, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(collectionWasUpdated), name: NSNotification.Name.CollectionDidChange, object: nil)
}
@objc func collectionWasUpdated(notification: Notification) {
@objc func collectionDidLoad(notification: Notification) {
self.objectWillChange.send()
if let object = notification.object as? StoredObject<User> {
Logger.log("StoredObject<User> loaded with user = \(object.item())")
Store.main.collectionsCanSynchronize = object.item() != nil
if let object: StoredSingleton<User> = notification.object as? StoredSingleton<User> {
Logger.log("StoredObject<User> loaded with user = \(String(describing: object.item()))")
if let user = object.item() {
self.user = user
}
}
}
@objc func collectionDidUpdate(notification: Notification) {
self.objectWillChange.send()
}
// var user: User {
// if let user = self.userStorage.item() {
// return user
// } else {
// let user = User(username: "", email: "", firstName: "", lastName: "", phone: nil, country: "")
// do {
// try self.userStorage.setItem(user)
// } catch {
// Logger.error(error)
// }
// return user
// }
// }
// func setUser(_ user: User) {
// do {
// try self.userStorage.setItem(user)
// Store.main.collectionsCanSynchronize = user.username.count > 0
// self._loadCollections()
// } catch {
// Logger.error(error)
// }
//// self._userStorage.item = user
// }
var globalRights: UserRight {
if let _ = Guard.main.currentPlan {
return .creation
}
if let user = self.user, user.clubs != nil {
if self.user.clubs != nil {
if user.umpireCode != nil {
return .creation
} else {
@ -132,7 +163,7 @@ class DataStore: ObservableObject {
}
fileprivate func _loadCollections() {
Store.main.loadCollections()
Store.main.loadCollectionFromServer()
}
}

@ -29,7 +29,7 @@ struct FederalTournament: Identifiable, Codable {
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: DataStore.shared.user.id, club: club?.id, name: libelle, tenupId: id.string)
do {
try DataStore.shared.events.addOrUpdate(instance: event!)
} catch {

@ -1,39 +0,0 @@
//
// ClubV1.swift
// PadelClub
//
// Created by Laurent Morvillier on 07/02/2024.
//
import Foundation
import LeStorage
class ClubV1 : ModelObject, Storable, MigrationSource {
static func resourceName() -> String { return "clubs" }
var id: String = Store.randomId()
var name: String
init(name: String) {
self.name = name
}
var tournaments: [Tournament] {
return []
}
override func deleteDependencies() throws {
try Store.main.deleteDependencies(items: self.tournaments)
}
// MARK: - MigrationSource
typealias Destination = Club
func migrate() -> Club {
return Club(name: self.name, acronym: "test", address: "3 impasse des chevreuils")
// return Club(name: self.name, address: "3 impasse des chevreuils")
}
}

@ -1,34 +0,0 @@
//
// Tournament_v1.swift
// PadelClub
//
// Created by Laurent Morvillier on 07/02/2024.
//
import Foundation
import LeStorage
class TournamentV1 : ModelObject, Storable, MigrationSource {
static func resourceName() -> String { "tournaments" }
var id: String = Store.randomId()
var name: String
var club_id: String
init(name: String, club_id: String) {
self.name = name
self.club_id = club_id
}
var club: Club? { return self.findById(self.club_id) }
// MARK: - MigrationSource
typealias Destination = TournamentV2
func migrate() -> TournamentV2 {
return TournamentV2(name: self.name, club_id: self.club_id, category: 0)
}
}

@ -1,36 +0,0 @@
//
// TournamentV2.swift
// PadelClub
//
// Created by Laurent Morvillier on 07/02/2024.
//
import Foundation
import LeStorage
class TournamentV2 : ModelObject, Storable, MigrationSource {
static func resourceName() -> String { "tournaments" }
var id: String = Store.randomId()
var name: String
var club_id: String
var category: Int
init(name: String, club_id: String, category: Int) {
self.name = name
self.club_id = club_id
self.category = category
}
var club: Club? { return self.findById(self.club_id) }
// MARK: - MigrationSource
typealias Destination = Tournament
func migrate() -> Tournament {
return Tournament.mock()
}
}

@ -950,11 +950,7 @@ class Tournament : ModelObject, Storable {
}
func umpireMail() -> [String]? {
if let email = DataStore.shared.user?.email {
return [email]
} else {
return nil
}
return [DataStore.shared.user.email]
}
func earnings() -> Double {

@ -91,6 +91,10 @@ class User: UserBase, Storable {
case _country = "country"
}
static func placeHolder() -> User {
return User(username: "", email: "", firstName: "", lastName: "", phone: nil, country: nil)
}
}
class UserCreationForm: User, UserPasswordBase {

@ -168,7 +168,7 @@ struct CallMessageCustomizationView: View {
@ViewBuilder
private func _clubNameView() -> some View {
if let eventClub = tournament.eventObject()?.clubObject() {
let hasBeenCreated: Bool = eventClub.hasBeenCreated(by: dataStore.user?.id)
let hasBeenCreated: Bool = eventClub.hasBeenCreated(by: dataStore.user.id)
Section {
TextField("Nom du club", text: $customClubName)
.autocorrectionDisabled()

@ -153,7 +153,7 @@ struct ClubDetailView: View {
RowButtonView("Supprimer ce club", role: .destructive) {
do {
try dataStore.clubs.deleteById(club.id)
dataStore.user?.clubs?.removeAll(where: { $0 == club.id })
dataStore.user.clubs?.removeAll(where: { $0 == club.id })
try dataStore.userStorage.update()
} catch {
Logger.error(error)
@ -176,9 +176,9 @@ struct ClubDetailView: View {
BarButtonView("Favori", icon: isFavorite ? "star.fill" : "star") {
do {
if isFavorite {
dataStore.user?.clubs?.removeAll(where: { $0 == club.id })
dataStore.user.clubs?.removeAll(where: { $0 == club.id })
} else {
dataStore.user?.clubs?.append(club.id)
dataStore.user.clubs?.append(club.id)
}
try dataStore.userStorage.update()
} catch {

@ -84,7 +84,7 @@ struct ClubSearchView: View {
Button {
let clubToEdit = club ?? Club.findOrCreate(name: clubMark.nom, code: clubMark.clubID)
if clubToEdit.creator == dataStore.user?.id && dataStore.user?.id != nil {
if clubToEdit.creator == dataStore.user.id {
if clubToEdit.name.isEmpty {
clubToEdit.name = clubMark.nom
clubToEdit.acronym = clubToEdit.automaticShortName()
@ -98,8 +98,8 @@ struct ClubSearchView: View {
if displayContext == .addition {
do {
try dataStore.clubs.addOrUpdate(instance: clubToEdit)
if dataStore.user?.clubs?.contains(where: { $0 == clubToEdit.id }) == false {
dataStore.user?.clubs?.append(clubToEdit.id)
if dataStore.user.clubs?.contains(where: { $0 == clubToEdit.id }) == false {
dataStore.user.clubs?.append(clubToEdit.id)
try dataStore.userStorage.update()
}
} catch {

@ -26,7 +26,7 @@ struct ClubsView: View {
// .tipStyle(tint: nil)
// }
// }
let clubs : [Club] = (dataStore.user?.clubsObjects(includeCreated: true)) ?? []
let clubs : [Club] = dataStore.user.clubsObjects(includeCreated: true)
ForEach(clubs) { club in
if let selection {
Button {
@ -40,7 +40,7 @@ struct ClubsView: View {
.buttonStyle(.plain)
} else {
NavigationLink {
ClubDetailView(club: club, displayContext: club.hasBeenCreated(by: dataStore.user?.id) ? .edition : .lockedForEditing)
ClubDetailView(club: club, displayContext: club.hasBeenCreated(by: dataStore.user.id) ? .edition : .lockedForEditing)
} label: {
ClubRowView(club: club)
}
@ -55,7 +55,7 @@ struct ClubsView: View {
}
}
.overlay {
if dataStore.user?.hasFavoriteClubsAndCreatedClubs() == false {
if dataStore.user.hasFavoriteClubsAndCreatedClubs() == false {
ContentUnavailableView {
Label("Aucun club", systemImage: "house.and.flag.fill")
} description: {

@ -33,7 +33,7 @@ struct CreateClubView: View {
let existingOrCreatedClub = 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 existingOrCreatedClub.hasBeenCreated(by: dataStore.user?.id) {
if existingOrCreatedClub.hasBeenCreated(by: dataStore.user.id) {
existingOrCreatedClub.update(fromClub: club)
do {
try dataStore.clubs.addOrUpdate(instance: existingOrCreatedClub)
@ -44,8 +44,8 @@ struct CreateClubView: View {
//save into user
do {
if dataStore.user?.clubs?.contains(where: { $0 == existingOrCreatedClub.id }) == false {
dataStore.user?.clubs?.append(existingOrCreatedClub.id)
if dataStore.user.clubs?.contains(where: { $0 == existingOrCreatedClub.id }) == false {
dataStore.user.clubs?.append(existingOrCreatedClub.id)
try dataStore.userStorage.update()
}
} catch {

@ -90,7 +90,7 @@ struct EventCreationView: View {
Section {
RowButtonView("Valider") {
let event = Event(creator: dataStore.user?.id, name: eventName)
let event = Event(creator: dataStore.user.id, name: eventName)
event.club = selectedClub?.id
tournaments.forEach { tournament in
tournament.event = event.id

@ -129,7 +129,7 @@ struct MatchDetailView: View {
showDetails = true
}
Spacer()
MenuWarningView(teams: match.teams(), message: match.matchWarningMessage(), umpireMail: dataStore.user?.email, subject: match.matchWarningSubject(), contactType: $contactType)
MenuWarningView(teams: match.teams(), message: match.matchWarningMessage(), umpireMail: dataStore.user.email, subject: match.matchWarningSubject(), contactType: $contactType)
.buttonStyle(.borderless)
}
}

@ -122,14 +122,14 @@ struct ActivityView: View {
// }
.task {
if navigation.agendaDestination == .tenup
&& dataStore.user?.hasClubs() == true
&& dataStore.user.hasClubs() == true
&& federalDataViewModel.federalTournaments.isEmpty {
_gatherFederalTournaments()
}
}
.onChange(of: navigation.agendaDestination) {
if navigation.agendaDestination == .tenup
&& dataStore.user?.hasClubs() == true
&& dataStore.user.hasClubs() == true
&& federalDataViewModel.federalTournaments.isEmpty {
_gatherFederalTournaments()
}
@ -203,7 +203,7 @@ struct ActivityView: View {
.tint(.master)
}
.sheet(isPresented: $presentClubSearchView, onDismiss: {
if dataStore.user?.hasClubs() == true {
if dataStore.user.hasClubs() == true {
navigation.agendaDestination = .tenup
}
}) {
@ -218,7 +218,7 @@ struct ActivityView: View {
isGatheringFederalTournaments = true
Task {
do {
let clubs : [Club] = (dataStore.user?.clubsObjects()) ?? []
let clubs : [Club] = dataStore.user.clubsObjects()
try await federalDataViewModel.gatherTournaments(clubs: clubs.filter { $0.code != nil }, startDate: .now.startOfMonth)
} catch {
self.error = error
@ -257,7 +257,7 @@ struct ActivityView: View {
RowButtonView("Créer un nouvel événement") {
newTournament = Tournament.newEmptyInstance()
}
if dataStore.user?.hasClubs() == false {
if dataStore.user.hasClubs() == false {
RowButtonView("Chercher l'un de vos clubs") {
presentClubSearchView = true
}
@ -278,7 +278,7 @@ struct ActivityView: View {
}
private func _tenupEmptyView() -> some View {
if dataStore.user?.hasClubs() == false {
if dataStore.user.hasClubs() == false {
ContentUnavailableView {
Label("Aucun tournoi", systemImage: "shield.slash")
} description: {

@ -51,7 +51,7 @@ struct EventListView: View {
.headerProminence(.increased)
.task {
if navigation.agendaDestination == .tenup
&& dataStore.user?.hasClubs() == true
&& dataStore.user.hasClubs() == true
&& _tournaments.isEmpty {
_gatherFederalTournaments(startDate: section)
}
@ -64,7 +64,7 @@ struct EventListView: View {
// isGatheringFederalTournaments = true
Task {
do {
let clubs : [Club] = (dataStore.user?.clubsObjects()) ?? []
let clubs : [Club] = dataStore.user.clubsObjects()
try await federalDataViewModel.gatherTournaments(clubs: clubs.filter { $0.code != nil }, startDate: startDate, endDate: startDate.endOfMonth)
} catch {
Logger.error(error)

@ -46,52 +46,51 @@ struct UmpireView: View {
Label("Mon compte", systemImage: "person.circle.fill")
}
if let user = dataStore.user {
let currentPlayerData = user.currentPlayerData()
Section {
if let currentPlayerData {
NavigationLink {
} label: {
ImportedPlayerView(player: currentPlayerData)
}
} else {
NavigationLink {
SelectablePlayerListView(allowSelection: 1, searchField: user.firstName + " " + user.lastName, playerSelectionAction: { players in
if let player = players.first {
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)
try dataStore.userStorage.update()
} catch {
Logger.error(error)
}
let user = dataStore.user
let currentPlayerData = user.currentPlayerData()
Section {
if let currentPlayerData {
NavigationLink {
} label: {
ImportedPlayerView(player: currentPlayerData)
}
} else {
NavigationLink {
SelectablePlayerListView(allowSelection: 1, searchField: user.firstName + " " + user.lastName, playerSelectionAction: { players in
if let player = players.first {
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)
try dataStore.userStorage.update()
} catch {
Logger.error(error)
}
}
})
.id(UUID())
} label: {
Label("Ma fiche joueur", systemImage: "person.bust.circle.fill")
}
}
} header: {
if currentPlayerData != nil {
Text("Ma fiche joueur")
}
} footer: {
if user.licenceId == nil {
Text("Si vous avez participé à un tournoi dans les 12 derniers mois, Padel Club peut vous retrouver.")
} else {
Button("supprimer", role: .destructive) {
user.licenceId = nil
do {
try dataStore.userStorage.update()
} catch {
Logger.error(error)
}
})
.id(UUID())
} label: {
Label("Ma fiche joueur", systemImage: "person.bust.circle.fill")
}
}
} header: {
if currentPlayerData != nil {
Text("Ma fiche joueur")
}
} footer: {
if user.licenceId == nil {
Text("Si vous avez participé à un tournoi dans les 12 derniers mois, Padel Club peut vous retrouver.")
} else {
Button("supprimer", role: .destructive) {
user.licenceId = nil
do {
try dataStore.userStorage.update()
} catch {
Logger.error(error)
}
}
}
@ -102,7 +101,7 @@ struct UmpireView: View {
ClubsView()
} label: {
LabeledContent {
Text((dataStore.user?.clubs ?? []).count.formatted())
Text((dataStore.user.clubs ?? []).count.formatted())
} label: {
Label("Mes clubs", systemImage: "house.and.flag.circle.fill")
}
@ -161,6 +160,17 @@ struct UmpireView: View {
// }
}
.navigationTitle("Juge-Arbitre")
.toolbar {
#if DEBUG
ToolbarItem(placement: .topBarTrailing) {
if Store.main.collectionsCanSynchronize {
Image(systemName: "checkmark.icloud")
} else {
Image(systemName: "icloud.slash")
}
}
#endif
}
}
}
}

@ -27,7 +27,7 @@ struct TournamentFilterView: View {
var body: some View {
NavigationView {
Form {
let clubs : [Club] = (dataStore.user?.clubsObjects()) ?? []
let clubs : [Club] = dataStore.user.clubsObjects()
if clubs.filter({ $0.code != nil }).isEmpty == false {
Section {
ForEach(clubs.filter({ $0.code != nil })) { club in

@ -135,7 +135,7 @@ import LeStorage
func userFilteredPurchases() -> [StoreKit.Transaction] {
let userTransactions = self.purchasedTransactions.filter { Store.main.currentUserUUID() == $0.appAccountToken }
let userTransactions = self.purchasedTransactions.filter { Store.main.mandatoryUserUUID() == $0.appAccountToken }
return userTransactions.filter { transaction in
if let expirationDate = transaction.expirationDate {
@ -219,7 +219,7 @@ struct PurchaseRow: Identifiable {
fileprivate extension StoreKit.Transaction {
func purchase() -> Purchase {
let userId = Store.main.currentUserUUID().uuidString
let userId = Store.main.mandatoryUserUUID().uuidString
return Purchase(user: userId,
identifier: self.originalID,
purchaseDate: self.purchaseDate,

@ -90,7 +90,7 @@ class StoreManager {
Logger.log("Store purchase started...")
var options: Set<Product.PurchaseOption> = []
let uuid: UUID = Store.main.currentUserUUID()
let uuid: UUID = Store.main.mandatoryUserUUID()
let tokenOption = Product.PurchaseOption.appAccountToken(uuid)
options.insert(tokenOption)

@ -21,7 +21,7 @@ struct TournamentClubSettingsView: View {
Section {
if let selectedClub {
NavigationLink {
ClubDetailView(club: selectedClub, displayContext: selectedClub.hasBeenCreated(by: dataStore.user?.id) ? .edition : .lockedForEditing)
ClubDetailView(club: selectedClub, displayContext: selectedClub.hasBeenCreated(by: dataStore.user.id) ? .edition : .lockedForEditing)
} label: {
ClubRowView(club: selectedClub)
}

@ -88,7 +88,7 @@ struct LoginView: View {
let user: User = try await service.login(
username: self.username,
password: self.password)
self.dataStore.setUser(user)
self.dataStore.user = user
self.handler(user)
} catch {
switch error {

@ -16,8 +16,8 @@ struct MainUserView: View {
var body: some View {
Group {
if self.isConnected, let user = dataStore.user {
AccountView(user: user) {
if self.isConnected {
AccountView(user: dataStore.user) {
self._checkConnection()
}
} else {
@ -31,7 +31,7 @@ struct MainUserView: View {
}
fileprivate func _checkConnection() {
self.isConnected = dataStore.user != nil && Store.main.hasToken()
self.isConnected = dataStore.user.username.count > 0 && Store.main.hasToken()
}
}

@ -122,7 +122,8 @@ struct UserCreationFormView: View {
country: self.countries[self.selectedCountryIndex])
let service = try Store.main.service()
let _: User = try await service.createAccount(user: userCreationForm)
let user: User = try await service.createAccount(user: userCreationForm)
DataStore.shared.user = user
self.isLoading = false
self.showLoginScreen = true

Loading…
Cancel
Save