Ver código fonte

Improve CV template mini preview demo content and dedupe layout logic

Expand CVPreviewDemoContent with experienceRole, education years, a third
bullet, career highlights, and a shared tools line so thumbnails read fuller
and avoid repeating the header title in experience blocks.

Reuse toolsLine in professional and executive sidebars; align modern
highlights with non-overlapping copy; add bullets and education where layouts
were thin.

Refactor CVMakerPageView grid relayout to use resolvedGridColumnCount only,
removing duplicated breakpoint math.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 3 semanas atrás
pai
commit
694f5cc6b4

+ 1 - 5
App for Indeed/Views/CVMakerPageView.swift

@@ -803,11 +803,7 @@ final class CVMakerPageView: NSView {
803 803
     }
804 804
 
805 805
     private func layoutGridCardsIfNeeded() {
806
-        let w = max(galleryLayoutWidth(), 400)
807
-        let cols: Int
808
-        if w < 780 { cols = 2 }
809
-        else if w < 1080 { cols = 3 }
810
-        else { cols = 4 }
806
+        let cols = resolvedGridColumnCount()
811 807
         guard cols != appliedGridColumnCount else { return }
812 808
         appliedGridColumnCount = cols
813 809
         reloadTemplateGrid()

+ 27 - 13
App for Indeed/Views/CVTemplateMiniPreview.swift

@@ -32,17 +32,26 @@ struct CVTemplateCardPalette {
32 32
 
33 33
 fileprivate enum CVPreviewDemoContent {
34 34
     static let fullName = "Sarah Johnson"
35
+    /// Shown in the header / contact band (broad role).
35 36
     static let title = "Senior Product Manager"
37
+    /// Scoped title under Experience so it is not a verbatim repeat of the header line.
38
+    static let experienceRole = "Group PM, Consumer Growth & Activation"
36 39
     static let company = "Google"
37 40
     static let companyLine = "Google · Mountain View, CA · 2019 – Present"
38 41
     static let university = "Stanford University"
39 42
     static let degree = "M.S. Management Science & Engineering"
43
+    static let educationYears = "2014 – 2016"
40 44
     static let email = "sarah.johnson@email.com"
41 45
     static let phone = "(415) 555-0198"
42 46
     static let location = "Mountain View, CA"
43 47
     static let summary = "Product leader shipping roadmap, discovery, and analytics for high-scale consumer experiences."
44 48
     static let bullet1 = "Defined multi-year platform strategy with exec stakeholders and quarterly OKRs."
45 49
     static let bullet2 = "Partnered with engineering and design to launch experiments improving activation by 12%."
50
+    static let bullet3 = "Stood up quarterly business reviews with finance and GTM, aligning spend to north-star metrics."
51
+    /// Sidebar “highlights” blurb kept distinct from the experience bullets.
52
+    static let careerHighlights = "Presented roadmap shifts to the leadership team and translated trade-offs into clear investment asks."
53
+    /// Single tools line reused wherever the résumé lists a stack (avoids scattered near-duplicate strings).
54
+    static let toolsLine = "Figma · SQL · Amplitude · Jira · BigQuery"
46 55
     static let skillsList = ["Product Strategy", "SQL", "Figma", "A/B Testing", "Roadmapping"]
47 56
 }
48 57
 
@@ -300,7 +309,7 @@ final class CVTemplatePreviewView: NSView {
300 309
         }
301 310
         if variant % 7 == 3 {
302 311
             inner.addArrangedSubview(sectionHeading("TOOLS"))
303
-            inner.addArrangedSubview(makeLabel("Amplitude · Jira · BigQuery", font: .systemFont(ofSize: 5.9), color: palette.previewMuted, alignment: .left, maxLines: 1))
312
+            inner.addArrangedSubview(makeLabel(CVPreviewDemoContent.toolsLine, font: .systemFont(ofSize: 5.9), color: palette.previewMuted, alignment: .left, maxLines: 1))
304 313
         }
305 314
         box.addArrangedSubview(inner)
306 315
         return box
@@ -319,10 +328,11 @@ final class CVTemplatePreviewView: NSView {
319 328
         }
320 329
         let experienceBlock: () -> Void = {
321 330
             stack.addArrangedSubview(self.sectionHeading("EXPERIENCE"))
322
-            stack.addArrangedSubview(self.makeLabel(CVPreviewDemoContent.title, font: .systemFont(ofSize: 6.8, weight: .semibold), color: self.palette.previewInk, alignment: .left, maxLines: 1))
331
+            stack.addArrangedSubview(self.makeLabel(CVPreviewDemoContent.experienceRole, font: .systemFont(ofSize: 6.8, weight: .semibold), color: self.palette.previewInk, alignment: .left, maxLines: 1))
323 332
             stack.addArrangedSubview(self.makeLabel(CVPreviewDemoContent.companyLine, font: .systemFont(ofSize: 6.2, weight: .medium), color: self.template.themeColor, alignment: .left, maxLines: 1))
324 333
             stack.addArrangedSubview(self.bulletRow(CVPreviewDemoContent.bullet1, size: sp))
325 334
             stack.addArrangedSubview(self.bulletRow(CVPreviewDemoContent.bullet2, size: sp))
335
+            stack.addArrangedSubview(self.bulletRow(CVPreviewDemoContent.bullet3, size: sp))
326 336
         }
327 337
 
328 338
         if experienceFirst {
@@ -334,7 +344,7 @@ final class CVTemplatePreviewView: NSView {
334 344
         }
335 345
         stack.addArrangedSubview(sectionHeading("EDUCATION"))
336 346
         stack.addArrangedSubview(makeLabel(CVPreviewDemoContent.university, font: .systemFont(ofSize: 6.6, weight: .semibold), color: palette.previewInk, alignment: .left, maxLines: 1))
337
-        stack.addArrangedSubview(makeLabel(CVPreviewDemoContent.degree, font: .systemFont(ofSize: 6.2), color: palette.previewMuted, alignment: .left, maxLines: 2))
347
+        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.degree) · \(CVPreviewDemoContent.educationYears)", font: .systemFont(ofSize: 6.2), color: palette.previewMuted, alignment: .left, maxLines: 2))
338 348
         return stack
339 349
     }
340 350
 
@@ -508,7 +518,7 @@ final class CVTemplatePreviewView: NSView {
508 518
         box.addArrangedSubview(modernSectionRow(symbol: "person.crop.circle", title: "About", theme: theme))
509 519
         box.addArrangedSubview(makeLabel(CVPreviewDemoContent.summary, font: .systemFont(ofSize: 6), color: palette.previewInk, alignment: .left, maxLines: 4))
510 520
         box.addArrangedSubview(modernSectionRow(symbol: "star.fill", title: "Highlights", theme: theme))
511
-        box.addArrangedSubview(makeLabel("Launched growth experiments, SQL deep dives, design QA.", font: .systemFont(ofSize: 6), color: palette.previewMuted, alignment: .left, maxLines: 3))
521
+        box.addArrangedSubview(makeLabel(CVPreviewDemoContent.careerHighlights, font: .systemFont(ofSize: 6), color: palette.previewMuted, alignment: .left, maxLines: 3))
512 522
         return box
513 523
     }
514 524
 
@@ -533,11 +543,11 @@ final class CVTemplatePreviewView: NSView {
533 543
         stack.spacing = 5
534 544
         stack.alignment = .leading
535 545
         stack.addArrangedSubview(modernSectionRow(symbol: "briefcase.fill", title: "Experience", theme: theme))
536
-        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.title) — \(CVPreviewDemoContent.company)", font: .systemFont(ofSize: 6.6, weight: .semibold), color: palette.previewInk, alignment: .left, maxLines: 2))
537
-        stack.addArrangedSubview(makeLabel("2019 – Present · Led cross-functional pods from discovery to launch.", font: .systemFont(ofSize: 6.1), color: palette.previewMuted, alignment: .left, maxLines: 2))
546
+        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.experienceRole) — \(CVPreviewDemoContent.company)", font: .systemFont(ofSize: 6.6, weight: .semibold), color: palette.previewInk, alignment: .left, maxLines: 2))
547
+        stack.addArrangedSubview(makeLabel("2019 – Present · Led cross-functional pods from discovery through launch and post-ship learning.", font: .systemFont(ofSize: 6.1), color: palette.previewMuted, alignment: .left, maxLines: 2))
538 548
         stack.addArrangedSubview(tagRow(theme: theme))
539 549
         stack.addArrangedSubview(modernSectionRow(symbol: "graduationcap.fill", title: "Education", theme: theme))
540
-        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.university), \(CVPreviewDemoContent.degree)", font: .systemFont(ofSize: 6.2), color: palette.previewInk, alignment: .left, maxLines: 2))
550
+        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.university), \(CVPreviewDemoContent.degree) (\(CVPreviewDemoContent.educationYears))", font: .systemFont(ofSize: 6.2), color: palette.previewInk, alignment: .left, maxLines: 2))
541 551
         return stack
542 552
     }
543 553
 
@@ -636,7 +646,7 @@ final class CVTemplatePreviewView: NSView {
636 646
 
637 647
         let edu: () -> Void = {
638 648
             stack.addArrangedSubview(self.sectionHeading("EDUCATION"))
639
-            stack.addArrangedSubview(self.makeLabel("\(CVPreviewDemoContent.university) — \(CVPreviewDemoContent.degree)", font: .systemFont(ofSize: 6.1, weight: .light), color: self.palette.previewInk, alignment: .left, maxLines: 2))
649
+            stack.addArrangedSubview(self.makeLabel("\(CVPreviewDemoContent.university) — \(CVPreviewDemoContent.degree) · \(CVPreviewDemoContent.educationYears)", font: .systemFont(ofSize: 6.1, weight: .light), color: self.palette.previewInk, alignment: .left, maxLines: 2))
640 650
         }
641 651
         let prof: () -> Void = {
642 652
             stack.addArrangedSubview(self.sectionHeading("PROFILE"))
@@ -644,8 +654,9 @@ final class CVTemplatePreviewView: NSView {
644 654
         }
645 655
         let exp: () -> Void = {
646 656
             stack.addArrangedSubview(self.sectionHeading("EXPERIENCE"))
647
-            stack.addArrangedSubview(self.makeLabel("\(CVPreviewDemoContent.title), \(CVPreviewDemoContent.company)", font: .systemFont(ofSize: 6.5, weight: .regular), color: self.palette.previewInk, alignment: .left, maxLines: 2))
657
+            stack.addArrangedSubview(self.makeLabel("\(CVPreviewDemoContent.experienceRole) · \(CVPreviewDemoContent.company)", font: .systemFont(ofSize: 6.5, weight: .regular), color: self.palette.previewInk, alignment: .left, maxLines: 2))
648 658
             stack.addArrangedSubview(self.makeLabel(CVPreviewDemoContent.bullet1, font: .systemFont(ofSize: 6, weight: .light), color: self.palette.previewMuted, alignment: .left, maxLines: 2))
659
+            stack.addArrangedSubview(self.makeLabel(CVPreviewDemoContent.bullet2, font: .systemFont(ofSize: 6, weight: .light), color: self.palette.previewMuted, alignment: .left, maxLines: 2))
649 660
         }
650 661
 
651 662
         if educationBeforeExperience {
@@ -744,11 +755,12 @@ final class CVTemplatePreviewView: NSView {
744 755
         stack.addArrangedSubview(makeLabel(CVPreviewDemoContent.summary, font: serif, color: ink, alignment: .left, maxLines: 3))
745 756
         stack.addArrangedSubview(sectionHeading("SELECTED EXPERIENCE"))
746 757
         let jobFont = NSFontManager.shared.convert(serif, toHaveTrait: .boldFontMask)
747
-        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.title), \(CVPreviewDemoContent.company)", font: jobFont, color: ink, alignment: .left, maxLines: 2))
758
+        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.experienceRole), \(CVPreviewDemoContent.company)", font: jobFont, color: ink, alignment: .left, maxLines: 2))
748 759
         stack.addArrangedSubview(makeLabel("2019 – Present", font: serif, color: theme, alignment: .left, maxLines: 1))
749 760
         stack.addArrangedSubview(makeLabel(CVPreviewDemoContent.bullet1, font: serif, color: muted, alignment: .left, maxLines: 2))
761
+        stack.addArrangedSubview(makeLabel(CVPreviewDemoContent.bullet2, font: serif, color: muted, alignment: .left, maxLines: 2))
750 762
         stack.addArrangedSubview(sectionHeading("EDUCATION"))
751
-        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.university), \(CVPreviewDemoContent.degree)", font: serif, color: ink, alignment: .left, maxLines: 2))
763
+        stack.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.university), \(CVPreviewDemoContent.degree) · \(CVPreviewDemoContent.educationYears)", font: serif, color: ink, alignment: .left, maxLines: 2))
752 764
         return stack
753 765
     }
754 766
 
@@ -771,7 +783,7 @@ final class CVTemplatePreviewView: NSView {
771 783
             stack.addArrangedSubview(makeLabel("· \(s)", font: serif, color: palette.previewInk, alignment: .left, maxLines: 1))
772 784
         }
773 785
         stack.addArrangedSubview(sectionHeading("TOOLS"))
774
-        stack.addArrangedSubview(makeLabel("Figma, SQL, Amplitude, Jira", font: serif, color: palette.previewMuted, alignment: .left, maxLines: 2))
786
+        stack.addArrangedSubview(makeLabel(CVPreviewDemoContent.toolsLine, font: serif, color: palette.previewMuted, alignment: .left, maxLines: 2))
775 787
         if showMetrics {
776 788
             stack.addArrangedSubview(sectionHeading("IMPACT"))
777 789
             stack.addArrangedSubview(makeLabel("+12% activation · $4.2M ARR influenced", font: serif, color: palette.previewInk, alignment: .left, maxLines: 2))
@@ -814,10 +826,12 @@ final class CVTemplatePreviewView: NSView {
814 826
         main.addArrangedSubview(sectionHeading("PROFILE"))
815 827
         main.addArrangedSubview(makeLabel(CVPreviewDemoContent.summary, font: .systemFont(ofSize: 6.2), color: palette.previewInk, alignment: .left, maxLines: 3))
816 828
         main.addArrangedSubview(sectionHeading("IMPACT"))
817
-        main.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.company) — \(CVPreviewDemoContent.title)", font: .systemFont(ofSize: 6.6, weight: .heavy), color: palette.previewInk, alignment: .left, maxLines: 2))
829
+        main.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.company) — \(CVPreviewDemoContent.experienceRole)", font: .systemFont(ofSize: 6.6, weight: .heavy), color: palette.previewInk, alignment: .left, maxLines: 2))
818 830
         let bMark = (idVariant % 2 == 0) ? "—  " : "▸  "
819 831
         main.addArrangedSubview(makeLabel("\(bMark)\(CVPreviewDemoContent.bullet1)", font: .systemFont(ofSize: 6), color: palette.previewMuted, alignment: .left, maxLines: 2))
820 832
         main.addArrangedSubview(makeLabel("\(bMark)\(CVPreviewDemoContent.bullet2)", font: .systemFont(ofSize: 6), color: palette.previewMuted, alignment: .left, maxLines: 2))
833
+        main.addArrangedSubview(sectionHeading("EDUCATION"))
834
+        main.addArrangedSubview(makeLabel("\(CVPreviewDemoContent.university) · \(CVPreviewDemoContent.degree) · \(CVPreviewDemoContent.educationYears)", font: .systemFont(ofSize: 6.1), color: palette.previewInk, alignment: .left, maxLines: 2))
821 835
 
822 836
         let sidebarMult = 0.32 + CGFloat(idVariant % 3) * 0.02
823 837