Explorar el Código

CV gallery: split templates by design vs profession; quiet window restore

- Map template families to design-based vs profession-based groups and
  filter the CV maker gallery accordingly; hide empty family chips.
- Extend catalog prompts so modern/creative vs minimal/professional/
  executive content matches each gallery tab.
- Set isRestorable false on main and premium windows and opt out of
  secure restorable state until real NSWindowRestoration is implemented,
  avoiding null className restoration warnings.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 hace 3 semanas
padre
commit
2c81504214

+ 4 - 1
App for Indeed/AppDelegate.swift

@@ -53,6 +53,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
53
 
53
 
54
             window.minSize = self.minimumWindowSize
54
             window.minSize = self.minimumWindowSize
55
             window.setContentSize(self.minimumWindowSize)
55
             window.setContentSize(self.minimumWindowSize)
56
+            // Prevents "className=(null)" restoration warnings; layout is applied each launch.
57
+            window.isRestorable = false
56
             window.title = "App for Indeed"
58
             window.title = "App for Indeed"
57
             window.styleMask.insert(.fullSizeContentView)
59
             window.styleMask.insert(.fullSizeContentView)
58
             window.titlebarAppearsTransparent = true
60
             window.titlebarAppearsTransparent = true
@@ -68,7 +70,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
68
     }
70
     }
69
 
71
 
70
     func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
72
     func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
71
-        return true
73
+        // Opt out until real `NSWindowRestoration` is implemented (avoids null className restore logs).
74
+        return false
72
     }
75
     }
73
 
76
 
74
 
77
 

+ 1 - 0
App for Indeed/Controllers/PremiumPlansWindowController.swift

@@ -16,6 +16,7 @@ final class PremiumPlansWindowController: NSWindowController {
16
         window.backgroundColor = Self.paywallSheetBackground
16
         window.backgroundColor = Self.paywallSheetBackground
17
         window.setContentSize(NSSize(width: 1160, height: 760))
17
         window.setContentSize(NSSize(width: 1160, height: 760))
18
         window.minSize = NSSize(width: 980, height: 680)
18
         window.minSize = NSSize(width: 980, height: 680)
19
+        window.isRestorable = false
19
         window.center()
20
         window.center()
20
         super.init(window: window)
21
         super.init(window: window)
21
     }
22
     }

+ 4 - 1
App for Indeed/Services/CVTemplateFetchService.swift

@@ -26,11 +26,14 @@ final class CVTemplateFetchService {
26
         Use creative but professional names; do not copy real commercial template trademarks. \
26
         Use creative but professional names; do not copy real commercial template trademarks. \
27
         Vary `headline`, `accent`, `layoutType`, `sidebarSide`, `sidebarTinted`, and `sectionLabelStyle` across the set — do not repeat \
27
         Vary `headline`, `accent`, `layoutType`, `sidebarSide`, `sidebarTinted`, and `sectionLabelStyle` across the set — do not repeat \
28
         the same six-tuple of those fields on consecutive rows. \
28
         the same six-tuple of those fields on consecutive rows. \
29
+        Niche split for the in-app gallery: `modern` and `creative` families are shown under Design-Based (portfolio / UX / visual roles); \
30
+        `minimal`, `professional`, and `executive` appear under Profession-Based (ATS-friendly / corporate / leadership). \
29
         Output must strictly match the JSON schema — no markdown or extra keys.
31
         Output must strictly match the JSON schema — no markdown or extra keys.
30
         """
32
         """
31
         static let userInput = """
33
         static let userInput = """
32
         Generate the template catalog now. Exactly six entries per family: professional, modern, creative, minimal, executive. \
34
         Generate the template catalog now. Exactly six entries per family: professional, modern, creative, minimal, executive. \
33
-        Use both singleColumn and twoColumn layouts across the 30 rows. For twoColumn rows vary leading vs trailing sidebars and tinted true/false.
35
+        Use both singleColumn and twoColumn layouts across the 30 rows. For twoColumn rows vary leading vs trailing sidebars and tinted true/false. \
36
+        Keep modern and creative entries suitable for design-led résumés; keep minimal, professional, and executive suitable for traditional industries.
34
         """
37
         """
35
     }
38
     }
36
 
39
 

+ 14 - 4
App for Indeed/Views/CVMakerPageView.swift

@@ -109,6 +109,14 @@ struct CVTemplate: Hashable {
109
         }
109
         }
110
     }
110
     }
111
 
111
 
112
+    /// Top-level gallery tab: expressive layouts for design-led roles vs. conservative ATS-friendly styles.
113
+    var galleryGroup: CVCategoryGroup {
114
+        switch family {
115
+        case .modern, .creative: return .designBased
116
+        case .minimal, .professional, .executive: return .professionBased
117
+        }
118
+    }
119
+
112
     var themeColor: NSColor {
120
     var themeColor: NSColor {
113
         NSColor(srgbRed: themeRed, green: themeGreen, blue: themeBlue, alpha: 1)
121
         NSColor(srgbRed: themeRed, green: themeGreen, blue: themeBlue, alpha: 1)
114
     }
122
     }
@@ -718,21 +726,23 @@ final class CVMakerPageView: NSView {
718
 
726
 
719
         for family in CVDesignFamily.allCases {
727
         for family in CVDesignFamily.allCases {
720
             let count = templates(forGroup: selectedGroup, family: family).count
728
             let count = templates(forGroup: selectedGroup, family: family).count
729
+            guard count > 0 else { continue }
721
             let chip = CVChipButton(title: family.title, badgeText: "\(count)", leadingSymbol: nil, style: .pillSmall)
730
             let chip = CVChipButton(title: family.title, badgeText: "\(count)", leadingSymbol: nil, style: .pillSmall)
722
             chip.onSelect = { [weak self] in self?.didSelectFamily(family) }
731
             chip.onSelect = { [weak self] in self?.didSelectFamily(family) }
723
             familyChipsRow.addArrangedSubview(chip)
732
             familyChipsRow.addArrangedSubview(chip)
724
             familyChipButtons[family] = chip
733
             familyChipButtons[family] = chip
725
         }
734
         }
735
+
736
+        if let f = selectedFamily, templates(forGroup: selectedGroup, family: f).isEmpty {
737
+            selectedFamily = nil
738
+        }
726
     }
739
     }
727
 
740
 
728
     // MARK: Data filtering
741
     // MARK: Data filtering
729
 
742
 
730
     private func templates(forGroup group: CVCategoryGroup, family: CVDesignFamily?) -> [CVTemplate] {
743
     private func templates(forGroup group: CVCategoryGroup, family: CVDesignFamily?) -> [CVTemplate] {
731
-        // The catalog is design-driven; profession-based reuses the same templates
732
-        // so the gallery is fully populated for both groups in this preview build.
733
-        let base = activeCatalog
744
+        let base = activeCatalog.filter { $0.galleryGroup == group }
734
         guard let family else { return base }
745
         guard let family else { return base }
735
-        _ = group
736
         return base.filter { $0.family == family }
746
         return base.filter { $0.family == family }
737
     }
747
     }
738
 
748