Instantly share code, notes, and snippets.
Last active
August 14, 2025 08:54
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save luthviar/c1bae66047cd461b416853d89772501b to your computer and use it in GitHub Desktop.
SimpleAddOtherProductBottomAndShare SwiftUI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // ContentView16.swift | |
| // Coba14July2025 | |
| // | |
| // Created by Luthfi Abdurrahim on 14/08/25. | |
| // | |
| import SwiftUI | |
| struct DiscoverProductsCard: View { | |
| let notificationCount: Int | |
| let title: String | |
| let onCardTap: () -> Void | |
| let onBackTap: () -> Void | |
| var body: some View { | |
| HStack(spacing: 16) { | |
| // Main card | |
| Button(action: onCardTap) { | |
| HStack(spacing: 0) { | |
| /// Folder icon with badge | |
| ZStack(alignment: .topTrailing) { | |
| Image(.bagIcon) | |
| .resizable() | |
| .scaledToFit() | |
| .frame(width: 35) | |
| if notificationCount > 0 { | |
| Circle() | |
| .fill(Color.red) | |
| .frame(width: 26, height: 26) | |
| .overlay( | |
| Text("\(notificationCount)") | |
| .font(.system(size: 13, weight: .bold)) | |
| .foregroundColor(.white) | |
| ) | |
| .offset(x: 10, y: -10) | |
| } | |
| } | |
| .padding(.trailing, 10) | |
| /// Title text | |
| Text(title) | |
| .font(.system(size: 14, weight: .bold)) | |
| .foregroundColor(.white) | |
| .multilineTextAlignment(.leading) | |
| Spacer() | |
| /// Chevron arrow | |
| Image(systemName: "chevron.right") | |
| .resizable() | |
| .scaledToFit() | |
| .frame(width: 12.7) | |
| .foregroundColor(.white) | |
| } | |
| .padding(.horizontal, 18) | |
| .padding(.vertical, 16) | |
| .background( | |
| RoundedRectangle(cornerRadius: .infinity) | |
| .fill(.ultraThinMaterial.opacity(0.3)) | |
| .background( | |
| // Liquid glass effect | |
| RoundedRectangle(cornerRadius: .infinity) | |
| .fill( | |
| LinearGradient( | |
| colors: [ | |
| Color.white.opacity(0.15), | |
| Color.white.opacity(0.05), | |
| Color.white.opacity(0.1) | |
| ], | |
| startPoint: .topLeading, | |
| endPoint: .bottomTrailing | |
| ) | |
| ) | |
| .blur(radius: 0.5) | |
| ) | |
| .overlay( | |
| // Inner glow | |
| RoundedRectangle(cornerRadius: .infinity) | |
| .stroke( | |
| LinearGradient( | |
| colors: [ | |
| Color.white.opacity(0.4), | |
| Color.white.opacity(0.1), | |
| Color.white.opacity(0.2) | |
| ], | |
| startPoint: .topLeading, | |
| endPoint: .bottomTrailing | |
| ), | |
| lineWidth: 1.5 | |
| ) | |
| ) | |
| .shadow(color: Color.black.opacity(0.1), radius: 2, x: 0, y: 1) | |
| ) | |
| } | |
| .buttonStyle(PlainButtonStyle()) | |
| /// Back button | |
| Button(action: onBackTap) { | |
| Image(.shareIconBigRight) | |
| .font(.system(size: 20, weight: .medium)) | |
| .frame(width: 69, height: 69) | |
| .background( | |
| Circle() | |
| .fill(.ultraThinMaterial.opacity(0.3)) | |
| .background( | |
| // Liquid glass effect | |
| Circle() | |
| .fill( | |
| LinearGradient( | |
| colors: [ | |
| Color.white.opacity(0.15), | |
| Color.white.opacity(0.05), | |
| Color.white.opacity(0.1) | |
| ], | |
| startPoint: .topLeading, | |
| endPoint: .bottomTrailing | |
| ) | |
| ) | |
| .blur(radius: 0.5) | |
| ) | |
| .overlay( | |
| // Inner glow | |
| Circle() | |
| .stroke( | |
| LinearGradient( | |
| colors: [ | |
| Color.white.opacity(0.4), | |
| Color.white.opacity(0.1), | |
| Color.white.opacity(0.2) | |
| ], | |
| startPoint: .topLeading, | |
| endPoint: .bottomTrailing | |
| ), | |
| lineWidth: 1.5 | |
| ) | |
| ) | |
| .shadow(color: Color.black.opacity(0.1), radius: 2, x: 0, y: 1) | |
| ) | |
| } | |
| .buttonStyle(PlainButtonStyle()) | |
| } | |
| .padding(.horizontal, 20) | |
| } | |
| } | |
| // Custom button style to handle press effects | |
| struct CardButtonStyle: ButtonStyle { | |
| func makeBody(configuration: Configuration) -> some View { | |
| configuration.label | |
| .scaleEffect(configuration.isPressed ? 0.98 : 1.0) | |
| .opacity(configuration.isPressed ? 0.8 : 1.0) | |
| .animation(.easeInOut(duration: 0.1), value: configuration.isPressed) | |
| } | |
| } | |
| #Preview { | |
| DiscoverProductsCard( | |
| notificationCount: 20, | |
| title: "Temukan Produk Lainnya", | |
| onCardTap: { | |
| print("Card tapped") | |
| }, | |
| onBackTap: { | |
| print("Back button tapped") | |
| } | |
| ) | |
| .background( | |
| // Sample background to match the image | |
| LinearGradient( | |
| colors: [ | |
| Color.purple.opacity(0.8), | |
| Color.purple.opacity(0.6), | |
| Color.pink.opacity(0.4) | |
| ], | |
| startPoint: .topLeading, | |
| endPoint: .bottomTrailing | |
| ) | |
| .blur(radius: 20) | |
| ) | |
| } | |
| import SwiftUI | |
| // Example of how to use the component in a real app with navigation | |
| struct DiscoverProductsView: View { | |
| var body: some View { | |
| NavigationStack { | |
| ZStack { | |
| // Your app's background | |
| LinearGradient( | |
| colors: [ | |
| Color.purple.opacity(0.9), | |
| Color.purple.opacity(0.7), | |
| Color.pink.opacity(0.5) | |
| ], | |
| startPoint: .topLeading, | |
| endPoint: .bottomTrailing | |
| ) | |
| .ignoresSafeArea() | |
| VStack(spacing: 30) { | |
| Text("Product Discovery") | |
| .font(.largeTitle) | |
| .fontWeight(.bold) | |
| .foregroundColor(.white) | |
| DiscoverProductsCard( | |
| notificationCount: 15, | |
| title: "Temukan Produk Lainnya", | |
| onCardTap: { | |
| // Navigate to products list | |
| print("Opening products catalog...") | |
| }, | |
| onBackTap: { | |
| // Go back to previous screen | |
| print("Returning to main menu...") | |
| } | |
| ) | |
| // You can have multiple cards with different configurations | |
| DiscoverProductsCard( | |
| notificationCount: 5, | |
| title: "Kategori Populer", | |
| onCardTap: { | |
| print("Opening popular categories...") | |
| }, | |
| onBackTap: { | |
| print("Going back...") | |
| } | |
| ) | |
| DiscoverProductsCard( | |
| notificationCount: 0, // No badge when count is 0 | |
| title: "Rekomendasi Untuk Anda", | |
| onCardTap: { | |
| print("Opening recommendations...") | |
| }, | |
| onBackTap: { | |
| print("Going back...") | |
| } | |
| ) | |
| Spacer() | |
| } | |
| .padding() | |
| } | |
| } | |
| } | |
| } | |
| #Preview { | |
| DiscoverProductsView() | |
| } | |
| import SwiftUI | |
| struct ContentView16: View { | |
| @State private var notificationCount = 20 | |
| var body: some View { | |
| ZStack { | |
| // Background that matches the image | |
| LinearGradient( | |
| colors: [ | |
| Color.purple.opacity(0.9), | |
| Color.purple.opacity(0.7), | |
| Color.pink.opacity(0.5), | |
| Color.purple.opacity(0.8) | |
| ], | |
| startPoint: .topLeading, | |
| endPoint: .bottomTrailing | |
| ) | |
| .blur(radius: 30) | |
| .ignoresSafeArea() | |
| // Overlay some blur effects to match the background | |
| Circle() | |
| .fill(Color.white.opacity(0.1)) | |
| .frame(width: 200, height: 200) | |
| .blur(radius: 50) | |
| .offset(x: -100, y: -200) | |
| Circle() | |
| .fill(Color.pink.opacity(0.2)) | |
| .frame(width: 150, height: 150) | |
| .blur(radius: 40) | |
| .offset(x: 120, y: 100) | |
| VStack { | |
| Spacer() | |
| DiscoverProductsCard( | |
| notificationCount: notificationCount, | |
| title: "Temukan Produk Lainnya", | |
| onCardTap: { | |
| print("Navigating to discover products...") | |
| // Add your navigation logic here | |
| // For example: navigationPath.append(DiscoverProductsView()) | |
| }, | |
| onBackTap: { | |
| print("Going back...") | |
| // Add your back navigation logic here | |
| // For example: navigationPath.removeLast() | |
| } | |
| ) | |
| Spacer() | |
| } | |
| } | |
| } | |
| } | |
| #Preview { | |
| ContentView() | |
| } | |
| //SimpleAddOtherProductBottomAndShare.swift |
Author
luthviar
commented
Aug 14, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment