You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
6.5 KiB
226 lines
6.5 KiB
//
|
|
// Club.swift
|
|
// PadelClub
|
|
//
|
|
// Created by Laurent Morvillier on 02/02/2024.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftUI
|
|
import LeStorage
|
|
|
|
@Observable
|
|
class Club : ModelObject, Storable, Hashable {
|
|
|
|
static func resourceName() -> String { return "clubs" }
|
|
static func tokenExemptedMethods() -> [HTTPMethod] { return [.get] }
|
|
|
|
static func == (lhs: Club, rhs: Club) -> Bool {
|
|
lhs.id == rhs.id
|
|
}
|
|
|
|
func hash(into hasher: inout Hasher) {
|
|
return hasher.combine(id)
|
|
}
|
|
|
|
var id: String = Store.randomId()
|
|
var creator: String?
|
|
var name: String
|
|
var acronym: String
|
|
var phone: String?
|
|
var code: String?
|
|
//var federalClubData: Data?
|
|
var address: String?
|
|
var city: String?
|
|
var zipCode: String?
|
|
var latitude: Double?
|
|
var longitude: Double?
|
|
var courtCount: Int = 2
|
|
// var alphabeticalName: Bool = false
|
|
|
|
internal init(creator: String? = nil, name: String, acronym: String? = nil, phone: String? = nil, code: String? = nil, address: String? = nil, city: String? = nil, zipCode: String? = nil, latitude: Double? = nil, longitude: Double? = nil, courtCount: Int = 2) {
|
|
self.creator = creator
|
|
self.name = name
|
|
self.acronym = acronym ?? name.acronym()
|
|
self.phone = phone
|
|
self.code = code
|
|
self.address = address
|
|
self.city = city
|
|
self.zipCode = zipCode
|
|
self.latitude = latitude
|
|
self.longitude = longitude
|
|
self.courtCount = courtCount
|
|
}
|
|
|
|
func clubTitle(_ displayStyle: DisplayStyle = .wide) -> String {
|
|
switch displayStyle {
|
|
case .wide:
|
|
return name
|
|
case .short:
|
|
return acronym
|
|
}
|
|
}
|
|
|
|
func shareURL() -> URL? {
|
|
return URLs.main.url.appending(path: "?club=\(id)")
|
|
}
|
|
|
|
var customizedCourts: [Court] {
|
|
Store.main.filter { $0.club == self.id }.sorted(by: \.index)
|
|
}
|
|
|
|
override func deleteDependencies() throws {
|
|
try Store.main.deleteDependencies(items: self.customizedCourts)
|
|
}
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case _id = "id"
|
|
case _creator = "creator"
|
|
case _name = "name"
|
|
case _acronym = "acronym"
|
|
case _phone = "phone"
|
|
case _code = "code"
|
|
case _address = "address"
|
|
case _city = "city"
|
|
case _zipCode = "zipCode"
|
|
case _latitude = "latitude"
|
|
case _longitude = "longitude"
|
|
case _courtCount = "courtCount"
|
|
// case _alphabeticalName = "alphabeticalName"
|
|
}
|
|
|
|
func encode(to encoder: Encoder) throws {
|
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
|
|
try container.encode(id, forKey: ._id)
|
|
|
|
if let creator = creator {
|
|
try container.encode(creator, forKey: ._creator)
|
|
} else {
|
|
try container.encodeNil(forKey: ._creator)
|
|
}
|
|
|
|
try container.encode(name, forKey: ._name)
|
|
try container.encode(acronym, forKey: ._acronym)
|
|
|
|
if let phone = phone {
|
|
try container.encode(phone, forKey: ._phone)
|
|
} else {
|
|
try container.encodeNil(forKey: ._phone)
|
|
}
|
|
|
|
if let code = code {
|
|
try container.encode(code, forKey: ._code)
|
|
} else {
|
|
try container.encodeNil(forKey: ._code)
|
|
}
|
|
|
|
if let address = address {
|
|
try container.encode(address, forKey: ._address)
|
|
} else {
|
|
try container.encodeNil(forKey: ._address)
|
|
}
|
|
|
|
if let city = city {
|
|
try container.encode(city, forKey: ._city)
|
|
} else {
|
|
try container.encodeNil(forKey: ._city)
|
|
}
|
|
|
|
if let zipCode = zipCode {
|
|
try container.encode(zipCode, forKey: ._zipCode)
|
|
} else {
|
|
try container.encodeNil(forKey: ._zipCode)
|
|
}
|
|
|
|
if let latitude = latitude {
|
|
try container.encode(latitude, forKey: ._latitude)
|
|
} else {
|
|
try container.encodeNil(forKey: ._latitude)
|
|
}
|
|
|
|
if let longitude = longitude {
|
|
try container.encode(longitude, forKey: ._longitude)
|
|
} else {
|
|
try container.encodeNil(forKey: ._longitude)
|
|
}
|
|
|
|
try container.encode(courtCount, forKey: ._courtCount)
|
|
// try container.encode(alphabeticalName, forKey: ._alphabeticalName)
|
|
}
|
|
|
|
}
|
|
|
|
extension Club {
|
|
var isValid: Bool {
|
|
name.isEmpty == false && acronym.isEmpty == false
|
|
}
|
|
|
|
func automaticShortName() -> String {
|
|
name.acronym()
|
|
}
|
|
|
|
enum AcronymMode: String, CaseIterable {
|
|
case automatic = "Automatique"
|
|
case custom = "Personalisée"
|
|
}
|
|
|
|
func shortNameMode() -> AcronymMode {
|
|
(acronym.isEmpty || acronym == automaticShortName()) ? .automatic : .custom
|
|
}
|
|
|
|
func hasTenupId() -> Bool {
|
|
code != nil
|
|
}
|
|
|
|
func federalLink() -> URL? {
|
|
guard let code else { return nil }
|
|
return URL(string: "https://tenup.fft.fr/club/\(code)")
|
|
}
|
|
|
|
func courtName(atIndex courtIndex: Int) -> String {
|
|
courtNameIfAvailable(atIndex: courtIndex) ?? Court.courtIndexedTitle(atIndex: courtIndex)
|
|
}
|
|
|
|
func courtNameIfAvailable(atIndex courtIndex: Int) -> String? {
|
|
customizedCourts.first(where: { $0.index == courtIndex })?.name
|
|
}
|
|
|
|
func update(fromClub club: Club) {
|
|
self.acronym = club.acronym
|
|
self.name = club.name
|
|
self.phone = club.phone
|
|
self.code = club.code
|
|
self.address = club.address
|
|
self.city = club.city
|
|
self.zipCode = club.zipCode
|
|
self.latitude = club.latitude
|
|
self.longitude = club.longitude
|
|
}
|
|
|
|
func hasBeenCreated(by creatorId: String?) -> Bool {
|
|
guard let creatorId else { return false }
|
|
guard let creator else { return false }
|
|
return creatorId == creator
|
|
}
|
|
|
|
func isFavorite() -> Bool {
|
|
return DataStore.shared.user.clubs.contains(where: { $0 == id })
|
|
}
|
|
|
|
static func findOrCreate(name: String, code: String?, city: String? = nil, zipCode: String? = nil) -> Club {
|
|
|
|
/*
|
|
|
|
identify a club : code, name, ??
|
|
|
|
*/
|
|
let clubs: [Club] = Store.main.filter(isIncluded: { (code == nil && $0.name == name && $0.city == city && $0.zipCode == zipCode) || $0.code == code })
|
|
|
|
if clubs.isEmpty == false {
|
|
return clubs.first!
|
|
} else {
|
|
return Club(creator: DataStore.shared.user.id, name: name, code: code)
|
|
}
|
|
}
|
|
}
|
|
|