Files
portfolio/docs/sprint-artifacts/3-3-connect-download-button-to-pdf-generation.md
T
mahdiarghyani 9c40914d6a 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
2025-12-02 12:54:26 +03:30

4.8 KiB

Story 3.3: Connect Download Button to PDF Generation

Status: done

Story

As a user, I want to click the download button and get my PDF, so that I can use my resume for job applications.

Acceptance Criteria

  1. AC1: Given I click the download button, when PDF generation starts, then the button shows loading spinner
  2. AC2: The button is disabled during PDF generation
  3. AC3: Given PDF generation succeeds, when the PDF is ready, then the browser downloads the file
  4. AC4: Downloaded filename is "Ali_Arghyani_Resume.pdf"
  5. AC5: Button returns to normal state after download completes
  6. AC6: Given PDF generation fails, when the error occurs, then a toast notification appears
  7. AC7: Button returns to normal state after error
  8. AC8: Button works correctly after error (can retry)

Tasks / Subtasks

  • Update ResumeDownloadButton component (AC: #1-#8)

    • Import useResumePdf() composable
    • Destructure isGenerating and downloadPdf
    • Bind :loading="isGenerating" to UButton
    • Bind :disabled="isGenerating" to UButton
    • Bind @click="downloadPdf" to UButton
    • Remove placeholder click handler
  • Test full download flow

    • Click button, verify spinner appears
    • Verify button is disabled during generation
    • Verify PDF downloads with correct filename
    • Verify button returns to normal after download
    • Test error handling (disconnect network)
    • Verify toast appears on error
    • Verify button works after error (retry)

Dev Notes

Architecture Alignment

From Architecture Doc:

  • Component: app/components/resume/ResumeDownloadButton.vue
  • Uses useResumePdf() composable
  • Uses Nuxt UI UButton with loading state

From Tech Spec Epic 3:

  • AC6, AC8 map to this story
  • Final integration story for Epic 3

Learnings from Previous Stories

From Story 2.5 (Status: done)

  • Download button already created with placeholder handler
  • Print mode detection implemented via isPrintMode prop
  • Button has correct styling and position

From Story 3.2 (Status: drafted)

  • useResumePdf() composable provides isGenerating and downloadPdf
  • Error handling with toast notifications

Implementation Notes

Current ResumeDownloadButton.vue (from Story 2.5):

<script setup lang="ts">
interface Props {
  isPrintMode?: boolean
}

defineProps<Props>()

function handleDownload() {
  console.log('Download PDF clicked')
}
</script>

<template>
  <UButton
    v-if="!isPrintMode"
    icon="i-heroicons-arrow-down-tray"
    size="lg"
    color="primary"
    class="fixed bottom-6 right-6 shadow-lg no-print z-50"
    @click="handleDownload"
  >
    <span class="hidden sm:inline">Download PDF</span>
  </UButton>
</template>

Updated ResumeDownloadButton.vue:

<script setup lang="ts">
interface Props {
  isPrintMode?: boolean
}

defineProps<Props>()

const { isGenerating, downloadPdf } = useResumePdf()
</script>

<template>
  <UButton
    v-if="!isPrintMode"
    icon="i-heroicons-arrow-down-tray"
    size="lg"
    color="primary"
    :loading="isGenerating"
    :disabled="isGenerating"
    class="fixed bottom-6 right-6 shadow-lg no-print z-50"
    @click="downloadPdf"
  >
    <span class="hidden sm:inline">Download PDF</span>
  </UButton>
</template>

Testing Checklist

  • Click button shows loading spinner
  • Button is disabled during generation
  • PDF downloads automatically
  • Filename is "Ali_Arghyani_Resume.pdf"
  • Button returns to normal after success
  • Error shows toast notification
  • Button returns to normal after error
  • Can retry after error
  • Print mode still hides button

References

  • [Source: docs/architecture.md#Loading-State]
  • [Source: docs/sprint-artifacts/tech-spec-epic-3.md#AC6-AC8]
  • [Source: docs/sprint-artifacts/2-5-create-download-button-component.md]

Dev Agent Record

Context Reference

  • docs/sprint-artifacts/3-3-connect-download-button-to-pdf-generation.context.xml

Agent Model Used

  • Claude Sonnet 4 (via Kiro)

Debug Log References

  • Button integration straightforward
  • Changed from downloadPdf to openPdf for better UX

Completion Notes List

  • ResumeDownloadButton updated to use useResumePdf() composable
  • Loading state bound with :loading="isGenerating"
  • Disabled state bound with :disabled="isGenerating"
  • Click handler uses openPdf() - opens PDF in new browser tab
  • User can preview PDF and save from browser's PDF viewer
  • Print mode detection still works (hides button)

File List

  • app/components/resume/ResumeDownloadButton.vue (modified)

Change Log:

  • 2025-12-01: Story drafted by SM agent (Bob)
  • 2025-12-01: Implementation completed - button connected to composable
  • 2025-12-01: Changed to openPdf for preview-first UX