import SwiftUI struct GiftRecipientAddressFormView: View { let model: ReceivedGiftDetailDisplayModel @ObservedObject var viewModel: GiftRecipientAddressViewModel var body: some View { ScrollView { VStack(alignment: .leading, spacing: SodaSpacing.s32) { privacyBanner GiftInfoSectionView(title: "전달 예정 선물") { if let nickname = model.senderNickname { GiftInfoRow(title: "보낸 사람", value: nickname) } GiftInfoRow(title: "선물 사이즈", value: model.sizeName) GiftInfoRow(title: "카테고리", value: model.categoryName) } addressSection agreementsSection } .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal, SodaSpacing.s14) .padding(.top, SodaSpacing.s24) .padding(.bottom, SodaSpacing.s32) } .scrollDismissesKeyboard(.interactively) .safeAreaInset(edge: .bottom, spacing: 0) { Button { viewModel.submit() } label: { SelectedButtonView(title: "배송지 입력 완료", isActive: viewModel.canSubmit, isSelected: false) } .disabled(!viewModel.canSubmit) .padding(SodaSpacing.s14) .background(Color.black) } .disabled(viewModel.isSubmitting || viewModel.hasSubmitted) } private var privacyBanner: some View { Text("필요 정보 외의 용도로 사용하지 않으며, 전달이 완료되면 파기됩니다") .appFont(.caption3) .foregroundColor(.gray500) .fixedSize(horizontal: false, vertical: true) .padding(SodaSpacing.s14) .frame(maxWidth: .infinity, alignment: .leading) .background(Color.gray900) .clipShape(RoundedRectangle(cornerRadius: SodaRadius.r14)) } private var addressSection: some View { VStack(alignment: .leading, spacing: SodaSpacing.s20) { VStack(alignment: .leading, spacing: SodaSpacing.s4) { Text("배송지 입력") .appFont(.heading3) .foregroundColor(.white) .accessibilityAddTraits(.isHeader) Text("제출 후 수정할 수 없으니 입력한 정보를 다시 한번 확인해 주세요") .appFont(.caption3) .foregroundColor(.gray500) .fixedSize(horizontal: false, vertical: true) } field("이름", helper: "입력한 이름으로 선물이 전달돼요") { GiftContactTextField(text: $viewModel.recipientName, rule: .name) } field("휴대폰 번호", helper: "문제 발생 시 연락이 가능한 번호를 입력해 주세요") { GiftContactTextField(text: $viewModel.recipientPhoneNumber, rule: .phoneNumber) } SodaAddressInputView(zipCode: $viewModel.recipientZipCode, address: $viewModel.recipientAddress, addressDetail: $viewModel.recipientAddressDetail) } .frame(maxWidth: .infinity, alignment: .leading) } private var agreementsSection: some View { VStack(alignment: .leading, spacing: SodaSpacing.s16) { Text("이용 약관 동의") .appFont(.heading3) .foregroundColor(.white) .accessibilityAddTraits(.isHeader) GiftAgreementRow(title: "소다라이브 크리에이터 선물 받기 이용약관에 동의합니다.", isAgreed: $viewModel.recipientTermsAgreed) GiftAgreementRow(title: "선물 받기를 위한 개인정보 수집·이용에 동의합니다.", isAgreed: $viewModel.recipientPrivacyAgreed) } .frame(maxWidth: .infinity, alignment: .leading) } private func field( _ title: String, helper: String, @ViewBuilder content: () -> Content ) -> some View { VStack(alignment: .leading, spacing: SodaSpacing.s4) { Text(title) .appFont(.body5) .foregroundColor(.grayee) content() .appFont(.body3) .foregroundColor(.white) .padding(SodaSpacing.s14) .background(Color.gray900) .cornerRadius(SodaRadius.r14) .accessibilityLabel(title) Text(helper) .appFont(.caption3) .foregroundColor(.gray500) .fixedSize(horizontal: false, vertical: true) } .frame(maxWidth: .infinity, alignment: .leading) } }