CasinoGames/Blackjack/Views/Table/InsurancePopupView.swift

120 lines
4.4 KiB
Swift

//
// InsurancePopupView.swift
// Blackjack
//
// Modal popup for insurance decision when dealer shows an Ace.
//
import SwiftUI
import CasinoKit
struct InsurancePopupView: View {
let betAmount: Int
let balance: Int
let onTake: () -> Void
let onDecline: () -> Void
var body: some View {
ZStack {
// Dimmed background
Color.black.opacity(Design.Opacity.medium)
.ignoresSafeArea()
.onTapGesture { } // Prevent taps passing through
// Popup card
VStack(spacing: Design.Spacing.large) {
// Icon
Image(systemName: "shield.fill")
.font(.system(size: Design.IconSize.xLarge))
.foregroundStyle(.yellow)
// Title
Text(String(localized: "INSURANCE?"))
.font(.system(size: Design.BaseFontSize.xLarge, weight: .bold))
.foregroundStyle(.white)
// Subtitle
Text(String(localized: "Dealer showing Ace"))
.font(.system(size: Design.BaseFontSize.medium))
.foregroundStyle(.white.opacity(Design.Opacity.strong))
// Cost info
Text(String(localized: "Cost: $\(betAmount) (half your bet)"))
.font(.system(size: Design.BaseFontSize.small))
.foregroundStyle(.white.opacity(Design.Opacity.medium))
.padding(.bottom, Design.Spacing.small)
// Buttons
HStack(spacing: Design.Spacing.large) {
// Decline button
Button(action: onDecline) {
Text(String(localized: "No Thanks"))
.font(.system(size: Design.BaseFontSize.medium, weight: .semibold))
.foregroundStyle(.white)
.padding(.horizontal, Design.Spacing.xLarge)
.padding(.vertical, Design.Spacing.medium)
.background(
Capsule()
.fill(Color.red.opacity(Design.Opacity.heavy))
)
}
// Accept button (only if can afford)
if balance >= betAmount {
Button(action: onTake) {
Text(String(localized: "Yes ($\(betAmount))"))
.font(.system(size: Design.BaseFontSize.medium, weight: .bold))
.foregroundStyle(.black)
.padding(.horizontal, Design.Spacing.xLarge)
.padding(.vertical, Design.Spacing.medium)
.background(
Capsule()
.fill(
LinearGradient(
colors: [Color.Button.goldLight, Color.Button.goldDark],
startPoint: .top,
endPoint: .bottom
)
)
)
}
}
}
}
.padding(Design.Spacing.xLarge)
.background(
RoundedRectangle(cornerRadius: Design.CornerRadius.xLarge)
.fill(Color.Modal.background)
.shadow(color: .black.opacity(Design.Opacity.medium), radius: Design.Shadow.radiusXLarge)
)
.overlay(
RoundedRectangle(cornerRadius: Design.CornerRadius.xLarge)
.strokeBorder(Color.yellow.opacity(Design.Opacity.light), lineWidth: Design.LineWidth.thin)
)
}
.accessibilityElement(children: .contain)
.accessibilityAddTraits(.isModal)
}
}
// MARK: - Previews
#Preview("Can Afford") {
InsurancePopupView(
betAmount: 500,
balance: 4500,
onTake: {},
onDecline: {}
)
}
#Preview("Cannot Afford") {
InsurancePopupView(
betAmount: 500,
balance: 200,
onTake: {},
onDecline: {}
)
}