|
@@ -109,6 +109,14 @@ struct CVTemplate: Hashable {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// Top-level gallery tab: expressive layouts for design-led roles vs. conservative ATS-friendly styles.
|
|
|
|
|
+ var galleryGroup: CVCategoryGroup {
|
|
|
|
|
+ switch family {
|
|
|
|
|
+ case .modern, .creative: return .designBased
|
|
|
|
|
+ case .minimal, .professional, .executive: return .professionBased
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
var themeColor: NSColor {
|
|
var themeColor: NSColor {
|
|
|
NSColor(srgbRed: themeRed, green: themeGreen, blue: themeBlue, alpha: 1)
|
|
NSColor(srgbRed: themeRed, green: themeGreen, blue: themeBlue, alpha: 1)
|
|
|
}
|
|
}
|
|
@@ -718,21 +726,23 @@ final class CVMakerPageView: NSView {
|
|
|
|
|
|
|
|
for family in CVDesignFamily.allCases {
|
|
for family in CVDesignFamily.allCases {
|
|
|
let count = templates(forGroup: selectedGroup, family: family).count
|
|
let count = templates(forGroup: selectedGroup, family: family).count
|
|
|
|
|
+ guard count > 0 else { continue }
|
|
|
let chip = CVChipButton(title: family.title, badgeText: "\(count)", leadingSymbol: nil, style: .pillSmall)
|
|
let chip = CVChipButton(title: family.title, badgeText: "\(count)", leadingSymbol: nil, style: .pillSmall)
|
|
|
chip.onSelect = { [weak self] in self?.didSelectFamily(family) }
|
|
chip.onSelect = { [weak self] in self?.didSelectFamily(family) }
|
|
|
familyChipsRow.addArrangedSubview(chip)
|
|
familyChipsRow.addArrangedSubview(chip)
|
|
|
familyChipButtons[family] = chip
|
|
familyChipButtons[family] = chip
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if let f = selectedFamily, templates(forGroup: selectedGroup, family: f).isEmpty {
|
|
|
|
|
+ selectedFamily = nil
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// MARK: Data filtering
|
|
// MARK: Data filtering
|
|
|
|
|
|
|
|
private func templates(forGroup group: CVCategoryGroup, family: CVDesignFamily?) -> [CVTemplate] {
|
|
private func templates(forGroup group: CVCategoryGroup, family: CVDesignFamily?) -> [CVTemplate] {
|
|
|
- // The catalog is design-driven; profession-based reuses the same templates
|
|
|
|
|
- // so the gallery is fully populated for both groups in this preview build.
|
|
|
|
|
- let base = activeCatalog
|
|
|
|
|
|
|
+ let base = activeCatalog.filter { $0.galleryGroup == group }
|
|
|
guard let family else { return base }
|
|
guard let family else { return base }
|
|
|
- _ = group
|
|
|
|
|
return base.filter { $0.family == family }
|
|
return base.filter { $0.family == family }
|
|
|
}
|
|
}
|
|
|
|
|
|