diff --git a/backend/src/reports/adoptionReport.ts b/backend/src/reports/adoptionReport.ts index d7c8b4b..ac4d69b 100644 --- a/backend/src/reports/adoptionReport.ts +++ b/backend/src/reports/adoptionReport.ts @@ -96,6 +96,17 @@ const drawFact = (doc: PDFKit.PDFDocument, label: string, value: string, x: numb doc.fillColor(colors.ink).fontSize(10).font('Helvetica-Bold').text(value, x + 8, y + 21, { width: width - 16, ellipsis: true }); }; +const drawTextCard = (doc: PDFKit.PDFDocument, label: string, value: string, x: number, y: number, width: number, height = 58) => { + doc.roundedRect(x, y, width, height, 6).fillAndStroke(colors.panel, colors.border); + doc.fillColor(colors.blue).fontSize(8).font('Helvetica-Bold').text(label.toUpperCase(), x + 8, y + 8, { width: width - 16 }); + doc.fillColor(colors.ink).fontSize(9.2).font('Helvetica').text(value, x + 8, y + 23, { + width: width - 16, + height: height - 31, + ellipsis: true, + lineGap: 1.2, + }); +}; + const drawSectionTitle = (doc: PDFKit.PDFDocument, title: string, y: number) => { doc.fillColor(colors.green).font('Helvetica-Bold').fontSize(14).text(title, page.margin, y); doc.moveTo(page.margin, y + 19).lineTo(page.width - page.margin, y + 19).strokeColor(colors.border).lineWidth(1).stroke(); @@ -227,21 +238,27 @@ export const renderAdoptionReportPdf = async ({ const qrDataUrl = await QRCode.toDataURL(transferCode, { margin: 1, width: 96, errorCorrectionLevel: 'H' }); const qrBuffer = dataUrlToBuffer(qrDataUrl); const qrX = page.width - page.margin - 110; - doc.fillColor(colors.green).font('Helvetica-Bold').fontSize(8).text('JOIN', qrX, headerY + 6, { width: 96, align: 'center' }); + doc.fillColor(colors.green).font('Helvetica-Bold').fontSize(8).text('JOIN', qrX - 8, headerY + 5, { width: 112, align: 'center' }); if (wordmarkPath) { - doc.image(wordmarkPath, qrX - 7, headerY + 12, { fit: [110, 42], align: 'center', valign: 'center' }); + doc.image(wordmarkPath, qrX - 20, headerY + 7, { fit: [136, 52], align: 'center', valign: 'center' }); } + doc.fillColor(colors.red).font('Helvetica-Bold').fontSize(7.5).text('Keep my story growing', qrX - 12, headerY + 40, { + width: 120, + align: 'center', + }); if (qrBuffer) { - doc.image(qrBuffer, qrX + 18, headerY + 50, { width: 60 }); + doc.image(qrBuffer, qrX + 18, headerY + 51, { width: 58 }); } - doc.fillColor(colors.ink).font('Helvetica').fontSize(7).text(transferCode, qrX - 8, headerY + 111, { width: 112, align: 'center' }); + doc.fillColor(colors.green).font('Helvetica-Bold').fontSize(7).text('Scan to continue tracking in FlockPal', qrX - 12, headerY + 110, { + width: 120, + align: 'center', + }); + doc.fillColor(colors.ink).font('Helvetica').fontSize(6.5).text(transferCode, qrX - 8, headerY + 119, { width: 112, align: 'center' }); - let y = headerY + headerHeight + 24; - y = drawSectionTitle(doc, 'Flock Member Info', y); + let y = headerY + headerHeight + 16; const factGap = 8; const factWidth = (contentWidth - factGap) / 2; const facts = [ - ['Name', bird.name], ['Species', bird.species], ['Band/tag ID', bird.tag_id || 'Not recorded'], ['Sex', genderLabel(bird.gender)], @@ -257,11 +274,16 @@ export const renderAdoptionReportPdf = async ({ const motivators = parseList(bird.motivators); const demotivators = parseList(bird.demotivators); - doc.fillColor(colors.blue).font('Helvetica-Bold').fontSize(10).text('Motivators', page.margin, y); - fitText(doc, motivators.length ? motivators.join(', ') : 'Not recorded', page.margin, y + 14, factWidth); - doc.fillColor(colors.blue).font('Helvetica-Bold').fontSize(10).text('Demotivators', page.margin + factWidth + factGap, y); - fitText(doc, demotivators.length ? demotivators.join(', ') : 'Not recorded', page.margin + factWidth + factGap, y + 14, factWidth); - y += 52; + drawTextCard(doc, 'Motivators', motivators.length ? motivators.join(', ') : 'Not recorded', page.margin, y, factWidth); + drawTextCard( + doc, + 'Demotivators', + demotivators.length ? demotivators.join(', ') : 'Not recorded', + page.margin + factWidth + factGap, + y, + factWidth, + ); + y += 72; y = drawSectionTitle(doc, 'Weight Graph', y); drawSimpleWeightChart(doc, weights, bird.chart_color, page.margin, y, contentWidth, 120);