import SwiftUI struct JoinModal: View { @Binding var isPresented: Bool var body: some View { ZStack(alignment: .bottom) { // Semi-transparent background if isPresented { Color.black.opacity(0.4) .edgesIgnoringSafeArea(.all) .onTapGesture { withAnimation { isPresented = false } } } // Modal content if isPresented { VStack(spacing: 0) { // IP Image peeking from top HStack { // Make sure you have an image named "IP" in your assets SVGImageHtml(svgName: "IP1") .frame(width: 116, height: 65) .offset(x: 30) Spacer() } .frame(height: 65) VStack(spacing: 0) { // Close button on the right HStack { Spacer() Button(action: { withAnimation { Router.shared.navigate(to: .blindBox(mediaType: .all)) } }) { Image(systemName: "xmark") .font(.system(size: 20, weight: .medium)) .foregroundColor(.themeTextMessageMain) .padding(12) } .padding(.trailing, 16) } // 文本 VStack(spacing: 8) { Text("Join us!") .font(Typography.font(for: .headline1, family: .quicksandBold)) .foregroundColor(.themeTextMessageMain) Text("Join us to get more exclusive benefits.") .font(.system(size: 14, weight: .regular)) .foregroundColor(.themeTextMessageMain) } .padding(.vertical, 12) // List content VStack (alignment: .leading) { HStack { SVGImage(svgName: "JoinList") .frame(width: 32, height: 32) HStack (alignment: .top){ Text("Unlimited") .font(.system(size: 16, weight: .bold)) .foregroundColor(.themeTextMessageMain) Text(" blind box purchases.") .font(.system(size: 16, weight: .regular)) .foregroundColor(.themeTextMessageMain) } } .padding(.vertical, 12) .padding(.leading,12) HStack (alignment: .center) { SVGImage(svgName: "JoinList") .frame(width: 32, height: 32) VStack (alignment: .leading,spacing: 4) { HStack { Text("Freely") .font(.system(size: 16, weight: .bold)) .foregroundColor(.themeTextMessageMain) Text(" upload image and video") .font(.system(size: 16, weight: .regular)) .foregroundColor(.themeTextMessageMain) } Text(" materials.") .font(.system(size: 16, weight: .regular)) .foregroundColor(.themeTextMessageMain) } } .padding(.vertical, 12) .padding(.leading,12) HStack(alignment: .top) { SVGImage(svgName: "JoinList") .frame(width: 32, height: 32) VStack (alignment: .leading,spacing: 4) { HStack { Text("500") .font(.system(size: 16, weight: .bold)) .foregroundColor(.themeTextMessageMain) Text(" credits daily,") .font(.system(size: 16, weight: .regular)) .foregroundColor(.themeTextMessageMain) } HStack(alignment: .top) { VStack (alignment: .leading, spacing: 4) { HStack { Text("5000") .font(.system(size: 16, weight: .bold)) .foregroundColor(.themeTextMessageMain) Text(" permanent credits on your first") .font(.system(size: 16, weight: .regular)) .foregroundColor(.themeTextMessageMain) } Text(" purchase!") .font(.system(size: 16, weight: .regular)) .foregroundColor(.themeTextMessageMain) } } } } .padding(.top, 12) .padding(.leading,12) HStack { Spacer() // This will push the button to the right Button(action: { // 点击跳转到会员页面 Router.shared.navigate(to: .subscribe) }) { HStack { Text("See More") .font(.system(size: 16)) Image(systemName: "chevron.right") .font(.system(size: 14)) } .foregroundColor(.themeTextMessageMain) .padding(.vertical, 12) .padding(.horizontal, 24) .cornerRadius(20) } } .padding(.trailing, 16) // Add some right padding to match the design Button(action: { // 点击跳转到会员页面 Router.shared.navigate(to: .subscribe) }) { HStack { Text("Subscribe") .font(Typography.font(for: .body, family: .quicksandBold)) Spacer() Text("$1.00/Mon") .font(Typography.font(for: .body, family: .quicksandBold)) } .foregroundColor(.themeTextMessageMain) .padding(.vertical, 12) .padding(.horizontal, 30) .background(Color.themePrimary) .cornerRadius(20) } .padding(.top, 16) // 协议条款 HStack(alignment: .center) { Button(action: { // Action for Terms of Service if let url = URL(string: "https://memorywake.com/privacy-policy") { UIApplication.shared.open(url) } }) { Text("Terms of Service") .font(.system(size: 12, weight: .regular)) .foregroundColor(.themeTextMessage) .underline() // Add underline } Rectangle() .fill(Color.gray.opacity(0.5)) .frame(width: 1, height: 16) .padding(.vertical, 4) Button(action: { // 打开网页 if let url = URL(string: "https://memorywake.com/privacy-policy") { UIApplication.shared.open(url) } }) { Text("Privacy Policy") .font(.system(size: 12, weight: .regular)) .foregroundColor(.themeTextMessage) .underline() // Add underline } Rectangle() .fill(Color.gray.opacity(0.5)) .frame(width: 1, height: 16) .padding(.vertical, 4) Button(action: { // Action for Restore Purchase if let url = URL(string: "https://memorywake.com/privacy-policy") { UIApplication.shared.open(url) } }) { Text("AI Usage Guidelines") .font(.system(size: 12, weight: .regular)) .foregroundColor(.themeTextMessage) .underline() // Add underline } } .padding(.bottom, 24) .frame(maxWidth: .infinity, alignment: .center) } .padding(.horizontal, 16) } .background(Color.white) .cornerRadius(20, corners: [.topLeft, .topRight]) } .frame(height: nil) .transition(.move(edge: .bottom)) } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) .edgesIgnoringSafeArea(.all) .animation(.easeInOut, value: isPresented) } } struct JoinModal_Previews: PreviewProvider { static var previews: some View { JoinModal(isPresented: .constant(true)) } }