import SwiftUI struct SidebarView: View { @Environment(\.requirePremiumAccess) private var requirePremiumAccess @EnvironmentObject private var subscriptions: SubscriptionManager @ObservedObject private var paywallConfigService = PaywallConfigService.shared @Bindable var viewModel: FrontPageViewModel var isPremium: Bool private var sidebarConfig: PaywallConfig.Sidebar { paywallConfigService.config.sidebar } var body: some View { VStack(spacing: 0) { header navigationSections Spacer(minLength: 0) upgradeCard } .frame(width: AppTheme.sidebarWidth) .frame(maxHeight: .infinity, alignment: .top) .background(AppTheme.sidebarBackground) } private var header: some View { HStack(spacing: AppTheme.sidebarRowSpacing) { Image("AppLogo") .resizable() .interpolation(.high) .scaledToFit() .frame(width: AppTheme.iconContainerSize, height: AppTheme.iconContainerSize) VStack(alignment: .leading, spacing: 2) { Text("Reddora AI") .font(.system(size: 15, weight: .bold)) .foregroundStyle(AppTheme.textPrimary) Text("AI Assistant for Reddit") .font(.system(size: 10)) .foregroundStyle(AppTheme.textSecondary) } Spacer(minLength: 0) } .padding(.horizontal, AppTheme.sidebarContentInset + AppTheme.sidebarRowPaddingH) .padding(.top, 20) .padding(.bottom, 16) } private var navigationSections: some View { ScrollView { VStack(alignment: .leading, spacing: AppTheme.sidebarSectionSpacing) { sidebarSection(title: SidebarSection.quickAccess.rawValue) { SidebarQuickAccessItemView(isSelected: viewModel.isRedditActive) { guard requirePremiumAccess() else { return } viewModel.openReddit() } } sidebarSection(title: SidebarSection.create.rawValue) { ForEach(viewModel.createItems) { item in SidebarNavItemView( item: item, isSelected: !viewModel.isSettingsActive && !viewModel.isHistoryActive && !viewModel.isRedditActive && viewModel.selectedNavItem == item ) { viewModel.selectNavItem(item) } } } sidebarSection(title: SidebarSection.history.rawValue) { SidebarNavItemView( item: FrontPageViewModel.historyItem, isSelected: viewModel.isHistoryActive ) { viewModel.openHistory() } } sidebarSection(title: SidebarSection.settings.rawValue) { SidebarNavItemView( item: FrontPageViewModel.settingsItem, isSelected: viewModel.isSettingsActive ) { viewModel.openSettings() } } } .padding(.horizontal, AppTheme.sidebarContentInset) .padding(.top, 4) } } private func sidebarSection( title: String, @ViewBuilder content: () -> Content ) -> some View { VStack(alignment: .leading, spacing: AppTheme.sidebarItemSpacing) { SidebarSectionHeader(title: title) content() } } private var upgradeCard: some View { VStack(spacing: 0) { Rectangle() .fill(AppTheme.border) .frame(height: 1) VStack(alignment: .center, spacing: 8) { VStack(spacing: 4) { Image(systemName: "crown.fill") .font(.system(size: 14)) .foregroundStyle(AppTheme.accentYellow) Text(isPremium ? sidebarConfig.proTitle : sidebarConfig.unlockTitle) .font(.system(size: 12, weight: .semibold)) .foregroundStyle(AppTheme.textPrimary) } .frame(maxWidth: .infinity, alignment: .center) Text(isPremium ? sidebarConfig.proDescription : sidebarConfig.unlockDescription) .font(.system(size: 10)) .foregroundStyle(AppTheme.textSecondary) .multilineTextAlignment(.center) .frame(maxWidth: .infinity, alignment: .center) .fixedSize(horizontal: false, vertical: true) .lineSpacing(2) Button(premiumActionTitle) { if isPremium { if subscriptions.hasActiveSubscription { subscriptions.openSubscriptionManagement() } else { viewModel.showPaywall() } } else { viewModel.showPaywall() } } .font(.system(size: 11, weight: .semibold)) .foregroundStyle(.white) .frame(maxWidth: .infinity) .padding(.vertical, 7.5) .background(AppTheme.accentPurple) .clipShape(RoundedRectangle(cornerRadius: 8)) .buttonStyle(AppPrimaryButtonStyle()) } .frame(maxWidth: .infinity, minHeight: 105) .padding(.horizontal, 12) .padding(.vertical, 12) .background( RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall) .fill(AppTheme.cardBackground) .overlay( RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall) .stroke(AppTheme.accentPurple.opacity(0.25), lineWidth: 1) ) ) .padding(.horizontal, AppTheme.sidebarContentInset + 8) .padding(.top, 12) .padding(.bottom, 20) } } private var premiumActionTitle: String { if isPremium { return subscriptions.hasLifetimeAccess ? sidebarConfig.lifetimeAction : sidebarConfig.manageSubscriptionAction } return sidebarConfig.upgradeAction } }