feat(resume): complete Epic 4 - Resume Content Strategy and Guidelines

- Update resume data with comprehensive professional summary and optimized work experience highlights
- Add resume content tech-spec and strategy documentation for 2025 best practices
- Create resume guidelines reference document for content consistency
- Enhance PDF composable with openPdf preview function alongside downloadPdf
- Expand CSS banner hiding rules to block certificates.dev promotional content
- Add research documentation on resume best practices and ATS optimization
- Update i18n translations for resume content in English and Persian
- Include sample Ali Arghyani resume PDF template in design assets
- Refactor resume.en.ts with improved professional positioning and achievement metrics
- Update API route documentation for PDF generation story artifacts
- Establish foundation for Epic 4 sprint planning with tech specifications
This commit is contained in:
mahdiarghyani
2025-12-02 12:54:26 +03:30
parent 43ad1bb5be
commit 9c40914d6a
20 changed files with 3889 additions and 123 deletions
+24 -26
View File
@@ -1,51 +1,49 @@
/**
* PDF Download Composable
* Handles PDF download logic with loading state and error handling
* Handles PDF generation with preview in new tab
*/
export function useResumePdf() {
const isGenerating = ref(false)
const toast = useToast()
const { getPdfFilename } = useResumeData()
async function downloadPdf() {
// Open PDF in new tab for preview (user can download from there)
async function openPdf() {
if (isGenerating.value) return
isGenerating.value = true
try {
// Fetch PDF as blob (AC1)
const response = await $fetch<Blob>('/api/resume/pdf', {
responseType: 'blob',
})
const filename = getPdfFilename()
// Opens PDF in browser's built-in viewer
window.open(`/api/resume/pdf?filename=${encodeURIComponent(filename)}`, '_blank')
// Create object URL from blob (AC2)
const url = URL.createObjectURL(response)
await new Promise((resolve) => setTimeout(resolve, 1500))
} finally {
isGenerating.value = false
}
}
// Create temporary anchor element and trigger download
const a = document.createElement('a')
a.href = url
a.download = getPdfFilename() // AC3: filename from composable
a.click()
// Force download PDF directly
async function downloadPdf() {
if (isGenerating.value) return
// Revoke object URL to prevent memory leaks (AC8)
URL.revokeObjectURL(url)
} catch (error) {
// Error handling (AC6)
console.error('PDF generation failed:', error)
isGenerating.value = true
toast.add({
title: 'Error generating PDF',
description: 'Please try again',
color: 'error',
})
try {
const filename = getPdfFilename()
// download=true forces attachment header
window.open(`/api/resume/pdf?filename=${encodeURIComponent(filename)}&download=true`, '_blank')
await new Promise((resolve) => setTimeout(resolve, 1500))
} finally {
// Always reset loading state (AC7)
isGenerating.value = false
}
}
// Return composable interface (AC4, AC5)
return {
isGenerating,
openPdf,
downloadPdf,
}
}