wake-ios/wake/View/Subscribe/Components/SubscriptionStatusBar.swift
2025-09-01 19:49:52 +08:00

133 lines
3.6 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)?
init(status: SubscriptionStatus, onSubscribeTap: (() -> Void)? = nil) {
self.status = status
self.onSubscribeTap = onSubscribeTap
}
var body: some View {
ZStack(alignment: .topLeading) {
// Background SVG - First layer
SVGImage(svgName: status.backgroundImageName, shouldFill: true)
.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)
// Expiry date or subscribe button
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.9))
Text(formatDate(expiryDate))
.font(.system(size: 16, weight: .semibold))
.foregroundColor(status.textColor)
}
.padding(.leading, 24)
.padding(.bottom, 20)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomLeading)
}
.frame(height: 155)
.frame(maxWidth: .infinity)
.cornerRadius(20)
.clipped()
}
// 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)
}