wake-ios/wake/View/Subscribe/Components/SubscriptionStatusBar.swift
2025-09-02 09:29:49 +08:00

142 lines
3.9 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 ""
case .pioneer:
return "Pioneer"
}
}
var backgroundColor: Color {
switch self {
case .free:
return .clear
case .pioneer:
return .clear
}
}
var textColor: Color {
switch self {
case .free:
return Theme.Colors.textPrimary
case .pioneer:
return .themeTextMessageMain
}
}
var backgroundImageName: String {
switch self {
case .free:
return "Free"
case .pioneer:
return "Pioneer"
}
}
}
// MARK: -
struct SubscriptionStatusBar: View {
let status: SubscriptionStatus
let onSubscribeTap: (() -> Void)?
private let height: CGFloat
init(status: SubscriptionStatus, height: CGFloat? = nil, onSubscribeTap: (() -> Void)? = nil) {
self.status = status
self.height = height ?? 155 // 155
self.onSubscribeTap = onSubscribeTap
}
var body: some View {
ZStack(alignment: .topLeading) {
// Background SVG - First layer
SVGImage(svgName: status.backgroundImageName)
.frame(maxWidth: .infinity, minHeight: 120)
.clipped()
// Content - Second layer
VStack(alignment: .leading, spacing: 0) {
Spacer()
// Subscription title
Text(status.title)
.font(.system(size: 28, weight: .bold, design: .rounded))
.foregroundColor(status.textColor)
.padding(.leading, 24)
Spacer()
.frame(height: 10)
// Expiry date or subscribe button
if case .pioneer(let expiryDate) = status {
VStack(alignment: .leading, spacing: 4) {
Text("Expires on :")
.font(.system(size: 12))
.foregroundColor(.themeTextMessageMain)
.padding(.top, 2)
Text(formatDate(expiryDate))
.font(.system(size: 12))
.fontWeight(.bold)
.foregroundColor(.themeTextMessageMain)
}
.padding(.leading, 24)
.padding(.bottom, 20)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomLeading)
}
.frame(height: height) // 使
.frame(maxWidth: .infinity)
.cornerRadius(20)
.clipped()
.contentShape(Rectangle()) // Make entire area tappable
.onTapGesture {
onSubscribeTap?()
}
}
// MARK: -
private func formatDate(_ date: Date) -> String {
let formatter = DateFormatter()
formatter.dateFormat = "MMM d, yyyy"
return formatter.string(from: date)
}
}
// MARK: -
#Preview {
VStack(spacing: 20) {
// Free status preview
SubscriptionStatusBar(
status: .free,
onSubscribeTap: {
print("Subscribe tapped")
}
)
.padding(.horizontal)
// Pioneer status preview
SubscriptionStatusBar(
status: .pioneer(
expiryDate: Calendar.current.date(byAdding: .month, value: 6, to: Date()) ?? Date()
)
)
.padding(.horizontal)
}
.padding()
.background(Theme.Colors.background)
}