| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import SwiftUI
- struct SidebarView: View {
- @Environment(\.requirePremiumAccess) private var requirePremiumAccess
- @Bindable var viewModel: FrontPageViewModel
- var isPremium: Bool
- 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<Content: View>(
- 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 ? "Reddora Premium" : "Upgrade to Premium")
- .font(.system(size: 12, weight: .semibold))
- .foregroundStyle(AppTheme.textPrimary)
- }
- .frame(maxWidth: .infinity, alignment: .center)
- Text(
- isPremium
- ? "You have unlimited AI generations and all premium features."
- : "Unlock unlimited AI generations and advanced analytics"
- )
- .font(.system(size: 10))
- .foregroundStyle(AppTheme.textSecondary)
- .multilineTextAlignment(.center)
- .frame(maxWidth: .infinity, alignment: .center)
- .fixedSize(horizontal: false, vertical: true)
- .lineSpacing(2)
- Button(isPremium ? "Manage Subscription" : "Upgrade Now") {
- 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)
- }
- }
- }
|