wake-ios/wake/View/Subscribe/Components/SubscriptionStatusBar.swift
2025-08-19 15:24:53 +08:00

141 lines
4.1 KiB
Swift

//
// SubscriptionStatusBar.swift
// wake
//
// Created by fairclip on 2025/8/19.
//
import SwiftUI
// MARK: -
enum SubscriptionStatus {
case free
case pioneer(expiryDate: Date)
var title: String {
switch self {
case .free:
return "Free"
case .pioneer:
return "Pioneer"
}
}
var hasExpiry: Bool {
switch self {
case .free:
return false
case .pioneer:
return true
}
}
var backgroundColor: Color {
switch self {
case .free:
return Theme.Colors.freeBackground //
case .pioneer:
return Theme.Colors.pioneerBackground //
}
}
var textColor: Color {
switch self {
case .free:
return Theme.Colors.textPrimary
case .pioneer:
return Theme.Colors.textPrimary
}
}
}
// MARK: -
struct SubscriptionStatusBar: View {
let status: SubscriptionStatus
let onSubscribeTap: (() -> Void)?
init(status: SubscriptionStatus, onSubscribeTap: (() -> Void)? = nil) {
self.status = status
self.onSubscribeTap = onSubscribeTap
}
var body: some View {
HStack(spacing: 16) {
VStack(alignment: .leading, spacing: 8) {
//
Text(status.title)
.font(.system(size: 28, weight: .bold, design: .rounded))
.foregroundColor(status.textColor)
//
if case .pioneer(let expiryDate) = status {
VStack(alignment: .leading, spacing: 4) {
Text("Expires on :")
.font(.system(size: 14, weight: .medium))
.foregroundColor(status.textColor.opacity(0.8))
Text(formatDate(expiryDate))
.font(.system(size: 16, weight: .semibold))
.foregroundColor(status.textColor)
}
} else {
Button(action: {
onSubscribeTap?()
}) {
Text("Subscribe")
.font(.system(size: 14, weight: .semibold))
.foregroundColor(Theme.Colors.textPrimary)
.padding(.horizontal, 20)
.padding(.vertical, 8)
.background(Theme.Colors.subscribeButton)
.cornerRadius(Theme.CornerRadius.large)
}
}
}
Spacer()
//
Circle()
.fill(Color.black)
.frame(width: 60, height: 60)
.overlay(
Image(systemName: "play.fill")
.foregroundColor(.white)
.font(.title2)
.offset(x: 2) //
)
}
.padding(20)
.background(status.backgroundColor)
.cornerRadius(20)
.shadow(color: Color.black.opacity(0.1), radius: 4, x: 0, y: 2)
}
// MARK: -
private func formatDate(_ date: Date) -> String {
let formatter = DateFormatter()
formatter.dateFormat = "MMMM d, yyyy"
return formatter.string(from: date)
}
}
// MARK: -
#Preview("Free Status") {
VStack(spacing: 20) {
SubscriptionStatusBar(
status: .free,
onSubscribeTap: {
print("Subscribe tapped")
}
)
.padding()
SubscriptionStatusBar(
status: .pioneer(expiryDate: Calendar.current.date(byAdding: .month, value: 6, to: Date()) ?? Date())
)
.padding()
}
.background(Color(.systemGroupedBackground))
}