119 lines
4.3 KiB
Swift
119 lines
4.3 KiB
Swift
//
|
||
// ScenicPromotionQueuePanelView.swift
|
||
// suixinkan
|
||
//
|
||
// Created by Codex on 2026/7/2.
|
||
//
|
||
|
||
import SwiftUI
|
||
|
||
/// 宣传页当前叫号模块,有排队数据时展示叫号,无排队时展示空状态。
|
||
struct ScenicPromotionQueuePanelView: View {
|
||
let queue: ScenicPromotionQueueInfo?
|
||
|
||
var body: some View {
|
||
Group {
|
||
if let queue {
|
||
HStack(spacing: 10) {
|
||
ScenicPromotionQueueSideView(
|
||
icon: "camera.aperture",
|
||
title: "下一位",
|
||
value: queue.nextNumber,
|
||
tint: Color(hex: 0x197BFF)
|
||
)
|
||
Divider()
|
||
.frame(height: 52)
|
||
VStack(spacing: 0) {
|
||
Text("当前叫号")
|
||
.font(.system(size: 15, weight: .bold))
|
||
.foregroundStyle(Color(hex: 0x123F86))
|
||
Text(queue.currentNumber)
|
||
.font(.system(size: 38, weight: .heavy))
|
||
.foregroundStyle(Color(hex: 0x197BFF))
|
||
.minimumScaleFactor(0.55)
|
||
}
|
||
.frame(maxWidth: .infinity)
|
||
Divider()
|
||
.frame(height: 52)
|
||
ScenicPromotionQueueSideView(
|
||
icon: "person.2.fill",
|
||
title: "拍摄用时",
|
||
value: queue.shootingDuration,
|
||
tint: Color(hex: 0x7A4DFF)
|
||
)
|
||
}
|
||
.padding(.horizontal, 14)
|
||
.padding(.vertical, 7)
|
||
} else {
|
||
HStack(spacing: 18) {
|
||
Image(systemName: "list.clipboard")
|
||
.font(.system(size: 46, weight: .semibold))
|
||
.foregroundStyle(Color(hex: 0x2F80ED))
|
||
.frame(width: 92, height: 92)
|
||
.background(Color(hex: 0xEAF4FF), in: RoundedRectangle(cornerRadius: 18))
|
||
VStack(alignment: .leading, spacing: 8) {
|
||
Text("当前暂无排队信息")
|
||
.font(.system(size: 22, weight: .heavy))
|
||
.foregroundStyle(Color(hex: 0x123F86))
|
||
Text("可先浏览景点样片,稍后再查看排队动态")
|
||
.font(.system(size: 14, weight: .medium))
|
||
.foregroundStyle(Color(hex: 0x5272A5))
|
||
}
|
||
Spacer(minLength: 0)
|
||
}
|
||
.padding(18)
|
||
}
|
||
}
|
||
.frame(maxWidth: .infinity)
|
||
.background(.white.opacity(0.86), in: RoundedRectangle(cornerRadius: 18))
|
||
.overlay(
|
||
RoundedRectangle(cornerRadius: 18)
|
||
.stroke(.white.opacity(0.9), lineWidth: 1)
|
||
)
|
||
.shadow(color: Color(hex: 0x0D47A1, alpha: 0.10), radius: 14, y: 6)
|
||
}
|
||
}
|
||
|
||
/// 叫号模块左右两侧的小信息块。
|
||
struct ScenicPromotionQueueSideView: View {
|
||
let icon: String
|
||
let title: String
|
||
let value: String
|
||
let tint: Color
|
||
|
||
var body: some View {
|
||
HStack(spacing: 7) {
|
||
Image(systemName: icon)
|
||
.font(.system(size: 18, weight: .semibold))
|
||
.foregroundStyle(tint)
|
||
.frame(width: 34, height: 34)
|
||
.background(tint.opacity(0.13), in: Circle())
|
||
|
||
VStack(alignment: .leading, spacing: 3) {
|
||
Text(title)
|
||
.font(.system(size: 11, weight: .medium))
|
||
.foregroundStyle(Color(hex: 0x113B79))
|
||
Text(value)
|
||
.font(.system(size: 13, weight: .heavy))
|
||
.foregroundStyle(tint)
|
||
.lineLimit(2)
|
||
.fixedSize(horizontal: false, vertical: true)
|
||
.minimumScaleFactor(0.76)
|
||
}
|
||
}
|
||
.frame(maxWidth: .infinity, alignment: .leading)
|
||
}
|
||
}
|
||
|
||
#if DEBUG
|
||
#Preview("叫号面板") {
|
||
ScenicPromotionQueuePanelView(queue: ScenicPromotionPreviewSupport.sampleQueue)
|
||
.padding(.horizontal, 20)
|
||
}
|
||
|
||
#Preview("叫号面板-空") {
|
||
ScenicPromotionQueuePanelView(queue: nil)
|
||
.padding(.horizontal, 20)
|
||
}
|
||
#endif
|