// Give Image Generator, 26.01.03 // 🎨 Generates dynamic SVG images for Stripe checkout with price display // Endpoints: // GET /api/give-image?amount=25¤cy=usd - 512x512 Stripe checkout image // GET /api/give-image?format=og - 1200x630 og:image for social sharing // GET /api/give-image?format=twitter - 1800x900 twitter:image // The purple pals SVG path data (extracted from purple-pals.svg) const palsSvgPath = ``; export async function handler(event, context) { // Get query params const params = event.queryStringParameters || {}; const format = params.format || 'stripe'; // 'stripe' (512x512), 'og' (1200x630), 'twitter' (1800x900) const amount = parseFloat(params.amount) || 25; const currency = (params.currency || 'usd').toLowerCase(); const recurring = params.recurring === 'true'; // Format display amount let displayAmount; if (currency === 'dkk') { displayAmount = `${Math.round(amount)} kr`; } else { displayAmount = `$${amount % 1 === 0 ? Math.round(amount) : amount.toFixed(2)}`; } // Add /month suffix for recurring if (recurring) { displayAmount += currency === 'dkk' ? '/md' : '/mo'; } let svg; if (format === 'og' || format === 'twitter') { // Social media preview image (1200x630 for og, 1800x900 for twitter) const W = format === 'twitter' ? 1800 : 1200; const H = format === 'twitter' ? 900 : 630; // Pals path bounding box is roughly: x=1 to x=23 (22 wide), y=5 to y=19 (14 tall) const palsWidth = 22; const palsHeight = 14; const palsOffsetX = 1; // Path starts at x=1 const palsOffsetY = 5; // Path starts at y=5 const palsScale = format === 'twitter' ? 28 : 22; // Shift the whole composition left and up for better visual centering with the GIVE badge const palsX = (W - palsWidth * palsScale) / 2 - palsOffsetX * palsScale - 60; const palsY = (H - palsHeight * palsScale) / 2 - palsOffsetY * palsScale - 30; svg = ` ${palsSvgPath} GIVE `; } else { // Stripe checkout image (512x512) - Pals with baby blue heart floating off hand // Pals path bounding box: x=1 to x=23 (22 wide), y=5 to y=19 (14 tall) const palsOriginalWidth = 22; const palsOriginalHeight = 14; const palsOriginalOffsetX = 1; const palsOriginalOffsetY = 5; const palsScale = 17; const palsX = (512 - palsOriginalWidth * palsScale) / 2 - palsOriginalOffsetX * palsScale - 40; const palsY = (512 - palsOriginalHeight * palsScale) / 2 - palsOriginalOffsetY * palsScale + 30; svg = ` ${palsSvgPath} ♥ `; } return { statusCode: 200, headers: { 'Content-Type': 'image/svg+xml', 'Cache-Control': 'public, max-age=31536000', // Cache for 1 year (format is in URL) 'Access-Control-Allow-Origin': '*', }, body: svg, }; }