Просмотр исходного кода

Replace insights card with wide search bar on dashboard.

Remove profile insights fields from DashboardData. Add a centered search field with icon and placeholder; width follows the main overlay at 82% instead of a fixed width.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 2 месяцев назад
Родитель
Сommit
528d160db1
2 измененных файлов с 55 добавлено и 74 удалено
  1. 1 5
      App for Indeed/Models/DashboardModels.swift
  2. 54 69
      App for Indeed/Views/DashboardView.swift

+ 1 - 5
App for Indeed/Models/DashboardModels.swift

@@ -14,8 +14,6 @@ struct SidebarItem {
 struct DashboardData {
     let subtitle: String
     let sidebarItems: [SidebarItem]
-    let profileInsightsTitle: String
-    let profileInsightsBody: String
 }
 
 protocol DashboardDataProviding {
@@ -32,9 +30,7 @@ final class MockDashboardDataProvider: DashboardDataProviding {
                 SidebarItem(title: "Interviews", systemImage: "list.bullet", badge: nil),
                 SidebarItem(title: "Profile", systemImage: "person", badge: nil),
                 SidebarItem(title: "Settings", systemImage: "gearshape", badge: nil)
-            ],
-            profileInsightsTitle: "AI insights",
-            profileInsightsBody: "Saved jobs and interviews at a glance."
+            ]
         )
     }
 }

+ 54 - 69
App for Indeed/Views/DashboardView.swift

