165 lines
5.3 KiB
Swift
165 lines
5.3 KiB
Swift
//
|
||
// PlanCompare.swift
|
||
// wake
|
||
//
|
||
// Created by fairclip on 2025/8/20.
|
||
//
|
||
|
||
import SwiftUI
|
||
|
||
// MARK: - 计划对比功能数据模型
|
||
struct PlanFeature {
|
||
let title: String
|
||
let subtitle: String?
|
||
let freeValue: String
|
||
let pioneerValue: String
|
||
let icon: String?
|
||
}
|
||
|
||
// MARK: - 计划对比组件
|
||
struct PlanCompare: View {
|
||
|
||
// MARK: - 功能对比数据
|
||
private let features: [PlanFeature] = [
|
||
PlanFeature(
|
||
title: "Mystery Box Purchase:",
|
||
subtitle: nil,
|
||
freeValue: "3 /week",
|
||
pioneerValue: "Unlimited",
|
||
icon: nil
|
||
),
|
||
PlanFeature(
|
||
title: "Material Upload:",
|
||
subtitle: nil,
|
||
freeValue: "50 images and\n5 videos/day",
|
||
pioneerValue: "Unlimited",
|
||
icon: nil
|
||
),
|
||
PlanFeature(
|
||
title: "Free Credits:",
|
||
subtitle: "Expires the next day",
|
||
freeValue: "200 /day",
|
||
pioneerValue: "500 /day",
|
||
icon: nil
|
||
)
|
||
]
|
||
|
||
var body: some View {
|
||
HStack(spacing: 0) {
|
||
// 功能名称列
|
||
featureNamesColumn
|
||
.frame(minWidth: 163)
|
||
|
||
// Free 计划列(更宽,优先占据剩余空间)
|
||
planColumn(title: "Free", isPioneer: false)
|
||
.layoutPriority(1)
|
||
|
||
// Pioneer 计划列(固定较窄宽度)
|
||
planColumn(title: "Pioneer", isPioneer: true)
|
||
.frame(width: 88)
|
||
}
|
||
.background(Theme.Colors.cardBackground)
|
||
.cornerRadius(Theme.CornerRadius.medium)
|
||
// .shadow(
|
||
// color: Theme.Shadows.small,
|
||
// radius: Theme.Shadows.cardShadow.radius,
|
||
// x: Theme.Shadows.cardShadow.x,
|
||
// y: Theme.Shadows.cardShadow.y
|
||
// )
|
||
}
|
||
|
||
// MARK: - 功能名称列
|
||
private var featureNamesColumn: some View {
|
||
VStack(spacing: 0) {
|
||
// 表头
|
||
Text("")
|
||
.font(Typography.font(for: .title, family: .quicksandBold, size: 14))
|
||
.padding(.vertical, Theme.Spacing.sm)
|
||
.frame(maxWidth: .infinity, minHeight: 30)
|
||
|
||
// 功能名称
|
||
ForEach(Array(features.enumerated()), id: \.offset) { index, feature in
|
||
VStack(alignment: .leading, spacing: Theme.Spacing.xs) {
|
||
Text(feature.title)
|
||
.font(Typography.font(for: .body, family: .quicksandBold, size: 12))
|
||
.foregroundColor(Theme.Colors.textPrimary)
|
||
.multilineTextAlignment(.leading)
|
||
|
||
if let subtitle = feature.subtitle {
|
||
Text(subtitle)
|
||
.font(Typography.font(for: .caption, family: .quicksandRegular))
|
||
.foregroundColor(Theme.Colors.textSecondary)
|
||
.multilineTextAlignment(.leading)
|
||
}
|
||
}
|
||
.frame(maxWidth: .infinity, minHeight: 30, alignment: .leading)
|
||
.padding(.horizontal, Theme.Spacing.sm)
|
||
.padding(.vertical, Theme.Spacing.sm)
|
||
}
|
||
}
|
||
.padding(Theme.Spacing.sm)
|
||
}
|
||
|
||
// MARK: - 计划列
|
||
private func planColumn(title: String, isPioneer: Bool) -> some View {
|
||
VStack(spacing: 0) {
|
||
// 表头
|
||
VStack(spacing: Theme.Spacing.xs) {
|
||
Text(title)
|
||
.font(Typography.font(for: .title, family: .quicksandBold, size: 14))
|
||
.foregroundColor(Color.black)
|
||
}
|
||
.frame(maxWidth: .infinity)
|
||
.padding(.vertical, Theme.Spacing.sm)
|
||
|
||
// 功能值
|
||
ForEach(Array(features.enumerated()), id: \.offset) { index, feature in
|
||
let value = isPioneer ? feature.pioneerValue : feature.freeValue
|
||
|
||
Text(value)
|
||
.font(Typography.font(for: .body, family: .quicksandRegular, size: 12))
|
||
.foregroundColor(isPioneer ? Color.black : Theme.Colors.textSecondary)
|
||
.fontWeight(isPioneer ? .semibold : .regular)
|
||
.multilineTextAlignment(.center)
|
||
.frame(maxWidth: .infinity, minHeight: 30)
|
||
.padding(.vertical, Theme.Spacing.sm)
|
||
|
||
}
|
||
}
|
||
.frame(maxWidth: .infinity)
|
||
.background(isPioneer ? Theme.Colors.primaryLight : Color.white)
|
||
.cornerRadius(Theme.CornerRadius.medium)
|
||
.overlay(
|
||
RoundedRectangle(cornerRadius: Theme.CornerRadius.medium)
|
||
.stroke(
|
||
isPioneer ? Theme.Colors.primary : Theme.Colors.border,
|
||
lineWidth: isPioneer ? 1 : 0
|
||
)
|
||
)
|
||
.padding(Theme.Spacing.sm)
|
||
|
||
}
|
||
}
|
||
|
||
|
||
// MARK: - 预览
|
||
#Preview("PlanCompare") {
|
||
ScrollView {
|
||
VStack(spacing: Theme.Spacing.xl) {
|
||
PlanCompare()
|
||
}
|
||
.padding()
|
||
}
|
||
.background(Theme.Colors.background)
|
||
}
|
||
|
||
#Preview("PlanCompare Dark") {
|
||
ScrollView {
|
||
VStack(spacing: Theme.Spacing.xl) {
|
||
PlanCompare()
|
||
}
|
||
.padding()
|
||
}
|
||
.background(Color.black)
|
||
.preferredColorScheme(.dark)
|
||
} |