parent
5f4c995fb8
commit
455074c155
@ -0,0 +1,56 @@ |
||||
// |
||||
// CashierSettingsView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 17/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct CashierSettingsView: View { |
||||
@EnvironmentObject var dataStore: DataStore |
||||
var tournaments: [Tournament] |
||||
|
||||
init(tournaments: [Tournament]) { |
||||
self.tournaments = tournaments |
||||
} |
||||
|
||||
init(tournament: Tournament) { |
||||
self.tournaments = [tournament] |
||||
} |
||||
|
||||
var body: some View { |
||||
List { |
||||
Section { |
||||
RowButtonView("Tout le monde a réglé", role: .destructive) { |
||||
let players = tournaments.flatMap({ $0.selectedPlayers() }) |
||||
players.forEach { player in |
||||
if player.hasPaid() == false { |
||||
player.registrationType = .gift |
||||
} |
||||
} |
||||
try? dataStore.playerRegistrations.addOrUpdate(contentOfs: players) |
||||
} |
||||
} footer: { |
||||
Text("Passe tous les joueurs qui n'ont pas réglé en offert") |
||||
} |
||||
|
||||
Section { |
||||
RowButtonView("Personne n'a réglé", role: .destructive) { |
||||
let players = tournaments.flatMap({ $0.selectedPlayers() }) |
||||
players.forEach { player in |
||||
player.registrationType = nil |
||||
} |
||||
try? dataStore.playerRegistrations.addOrUpdate(contentOfs: players) |
||||
} |
||||
} footer: { |
||||
Text("Remet à zéro le type d'encaissement de tous les joueurs") |
||||
} |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
#Preview { |
||||
CashierSettingsView(tournaments: []) |
||||
} |
||||
@ -0,0 +1,18 @@ |
||||
// |
||||
// PlayerListView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 17/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct PlayerListView: View { |
||||
var body: some View { |
||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) |
||||
} |
||||
} |
||||
|
||||
#Preview { |
||||
PlayerListView() |
||||
} |
||||
@ -0,0 +1,100 @@ |
||||
// |
||||
// EditablePlayerView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 17/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct EditablePlayerView: View { |
||||
|
||||
enum PlayerEditingOption { |
||||
case payment |
||||
case licenceId |
||||
} |
||||
|
||||
@EnvironmentObject var dataStore: DataStore |
||||
var player: PlayerRegistration |
||||
var editingOptions: [PlayerEditingOption] |
||||
@State private var editedLicenceId = "" |
||||
@State private var shouldPresentLicenceIdEdition: Bool = false |
||||
|
||||
var body: some View { |
||||
computedPlayerView(player) |
||||
.alert("Numéro de licence", isPresented: $shouldPresentLicenceIdEdition) { |
||||
TextField("Numéro de licence", text: $editedLicenceId) |
||||
.onSubmit { |
||||
player.licenceId = editedLicenceId |
||||
editedLicenceId = "" |
||||
try? dataStore.playerRegistrations.addOrUpdate(instance: player) |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ViewBuilder |
||||
func computedPlayerView(_ player: PlayerRegistration) -> some View { |
||||
VStack(alignment: .leading) { |
||||
ImportedPlayerView(player: player) |
||||
HStack { |
||||
Menu { |
||||
if let number = player.phoneNumber?.replacingOccurrences(of: " ", with: ""), let url = URL(string: "tel:\(number)") { |
||||
Link(destination: url) { |
||||
Label("Appeler", systemImage: "phone") |
||||
} |
||||
} |
||||
if let number = player.phoneNumber?.replacingOccurrences(of: " ", with: ""), let url = URL(string: "sms:\(number)") { |
||||
Link(destination: url) { |
||||
Label("SMS", systemImage: "message") |
||||
} |
||||
} |
||||
|
||||
if editingOptions.contains(.licenceId) { |
||||
Divider() |
||||
if let licenseYearValidity = player.tournament()?.licenseYearValidity(), player.isValidLicenseNumber(year: licenseYearValidity) == false, player.licenceId != nil { |
||||
Button { |
||||
player.validateLicenceId(licenseYearValidity) |
||||
} label: { |
||||
Text("Valider la licence \(licenseYearValidity)") |
||||
} |
||||
} |
||||
} |
||||
|
||||
if let license = player.licenceId?.strippedLicense { |
||||
Button { |
||||
let pasteboard = UIPasteboard.general |
||||
pasteboard.string = license |
||||
} label: { |
||||
Label("Copier la licence", systemImage: "doc.on.doc") |
||||
} |
||||
} |
||||
|
||||
Section { |
||||
Button { |
||||
editedLicenceId = player.licenceId ?? "" |
||||
shouldPresentLicenceIdEdition = true |
||||
} label: { |
||||
if player.licenceId == nil { |
||||
Text("Ajouter la licence") |
||||
} else { |
||||
Text("Modifier la licence") |
||||
} |
||||
} |
||||
PasteButton(payloadType: String.self) { strings in |
||||
guard let first = strings.first else { return } |
||||
player.licenceId = first |
||||
} |
||||
} header: { |
||||
Text("Modification de licence") |
||||
} |
||||
} label: { |
||||
Text("Options") |
||||
} |
||||
if editingOptions.contains(.payment) { |
||||
Spacer() |
||||
PlayerPayView(player: player) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,100 @@ |
||||
// |
||||
// TournamentCashierView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 17/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
enum CashierDestination: Identifiable, Selectable { |
||||
case summary |
||||
case groupStage(GroupStage) |
||||
case bracket(Round) |
||||
case all |
||||
|
||||
var id: String { |
||||
switch self { |
||||
case .summary, .all: |
||||
return String(describing: self) |
||||
case .groupStage(let groupStage): |
||||
return groupStage.id |
||||
case .bracket(let round): |
||||
return round.id |
||||
} |
||||
} |
||||
|
||||
func selectionLabel() -> String { |
||||
switch self { |
||||
case .summary: |
||||
return "Bilan" |
||||
case .groupStage(let groupStage): |
||||
return groupStage.selectionLabel() |
||||
case .bracket(let round): |
||||
return round.selectionLabel() |
||||
case .all: |
||||
return "Tous" |
||||
} |
||||
} |
||||
|
||||
func badgeValue() -> Int? { |
||||
nil |
||||
} |
||||
} |
||||
|
||||
struct TournamentCashierView: View { |
||||
var tournament: Tournament |
||||
@State private var selectedDestination: CashierDestination? |
||||
|
||||
func allDestinations() -> [CashierDestination] { |
||||
var allDestinations : [CashierDestination] = [.summary, .all] |
||||
let destinations : [CashierDestination] = tournament.groupStages().map { CashierDestination.groupStage($0) } |
||||
allDestinations.append(contentsOf: destinations) |
||||
tournament.rounds().forEach { round in |
||||
if round.seeds().isEmpty == false { |
||||
allDestinations.append(CashierDestination.bracket(round)) |
||||
} |
||||
} |
||||
return allDestinations |
||||
} |
||||
|
||||
init(tournament: Tournament) { |
||||
self.tournament = tournament |
||||
let gs = tournament.getActiveGroupStage() |
||||
if let gs { |
||||
_selectedDestination = State(wrappedValue: .groupStage(gs)) |
||||
} else if let rs = tournament.getActiveRound(withSeeds: true) { |
||||
_selectedDestination = State(wrappedValue: .bracket(rs)) |
||||
} |
||||
} |
||||
|
||||
var body: some View { |
||||
VStack(spacing: 0) { |
||||
GenericDestinationPickerView(selectedDestination: $selectedDestination, destinations: allDestinations(), nilDestinationIsValid: true) |
||||
switch selectedDestination { |
||||
case .none: |
||||
CashierSettingsView(tournament: tournament) |
||||
.navigationTitle("Réglages") |
||||
case .some(let selectedCall): |
||||
switch selectedCall { |
||||
case .summary: |
||||
CashierDetailView(tournament: tournament) |
||||
case .groupStage(let groupStage): |
||||
CashierView(tournament: tournament, teams: groupStage.teams()) |
||||
case .bracket(let round): |
||||
CashierView(tournament: tournament, teams: round.seeds()) |
||||
case .all: |
||||
CashierView(tournament: tournament, teams: tournament.selectedSortedTeams()) |
||||
} |
||||
} |
||||
} |
||||
.environment(tournament) |
||||
.navigationBarTitleDisplayMode(.inline) |
||||
.toolbarBackground(.visible, for: .navigationBar) |
||||
.navigationTitle("Encaissement") |
||||
} |
||||
} |
||||
|
||||
#Preview { |
||||
TournamentCashierView(tournament: Tournament.mock()) |
||||
} |
||||
Loading…
Reference in new issue