From 56676771cab56baabc30793aa5ea59d726c9e285 Mon Sep 17 00:00:00 2001 From: mahdiarghyani Date: Mon, 1 Dec 2025 11:46:46 +0330 Subject: [PATCH] feat(resume): complete Epic 2 - Resume Preview Page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Epic 2: Resume Preview Page - All 5 stories completed Story 2-1: Create Resume Page Route - Add /resume standalone page with layout: false - Implement print mode detection (?print=true) - Add SEO meta tags (noindex for privacy) - Set page title "Resume - Ali Arghyani" Story 2-2: Create ResumePreview Container - Add single-column A4 container (210mm × 297mm) - Implement white background with 24px margins - Add print styles with .no-print class - Configure responsive layout Story 2-3: Create Header, Summary, Experience Components - Add ResumeHeader with profile photo, name, contact info - Add ResumeSummary with blue uppercase section header - Add ResumeExperience with sorted jobs and date formatting - Add image property to ResumeBasics interface - Integrate all components into ResumePreview Story 2-4: Create Education & Additional Info Components - Add ResumeEducation with date formatting - Add ResumeAdditionalInfo with skills, languages, certifications - Integrate components into ResumePreview Story 2-5: Create Download Button Component - Add ResumeDownloadButton FAB (fixed bottom-right) - Add download icon and "Download PDF" text - Implement print mode detection - Add placeholder click handler for Epic 3 integration - Responsive: text on desktop, icon-only on mobile Additional: - Add profile image to resume data (/img/AliProfile.webp) - Update sprint-status.yaml: all Epic 2 stories marked done Files Created: - app/pages/resume.vue - app/components/resume/ResumePreview.vue - app/components/resume/ResumeHeader.vue - app/components/resume/ResumeSummary.vue - app/components/resume/ResumeExperience.vue - app/components/resume/ResumeEducation.vue - app/components/resume/ResumeAdditionalInfo.vue - app/components/resume/ResumeDownloadButton.vue Files Modified: - app/types/resume.ts (added image property) - app/data/resume.en.ts (added profile image) - docs/sprint-artifacts/sprint-status.yaml (updated story statuses) - docs/sprint-artifacts/2-1-create-resume-page-route.md (completed) - docs/sprint-artifacts/2-2-create-resume-preview-container-component.md (completed) - docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md (completed) - docs/sprint-artifacts/2-4-create-resume-sidebar-components.md (completed) - docs/sprint-artifacts/2-5-create-download-button-component.md (completed) Closes Epic 2 Closes Story 2-1, 2-2, 2-3, 2-4, 2-5 --- .../resume/ResumeAdditionalInfo.vue | 49 +++++++++ .../resume/ResumeDownloadButton.vue | 29 +++++ app/components/resume/ResumeEducation.vue | 36 ++++++ app/components/resume/ResumeExperience.vue | 50 +++++++++ app/components/resume/ResumeHeader.vue | 32 ++++++ app/components/resume/ResumePreview.vue | 103 ++---------------- app/components/resume/ResumeSummary.vue | 16 +++ app/data/resume.en.ts | 1 + app/pages/resume.vue | 4 +- app/types/resume.ts | 1 + ...e-resume-header-main-content-components.md | 87 ++++++++------- .../2-4-create-resume-sidebar-components.md | 66 ++++++----- .../2-5-create-download-button-component.md | 74 +++++++------ docs/sprint-artifacts/sprint-status.yaml | 6 +- 14 files changed, 353 insertions(+), 201 deletions(-) create mode 100644 app/components/resume/ResumeAdditionalInfo.vue create mode 100644 app/components/resume/ResumeDownloadButton.vue create mode 100644 app/components/resume/ResumeEducation.vue create mode 100644 app/components/resume/ResumeExperience.vue create mode 100644 app/components/resume/ResumeHeader.vue create mode 100644 app/components/resume/ResumeSummary.vue diff --git a/app/components/resume/ResumeAdditionalInfo.vue b/app/components/resume/ResumeAdditionalInfo.vue new file mode 100644 index 0000000..84b7b7d --- /dev/null +++ b/app/components/resume/ResumeAdditionalInfo.vue @@ -0,0 +1,49 @@ + + + diff --git a/app/components/resume/ResumeDownloadButton.vue b/app/components/resume/ResumeDownloadButton.vue new file mode 100644 index 0000000..c01b441 --- /dev/null +++ b/app/components/resume/ResumeDownloadButton.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/app/components/resume/ResumeEducation.vue b/app/components/resume/ResumeEducation.vue new file mode 100644 index 0000000..0afd5a4 --- /dev/null +++ b/app/components/resume/ResumeEducation.vue @@ -0,0 +1,36 @@ + + + diff --git a/app/components/resume/ResumeExperience.vue b/app/components/resume/ResumeExperience.vue new file mode 100644 index 0000000..2728be8 --- /dev/null +++ b/app/components/resume/ResumeExperience.vue @@ -0,0 +1,50 @@ + + + diff --git a/app/components/resume/ResumeHeader.vue b/app/components/resume/ResumeHeader.vue new file mode 100644 index 0000000..7070c1e --- /dev/null +++ b/app/components/resume/ResumeHeader.vue @@ -0,0 +1,32 @@ + + + diff --git a/app/components/resume/ResumePreview.vue b/app/components/resume/ResumePreview.vue index 33d077e..9406748 100644 --- a/app/components/resume/ResumePreview.vue +++ b/app/components/resume/ResumePreview.vue @@ -9,102 +9,21 @@ const { resume } = useResumeData() class="resume-container bg-white shadow-lg max-w-[210mm] min-h-[297mm] w-full print:shadow-none print:max-w-none">
- -
-

{{ resume.basics.name }}

-

{{ resume.basics.label }}

