| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- import SwiftUI
- struct SidebarView: View {
- @Binding var selectedDestination: NavigationDestination
- let isPremium: Bool
- let onUpgradeTapped: () -> Void
- var body: some View {
- VStack(alignment: .leading, spacing: 0) {
- logoHeader
- .padding(.horizontal, 20)
- .padding(.top, 24)
- .padding(.bottom, 20)
- VStack(spacing: 2) {
- ForEach(NavigationDestination.allCases) { destination in
- SidebarNavItem(
- destination: destination,
- isSelected: selectedDestination == destination
- ) {
- selectedDestination = destination
- }
- }
- }
- .padding(.horizontal, 12)
- Spacer(minLength: 12)
- if !isPremium {
- PremiumCardView(onUpgradeTapped: onUpgradeTapped)
- .padding(.horizontal, 16)
- .padding(.bottom, 20)
- }
- }
- .frame(width: AppTheme.sidebarWidth, alignment: .top)
- .frame(maxHeight: .infinity)
- .background {
- AppTheme.sidebarBackground
- .ignoresSafeArea(edges: .top)
- }
- }
- private var logoHeader: some View {
- HStack(spacing: 10) {
- ZStack {
- Circle()
- .fill(AppTheme.teal)
- .frame(width: 36, height: 36)
- Text("G")
- .font(.system(size: 18, weight: .bold))
- .foregroundStyle(.white)
- }
- Text("Gramora")
- .font(.system(size: 18, weight: .bold))
- .foregroundStyle(AppTheme.textPrimary)
- }
- }
- }
- private struct SidebarNavItem: View {
- let destination: NavigationDestination
- let isSelected: Bool
- let action: () -> Void
- @State private var isHovered = false
- var body: some View {
- Button(action: action) {
- HStack(spacing: 10) {
- Image(systemName: destination.iconName(isSelected: isSelected))
- .font(.system(size: 14))
- .frame(width: 20)
- Text(destination.title)
- .font(.system(size: 13, weight: isSelected ? .semibold : .regular))
- .lineLimit(1)
- Spacer()
- }
- .foregroundStyle(foregroundColor)
- .padding(.horizontal, 12)
- .padding(.vertical, 9)
- .background(
- RoundedRectangle(cornerRadius: AppTheme.navItemCornerRadius)
- .fill(backgroundColor)
- )
- .scaleEffect(isHovered ? 1.02 : 1.0)
- .animation(.easeOut(duration: 0.15), value: isHovered)
- }
- .buttonStyle(.plain)
- .onHover { isHovered = $0 }
- }
- private var foregroundColor: Color {
- if isSelected {
- return AppTheme.teal
- }
- return isHovered ? AppTheme.navForegroundHover : AppTheme.textSecondary
- }
- private var backgroundColor: Color {
- if isSelected {
- return isHovered ? AppTheme.navBackgroundHover : AppTheme.tealLight
- }
- return isHovered ? AppTheme.tealLight : Color.clear
- }
- }
|