SidebarView.swift
1 // 2 // SidebarView.swift 3 // RacerTracer 4 // 5 // Created by Alexander Kunau on 29.09.25. 6 // 7 8 import SwiftUI 9 10 enum SidebarItem: String, CaseIterable, Identifiable { 11 case dashboard = "Dashboard" 12 case analysis = "URL Analysis" 13 case linksAnalysis = "Links Analysis" 14 case externalLinks = "External Links" 15 case internalLinks = "Internal Links" 16 case imageAnalysis = "Image Analysis" 17 case cssAnalysis = "CSS Analysis" 18 case jsAnalysis = "JavaScript Analysis" 19 case keywords = "Keyword Analysis" 20 case competitors = "Competitor Analysis" 21 case technical = "Technical SEO" 22 case pageSpeed = "PageSpeed Insights" 23 case searchConsole = "Search Console" 24 case reports = "Reports" 25 case settings = "Settings" 26 27 var id: String { rawValue } 28 29 var icon: String { 30 switch self { 31 case .dashboard: 32 return "chart.bar.fill" 33 case .analysis: 34 return "magnifyingglass.circle.fill" 35 case .linksAnalysis: 36 return "link" 37 case .externalLinks: 38 return "arrow.up.right.square" 39 case .internalLinks: 40 return "arrow.turn.down.right" 41 case .imageAnalysis: 42 return "photo.fill" 43 case .cssAnalysis: 44 return "paintbrush.fill" 45 case .jsAnalysis: 46 return "curlybraces" 47 case .keywords: 48 return "key.fill" 49 case .competitors: 50 return "chart.line.uptrend.xyaxis" 51 case .technical: 52 return "gearshape.fill" 53 case .pageSpeed: 54 return "speedometer" 55 case .searchConsole: 56 return "magnifyingglass" 57 case .reports: 58 return "doc.text.fill" 59 case .settings: 60 return "gear" 61 } 62 } 63 } 64 65 struct SidebarView: View { 66 @Binding var selectedView: SidebarItem 67 68 var body: some View { 69 VStack(spacing: 0) { 70 // Compact Header 71 VStack(spacing: 6) { 72 Image(systemName: "magnifyingglass.circle.fill") 73 .font(.system(size: 24)) 74 .foregroundStyle(.blue.gradient) 75 76 Text("SEO Tracker") 77 .font(.headline) 78 .fontWeight(.semibold) 79 .foregroundColor(.primary) 80 } 81 .padding(.top, 16) 82 .padding(.bottom, 20) 83 .background(.ultraThinMaterial, in: Rectangle()) 84 85 // Navigation Items with minimal spacing 86 List(SidebarItem.allCases, selection: $selectedView) { item in 87 NavigationLink(value: item) { 88 HStack(spacing: 8) { 89 Image(systemName: item.icon) 90 .font(.system(size: 14, weight: .medium)) 91 .foregroundColor(.secondary) 92 .frame(width: 16, alignment: .center) 93 94 Text(item.rawValue) 95 .font(.system(size: 13, weight: .medium)) 96 .foregroundColor(.primary) 97 98 Spacer() 99 } 100 .contentShape(Rectangle()) 101 } 102 .listRowInsets(EdgeInsets(top: 4, leading: 12, bottom: 4, trailing: 12)) 103 .listRowSeparator(.hidden) 104 .listRowBackground( 105 RoundedRectangle(cornerRadius: 6) 106 .fill(.clear) 107 .overlay( 108 RoundedRectangle(cornerRadius: 6) 109 .fill(.ultraThinMaterial) 110 .opacity(selectedView == item ? 0.6 : 0) 111 ) 112 ) 113 } 114 .listStyle(.sidebar) 115 .scrollContentBackground(.hidden) 116 .background(.thinMaterial.opacity(0.3)) 117 118 Spacer() 119 } 120 .background(.ultraThinMaterial.opacity(0.7)) 121 .navigationSplitViewColumnWidth(min: 180, ideal: 200) 122 } 123 } 124 125 #Preview { 126 NavigationSplitView { 127 SidebarView(selectedView: .constant(.dashboard)) 128 } detail: { 129 Text("Detail View") 130 } 131 .frame(width: 800, height: 600) 132 }