← back to Jill Website

src/routes/unsubscribe.ts

137 lines

import { Router, Request, Response } from 'express';

function escapeHtml(value: unknown): string {
  return String(value ?? '')
    .replace(/&/g, '&')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

export function createUnsubscribeRouter(): Router {
  const router = Router();

  /**
   * GET /api/unsubscribe
   * Unsubscribe from future emails
   */
  router.get('/unsubscribe', async (req: Request, res: Response): Promise<void> => {
    try {
      const email = req.query.email as string;

      if (!email) {
        res.status(400).send(`
          <!DOCTYPE html>
          <html>
          <head>
            <title>Invalid Unsubscribe Link</title>
            <style>
              body { font-family: Arial, sans-serif; padding: 40px; text-align: center; }
              .message { max-width: 500px; margin: 0 auto; padding: 30px; background: #f9f9f9; border-radius: 8px; }
              .error { color: #d32f2f; }
            </style>
          </head>
          <body>
            <div class="message">
              <h1 class="error">Invalid Link</h1>
              <p>This unsubscribe link is invalid or malformed.</p>
            </div>
          </body>
          </html>
        `);
        return;
      }

      // In a real application, this would:
      // 1. Store the email in a database table of unsubscribed users
      // 2. Check this table before sending emails
      // For now, we'll just show a confirmation message

      res.status(200).send(`
        <!DOCTYPE html>
        <html>
        <head>
          <title>Unsubscribed Successfully</title>
          <style>
            body {
              font-family: Arial, sans-serif;
              padding: 40px;
              text-align: center;
              background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
              min-height: 100vh;
              margin: 0;
              display: flex;
              align-items: center;
              justify-content: center;
            }
            .message {
              max-width: 500px;
              margin: 0 auto;
              padding: 40px;
              background: white;
              border-radius: 12px;
              box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
            }
            .success { color: #2e7d32; }
            h1 { margin-top: 0; }
            .email {
              background: #f5f5f5;
              padding: 10px 15px;
              border-radius: 6px;
              display: inline-block;
              font-family: monospace;
              font-size: 14px;
            }
            .note {
              margin-top: 20px;
              font-size: 14px;
              color: #666;
              line-height: 1.6;
            }
          </style>
        </head>
        <body>
          <div class="message">
            <h1 class="success">✓ Unsubscribed Successfully</h1>
            <p>The email address</p>
            <div class="email">${escapeHtml(email)}</div>
            <p>has been removed from our mailing list.</p>
            <div class="note">
              You will no longer receive automated emails from Nosara Beachfront Rentals.
              <br><br>
              If you have an active inquiry or reservation, you may still receive direct communication from our team regarding your booking.
            </div>
          </div>
        </body>
        </html>
      `);
    } catch (error) {
      console.error('Error processing unsubscribe:', error);
      res.status(500).send(`
        <!DOCTYPE html>
        <html>
        <head>
          <title>Error</title>
          <style>
            body { font-family: Arial, sans-serif; padding: 40px; text-align: center; }
            .message { max-width: 500px; margin: 0 auto; padding: 30px; background: #f9f9f9; border-radius: 8px; }
            .error { color: #d32f2f; }
          </style>
        </head>
        <body>
          <div class="message">
            <h1 class="error">Error</h1>
            <p>An error occurred while processing your unsubscribe request. Please try again later.</p>
          </div>
        </body>
        </html>
      `);
    }
  });

  return router;
}

export default createUnsubscribeRouter();