import SwiftUI struct CreatorChannelSnsSection: View { let sns: CreatorChannelSnsResponse @Environment(\.openURL) private var openURL private var snsItems: [CreatorChannelSnsItem] { [ CreatorChannelSnsItem(iconName: "ic_sns_instagram", url: sns.instagramUrl), CreatorChannelSnsItem(iconName: "ic_sns_youtube", url: sns.youtubeUrl), CreatorChannelSnsItem(iconName: "ic_sns_x", url: sns.xurl), CreatorChannelSnsItem(iconName: "ic_sns_kakao", url: sns.kakaoOpenChatUrl), CreatorChannelSnsItem(iconName: "ic_sns_fancimm", url: sns.fancimmUrl) ] .compactMap { item in guard normalizedUrl(item.url) != nil else { return nil } return item } } var body: some View { if !snsItems.isEmpty { VStack(alignment: .leading, spacing: 0) { SectionTitle(title: I18n.CreatorChannelHome.sns) HStack(alignment: .center, spacing: SodaSpacing.s16) { ForEach(snsItems) { item in Button { if let url = normalizedUrl(item.url) { openURL(url) } } label: { Image(item.iconName) .resizable() .scaledToFill() .frame(width: 52, height: 52) .clipShape(Circle()) } .buttonStyle(.plain) } } .padding(.horizontal, SodaSpacing.s20) } .padding(.top, SodaSpacing.s20) } } private func normalizedUrl(_ urlString: String) -> URL? { let trimmed = urlString.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return nil } if trimmed.hasPrefix("http://") || trimmed.hasPrefix("https://") { return URL(string: trimmed) } return URL(string: "https://\(trimmed)") } } private struct CreatorChannelSnsItem: Identifiable { let iconName: String let url: String var id: String { iconName } } struct CreatorChannelSnsSection_Previews: PreviewProvider { static var previews: some View { CreatorChannelSnsSection( sns: CreatorChannelSnsResponse( instagramUrl: "https://instagram.com/voiceon", fancimmUrl: "https://fancimm.com", xurl: "https://x.com/voiceon", youtubeUrl: "https://youtube.com", kakaoOpenChatUrl: "https://open.kakao.com" ) ) .background(Color.black) .previewLayout(.sizeThatFits) } }