import { Document, Font, Page, StyleSheet, Text, View } from '@react-pdf/renderer'; import type { Paper } from '../domain/paperModel'; /** * Register a Unicode TTF so Vietnamese diacritics render (react-pdf's built-in Helvetica does not * cover them). The Roboto TTFs are SELF-HOSTED under public/fonts so PDF export also works in * air-gapped production deploys (no CDN fetch at render time). If glyphs ever render as blanks, * replace the files with a Noto-with-Vietnamese TTF — registration is the only place it is configured. */ Font.register({ family: 'Roboto', fonts: [ { src: '/fonts/roboto-regular.ttf' }, { src: '/fonts/roboto-bold.ttf', fontWeight: 'bold' }, ], }); const styles = StyleSheet.create({ page: { fontFamily: 'Roboto', fontSize: 11, lineHeight: 1.5, padding: 48, color: '#1f2937' }, title: { fontSize: 18, fontWeight: 'bold', marginBottom: 4 }, titleEn: { fontSize: 12, color: '#6b7280', marginBottom: 12 }, meta: { fontSize: 9, color: '#6b7280', marginBottom: 16 }, h2: { fontSize: 12, fontWeight: 'bold', marginTop: 14, marginBottom: 4 }, body: { textAlign: 'justify' }, source: { marginBottom: 3 }, badge: { fontSize: 9, color: '#047857', marginTop: 16 }, }); export function PaperPdfDocument({ paper, projectTitle }: { paper: Paper; projectTitle?: string }) { return ( {paper.title || '(Chưa đặt tiêu đề)'} {paper.titleEn ? {paper.titleEn} : null} {projectTitle ? `Đề tài: ${projectTitle}` : ''} {paper.publishedAt ? ` · Xuất bản: ${new Date(paper.publishedAt).toLocaleDateString('vi-VN')}` : ' · Bản thảo'} {paper.approval ? ` · Phê duyệt: ${paper.approval.approvedByName}` : ''} {paper.abstractVi ? ( Tóm tắt {paper.abstractVi} ) : null} {paper.abstractEn ? ( Abstract {paper.abstractEn} ) : null} {paper.body ? ( Nội dung {paper.body} ) : null} {paper.sources.length > 0 ? ( Tài liệu tham khảo {paper.sources.map((s, i) => ( [{i + 1}] {s.title} {s.authors ? ` — ${s.authors}` : ''} {s.doiOrUrl ? ` (${s.doiOrUrl})` : ''} {s.verifiedReal ? ' ✓' : ''} ))} ) : null} {paper.status === 'published' && paper.approval ? ( Đã phê duyệt & xuất bản bởi {paper.approval.approvedByName} —{' '} {new Date(paper.approval.approvedAt).toLocaleString('vi-VN')} ) : null} ); }