Files
Puechberty Arthur 49fd31f4db first commit
2026-03-30 23:07:36 +02:00

133 lines
4.4 KiB
TypeScript

'use client';
import { useLocale } from './LocaleProvider';
import { ts, getMonths } from '@/lib/i18n';
import { getFullMoonsForYear, getMoonPhaseInfo } from '@/lib/lunar';
export default function PDFDownload() {
const { locale } = useLocale();
const generatePDF = async () => {
const { jsPDF } = await import('jspdf');
const year = new Date().getFullYear();
const fullMoons = getFullMoonsForYear(year);
const months = getMonths(locale);
const doc = new jsPDF();
// Colors
const dark = '#0a0a1a';
const accent = '#6366f1';
const white = '#ffffff';
const gray = '#a0a0b0';
// Background
doc.setFillColor(dark);
doc.rect(0, 0, 210, 297, 'F');
// Title
doc.setTextColor(accent);
doc.setFontSize(28);
doc.text(`🌕 ${ts('pdf_title', locale)}`, 105, 30, { align: 'center' });
doc.setTextColor(white);
doc.setFontSize(18);
doc.text(`${year}`, 105, 42, { align: 'center' });
doc.setTextColor(gray);
doc.setFontSize(9);
doc.text(ts('pdf_generated', locale) + ': ' + new Date().toLocaleDateString(locale), 105, 50, { align: 'center' });
// Table header
const startY = 65;
const colMonth = 20;
const colDate = 70;
const colTime = 110;
const colName = 140;
doc.setFillColor('#1a1a2e');
doc.rect(15, startY - 6, 180, 10, 'F');
doc.setTextColor(accent);
doc.setFontSize(10);
doc.setFont('helvetica', 'bold');
doc.text(ts('pdf_col_month', locale), colMonth, startY);
doc.text(ts('pdf_col_date', locale), colDate, startY);
doc.text(ts('pdf_col_time', locale), colTime, startY);
doc.text(ts('pdf_col_name', locale), colName, startY);
// Table rows
doc.setFont('helvetica', 'normal');
doc.setFontSize(10);
fullMoons.forEach((fm, i) => {
const y = startY + 14 + i * 16;
const phaseInfo = getMoonPhaseInfo(fm.date);
// Alternate row background
if (i % 2 === 0) {
doc.setFillColor('#12122a');
doc.rect(15, y - 6, 180, 16, 'F');
}
// Row separator
doc.setDrawColor('#2a2a4a');
doc.line(15, y + 10, 195, y + 10);
doc.setTextColor(white);
doc.text(months[fm.date.getMonth()], colMonth, y);
doc.setTextColor(gray);
doc.text(fm.date.toLocaleDateString(locale, { day: 'numeric', month: 'short' }), colDate, y);
doc.text(fm.date.toLocaleTimeString(locale, { hour: '2-digit', minute: '2-digit' }), colTime, y);
doc.setTextColor('#c4b5fd');
doc.text(fm.traditionalName || phaseInfo.phaseName, colName, y);
});
// Footer
const footY = startY + 14 + fullMoons.length * 16 + 15;
// Stats box
doc.setFillColor('#1a1a2e');
doc.roundedRect(15, footY, 180, 30, 3, 3, 'F');
doc.setTextColor(accent);
doc.setFontSize(11);
doc.text(`📊 ${locale === 'fr' ? 'Statistiques' : 'Statistics'} ${year}`, 25, footY + 10);
doc.setTextColor(gray);
doc.setFontSize(9);
doc.text(`${locale === 'fr' ? 'Nombre de pleines lunes' : 'Number of full moons'}: ${fullMoons.length}`, 25, footY + 18);
if (fullMoons.length > 0) {
const first = fullMoons[0].date.toLocaleDateString(locale, { day: 'numeric', month: 'long' });
const last = fullMoons[fullMoons.length - 1].date.toLocaleDateString(locale, { day: 'numeric', month: 'long' });
doc.text(`${locale === 'fr' ? 'Première' : 'First'}: ${first} | ${locale === 'fr' ? 'Dernière' : 'Last'}: ${last}`, 25, footY + 24);
}
// Credit
doc.setTextColor('#4a4a6a');
doc.setFontSize(7);
doc.text('Generated by Moon Phases - moon.arthurp.fr', 105, 290, { align: 'center' });
doc.save(`calendrier-lunaire-${year}.pdf`);
};
return (
<section id="pdf" aria-label="Download PDF Lunar Calendar" className="section-container">
<div className="glass-card max-w-xl mx-auto p-5 sm:p-8 text-center">
<p className="text-5xl mb-4">📥</p>
<h2 className="text-2xl font-bold mb-3">{ts('pdf_download', locale)}</h2>
<p className="text-white/50 mb-6">
{locale === 'fr'
? `Téléchargez le calendrier des pleines lunes ${new Date().getFullYear()} en PDF pour l'imprimer ou le consulter hors ligne.`
: `Download the ${new Date().getFullYear()} full moon calendar as a PDF to print or view offline.`}
</p>
<button onClick={generatePDF} className="glow-btn text-lg px-8 py-3">
{ts('pdf_download', locale)} (PDF)
</button>
</div>
</section>
);
}