import SwiftUI struct FeaturedStoreCard: View { let store: FeaturedStoreCardModel var body: some View { VStack(alignment: .leading, spacing: 12) { ZStack(alignment: .topLeading) { mediaBlock if let promo = store.promoText { Text(promo) .font(AppTypography.caption) .foregroundStyle(AppColors.textInverse) .padding(.horizontal, 10) .padding(.vertical, 6) .background(Color.red) .clipShape(Capsule()) .padding(10) } HStack { Spacer() Button(action: {}) { Image(systemName: store.isFavorite ? "heart.fill" : "heart") .foregroundStyle(store.isFavorite ? Color.red : AppColors.textMuted) .padding(8) .background(AppColors.surface) .clipShape(Circle()) .shadow(color: AppShadow.soft.color, radius: AppShadow.soft.radius, y: AppShadow.soft.y) } .padding(10) } } Text(store.name) .font(AppTypography.heading3) .foregroundStyle(AppColors.textPrimary) if store.isOpen { HStack(spacing: 6) { Image(systemName: "star.fill") .font(.caption) .foregroundStyle(Color(hex: "#F5B335")) Text(String(format: "%.1f", store.rating)) .font(.caption) .foregroundStyle(AppColors.textPrimary) Text("(\(store.reviews))") .font(.caption) .foregroundStyle(AppColors.textMuted) Text("ยท") .font(.caption) .foregroundStyle(AppColors.textMuted) Text(store.distance) .font(.caption) .foregroundStyle(AppColors.textMuted) } } else { Text(store.statusLabel?.isEmpty == false ? (store.statusLabel ?? "Fechado") : "Fechado") .font(AppTypography.heading3) .foregroundStyle(AppColors.textPrimary) } Text(store.category) .font(.caption) .foregroundStyle(AppColors.textMuted) } .padding(14) .background(AppColors.surface) .clipShape(RoundedRectangle(cornerRadius: AppLayout.radiusXL, style: .continuous)) .saturation(store.isOpen ? 1 : 0) .opacity(store.isOpen ? 1 : 0.9) } private var mediaBlock: some View { ZStack { RoundedRectangle(cornerRadius: AppLayout.radiusLG, style: .continuous) .fill(AppColors.brandSoft) mediaImage } .frame(height: 120) .clipShape(RoundedRectangle(cornerRadius: AppLayout.radiusLG, style: .continuous)) } @ViewBuilder private var mediaImage: some View { AsyncStoreImage(imageURL: store.imageURL) } private var storeIconPlaceholder: some View { ZStack { Image("placeholder-product") .resizable() .scaledToFill() .opacity(0.7) .frame(maxWidth: .infinity, maxHeight: .infinity) .clipped() Circle() .fill(AppColors.surface.opacity(0.92)) .frame(width: 64, height: 64) .overlay( Image(systemName: store.iconName) .font(.title2) .foregroundStyle(AppColors.primary) ) } } } struct FeaturedStoreCardModel: Identifiable { let id: String let name: String let rating: Double let reviews: String let distance: String let category: String let promoText: String? let isFavorite: Bool let iconName: String let imageURL: String? let logoURL: String? let coverURL: String? let isOpen: Bool let statusLabel: String? } struct SpecialOfferCard: View { let model: SpecialOfferCardModel var body: some View { ZStack(alignment: .leading) { RoundedRectangle(cornerRadius: AppLayout.radiusXL, style: .continuous) .fill( LinearGradient( colors: model.colors, startPoint: .leading, endPoint: .trailing ) ) Circle() .fill(Color.white.opacity(0.18)) .frame(width: 120, height: 120) .offset(x: 140, y: 10) VStack(alignment: .leading, spacing: 8) { Text(model.title) .font(AppTypography.heading2) .foregroundStyle(AppColors.textInverse) Text(model.subtitle) .font(AppTypography.body) .foregroundStyle(AppColors.textInverse.opacity(0.85)) } .padding(20) } .shadow(color: AppShadow.soft.color, radius: AppShadow.soft.radius, y: AppShadow.soft.y) } } struct SpecialOfferCardModel: Identifiable { let id: String let title: String let subtitle: String let colors: [Color] }