-

- {{ resume.basics.location.city }}, {{ resume.basics.location.country }} | - {{ resume.basics.email }} | {{ resume.basics.phone }} -

-
+ + - -
-

- Summary -

-

{{ resume.basics.summary }}

-
+ + - -
-

- Work Experience -

-
-
-
-

{{ job.position }}

-

{{ job.company }}

-
- - {{ job.startDate }} - {{ job.endDate || 'Present' }} - -
-
    -
  • - {{ highlight }} -
  • -
-
-
+ + - -
-

- Education -

-
-
-
-

{{ edu.studyType }} in {{ edu.area }}

-

{{ edu.institution }}

-
- - {{ edu.startDate }} - {{ edu.endDate || 'Present' }} - -
-
-
+ + - -
-

- Additional Information -

- - -
- Technical Skills: - - - -
- - -
- Languages: - - - -
- - -
- Certifications: - - - -
-
+ +
diff --git a/app/components/resume/ResumeSummary.vue b/app/components/resume/ResumeSummary.vue new file mode 100644 index 0000000..c1c7094 --- /dev/null +++ b/app/components/resume/ResumeSummary.vue @@ -0,0 +1,16 @@ + + + diff --git a/app/data/resume.en.ts b/app/data/resume.en.ts index 16d7dd9..0b29fb9 100644 --- a/app/data/resume.en.ts +++ b/app/data/resume.en.ts @@ -13,6 +13,7 @@ export const resumeData: Resume = { email: 'ali@example.com', phone: '+98 912 345 6789', url: 'https://aliarghyani.com', + image: '/img/AliProfile.webp', location: { city: 'Tehran', country: 'Iran', diff --git a/app/pages/resume.vue b/app/pages/resume.vue index 5b3edf3..31537e1 100644 --- a/app/pages/resume.vue +++ b/app/pages/resume.vue @@ -17,8 +17,6 @@ useHead({ diff --git a/app/types/resume.ts b/app/types/resume.ts index aa3bf2c..cf651ad 100644 --- a/app/types/resume.ts +++ b/app/types/resume.ts @@ -10,6 +10,7 @@ export interface ResumeBasics { email: string phone: string url?: string + image?: string // Profile photo URL location: { city: string country: string diff --git a/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md b/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md index 1cb48d8..32a73ae 100644 --- a/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md +++ b/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md @@ -1,6 +1,6 @@ # Story 2.3: Create Resume Header & Main Content Components -Status: ready-for-dev +Status: done ## Story @@ -31,53 +31,53 @@ so that recruiters see the most important information first. ## Tasks / Subtasks -- [ ] Create ResumeHeader component (AC: #1-#6) - - [ ] Create `app/components/resume/ResumeHeader.vue` - - [ ] Accept props: `basics` (ResumeBasics) - includes name, label, email, phone, location, url, image - - [ ] Display profile photo (if provided) with proper sizing (150px max width) - - [ ] Display name with `text-3xl font-bold` (2rem) - - [ ] Display job title with `text-xl text-gray-600` (1.25rem) - - [ ] Display address, phone, email, website in structured format - - [ ] Make email, phone, website clickable with proper href attributes - - [ ] Use horizontal layout: photo left, info right +- [x] Create ResumeHeader component (AC: #1-#6) + - [x] Create `app/components/resume/ResumeHeader.vue` + - [x] Accept props: `basics` (ResumeBasics) - includes name, label, email, phone, location, url, image + - [x] Display profile photo (if provided) with proper sizing (150px max width) + - [x] Display name with `text-3xl font-bold` (2rem) + - [x] Display job title with `text-xl text-gray-600` (1.25rem) + - [x] Display address, phone, email, website in structured format + - [x] Make email, phone, website clickable with proper href attributes + - [x] Use horizontal layout: photo left, info right -- [ ] Create ResumeSummary component (AC: #7-#9) - - [ ] Create `app/components/resume/ResumeSummary.vue` - - [ ] Accept props: `summary` (string) - - [ ] Add section header "SUMMARY" with blue, uppercase, bold styling - - [ ] Add blue bottom border to header: `border-b-2 border-blue-600` - - [ ] Display summary paragraph with `leading-relaxed` (line-height: 1.6) - - [ ] Use `text-sm text-gray-800` +- [x] Create ResumeSummary component (AC: #7-#9) + - [x] Create `app/components/resume/ResumeSummary.vue` + - [x] Accept props: `summary` (string) + - [x] Add section header "SUMMARY" with blue, uppercase, bold styling + - [x] Add blue bottom border to header: `border-b-2 border-blue-600` + - [x] Display summary paragraph with `leading-relaxed` (line-height: 1.6) + - [x] Use `text-sm text-gray-800` -- [ ] Create ResumeExperience component (AC: #10-#13) - - [ ] Create `app/components/resume/ResumeExperience.vue` - - [ ] Accept props: `work` (WorkExperience[]) - - [ ] Add section header "WORK EXPERIENCE" with blue, uppercase, bold styling - - [ ] Add blue bottom border to header: `border-b-2 border-blue-600` - - [ ] Sort jobs by startDate (most recent first) - - [ ] For each job, display: +- [x] Create ResumeExperience component (AC: #10-#13) + - [x] Create `app/components/resume/ResumeExperience.vue` + - [x] Accept props: `work` (WorkExperience[]) + - [x] Add section header "WORK EXPERIENCE" with blue, uppercase, bold styling + - [x] Add blue bottom border to header: `border-b-2 border-blue-600` + - [x] Sort jobs by startDate (most recent first) + - [x] For each job, display: - Position title: `font-semibold text-gray-900` (left-aligned) - Company name: `text-gray-700` - Date range: Use `formatDate()` helper from composable (right-aligned) - Highlights: `