mirror of
https://github.com/mmahdium/portfolio.git
synced 2026-09-28 02:21:41 +03:30
feat(resume): enhance print styling and refactor component structure
- Add print media queries to main.css for proper PDF export formatting - Ensure white background and light color scheme when printing - Refactor ResumeAdditionalInfo component to display skills in categorized format - Remove languages and certifications from additional info section - Add ResumeLanguages component for dedicated language display - Optimize spacing with print-specific margin utilities across all resume sections - Improve text wrapping and hyphenation in ResumeExperience component - Enhance ResumeHeader layout with print-optimized image sizing - Update resume data structure to support new component organization - Add research documentation on mentioning AI skills in resume - Update PDF export endpoint to work with refactored component structure - Remove outdated chat history file
This commit is contained in:
@@ -89,6 +89,16 @@
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
@media print {
|
||||
html,
|
||||
body,
|
||||
#__nuxt,
|
||||
#__layout {
|
||||
background: white !important;
|
||||
min-height: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dark html,
|
||||
.dark body,
|
||||
.dark #__nuxt,
|
||||
@@ -106,6 +116,18 @@
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
@media print {
|
||||
:root.dark #__nuxt,
|
||||
:root.dark #__layout,
|
||||
html.dark,
|
||||
html.dark body,
|
||||
html.dark #__nuxt,
|
||||
html.dark #__layout {
|
||||
background: white !important;
|
||||
color-scheme: light !important;
|
||||
}
|
||||
}
|
||||
|
||||
div,
|
||||
span,
|
||||
input,
|
||||
|
||||
@@ -1,54 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import type { Skill, Language, Certification } from '~/types/resume'
|
||||
import type { Skill } from '~/types/resume'
|
||||
|
||||
interface Props {
|
||||
skills: Skill[]
|
||||
languages?: Language[]
|
||||
certifications?: Certification[]
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
// Get only key technical skills (first 3 categories)
|
||||
const keySkills = computed(() => {
|
||||
return props.skills.slice(0, 3)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<section class="mb-6 print:mb-4">
|
||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-3">
|
||||
Additional Information
|
||||
Skills & Qualifications
|
||||
</h2>
|
||||
|
||||
<!-- Key Technical Skills (simplified) -->
|
||||
<div v-if="keySkills?.length" class="mb-3">
|
||||
<span class="text-sm font-semibold text-gray-800">Technical Skills: </span>
|
||||
<span class="text-sm text-gray-700">
|
||||
<template v-for="(skill, idx) in keySkills" :key="skill.name">
|
||||
{{ skill.keywords.join(', ') }}<template v-if="idx < keySkills.length - 1">; </template>
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Languages -->
|
||||
<div v-if="languages?.length" class="mb-2">
|
||||
<span class="text-sm font-semibold text-gray-800">Languages: </span>
|
||||
<span class="text-sm text-gray-700">
|
||||
<template v-for="(lang, idx) in languages" :key="lang.language">
|
||||
{{ lang.language }} ({{ lang.fluency }})<template v-if="idx < languages.length - 1">, </template>
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Certifications -->
|
||||
<div v-if="certifications?.length">
|
||||
<span class="text-sm font-semibold text-gray-800">Certifications: </span>
|
||||
<span class="text-sm text-gray-700">
|
||||
<template v-for="(cert, idx) in certifications" :key="cert.name">
|
||||
{{ cert.issuer }} - {{ cert.summary }}<template v-if="idx < certifications.length - 1">, </template>
|
||||
</template>
|
||||
</span>
|
||||
<!-- Technical Skills (categorized) -->
|
||||
<div v-if="skills?.length">
|
||||
<div class="space-y-0.5">
|
||||
<div v-for="skill in skills" :key="skill.name" class="text-sm">
|
||||
<span class="font-medium text-gray-800">{{ skill.name }}:</span>
|
||||
<span class="text-gray-700"> {{ skill.keywords.join(', ') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -16,7 +16,7 @@ function formatDateRange(start: string, end?: string): string {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="mb-6">
|
||||
<section class="mb-6 print:mb-4">
|
||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-3">
|
||||
Education
|
||||
</h2>
|
||||
|
||||
@@ -24,27 +24,40 @@ function formatDateRange(start: string, end?: string): string {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="mb-6">
|
||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-3">
|
||||
<section class="mb-6 print:mb-3">
|
||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-2 print:mb-1.5">
|
||||
Work Experience
|
||||
</h2>
|
||||
|
||||
<div v-for="job in sortedWork" :key="job.company + job.startDate" class="mb-4 last:mb-0">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-gray-800">{{ job.position }}</h3>
|
||||
<div v-for="job in sortedWork" :key="job.company + job.startDate" class="mb-4 last:mb-0 print:mb-3">
|
||||
<div class="flex justify-between items-start gap-4">
|
||||
<div class="flex-1 min-w-0">
|
||||
<h3 class="text-sm font-semibold text-gray-800 break-words hyphens-none">{{ job.position }}</h3>
|
||||
<p class="text-sm text-gray-600">{{ job.company }}</p>
|
||||
</div>
|
||||
<span class="text-sm text-gray-500 whitespace-nowrap">
|
||||
<span class="text-sm text-gray-500 whitespace-nowrap flex-shrink-0">
|
||||
{{ formatDateRange(job.startDate, job.endDate) }}
|
||||
</span>
|
||||
</div>
|
||||
<ul class="mt-2 space-y-1">
|
||||
<ul class="mt-2 space-y-1 print:mt-1 print:space-y-0.5">
|
||||
<li v-for="(highlight, idx) in job.highlights" :key="idx"
|
||||
class="text-sm text-gray-700 pl-4 relative before:content-['•'] before:absolute before:left-0">
|
||||
class="text-sm text-gray-700 pl-4 relative before:content-['•'] before:absolute before:left-0 break-words hyphens-none">
|
||||
{{ highlight }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.hyphens-none {
|
||||
hyphens: none;
|
||||
-webkit-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
}
|
||||
|
||||
.break-words {
|
||||
word-break: normal;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,23 +9,61 @@ defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex gap-6 mb-6">
|
||||
<div class="flex gap-6 mb-6 print:mb-2 print:pb-0">
|
||||
<!-- Profile Photo (if provided) -->
|
||||
<div v-if="basics.image" class="flex-shrink-0">
|
||||
|
||||
<img :src="basics.image" :alt="basics.name" class="w-32 h-32 object-cover rounded-full " />
|
||||
<img :src="basics.image" :alt="basics.name" class="w-32 h-32 object-cover rounded-full print:w-24 print:h-24" />
|
||||
</div>
|
||||
|
||||
<!-- Name + Contact Info -->
|
||||
<div class="flex-1">
|
||||
<h1 class="text-3xl font-bold text-gray-900">{{ basics.name }}</h1>
|
||||
<p class="text-xl text-gray-600 mt-1">{{ basics.label }}</p>
|
||||
<h1 class="text-3xl font-bold text-gray-900 print:text-xl print:mb-0.5">{{ basics.name }}</h1>
|
||||
<p class="text-xl text-gray-600 mt-1 print:text-base print:mt-0">{{ basics.label }}</p>
|
||||
|
||||
<div class="mt-3 flex flex-wrap gap-x-4 gap-y-1 text-sm text-gray-700">
|
||||
<span>{{ basics.location.city }}, {{ basics.location.country }}</span>
|
||||
<a :href="`tel:${basics.phone}`" class="hover:text-blue-600">{{ basics.phone }}</a>
|
||||
<a :href="`mailto:${basics.email}`" class="hover:text-blue-600">{{ basics.email }}</a>
|
||||
<a v-if="basics.url" :href="basics.url" target="_blank" class="hover:text-blue-600">{{ basics.url }}</a>
|
||||
<div class="mt-3 flex flex-wrap gap-x-4 gap-y-1.5 text-sm text-gray-700 print:mt-1.5 print:text-xs print:gap-x-3">
|
||||
<!-- Location -->
|
||||
<span class="inline-flex items-center gap-1.5">
|
||||
<UIcon name="i-heroicons-map-pin" class="text-gray-500 flex-shrink-0" />
|
||||
{{ basics.location.city }}, {{ basics.location.country }}
|
||||
</span>
|
||||
|
||||
<!-- Phone -->
|
||||
<a :href="`tel:${basics.phone}`" class="inline-flex items-center gap-1.5 hover:text-blue-600 transition-colors">
|
||||
<UIcon name="i-heroicons-phone" class="text-gray-500 flex-shrink-0" />
|
||||
{{ basics.phone }}
|
||||
</a>
|
||||
|
||||
<!-- Email -->
|
||||
<span class="inline-flex items-center gap-1.5">
|
||||
<UIcon name="i-heroicons-envelope" class="text-gray-500 flex-shrink-0" />
|
||||
<a :href="`mailto:${basics.email}`" class="hover:text-blue-600 transition-colors">
|
||||
{{ basics.email }}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<!-- LinkedIn -->
|
||||
<a v-if="basics.profiles?.find(p => p.network === 'LinkedIn')"
|
||||
:href="basics.profiles.find(p => p.network === 'LinkedIn')!.url" target="_blank"
|
||||
class="inline-flex items-center gap-1.5 hover:text-blue-600 transition-colors">
|
||||
<UIcon name="i-mdi-linkedin" class="text-gray-500 flex-shrink-0" />
|
||||
LinkedIn
|
||||
</a>
|
||||
|
||||
<!-- Website (Portfolio) -->
|
||||
<a v-if="basics.profiles?.find(p => p.network === 'Portfolio')"
|
||||
:href="basics.profiles.find(p => p.network === 'Portfolio')!.url" target="_blank"
|
||||
class="inline-flex items-center gap-1.5 hover:text-blue-600 transition-colors">
|
||||
<UIcon name="i-heroicons-globe-alt" class="text-gray-500 flex-shrink-0" />
|
||||
Website
|
||||
</a>
|
||||
|
||||
<!-- GitHub -->
|
||||
<a v-if="basics.profiles?.find(p => p.network === 'GitHub')"
|
||||
:href="basics.profiles.find(p => p.network === 'GitHub')!.url" target="_blank"
|
||||
class="inline-flex items-center gap-1.5 hover:text-blue-600 transition-colors">
|
||||
<UIcon name="i-mdi-github" class="text-gray-500 flex-shrink-0" />
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
import type { Language, Certification } from '~/types/resume'
|
||||
|
||||
interface Props {
|
||||
languages?: Language[]
|
||||
certifications?: Certification[]
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="mb-6 print:mb-4">
|
||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-3">
|
||||
Languages & Certifications
|
||||
</h2>
|
||||
|
||||
<!-- Languages -->
|
||||
<div v-if="languages?.length" class="mb-2">
|
||||
<span class="text-sm font-semibold text-gray-800">Languages: </span>
|
||||
<span class="text-sm text-gray-700">
|
||||
<template v-for="(lang, idx) in languages" :key="lang.language">
|
||||
{{ lang.language }} ({{ lang.fluency }})<template v-if="idx < languages.length - 1">, </template>
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Certifications -->
|
||||
<div v-if="certifications?.length">
|
||||
<span class="text-sm font-semibold text-gray-800">Certifications: </span>
|
||||
<span class="text-sm text-gray-700">
|
||||
<template v-for="(cert, idx) in certifications" :key="cert.name">
|
||||
{{ cert.issuer }} - {{ cert.summary }}<template v-if="idx < certifications.length - 1">, </template>
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -3,46 +3,79 @@ const { resume } = useResumeData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen bg-gray-100 flex items-center justify-center p-4 print:p-0 print:bg-white">
|
||||
<div class="resume-wrapper">
|
||||
<!-- A4 Container -->
|
||||
<div
|
||||
class="resume-container bg-white shadow-lg max-w-[210mm] min-h-[297mm] w-full print:shadow-none print:max-w-none">
|
||||
<div class="resume-container">
|
||||
<!-- Single-column vertical stack -->
|
||||
<div class="flex flex-col p-6">
|
||||
<div class="resume-content">
|
||||
<!-- Header with Photo + Name + Contact -->
|
||||
<ResumeHeader :basics="resume.basics" />
|
||||
|
||||
<!-- Summary -->
|
||||
<ResumeSummary :summary="resume.basics.summary" />
|
||||
|
||||
<!-- Skills & Qualifications -->
|
||||
<ResumeAdditionalInfo :skills="resume.skills" />
|
||||
|
||||
<!-- Experience -->
|
||||
<ResumeExperience :work="resume.work" />
|
||||
|
||||
<!-- Education -->
|
||||
<ResumeEducation :education="resume.education" />
|
||||
|
||||
<!-- Additional Information -->
|
||||
<ResumeAdditionalInfo :skills="resume.skills" :languages="resume.languages"
|
||||
:certifications="resume.certifications" />
|
||||
<!-- Languages & Certifications -->
|
||||
<ResumeLanguages :languages="resume.languages" :certifications="resume.certificates" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.resume-wrapper {
|
||||
background: #f3f4f6;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.resume-container {
|
||||
background: white;
|
||||
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
||||
max-width: 210mm;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.resume-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1.5rem !important;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.no-print {
|
||||
display: none !important;
|
||||
.resume-wrapper {
|
||||
background: white !important;
|
||||
padding: 0 !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.resume-container {
|
||||
width: 210mm;
|
||||
min-height: 297mm;
|
||||
width: 210mm !important;
|
||||
max-width: none !important;
|
||||
box-shadow: none !important;
|
||||
border: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.resume-content {
|
||||
padding: 0.75rem !important;
|
||||
}
|
||||
|
||||
* {
|
||||
print-color-adjust: exact;
|
||||
-webkit-print-color-adjust: exact;
|
||||
hyphens: none !important;
|
||||
-webkit-hyphens: none !important;
|
||||
}
|
||||
|
||||
section {
|
||||
|
||||
@@ -7,10 +7,10 @@ defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="mb-6">
|
||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-3">
|
||||
<section class="mb-6 print:mb-3">
|
||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-2 print:mb-1.5">
|
||||
Summary
|
||||
</h2>
|
||||
<p class="text-sm text-gray-800 leading-relaxed">{{ summary }}</p>
|
||||
<p class="text-sm text-gray-800 leading-relaxed print:leading-normal">{{ summary }}</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
+50
-65
@@ -11,6 +11,7 @@ export const resumeData: Resume = {
|
||||
basics: {
|
||||
name: 'Ali Arghyani',
|
||||
label: 'Frontend Developer | Vue.js • Nuxt.js • TypeScript',
|
||||
image: '/img/AliProfile.webp',
|
||||
email: 'aliarghyani@gmail.com',
|
||||
phone: '+98 912 322 0694',
|
||||
url: 'https://aliarghyani.vercel.app',
|
||||
@@ -36,7 +37,7 @@ export const resumeData: Resume = {
|
||||
},
|
||||
],
|
||||
summary:
|
||||
'Frontend Developer with 3+ years building high-performance Vue.js/Nuxt applications for international clients, with background in operations leadership at Huawei. Specialized in performance optimization, scalable architecture (SSR, PWA, RBAC), and accessibility (WCAG 2.1). Delivered 6+ production applications with focus on code quality, maintainability, and distributed team collaboration. Advanced English proficiency (Duolingo 85/100).',
|
||||
'Frontend Developer with 3+ years building high-performance Vue.js/Nuxt applications for international clients. AI-first engineer leveraging Cursor, GitHub Copilot, and AI-powered tools & methodologies to accelerate development by 40% while maintaining code quality. Specialized in performance optimization, scalable architecture (SSR, PWA, RBAC), and accessibility. Delivered 6+ production applications with focus on maintainability and distributed team collaboration. Fluent in English (6+ years in fully English-speaking environment at Huawei).',
|
||||
},
|
||||
|
||||
work: [
|
||||
@@ -47,10 +48,11 @@ export const resumeData: Resume = {
|
||||
startDate: '2024-12',
|
||||
highlights: [
|
||||
'Architected medical tourism platform (Elara Medical) serving international patients across 10+ languages with real-time scheduling via WebSocket, multi-language support (3 languages), and PWA capabilities for offline access',
|
||||
'Accelerated feature development at least by 50% using Cursor and other tools for component generation and real-time debugging, while maintaining zero critical bugs through AI-assisted code review and automated testing',
|
||||
'Optimized application performance through code splitting, lazy loading, and Pinia state management restructuring, significantly reducing bundle size and improving initial load time',
|
||||
'Engineered RBAC (Role-Based Access Control) system with role-based permissions, multi-tenant architecture supporting 3 languages (English, Persian, Turkish), and PWA features enabling offline functionality across mobile and desktop devices',
|
||||
'Implemented comprehensive E2E testing suite using Cypress, establishing quality gates with ESLint strict mode and CI/CD automation with GitHub Actions to ensure stable releases',
|
||||
'Led frontend architecture decisions for cross-functional team of 8; conducted code reviews and mentored 2 junior developers on accessibility standards (WCAG 2.1) and performance best practices',
|
||||
'Established code quality standards with ESLint and implementing CI/CD automation with GitHub Actions to ensure stable releases',
|
||||
'Collaborated with CEO on product strategy and frontend architecture, maintaining full visibility into product roadmap',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -60,11 +62,12 @@ export const resumeData: Resume = {
|
||||
startDate: '2023-09',
|
||||
endDate: '2024-12',
|
||||
highlights: [
|
||||
'Delivered 6+ production-grade web applications for international clients using Vue 3/Nuxt 3, consistently achieving strong performance metrics and high client satisfaction',
|
||||
'Delivered 6+ production-grade web applications for international clients using Vue.js/Nuxt.js, consistently achieving strong performance metrics and high client satisfaction',
|
||||
'Leveraged AI development tools (Cursor and Github Copilot) to reduce development time by at least 40% across 6 projects, enabling faster client delivery and 100% on-time project completion rate',
|
||||
'Elara Medical - Medical tourism platform with RBAC system, i18n for 3 languages, PWA features, and optimized performance through code splitting and lazy loading',
|
||||
'Ideh - Idea evaluation platform with reusable component library reducing development time by 30% and scalable Vue 3 architecture',
|
||||
'Ideh - Idea evaluation platform with reusable component library reducing development time by 30% and scalable Vue.js architecture',
|
||||
'Insho - Advertising marketplace with responsive UI, matching engine for campaign collaboration, and comprehensive listing/proposal flows',
|
||||
'BaMashin - Mobility rental platform with payment integration, responsive UI optimized for mobile/desktop, and WCAG 2.1 compliant interface',
|
||||
'BaMashin - Mobility rental platform with payment integration and responsive UI optimized for mobile/desktop',
|
||||
'Additional Projects: 2 custom B2B SaaS applications with real-time collaboration, analytics dashboards, and third-party API integrations',
|
||||
'Led client communications, translated business requirements into technical specifications, delivered iteratively with clear documentation and transparent progress updates',
|
||||
],
|
||||
@@ -77,10 +80,11 @@ export const resumeData: Resume = {
|
||||
endDate: '2023-08',
|
||||
highlights: [
|
||||
'Led team managing performance and availability for 14,500+ network sites nationwide, ensuring 99.5%+ uptime and rapid incident response across distributed infrastructure',
|
||||
'Leveraged AI-powered analytics tools for pattern recognition in network performance data, identifying optimization opportunities 50% faster than manual analysis methods',
|
||||
'Established operational standards and best practices; mentored 5 team members improving team efficiency by 30% through process optimization and knowledge sharing',
|
||||
'Conducted comprehensive data analysis and KPI monitoring using advanced analytics; identified performance trends and improvement opportunities, reducing network downtime by 22% year-over-year',
|
||||
'Owned stakeholder communication interface; delivered weekly performance reports and monthly strategic updates to C-level executives, translating technical metrics into business impact',
|
||||
'Developed rigorous operations mindset: documentation discipline, quality gates, monitoring systems, incident response protocols—foundational skills applied to frontend development with strong architecture and quality focus',
|
||||
'Built strong operational discipline (documentation, monitoring, incident management, quality gates) that directly enhances frontend engineering quality and architectural decision-making',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -113,79 +117,60 @@ export const resumeData: Resume = {
|
||||
|
||||
skills: [
|
||||
{
|
||||
name: 'Frontend Frameworks & Languages',
|
||||
name: 'Frontend Core',
|
||||
keywords: [
|
||||
'Vue 3',
|
||||
'Nuxt 3',
|
||||
'Vue.js',
|
||||
'Nuxt.js',
|
||||
'TypeScript',
|
||||
'JavaScript (ES6+)',
|
||||
'HTML5',
|
||||
'CSS3',
|
||||
'Pinia',
|
||||
'Tailwind CSS',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Architecture & Advanced',
|
||||
name: 'AI-Assisted Development',
|
||||
keywords: [
|
||||
'Cursor AI',
|
||||
'GitHub Copilot',
|
||||
'Claude/ChatGPT',
|
||||
'Prompt Engineering',
|
||||
'AI-Powered Code Review',
|
||||
'AI Workflow Integration',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Architecture & Performance',
|
||||
keywords: [
|
||||
'SSR (Server-Side Rendering)',
|
||||
'SSG (Static Site Generation)',
|
||||
'PWA (Progressive Web Apps)',
|
||||
'Component Libraries',
|
||||
'RBAC Systems',
|
||||
'i18n Internationalization',
|
||||
'WebSocket Real-Time Features',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Styling & UI',
|
||||
keywords: [
|
||||
'Tailwind CSS',
|
||||
'Vuetify',
|
||||
'Responsive Design',
|
||||
'CSS Modules',
|
||||
'BEM Methodology',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'State Management & APIs',
|
||||
keywords: [
|
||||
'Pinia',
|
||||
'REST APIs',
|
||||
'Async/Await Patterns',
|
||||
'API Integration',
|
||||
'Code Splitting & Lazy Loading',
|
||||
'Performance Optimization',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Development Tools & Workflow',
|
||||
keywords: [
|
||||
'Vite',
|
||||
'Git/GitHub',
|
||||
'GitHub Actions',
|
||||
'ESLint',
|
||||
'Prettier',
|
||||
'Jira',
|
||||
'GitHub Actions (CI/CD)',
|
||||
'ESLint/Prettier',
|
||||
'Vite',
|
||||
'REST APIs',
|
||||
'WebSocket',
|
||||
'Agile/Scrum',
|
||||
'CI/CD Pipelines',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Quality & Accessibility',
|
||||
keywords: [
|
||||
'WCAG 2.1 Compliance',
|
||||
'Lighthouse Optimization',
|
||||
'Code Review',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Testing & Quality',
|
||||
keywords: [
|
||||
'Cypress E2E Testing',
|
||||
'ESLint Strict Mode',
|
||||
'Performance Optimization',
|
||||
'Accessibility (a11y/WCAG)',
|
||||
'Lighthouse Audits',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Collaboration & Remote',
|
||||
keywords: [
|
||||
'Cross-Functional Leadership',
|
||||
'Mentorship',
|
||||
'Asynchronous Communication',
|
||||
'Distributed Team Collaboration',
|
||||
'Stakeholder Management',
|
||||
'i18n Internationalization',
|
||||
'Responsive Design',
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -197,7 +182,7 @@ export const resumeData: Resume = {
|
||||
},
|
||||
{
|
||||
language: 'English',
|
||||
fluency: 'Fluent (Duolingo 85/100)',
|
||||
fluency: 'Fluent',
|
||||
},
|
||||
],
|
||||
|
||||
@@ -218,10 +203,10 @@ export const resumeData: Resume = {
|
||||
'Idea evaluation & market insights platform with scalable architecture and reusable component library',
|
||||
highlights: [
|
||||
'Component library reduced development time by 30%',
|
||||
'Scalable Vue 3 architecture',
|
||||
'Scalable Vue.js architecture',
|
||||
'Dynamic form generation system',
|
||||
],
|
||||
keywords: ['Vue 3', 'Nuxt 3', 'Component Library'],
|
||||
keywords: ['Vue.js', 'Nuxt.js', 'Component Library'],
|
||||
startDate: '2023-09',
|
||||
endDate: '2024-12',
|
||||
url: 'https://ideh.app',
|
||||
@@ -235,9 +220,9 @@ export const resumeData: Resume = {
|
||||
highlights: [
|
||||
'Responsive UI optimized for creator-brand matching',
|
||||
'Comprehensive listing and proposal management system',
|
||||
'Modern Vue 3 architecture with clean, maintainable code',
|
||||
'Modern Vue.js architecture with clean, maintainable code',
|
||||
],
|
||||
keywords: ['Vue 3', 'Nuxt 3', 'Responsive Design', 'Marketplace'],
|
||||
keywords: ['Vue.js', 'Nuxt.js', 'Responsive Design', 'Marketplace'],
|
||||
startDate: '2023-09',
|
||||
endDate: '2024-12',
|
||||
url: 'https://insho.app',
|
||||
@@ -253,7 +238,7 @@ export const resumeData: Resume = {
|
||||
'WCAG 2.1 compliant interface',
|
||||
'Payment integration',
|
||||
],
|
||||
keywords: ['Vue 3', 'TypeScript', 'Responsive Design', 'Accessibility'],
|
||||
keywords: ['Vue.js', 'TypeScript', 'Responsive Design', 'Accessibility'],
|
||||
startDate: '2023-09',
|
||||
endDate: '2024-12',
|
||||
url: 'https://bamashin.net',
|
||||
|
||||
@@ -21,9 +21,9 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen bg-white dark:bg-gray-900">
|
||||
<div class="bg-white dark:bg-gray-900 print:bg-white">
|
||||
<!-- Back to Home Button -->
|
||||
<NuxtLink v-if="!isPrintMode" to="/" class="fixed top-4 left-4 z-50 inline-flex items-center gap-2 px-4 py-2 text-sm font-medium
|
||||
<NuxtLink v-if="!isPrintMode" to="/" class="fixed top-4 right-4 z-50 inline-flex items-center gap-2 px-4 py-2 text-sm font-medium
|
||||
bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700
|
||||
text-gray-700 dark:text-gray-200 rounded-full shadow-lg
|
||||
transition-all duration-200 hover:scale-105 no-print">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,293 @@
|
||||
<img src="https://r2cdn.perplexity.ai/pplx-full-logo-primary-dark%402x.png" style="height:64px;margin-right:32px"/>
|
||||
|
||||
# ذکر کردن کار با ai و ابزار ها و agent های مختلف ایا مهمه توی رزومه ؟
|
||||
|
||||
تحقیق قوی کن
|
||||
اطلاعان در بیار از نمونه های قوی و همچنین اطلاعات اپدیت الان
|
||||
|
||||
Now I have comprehensive information. Let me create a detailed response addressing whether mentioning AI work and tools is important for resumes, with strong current examples.
|
||||
|
||||
## نتیجهگیری: بلی، ذکر مهارتهای AI و ابزار ها **حتماً و بسیار مهم است**
|
||||
|
||||
**۴۷ درصد از کارفرمایان** در سال ۲۰۲۵ AI را **مهمترین مهارت سخت** برای استخدام میدانند. این فقط یک روند موقتی نیست؛ بلکه یک **نیاز بنیادی** شده است که مشابه نقشی است که cloud computing دهه ۲۰۱۰ ایفا کرد.[^1][^2][^3]
|
||||
|
||||
### چرا AI مهارتها حیاتی هستند؟
|
||||
|
||||
**۹۰ درصد شرکتها** تا سال ۲۰۲۸ AI را به کار میگیرند. اگر شما این مهارتها را بر روی رزومه نداشته باشید، نه تنها فرصت استخدام را از دست میدهید، بلکه **معرض خطرِ اخراج در اولویت** قرار میگیرید. شرکت آکسنتور اخیراً ۱۱۰۰۰ کارمند را به دلیل عدم تطابق با AI برکنار کرد.[^4][^5]
|
||||
|
||||
***
|
||||
|
||||
## ابزار ها و AI Agents مهمی که باید در رزومه ذکر شوند
|
||||
|
||||
### **۱. ابزارهای Code Generation و Development**
|
||||
|
||||
اینها **الزامی** برای توسعهدهندگان هستند:[^2]
|
||||
|
||||
|
||||
| ابزار | اهمیت | توضیح |
|
||||
| :-- | :-- | :-- |
|
||||
| **GitHub Copilot** | بسیار بالا | ۴۰% از توسعهدهندگان استفاده میکنند، ۷۵% میخواهند ادامه دهند[^6] |
|
||||
| **Cursor** | بسیار بالا | محیط کدنویسی مخصوص برای AI، ۳-۴ برابر سریعتر[^6] |
|
||||
| **Claude/Anthropic** | بالا | مدلهای پیشرفتهتر برای تحلیل کد |
|
||||
| **ChatGPT** | بالا | ۷۶% توسعهدهندگان استفاده میکنند یا برنامهریزی میکنند[^6] |
|
||||
| **VSCode AI Extensions** | متوسط | ابزار داخلی برای محیط VS Code |
|
||||
|
||||
### **۲. AI Agent Frameworks - بسیار مهم برای Portfolio**
|
||||
|
||||
اینها **باید در رزومه و پروژههای شخصی** قرار بگیرند:[^7][^8][^2]
|
||||
|
||||
|
||||
| Framework | بهترین استفاده | اولویت برای Front-end Dev |
|
||||
| :-- | :-- | :-- |
|
||||
| **LangChain** | ابزار عامالغرض، پایهای ترین | **بالا** - معروفترین |
|
||||
| **LangGraph** | Multi-agent workflows، decision trees | **بسیار بالا** - برای پروژههای پیشرفته |
|
||||
| **CrewAI** | Role-based teams، collaboration | **بالا** - برای سیستمهای پیچیده |
|
||||
| **AutoGen** | Multi-agent orchestration | **متوسط** - اکثراً data science |
|
||||
| **LlamaIndex** | RAG، knowledge bases، data processing | **متوسط تا بالا** |
|
||||
| **OpenAI Swarm** | Simple multi-agent | **متوسط** - جدیدتر |
|
||||
|
||||
### **۳. ابزارهای Productivity و Testing**
|
||||
|
||||
ذکر کردن استفاده از این ابزارها **بیانگر کارایی و بهرهوری است**:[^1]
|
||||
|
||||
- **Automation tools**: RPA (Robotic Process Automation)
|
||||
- **AI-powered testing**: Automated code review
|
||||
- **Documentation tools**: AI-based documentation generation
|
||||
- **Data analysis**: Python + AI libraries (TensorFlow, PyTorch)
|
||||
|
||||
***
|
||||
|
||||
## چگونه AI را در رزومه شامل کنید؟
|
||||
|
||||
### **۱. قالب مناسب - جایگذاری استراتژیک**
|
||||
|
||||
**۶۱ درصد** کارفرمایان توصیه میکنند که مهارتها را **درون bullet points تجربه شامل کنید**:[^3]
|
||||
|
||||
```
|
||||
❌ اشتباه:
|
||||
Skills: Python, ChatGPT, Copilot
|
||||
|
||||
✅ درست:
|
||||
• Accelerated feature development by 35% using GitHub Copilot
|
||||
for real-time code suggestions and pair programming
|
||||
```
|
||||
|
||||
|
||||
### **۲. منطق Metrics و نتایج**
|
||||
|
||||
**صفر شانس برای بلیچ بند - رقم بگذارید!**:[^9][^10]
|
||||
|
||||
```
|
||||
❌ اشتباه:
|
||||
- Used AI tools to improve code quality
|
||||
|
||||
✅ درست:
|
||||
- Leveraged GitHub Copilot to reduce code review time by 40%
|
||||
and improved test coverage from 62% to 88%
|
||||
- Implemented LangChain-based RAG system that reduced
|
||||
customer support response time by 30%
|
||||
```
|
||||
|
||||
|
||||
### **۳. در مقدمه/Summary و Skills Section**
|
||||
|
||||
```
|
||||
🎯 خلاصه (Summary) - نمونه:
|
||||
"AI-first front-end developer with 3+ years experience
|
||||
leveraging GitHub Copilot, Cursor, and LangChain to
|
||||
build scalable, intelligent web applications.
|
||||
Expertise in prompt engineering and multi-agent systems."
|
||||
|
||||
🎯 بخش مهارتها:
|
||||
AI & Automation:
|
||||
• Code Generation: GitHub Copilot, Cursor, Claude
|
||||
• Agent Frameworks: LangChain, LangGraph, CrewAI
|
||||
• Prompt Engineering & AI Integration
|
||||
• AI-Powered Automation (RPA)
|
||||
```
|
||||
|
||||
|
||||
***
|
||||
|
||||
## نمونههای قوی برای Front-End Developer (شما!)
|
||||
|
||||
### **نمونه ۱: AI Agent-Based Project**
|
||||
|
||||
```
|
||||
AI Resume Optimizer Platform
|
||||
• Built full-stack AI application using Next.js + TypeScript
|
||||
• Integrated OpenAI API with LangChain for advanced
|
||||
resume analysis and optimization
|
||||
• Implemented multi-agent system (CrewAI) for parallel
|
||||
content analysis: formatting agent, keyword agent,
|
||||
ATS compliance agent
|
||||
• Reduced processing time by 45% through optimized
|
||||
prompt engineering and token budgeting
|
||||
• Achieved 92% ATS score improvement for test resumes
|
||||
```
|
||||
|
||||
|
||||
### **نمونه ۲: Productivity Enhancement**
|
||||
|
||||
```
|
||||
Development Workflow Optimization
|
||||
• Increased development velocity by 3x using GitHub Copilot
|
||||
for component generation and boilerplate automation
|
||||
• Implemented automated testing pipeline with AI-powered
|
||||
code review (Snyk Code)
|
||||
• Used Cursor for advanced cross-repository analysis,
|
||||
reducing debugging time by 50%
|
||||
```
|
||||
|
||||
|
||||
### **نمونه ۳: AI Integration in Products**
|
||||
|
||||
```
|
||||
Real-Time Recommendation Engine
|
||||
• Developed React-based dashboard consuming LangChain-powered
|
||||
recommendation API
|
||||
• Integrated RAG (Retrieval-Augmented Generation) system
|
||||
to provide context-aware suggestions
|
||||
• Optimized API responses by 60% through prompt engineering
|
||||
and model selection optimization
|
||||
• Achieved 4.8/5 user satisfaction score
|
||||
```
|
||||
|
||||
|
||||
***
|
||||
|
||||
## آمار و دادههای جدید (دسمبر ۲۰۲۵)
|
||||
|
||||
✅ **۴۷%** کارفرمایان AI را top hard skill میدانند[^3]
|
||||
|
||||
✅ **۹۰%** شرکت تا ۲۰۲۸ AI خواهند پذیرفت[^4]
|
||||
|
||||
✅ **۷۶%** توسعهدهندگان استفاده میکنند یا برنامه میریزند AI استفاده کنند[^6]
|
||||
|
||||
✅ **۴۸%** کارفرمایان از AI برای screening رزومه استفاده میکنند[^11]
|
||||
|
||||
✅ **۳ برابر تا ۴ برابر** سریعتر کدنویسی با Cursor[^6]
|
||||
|
||||
***
|
||||
|
||||
## نکات مهم و هشدارها
|
||||
|
||||
### ⚠️ **چه کاری نکنید:**
|
||||
|
||||
1. **AI چپلکی نکنید**: "من ChatGPT برای نوشتن رزومه استفاده کردم" → غلط!
|
||||
2. **عمومی نباشید**: "مهارت AI" یا "ChatGPT" ← خیلی vague است
|
||||
3. **Buzzword بی معنی**: فقط اسم ابزار ها ذکر کنند بدون context
|
||||
|
||||
### ✅ **چه کاری کنید:**
|
||||
|
||||
1. **مخصوص باشید**: فریمورکها، ابزارها، خروجیها را نام ببرید
|
||||
2. **نتایج بگذارید**: هر AI integration با metric و result
|
||||
3. **تطبیق با شغل**: از job description keywords استفاده کنید
|
||||
4. **Practical projects**: AI-based portfolio projects ارائه دهید
|
||||
|
||||
***
|
||||
|
||||
## توصیههای فوری برای شما (Front-end Developer):
|
||||
|
||||
### **فوری:**
|
||||
|
||||
1. ✅ افزودن **۲-۳ ابزار** که واقعاً استفاده میکنید (Cursor, Copilot, Claude)
|
||||
2. ✅ افزودن **۱ AI framework** که با آن کار کردید (LangChain یا CrewAI)
|
||||
3. ✅ یک **AI-powered project** در portfolio
|
||||
4. ✅ نوشتن **۲-۳ bullet point** برای هر job experience که AI استفاده کردید
|
||||
|
||||
### **میانمدت:**
|
||||
|
||||
- تولید projectی مثل "AI Resume Optimizer" (دیدهها شگفتزده میشوند!)
|
||||
- یادگیری **LangGraph** (۱۰ چرت بهتر از صرف LangChain)
|
||||
- کتابخانه MCP探索 (شما قبلاً عنوان کردید)
|
||||
|
||||
|
||||
### **بلندمدت:**
|
||||
|
||||
- Certification: Google Cloud AI, AWS AI بگیرید
|
||||
- **Prompt engineering** را متقن کنید
|
||||
- Agent coordination و Human-in-the-Loop patterns مطالعه کنید
|
||||
|
||||
***
|
||||
|
||||
## خلاصه نهایی
|
||||
|
||||
**سوال شما**: آیا ذکر کار با AI و ابزارهای مختلف مهم است؟
|
||||
|
||||
**جواب**: **نه فقط مهم است، بلکه اجباری است**. اگر شما ابزارهای AI را روی رزومه نگذارید:
|
||||
|
||||
- ✗ ۴۷% کارفرمایان شما را pass میکنند
|
||||
- ✗ ATS های جدید شما را lower rank میکنند
|
||||
- ✗ شماس در "پزن خطر" لیست قرار میگیری
|
||||
|
||||
اما اگر **درست** ذکر کنید:
|
||||
|
||||
- ✓ بلافاصله جلب توجه میکنید
|
||||
- ✓ competitiveness سی برابر بالاتر
|
||||
- ✓ مذاکرات حقوق بهتر
|
||||
- ✓ Portfolio قویتر
|
||||
|
||||
**خط پایه**: رزومه بدون AI مهارتها در ۲۰۲۵ مثل است **رزومه بدون LinkedIn در ۲۰۱۵** - فقط خود حذف کردی.[^12][^1][^4]
|
||||
<span style="display:none">[^13][^14][^15][^16][^17][^18][^19][^20][^21][^22][^23][^24][^25][^26][^27][^28][^29]</span>
|
||||
|
||||
<div align="center">⁂</div>
|
||||
|
||||
[^1]: https://www.rezi.ai/posts/ai-skills-for-your-resume
|
||||
|
||||
[^2]: https://www.linkedin.com/pulse/must-have-ai-tools-agent-frameworks-all-software-resumes-2025-vmiic
|
||||
|
||||
[^3]: https://www.resumebuilder.com/resume-examples/nearly-half-of-hiring-managers-say-ai-is-the-most-important-skill-to-have-on-your-resume-in-2025/
|
||||
|
||||
[^4]: https://novoresume.com/career-blog/include-ai-skills-on-your-resume
|
||||
|
||||
[^5]: https://www.forbes.com/sites/rachelwells/2025/10/08/3-ai-certifications-you-need-to-put-on-your-resume-in-2025/
|
||||
|
||||
[^6]: https://kingy.ai/blog/ai-coding-agents-in-2025-cursor-vs-windsurf-vs-copilot-vs-claude-vs-vs-code-ai/
|
||||
|
||||
[^7]: https://www.codecademy.com/article/top-ai-agent-frameworks-in-2025
|
||||
|
||||
[^8]: https://www.turing.com/resources/ai-agent-frameworks
|
||||
|
||||
[^9]: https://www.resumegiants.com/blog/ai-skills-resume/
|
||||
|
||||
[^10]: https://cvcompiler.com/artificial-intelligence-resume-examples
|
||||
|
||||
[^11]: https://www.cnn.com/2025/04/08/tech/ai-resume-job-hunters
|
||||
|
||||
[^12]: https://www.resufit.com/blog/essential-ai-skills-to-add-to-your-resume-in-2025-stay-competitive-in-todays-job-market/
|
||||
|
||||
[^13]: https://huntr.co/resume-examples/ai-engineer
|
||||
|
||||
[^14]: https://enhancv.com/blog/ai-skills-on-resume/
|
||||
|
||||
[^15]: https://www.resume-now.com/resume/examples/ai-software-developer
|
||||
|
||||
[^16]: https://cvcompiler.com/artificial-intelligence-specialist-resume-examples
|
||||
|
||||
[^17]: https://insight.ieeeusa.org/articles/what-tech-hiring-managers-really-think-of-ai-created-resumes-and-cover-letters/
|
||||
|
||||
[^18]: https://www.reddit.com/r/LLMDevs/comments/1mpwg8v/a_free_goldmine_of_ai_agent_examples_templates/
|
||||
|
||||
[^19]: https://www.reddit.com/r/webdev/comments/1it25cm/i_created_chatgptcursor_inspired_resume_copilot/
|
||||
|
||||
[^20]: https://www.upwork.com/resources/ai-skills-for-resumes
|
||||
|
||||
[^21]: https://dev.to/stevengonsalvez/2025s-best-ai-coding-tools-real-cost-geeky-value-honest-comparison-4d63
|
||||
|
||||
[^22]: https://www.designgurus.io/blog/10-best-ai-tools-for-developers-in-2025
|
||||
|
||||
[^23]: https://www.linkedin.com/pulse/10-smart-ways-use-ai-resume-optimization-2025-magicalapi-eeoaf
|
||||
|
||||
[^24]: https://dev.to/finalroundai/10-genius-technical-projects-that-can-10x-your-resume-in-2025-454c
|
||||
|
||||
[^25]: https://www.indeed.com/career-advice/resumes-cover-letters/resume-ai
|
||||
|
||||
[^26]: https://www.edstellar.com/blog/ai-agent-frameworks
|
||||
|
||||
[^27]: https://webdesignerdepot.com/10-web-dev-trends-for-2025-that-will-make-or-break-your-career/
|
||||
|
||||
[^28]: https://www.nationalsearchgroup.com/optimize-resume-for-ats-ai-screening/
|
||||
|
||||
[^29]: https://recruiter.daily.dev/resources/best-tools-screening-developer-resumes-2025
|
||||
|
||||
@@ -32,7 +32,15 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
|
||||
const page = await browser.newPage()
|
||||
await page.setViewport({ width: 794, height: 1123 })
|
||||
|
||||
// Set viewport to A4 dimensions (210mm x 297mm at 96 DPI)
|
||||
await page.setViewport({
|
||||
width: 794, // 210mm
|
||||
height: 1123 // 297mm
|
||||
})
|
||||
|
||||
// Enable print media type BEFORE loading page
|
||||
await page.emulateMediaType('print')
|
||||
|
||||
const response = await page.goto(resumeUrl, {
|
||||
waitUntil: 'networkidle0',
|
||||
@@ -43,10 +51,65 @@ export default defineEventHandler(async (event) => {
|
||||
throw new Error(`Failed to load: ${response?.status()}`)
|
||||
}
|
||||
|
||||
// Inject critical CSS fixes
|
||||
await page.addStyleTag({
|
||||
content: `
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 1.2cm;
|
||||
}
|
||||
|
||||
* {
|
||||
box-shadow: none !important;
|
||||
word-break: normal !important;
|
||||
hyphens: none !important;
|
||||
-webkit-hyphens: none !important;
|
||||
-ms-hyphens: none !important;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
background: white !important;
|
||||
min-height: auto !important;
|
||||
}
|
||||
|
||||
.resume-wrapper {
|
||||
background: white !important;
|
||||
padding: 0 !important;
|
||||
display: block !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.resume-container {
|
||||
box-shadow: none !important;
|
||||
max-width: none !important;
|
||||
width: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.resume-content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
section {
|
||||
page-break-inside: auto !important;
|
||||
break-inside: auto !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
page-break-after: avoid !important;
|
||||
break-after: avoid !important;
|
||||
}
|
||||
`,
|
||||
})
|
||||
|
||||
const pdf = await page.pdf({
|
||||
format: 'A4',
|
||||
printBackground: true,
|
||||
margin: { top: 0, right: 0, bottom: 0, left: 0 },
|
||||
preferCSSPageSize: true,
|
||||
})
|
||||
|
||||
const query = getQuery(event)
|
||||
|
||||
Reference in New Issue
Block a user