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

238 lines
6.9 KiB
Markdown

# 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**:
```tsx
// 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**:
```typescript
// 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):
```html
<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
## Related Files
- `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