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

Add Premium upgrade card to sidebar and trim dashboard model

Introduce a bordered sidebar card with gold accent, sparkles label,
headline, supporting copy, and pill-shaped Upgrade to Pro CTA that
opens the default browser. Remove unused greetingName from
DashboardData and the mock provider so the model matches the view.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 2 месяцев назад
Родитель
Сommit
3a14a46687

+ 0 - 2
App for Indeed/Models/DashboardModels.swift

@@ -12,7 +12,6 @@ struct SidebarItem {
 }
 
 struct DashboardData {
-    let greetingName: String
     let subtitle: String
     let sidebarItems: [SidebarItem]
     let profileInsightsTitle: String
@@ -26,7 +25,6 @@ protocol DashboardDataProviding {
 final class MockDashboardDataProvider: DashboardDataProviding {
     func loadDashboardData() -> DashboardData {
         DashboardData(
-            greetingName: "Olivia",
             subtitle: "Find your perfect job with the power of AI.",
             sidebarItems: [
                 SidebarItem(title: "Overview", systemImage: "house.fill", badge: nil),

+ 95 - 1
App for Indeed/Views/DashboardView.swift

@@ -17,6 +17,11 @@ final class DashboardView: NSView {
         static let primaryText = NSColor(calibratedWhite: 0.96, alpha: 1)
         static let secondaryText = NSColor(calibratedWhite: 0.62, alpha: 1)
         static let tertiaryText = NSColor(calibratedWhite: 0.48, alpha: 1)
+        static let proCardFill = NSColor(calibratedRed: 0.1, green: 0.09, blue: 0.12, alpha: 1)
+        static let proCardBorder = NSColor(calibratedWhite: 1, alpha: 0.09)
+        static let proAccent = NSColor(calibratedRed: 0.98, green: 0.82, blue: 0.38, alpha: 1)
+        static let proCTABackground = NSColor(calibratedWhite: 0.97, alpha: 1)
+        static let proCTAText = NSColor(calibratedWhite: 0.05, alpha: 1)
     }
 
     private let contentStack = NSStackView()
@@ -52,7 +57,7 @@ final class DashboardView: NSView {
     }
 
     func render(_ data: DashboardData) {
-        greetingLabel.stringValue = "Welcome back, \(data.greetingName)! 👋"
+        greetingLabel.stringValue = "Welcome"
         subtitleLabel.stringValue = data.subtitle
         insightsTitleLabel.stringValue = data.profileInsightsTitle
         insightsBodyLabel.stringValue = data.profileInsightsBody
@@ -321,6 +326,95 @@ final class DashboardView: NSView {
         sidebarBottomSpacer.setContentHuggingPriority(.defaultLow, for: .vertical)
         sidebarBottomSpacer.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
         sidebar.addArrangedSubview(sidebarBottomSpacer)
+
+        let upgradeCard = NSView()
+        upgradeCard.translatesAutoresizingMaskIntoConstraints = false
+        upgradeCard.wantsLayer = true
+        upgradeCard.layer?.backgroundColor = Theme.proCardFill.cgColor
+        upgradeCard.layer?.cornerRadius = 14
+        upgradeCard.layer?.borderWidth = 1
+        upgradeCard.layer?.borderColor = Theme.proCardBorder.cgColor
+        upgradeCard.layer?.masksToBounds = true
+
+        let accentBar = NSView()
+        accentBar.translatesAutoresizingMaskIntoConstraints = false
+        accentBar.wantsLayer = true
+        accentBar.layer?.backgroundColor = Theme.proAccent.cgColor
+
+        let inner = NSStackView()
+        inner.translatesAutoresizingMaskIntoConstraints = false
+        inner.orientation = .vertical
+        inner.spacing = 10
+        inner.alignment = .leading
+
+        let proIcon = NSImageView()
+        proIcon.translatesAutoresizingMaskIntoConstraints = false
+        proIcon.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 13, weight: .semibold)
+        proIcon.image = NSImage(systemSymbolName: "sparkles", accessibilityDescription: nil)
+        proIcon.contentTintColor = Theme.proAccent
+
+        let proEyebrow = NSTextField(labelWithString: "Premium")
+        proEyebrow.font = .systemFont(ofSize: 11, weight: .heavy)
+        proEyebrow.textColor = Theme.proAccent
+        proEyebrow.alignment = .left
+
+        let eyebrowRow = NSStackView(views: [proIcon, proEyebrow])
+        eyebrowRow.orientation = .horizontal
+        eyebrowRow.spacing = 6
+        eyebrowRow.alignment = .centerY
+
+        let headline = NSTextField(labelWithString: "Upgrade to Pro")
+        headline.font = .systemFont(ofSize: 16, weight: .bold)
+        headline.textColor = Theme.primaryText
+        headline.alignment = .left
+
+        let upgradeDescription = NSTextField(wrappingLabelWithString: "Unlimited AI matches, smart alerts, and interview prep—all in one place.")
+        upgradeDescription.font = .systemFont(ofSize: 12, weight: .regular)
+        upgradeDescription.textColor = Theme.secondaryText
+        upgradeDescription.preferredMaxLayoutWidth = 165
+
+        let upgradeButton = NSButton(title: "Upgrade to Pro", target: self, action: #selector(didTapUpgradeToPro))
+        upgradeButton.isBordered = false
+        upgradeButton.bezelStyle = .rounded
+        upgradeButton.font = .systemFont(ofSize: 13, weight: .bold)
+        upgradeButton.contentTintColor = Theme.proCTAText
+        upgradeButton.wantsLayer = true
+        upgradeButton.layer?.backgroundColor = Theme.proCTABackground.cgColor
+        upgradeButton.layer?.cornerRadius = 20
+        upgradeButton.translatesAutoresizingMaskIntoConstraints = false
+        upgradeButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
+
+        inner.addArrangedSubview(eyebrowRow)
+        inner.addArrangedSubview(headline)
+        inner.addArrangedSubview(upgradeDescription)
+        inner.addArrangedSubview(upgradeButton)
+
+        upgradeCard.addSubview(accentBar)
+        upgradeCard.addSubview(inner)
+
+        let cardWidth: CGFloat = 197
+        NSLayoutConstraint.activate([
+            upgradeCard.widthAnchor.constraint(equalToConstant: cardWidth),
+
+            accentBar.topAnchor.constraint(equalTo: upgradeCard.topAnchor),
+            accentBar.leadingAnchor.constraint(equalTo: upgradeCard.leadingAnchor),
+            accentBar.trailingAnchor.constraint(equalTo: upgradeCard.trailingAnchor),
+            accentBar.heightAnchor.constraint(equalToConstant: 2),
+
+            inner.leadingAnchor.constraint(equalTo: upgradeCard.leadingAnchor, constant: 14),
+            inner.trailingAnchor.constraint(equalTo: upgradeCard.trailingAnchor, constant: -14),
+            inner.topAnchor.constraint(equalTo: accentBar.bottomAnchor, constant: 12),
+            inner.bottomAnchor.constraint(equalTo: upgradeCard.bottomAnchor, constant: -14),
+
+            upgradeButton.widthAnchor.constraint(equalTo: inner.widthAnchor)
+        ])
+
+        sidebar.addArrangedSubview(upgradeCard)
+    }
+
+    @objc private func didTapUpgradeToPro() {
+        guard let url = URL(string: "https://www.indeed.com") else { return }
+        NSWorkspace.shared.open(url)
     }
 
     private func updateDocumentLayout() {