Files
MyClub/DOCS/PDF_PREVIEW_AND_POLL_FIX.md
T
Tomas Dvorak 68e69e00cc dev day #65,5
2025-10-20 10:40:55 +02:00

6.9 KiB

PDF Preview and Poll Creation Fix

Issues Fixed

1. PDF Preview Not Working (Blank Screen)

Problem: When trying to preview PDF files, the screen was blank due to Content Security Policy (CSP) restrictions blocking iframe embedding.

Root Cause: CSP header frame-ancestors 'self' prevented PDF files from being embedded in iframes.

Solution: Enhanced FilePreview.tsx component with multiple fallback options:

  • Primary: Direct iframe embed (works if CSP allows)
  • Fallback buttons:
    • Open in new window
    • View with Mozilla PDF.js
    • View via Google Docs Viewer
    • Download PDF

2. Poll Creation Requires Saved Article

Problem: Users couldn't create or link polls to articles until the article was saved first. The UI showed "Nejprve uložte článek" (Save article first).

Root Cause: PollLinker component requires an articleId which only exists after the article is saved.

Solution:

  • Added "Save as draft and add polls" button
  • Modified onSubmit function to support keepOpen option
  • After saving, modal stays open and switches to Poll tab automatically
  • Article is saved as draft (published=true by default, but can be unpublished)

Files Modified

/frontend/src/components/common/FilePreview.tsx

Lines changed: 124-189

What changed:

  • Wrapped PDF iframe in a VStack with fallback options
  • Added 4 alternative viewing methods
  • Added helpful message when PDF doesn't display
  • Added error handler to iframe

Key improvements:

// Before: Simple iframe only
<iframe src={`${fullUrl}#view=FitH`} />

// After: Iframe + fallback buttons
<VStack>
  <Box>
    <iframe src={`${fullUrl}#view=FitH&toolbar=1`} />
  </Box>
  <HStack>
    <Button href={fullUrl}>Open in new window</Button>
    <Button href={pdfjs_url}>View with PDF.js</Button>
    <Button href={google_viewer_url}>View via Google</Button>
    <Button download>Download PDF</Button>
  </HStack>
</VStack>

/frontend/src/pages/admin/ArticlesAdminPage.tsx

Lines changed:

  • 852: Modified onSubmit function signature
  • 994-997: Added conditional modal closing
  • 1840-1870: Enhanced Poll tab UI

What changed:

  1. Modified onSubmit function:

    // Before
    const onSubmit = async () => { ... }
    
    // After  
    const onSubmit = async (options: { keepOpen?: boolean } = {}) => {
      // ... save logic ...
      if (!options.keepOpen) {
        closeModal();
      }
    }
    
  2. Updated Poll tab:

    • Changed from "info" alert to "warning" alert
    • Added "Save as draft and add polls" button
    • Button calls onSubmit({ keepOpen: true })
    • After save, switches to Poll tab: setActiveTabIndex(5)

Testing Instructions

Test 1: PDF Preview

  1. Upload PDF to article:

    • Go to Admin → Články → Edit article
    • Go to "Média" tab
    • Upload a PDF file in attachments
  2. Test preview:

    • Click "Náhled" button
    • Expected: Modal opens with PDF preview
    • If PDF doesn't show: Fallback buttons appear
    • Click "Otevřít v novém okně" - PDF opens in new tab
    • Click "Zobrazit pomocí PDF.js" - PDF opens in Mozilla viewer
    • Click "Zobrazit přes Google" - PDF opens in Google Docs viewer
    • Click "Stáhnout PDF" - PDF downloads

Test 2: Poll Creation for New Article

  1. Create new article:

    • Go to Admin → Články → Nový článek
    • Fill in title and category
    • Go to "Anketa" tab
  2. See warning message:

    • Expected: Orange warning box with "Článek ještě není uložen"
    • Button: "Uložit jako koncept a přidat ankety"
  3. Save as draft:

    • Click the button
    • Expected:
      • Article saves successfully
      • Modal stays open
      • Tab switches to Poll tab (still showing)
      • PollLinker component now visible
      • Can create/link polls
  4. Create poll:

    • Click "Vytvořit novou" tab
    • Fill in poll title and options
    • Click "Vytvořit anketu"
    • Expected: Poll created and linked to article

Test 3: Poll Creation for Existing Article

  1. Edit existing article:

    • Go to Admin → Články → Edit article
    • Go to "Anketa" tab
  2. Expected: PollLinker shows immediately (no warning)

  3. Create or link polls as normal

Technical Details

PDF Viewing Methods

  1. Direct iframe (default):

    <iframe src="/uploads/file.pdf#view=FitH&toolbar=1" />
    
    • Works if CSP allows
    • Fastest method
    • Native browser PDF viewer
  2. Mozilla PDF.js (fallback 1):

    https://mozilla.github.io/pdf.js/web/viewer.html?file=<encoded_url>
    
    • Works even with strict CSP
    • JavaScript-based PDF renderer
    • Requires internet connection
  3. Google Docs Viewer (fallback 2):

    https://docs.google.com/viewer?url=<encoded_url>&embedded=true
    
    • Requires public URL
    • May have privacy concerns
    • Reliable for most PDFs
  4. Direct download (fallback 3):

    • Always works
    • User opens in their PDF app

Poll Creation Flow

New Article (no ID yet)
  ↓
User clicks "Save as draft and add polls"
  ↓
onSubmit({ keepOpen: true })
  ↓
Article created in database
  ↓
Modal stays open (closeModal not called)
  ↓
setActiveTabIndex(5) - Switch to Poll tab
  ↓
PollLinker now has articleId
  ↓
User can create/link polls

Known Limitations

PDF Preview

  • PDF.js fallback requires internet connection
  • Google Viewer requires publicly accessible URLs
  • Some browsers may block cross-origin iframes
  • Very large PDFs (>10MB) may be slow

Poll Creation

  • Article must still be saved before linking polls (can't be fully offline)
  • "Keep open" mode doesn't work if there's a network error
  • If save fails, modal closes and poll tab doesn't appear

Browser Compatibility

PDF Preview

  • Chrome/Edge: Native PDF viewer works
  • Firefox: Native PDF viewer works
  • Safari: Native PDF viewer works
  • All browsers: Fallback buttons work

Poll Creation

  • All modern browsers (Chrome, Firefox, Safari, Edge)
  • Mobile browsers

Future Improvements

PDF Preview

  • Add PDF.js embed directly in application (no external CDN)
  • Add thumbnail generation for PDFs
  • Add page navigation controls
  • Add zoom controls
  • Add print button

Poll Creation

  • Allow poll creation before article save (store in temp state)
  • Add poll preview in article form
  • Bulk poll creation/linking
  • Poll templates
  • frontend/src/components/common/FilePreview.tsx - PDF preview component
  • frontend/src/components/admin/PollLinker.tsx - Poll management component
  • frontend/src/pages/admin/ArticlesAdminPage.tsx - Article editor
  • internal/controllers/base_controller.go - Backend file upload handler

API Endpoints

  • POST /api/v1/upload - File upload (including PDFs)
  • GET /uploads/** - Serve uploaded files
  • POST /api/v1/polls - Create poll
  • PUT /api/v1/polls/:id - Update poll (link to article)
  • GET /api/v1/polls?article_id=X - Get polls for article