@@ -32,12 +32,9 @@ final class DashboardView: NSView {
     private let mainOverlay = NSStackView()
     private let greetingLabel = NSTextField(labelWithString: "")
     private let subtitleLabel = NSTextField(labelWithString: "")
-    private let insightsCard = NSView()
-    private let insightsTitleLabel = NSTextField(labelWithString: "")
-    private let insightsBodyLabel = NSTextField(labelWithString: "")
-    private let togglesLabel = NSTextField(labelWithString: "Show:")
-    private let savedToggleButton = NSButton(title: "Saved", target: nil, action: nil)
-    private let interviewsToggleButton = NSButton(title: "Interviews", target: nil, action: nil)
+    private let searchCard = NSView()
+    private let searchIcon = NSImageView()
+    private let searchField = NSTextField()
     private let sparkleView = NSImageView()
     private let scrollView = NSScrollView()
 
@@ -59,8 +56,6 @@ final class DashboardView: NSView {
     func render(_ data: DashboardData) {
         greetingLabel.stringValue = "Welcome"
         subtitleLabel.stringValue = data.subtitle
-        insightsTitleLabel.stringValue = data.profileInsightsTitle
-        insightsBodyLabel.stringValue = data.profileInsightsBody
         configureSidebar(data.sidebarItems)
         updateDocumentLayout()
     }
@@ -130,7 +125,7 @@ final class DashboardView: NSView {
         topInset.translatesAutoresizingMaskIntoConstraints = false
         topInset.heightAnchor.constraint(equalToConstant: 32).isActive = true
 
-        configureInsightsCard()
+        configureSearchCard()
 
         let titleBlock = NSStackView(views: [greetingLabel, subtitleLabel])
         titleBlock.orientation = .vertical
@@ -149,7 +144,7 @@ final class DashboardView: NSView {
         mainOverlay.addArrangedSubview(topInset)
         mainOverlay.addArrangedSubview(titleBlock)
         mainOverlay.addArrangedSubview(midSpacer)
-        mainOverlay.addArrangedSubview(insightsCard)
+        mainOverlay.addArrangedSubview(searchCard)
         mainOverlay.addArrangedSubview(overlayBottomSpacer)
 
         sparkleView.translatesAutoresizingMaskIntoConstraints = false
@@ -185,6 +180,8 @@ final class DashboardView: NSView {
             mainOverlay.topAnchor.constraint(equalTo: mainHost.topAnchor),
             mainOverlay.bottomAnchor.constraint(equalTo: mainHost.bottomAnchor, constant: -24),
 
+            searchCard.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.82),
+
             greetingLabel.leadingAnchor.constraint(equalTo: mainOverlay.leadingAnchor, constant: 24),
             greetingLabel.trailingAnchor.constraint(equalTo: mainOverlay.trailingAnchor, constant: -24),
             subtitleLabel.leadingAnchor.constraint(equalTo: greetingLabel.leadingAnchor),
@@ -195,70 +192,58 @@ final class DashboardView: NSView {
         ])
     }
 
-    private func configureInsightsCard() {
-        insightsCard.wantsLayer = true
-        insightsCard.layer?.backgroundColor = Theme.cardBackground.cgColor
-        insightsCard.layer?.cornerRadius = 18
-        insightsCard.translatesAutoresizingMaskIntoConstraints = false
-
-        insightsTitleLabel.font = .systemFont(ofSize: 20, weight: .semibold)
-        insightsTitleLabel.textColor = Theme.primaryText
-        insightsTitleLabel.alignment = .center
-        insightsTitleLabel.maximumNumberOfLines = 1
-
-        insightsBodyLabel.font = .systemFont(ofSize: 13, weight: .regular)
-        insightsBodyLabel.textColor = Theme.secondaryText
-        insightsBodyLabel.alignment = .center
-        insightsBodyLabel.maximumNumberOfLines = 4
-        insightsBodyLabel.lineBreakMode = .byWordWrapping
-        insightsBodyLabel.preferredMaxLayoutWidth = 400
-
-        togglesLabel.font = .systemFont(ofSize: 12, weight: .medium)
-        togglesLabel.textColor = Theme.tertiaryText
-        togglesLabel.alignment = .center
-        togglesLabel.maximumNumberOfLines = 1
-
-        styleToggle(savedToggleButton)
-        styleToggle(interviewsToggleButton)
-
-        let toggleRow = NSStackView(views: [savedToggleButton, interviewsToggleButton])
-        toggleRow.orientation = .horizontal
-        toggleRow.spacing = 10
-        toggleRow.alignment = .centerY
-
-        let inner = NSStackView(views: [
-            insightsTitleLabel,
-            insightsBodyLabel,
-            togglesLabel,
-            toggleRow
-        ])
-        inner.orientation = .vertical
-        inner.spacing = 10
-        inner.alignment = .centerX
-        inner.distribution = .fill
-        inner.translatesAutoresizingMaskIntoConstraints = false
+    private func configureSearchCard() {
+        searchCard.wantsLayer = true
+        searchCard.layer?.backgroundColor = Theme.cardBackground.cgColor
+        searchCard.layer?.cornerRadius = 14
+        searchCard.layer?.borderWidth = 1
+        searchCard.layer?.borderColor = NSColor(calibratedWhite: 1, alpha: 0.06).cgColor
+        searchCard.translatesAutoresizingMaskIntoConstraints = false
+        searchCard.setContentHuggingPriority(.defaultHigh, for: .vertical)
+
+        searchIcon.translatesAutoresizingMaskIntoConstraints = false
+        searchIcon.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 15, weight: .medium)
+        searchIcon.image = NSImage(systemSymbolName: "magnifyingglass", accessibilityDescription: "Search")
+        searchIcon.contentTintColor = Theme.secondaryText
+
+        searchField.translatesAutoresizingMaskIntoConstraints = false
+        searchField.isBordered = false
+        searchField.drawsBackground = false
+        searchField.focusRingType = .none
+        searchField.font = .systemFont(ofSize: 14, weight: .regular)
+        searchField.textColor = Theme.primaryText
+        searchField.placeholderAttributedString = NSAttributedString(
+            string: "Search jobs, companies, or locations",
+            attributes: [
+                .foregroundColor: Theme.tertiaryText,
+                .font: NSFont.systemFont(ofSize: 14, weight: .regular)
+            ]
+        )
+        searchField.cell?.usesSingleLineMode = true
+        searchField.cell?.wraps = false
+        searchField.cell?.isScrollable = true
+        searchField.target = self
+        searchField.action = #selector(didSubmitSearch)
+
+        searchCard.addSubview(searchIcon)
+        searchCard.addSubview(searchField)
 
-        insightsCard.setContentHuggingPriority(.defaultHigh, for: .vertical)
-        insightsCard.addSubview(inner)
         NSLayoutConstraint.activate([
-            inner.leadingAnchor.constraint(equalTo: insightsCard.leadingAnchor, constant: 32),
-            inner.trailingAnchor.constraint(equalTo: insightsCard.trailingAnchor, constant: -32),
-            inner.topAnchor.constraint(equalTo: insightsCard.topAnchor, constant: 22),
-            inner.bottomAnchor.constraint(equalTo: insightsCard.bottomAnchor, constant: -22),
-            insightsCard.widthAnchor.constraint(equalToConstant: 440)
+            searchCard.heightAnchor.constraint(equalToConstant: 48),
+
+            searchIcon.leadingAnchor.constraint(equalTo: searchCard.leadingAnchor, constant: 16),
+            searchIcon.centerYAnchor.constraint(equalTo: searchCard.centerYAnchor),
+            searchIcon.widthAnchor.constraint(equalToConstant: 18),
+            searchIcon.heightAnchor.constraint(equalToConstant: 18),
+
+            searchField.leadingAnchor.constraint(equalTo: searchIcon.trailingAnchor, constant: 10),
+            searchField.trailingAnchor.constraint(equalTo: searchCard.trailingAnchor, constant: -16),
+            searchField.centerYAnchor.constraint(equalTo: searchCard.centerYAnchor)
         ])
     }
 
-    private func styleToggle(_ button: NSButton) {
-        button.bezelStyle = .rounded
-        button.font = .systemFont(ofSize: 12, weight: .medium)
-        button.contentTintColor = Theme.secondaryText
-        button.wantsLayer = true
-        button.layer?.backgroundColor = Theme.toggleBackground.cgColor
-        button.layer?.cornerRadius = 8
-        button.translatesAutoresizingMaskIntoConstraints = false
-        button.widthAnchor.constraint(equalToConstant: 108).isActive = true
-        button.heightAnchor.constraint(equalToConstant: 30).isActive = true
+    @objc private func didSubmitSearch() {
+        // Hook up search submission here when wiring up real data.
     }
 
     private func configureSidebar(_ items: [SidebarItem]) {