diff --git a/scripts/assets/logo.png b/scripts/assets/logo.png new file mode 100644 index 00000000..8433be78 Binary files /dev/null and b/scripts/assets/logo.png differ diff --git a/scripts/generateSeeds.ts b/scripts/generateSeeds.ts index 987187b4..66f754f9 100644 --- a/scripts/generateSeeds.ts +++ b/scripts/generateSeeds.ts @@ -1,5 +1,6 @@ #!/usr/bin/env tsx /** + * NOTE: Make sure to set CLIENT_URL in .env to the correct deployment URL * Script to generate N seeds for a given location * Usage: npm run generate-seeds -- * Example: npm run generate-seeds -- "Main Hub" 10 @@ -21,6 +22,7 @@ const __dirname = dirname(__filename); const serverRequire = createRequire(path.join(__dirname, '../server/package.json')); const QRCode = serverRequire('qrcode'); const PDFDocument = serverRequire('pdfkit'); +const logoPath = path.join(__dirname, 'assets/logo.png'); // ===== PDF Generation Helper Functions ===== @@ -69,33 +71,144 @@ async function addQRCodePage( } const pageWidth = doc.page.width; - const pageHeight = doc.page.height; - const qrSize = 200; + const margin = 50; + const contentWidth = pageWidth - (margin * 2); + + let currentY = margin; - // Generate and position QR code - const qrBuffer = await generateQRCodeBuffer(surveyCode, baseUrl, qrSize); - const qrX = (pageWidth - qrSize) / 2; - const qrY = (pageHeight - qrSize) / 2 - 50; + if (fs.existsSync(logoPath)) { + const logoWidth = 60; + doc.image(logoPath, (pageWidth - logoWidth) / 2, currentY, { + fit: [logoWidth, logoWidth], + }); + currentY += logoWidth + 10; + } - doc.image(qrBuffer, qrX, qrY, { + // Title + doc.fontSize(18) + .font('Helvetica-Bold') + .text('Understanding Unsheltered Homelessness', margin, currentY, { + align: 'center', + width: contentWidth + }); + + currentY += 40; + + // Instructions + doc.fontSize(12) + .font('Helvetica') + .text( + 'Bring this coupon to one of the locations below to complete a survey about your experience being unsheltered (including living in an RV or car/vehicle) and to receive a ', + margin, + currentY, + { + align: 'left', + width: contentWidth, + continued: true + } + ) + .font('Helvetica-Bold') + .text('$20', { continued: true }) + .font('Helvetica') + .text(' Gift Card.'); + + currentY += 50; + + doc.fontSize(12) + .font('Helvetica') + .text( + 'Our locations are accessible with free parking and bike racks unless marked otherwise.', + margin, + currentY, + { + align: 'left', + width: contentWidth + } + ); + + currentY += 25; + + doc.text('Pets and service animals welcome.', margin, currentY, { + align: 'left', + width: contentWidth + }); + + currentY += 50; + + // QR Code and Referral Code + const qrSize = 100; + const qrX = (pageWidth - qrSize) / 2; + + const qrBuffer = await generateQRCodeBuffer(surveyCode, baseUrl, qrSize); + doc.image(qrBuffer, qrX, currentY, { width: qrSize, height: qrSize }); - // Add referral code text - doc.fontSize(20) + currentY += qrSize + 15; + + doc.fontSize(16) .font('Helvetica-Bold') - .text(`Referral Code: ${surveyCode}`, 0, qrY + qrSize + 30, { + .text(`Referral Code: ${surveyCode}`, margin, currentY, { align: 'center', - width: pageWidth + width: contentWidth }); - // Add location text + currentY += 50; + + // Locations section doc.fontSize(12) + .font('Helvetica-Bold') + .text('Locations', margin, currentY, { + align: 'left', + width: contentWidth + }); + + currentY += 20; + + doc.fontSize(11) .font('Helvetica') - .text(`Location: ${locationName}`, 0, pageHeight - 80, { + .text('• Highline United Methodist Church', margin + 10, currentY, { + align: 'left', + width: contentWidth - 10 + }); + + currentY += 15; + + doc.text(' 13015 1st AVE S, Burien, WA 98168', margin + 10, currentY, { + align: 'left', + width: contentWidth - 10 + }); + + currentY += 20; + + doc.text('• Interview Dates and Hours:', margin + 10, currentY, { + align: 'left', + width: contentWidth - 10 + }); + + currentY += 15; + + doc.text(' Monday - Friday (11/17 - 11/21)', margin + 10, currentY, { + align: 'left', + width: contentWidth - 10 + }); + + currentY += 15; + + doc.text(' 10am to 3pm', margin + 10, currentY, { + align: 'left', + width: contentWidth - 10 + }); + + currentY += 50; + + // Contact info + doc.fontSize(10) + .font('Helvetica') + .text('For questions, please call +1 (833) 393-1621', margin, currentY, { align: 'center', - width: pageWidth + width: contentWidth }); } @@ -112,9 +225,6 @@ async function generatePDF(seeds: any[], locationName: string): Promise { const stream = fs.createWriteStream(filepath); doc.pipe(stream); - // BE SURE TO SET THIS TO CORRECT URL IN ENV - const baseUrl = process.env.CLIENT_URL || 'http://localhost:3000'; - // Generate one page per seed for (let i = 0; i < seeds.length; i++) { await addQRCodePage(doc, seeds[i].surveyCode, locationName, baseUrl, i === 0); @@ -236,6 +346,15 @@ async function generateSeeds(locationIdentifier: string, count: number): Promise } } +// Require CLIENT_URL to be set +const baseUrl = process.env.CLIENT_URL; +if (!baseUrl) { + console.error('\n✗ Error: CLIENT_URL environment variable is not set'); + console.error(' Please set CLIENT_URL in your .env file before running this script.'); + console.error(' Example: CLIENT_URL=https://your-domain.com\n'); + process.exit(1); +} + // Parse command line arguments const args = process.argv.slice(2);