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.
341 lines
13 KiB
341 lines
13 KiB
//
|
|
// CallMessageCustomizationView.swift
|
|
// Padel Tournament
|
|
//
|
|
// Created by Razmig Sarkissian on 02/11/2023.
|
|
//
|
|
|
|
import SwiftUI
|
|
import LeStorage
|
|
import PadelClubData
|
|
|
|
struct CallMessageCustomizationView: View {
|
|
@EnvironmentObject var dataStore: DataStore
|
|
var tournament: Tournament
|
|
enum Field {
|
|
case signature
|
|
case body
|
|
case paymentMethods
|
|
case clubName
|
|
}
|
|
|
|
@FocusState var focusedField: CallMessageCustomizationView.Field?
|
|
@State private var customClubName: String = ""
|
|
@State private var customCallMessageBody: String = ""
|
|
@State private var customCallMessageSignature: String = ""
|
|
@State private var summonsAvailablePaymentMethods: String = ""
|
|
|
|
var columns: [GridItem] = Array(repeating: .init(.flexible()), count: 3)
|
|
|
|
init(tournament: Tournament) {
|
|
self.tournament = tournament
|
|
_customCallMessageBody = State(wrappedValue: DataStore.shared.user.summonsMessageBody ?? (DataStore.shared.user.summonsUseFullCustomMessage ? "" : ContactType.defaultCustomMessage))
|
|
_customCallMessageSignature = State(wrappedValue: DataStore.shared.user.getSummonsMessageSignature() ?? DataStore.shared.user.defaultSignature(tournament))
|
|
_customClubName = State(wrappedValue: tournament.clubName ?? "Lieu du tournoi")
|
|
_summonsAvailablePaymentMethods = State(wrappedValue: DataStore.shared.user.summonsAvailablePaymentMethods ?? ContactType.defaultAvailablePaymentMethods)
|
|
}
|
|
|
|
var clubName: String {
|
|
customClubName
|
|
}
|
|
|
|
var entryFeeMessage: String? {
|
|
dataStore.user.summonsDisplayEntryFee ? tournament.entryFeeMessage : nil
|
|
}
|
|
|
|
var computedMessage: String {
|
|
var linkMessage: String? {
|
|
if tournament.isPrivate == false, let shareLink = tournament.shareURL(.matches)?.absoluteString {
|
|
return "Vous pourrez suivre tous les résultats de ce tournoi sur le site :\n\n".appending(shareLink)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return [entryFeeMessage, customCallMessageBody, linkMessage].compacted().map { $0.trimmedMultiline }.joined(separator: "\n")
|
|
}
|
|
|
|
var finalMessage: String? {
|
|
let localizedCalled = "convoqué" + (tournament.tournamentCategory == .women ? "e" : "") + "s"
|
|
return "Bonjour,\n\nVous êtes \(localizedCalled) pour jouer en \(RoundRule.roundName(fromRoundIndex: 2).lowercased()) du \(tournament.tournamentTitle(.title, hideSenior: true)) au \(clubName) le \(tournament.startDate.formatted(Date.FormatStyle().weekday(.wide).day().month(.wide))) à \(tournament.startDate.formatted(Date.FormatStyle().hour().minute())).\n\n" + computedMessage + "\n\n\(customCallMessageSignature)"
|
|
}
|
|
|
|
var body: some View {
|
|
@Bindable var user = dataStore.user
|
|
List {
|
|
_renderingView()
|
|
.disabled(true)
|
|
_optionsView()
|
|
_editorView()
|
|
|
|
if user.summonsUseFullCustomMessage && tournament.isFree() == false {
|
|
_paymentMethodsView()
|
|
}
|
|
|
|
Section {
|
|
ZStack {
|
|
Text(customCallMessageSignature).hidden()
|
|
TextEditor(text: $customCallMessageSignature)
|
|
.autocorrectionDisabled()
|
|
.focused($focusedField, equals: .signature)
|
|
}
|
|
} header: {
|
|
Text("Signature du message")
|
|
} footer: {
|
|
HStack {
|
|
Spacer()
|
|
FooterButtonView("effacer") {
|
|
customCallMessageSignature = ""
|
|
_save()
|
|
}
|
|
Divider()
|
|
FooterButtonView("défaut") {
|
|
customCallMessageSignature = DataStore.shared.user.defaultSignature(tournament)
|
|
_save()
|
|
}
|
|
Divider()
|
|
FooterButtonView("éditer") {
|
|
focusedField = .signature
|
|
}
|
|
}
|
|
}
|
|
|
|
_clubNameView()
|
|
}
|
|
.headerProminence(.increased)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.navigationBarBackButtonHidden(focusedField != nil)
|
|
.toolbar(content: {
|
|
if focusedField != nil {
|
|
ToolbarItem(placement: .topBarLeading) {
|
|
Button("Annuler", role: .cancel) {
|
|
focusedField = nil
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.toolbarBackground(.visible, for: .navigationBar)
|
|
.navigationTitle("Message de convocation")
|
|
.toolbar {
|
|
ToolbarItemGroup(placement: .keyboard) {
|
|
if focusedField != .clubName {
|
|
Spacer()
|
|
Button {
|
|
focusedField = nil
|
|
_save()
|
|
} label: {
|
|
Text("Valider")
|
|
}
|
|
.buttonStyle(.bordered)
|
|
}
|
|
}
|
|
}
|
|
.onChange(of: user.summonsUseFullCustomMessage) {
|
|
user.summonsMessageBody = nil
|
|
if user.summonsUseFullCustomMessage == false {
|
|
customCallMessageBody = ContactType.defaultCustomMessage
|
|
} else {
|
|
customCallMessageBody = ""
|
|
}
|
|
_save()
|
|
}
|
|
.onChange(of: user.summonsDisplayEntryFee) {
|
|
_save()
|
|
}
|
|
}
|
|
|
|
private func _save() {
|
|
if customCallMessageBody.isEmpty {
|
|
self.dataStore.user.summonsMessageBody = nil
|
|
} else {
|
|
self.dataStore.user.summonsMessageBody = customCallMessageBody
|
|
}
|
|
if customCallMessageSignature.isEmpty {
|
|
self.dataStore.user.summonsMessageSignature = nil
|
|
} else {
|
|
self.dataStore.user.summonsMessageSignature = customCallMessageSignature
|
|
}
|
|
self.dataStore.user.summonsAvailablePaymentMethods = summonsAvailablePaymentMethods
|
|
self.dataStore.saveUser()
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func _editorView() -> some View {
|
|
@Bindable var user = dataStore.user
|
|
|
|
Section {
|
|
ZStack {
|
|
Text(customCallMessageBody).hidden()
|
|
.padding(.vertical, 20)
|
|
TextEditor(text: $customCallMessageBody)
|
|
.autocorrectionDisabled()
|
|
.focused($focusedField, equals: .body)
|
|
}
|
|
} header: {
|
|
if user.summonsUseFullCustomMessage {
|
|
Text("Message de convocation")
|
|
} else {
|
|
Text("Information supplémentaire")
|
|
}
|
|
} footer: {
|
|
if user.summonsUseFullCustomMessage == false {
|
|
HStack {
|
|
Spacer()
|
|
FooterButtonView("effacer") {
|
|
customCallMessageBody = ""
|
|
_save()
|
|
}
|
|
Divider()
|
|
FooterButtonView("défaut") {
|
|
customCallMessageBody = ContactType.defaultCustomMessage
|
|
_save()
|
|
}
|
|
Divider()
|
|
FooterButtonView("éditer") {
|
|
focusedField = .body
|
|
}
|
|
}
|
|
} else {
|
|
LazyVGrid(columns: columns, spacing: 0) {
|
|
FooterButtonView("#titre") {
|
|
customCallMessageBody.append("#titre")
|
|
focusedField = .body
|
|
}
|
|
FooterButtonView("#manche") {
|
|
customCallMessageBody.append("#manche")
|
|
focusedField = .body
|
|
}
|
|
FooterButtonView("#prix") {
|
|
customCallMessageBody.append("#prix")
|
|
focusedField = .body
|
|
}
|
|
FooterButtonView("#jour") {
|
|
customCallMessageBody.append("#jour")
|
|
focusedField = .body
|
|
}
|
|
FooterButtonView("#horaire") {
|
|
customCallMessageBody.append("#horaire")
|
|
focusedField = .body
|
|
}
|
|
FooterButtonView("#club") {
|
|
customCallMessageBody.append("#club")
|
|
focusedField = .body
|
|
}
|
|
FooterButtonView("#signature") {
|
|
customCallMessageBody.append("#signature")
|
|
focusedField = .body
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func _clubNameView() -> some View {
|
|
if let eventClub = tournament.eventObject()?.clubObject() {
|
|
let hasBeenCreated: Bool = eventClub.hasBeenCreated(by: StoreCenter.main.userId)
|
|
Section {
|
|
TextField("Nom du club", text: $customClubName, axis: .vertical)
|
|
.lineLimit(2)
|
|
.autocorrectionDisabled()
|
|
.focused($focusedField, equals: .clubName)
|
|
.onSubmit {
|
|
eventClub.name = customClubName
|
|
do {
|
|
try dataStore.clubs.addOrUpdate(instance: eventClub)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
}
|
|
.disabled(hasBeenCreated == false)
|
|
} footer: {
|
|
if hasBeenCreated == false {
|
|
Text("Édition impossible, vous n'êtes pas le créateur de ce club.").foregroundStyle(.logoRed)
|
|
} else {
|
|
HStack {
|
|
Spacer()
|
|
FooterButtonView("éditer") {
|
|
focusedField = .clubName
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func _renderingView() -> some View {
|
|
@Bindable var user = dataStore.user
|
|
Section {
|
|
Group {
|
|
if user.summonsUseFullCustomMessage {
|
|
Text(self.computedFullCustomMessage())
|
|
}
|
|
else if let finalMessage {
|
|
Text(finalMessage)
|
|
}
|
|
}.italic().foregroundStyle(.gray)
|
|
} header: {
|
|
Text("Exemple généré automatiquement")
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func _optionsView() -> some View {
|
|
@Bindable var user = dataStore.user
|
|
Section {
|
|
Toggle(isOn: $user.summonsUseFullCustomMessage) {
|
|
Text("Tout personnaliser")
|
|
Text("Écrivez votre propre message.")
|
|
}
|
|
if user.summonsUseFullCustomMessage == false {
|
|
Toggle(isOn: $user.summonsDisplayEntryFee) {
|
|
Text("Afficher le prix d'inscription")
|
|
Text("et les informations sur le paiement")
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Options")
|
|
}
|
|
|
|
if user.summonsDisplayEntryFee && user.summonsUseFullCustomMessage == false && tournament.isFree() == false {
|
|
_paymentMethodsView()
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func _paymentMethodsView() -> some View {
|
|
Section {
|
|
ZStack {
|
|
Text(summonsAvailablePaymentMethods).hidden()
|
|
.padding(.vertical, 20)
|
|
TextEditor(text: $summonsAvailablePaymentMethods)
|
|
.autocorrectionDisabled()
|
|
.focused($focusedField, equals: .paymentMethods)
|
|
}
|
|
} header: {
|
|
Text("Information sur le paiement")
|
|
} footer: {
|
|
HStack {
|
|
Spacer()
|
|
FooterButtonView("effacer") {
|
|
summonsAvailablePaymentMethods = ""
|
|
_save()
|
|
}
|
|
Divider()
|
|
FooterButtonView("défaut") {
|
|
summonsAvailablePaymentMethods = ContactType.defaultAvailablePaymentMethods
|
|
_save()
|
|
}
|
|
Divider()
|
|
FooterButtonView("éditer") {
|
|
focusedField = .paymentMethods
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func computedFullCustomMessage() -> String {
|
|
return ContactType.callingCustomMessage(source: customCallMessageBody, tournament: tournament, startDate: Date(), roundLabel: RoundRule.roundName(fromRoundIndex: 2))
|
|
}
|
|
}
|
|
|