import SwiftUI struct GiftBoxCardView: View { let model: GiftListCardDisplayModel let onTap: () -> Void var body: some View { Button(action: onTap) { VStack(alignment: .leading, spacing: SodaSpacing.s14) { HStack(alignment: .top, spacing: SodaSpacing.s8) { DownsampledKFImage( url: profileURL, size: CGSize(width: SodaSpacing.s20, height: SodaSpacing.s20) ) .background(Color.gray800) .clipShape(Circle()) .accessibilityHidden(true) Text(model.counterpartNickname) .appFont(.caption3) .foregroundColor(.white) .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) if let dateText { Text(dateText) .appFont(.caption3) .foregroundColor(.gray500) .multilineTextAlignment(.trailing) .fixedSize(horizontal: false, vertical: true) } } .frame(minHeight: SodaSpacing.s20) HStack(spacing: SodaSpacing.s12) { VStack(alignment: .leading, spacing: SodaSpacing.s4) { Text(model.statusDisplay.title) .appFont(.body4) .foregroundColor(.white) if let subtitle { Text(subtitle) .appFont(.caption3) .foregroundColor(.gray400) } } .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) Image("ic_chevron_right") .resizable() .renderingMode(.template) .scaledToFit() .foregroundColor(.white) .frame(width: SodaSpacing.s20, height: SodaSpacing.s20) .accessibilityHidden(true) } .frame(minHeight: 39) } .multilineTextAlignment(.leading) .padding(SodaSpacing.s14) .frame(maxWidth: .infinity, minHeight: 101, alignment: .topLeading) .background(Color.gray900) .clipShape(RoundedRectangle(cornerRadius: SodaRadius.r14)) .contentShape(RoundedRectangle(cornerRadius: SodaRadius.r14)) } .buttonStyle(.plain) .accessibilityElement(children: .ignore) .accessibilityLabel(accessibilityText) .accessibilityAddTraits(.isButton) .padding(.horizontal, SodaSpacing.s14) } private var profileURL: URL? { guard let text = model.counterpartProfileImageUrl, !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty, let url = URL(string: text), let scheme = url.scheme?.lowercased(), ["https", "http"].contains(scheme), let host = url.host, !host.isEmpty else { return nil } return url } private var dateText: String? { model.createdDateText.map { "\($0) 신청" } } private var subtitle: String? { model.direction == .sent ? "\(model.sizeName) · \(model.categoryName)" : model.statusDisplay.subtitle } private var accessibilityText: String { [model.counterpartNickname, dateText, model.statusDisplay.title, subtitle, model.direction == .received ? "\(model.sizeName) · \(model.categoryName)" : nil] .compactMap { $0 } .joined(separator: ", ") } }