All files / app/services email.service.ts

100% Statements 14/14
100% Branches 4/4
100% Functions 6/6
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181                      1x 11x     11x 11x 11x             6x                   3x     3x     3x             3x             3x                       3x                                                                                                                                                                                                     2x                 2x            
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../config/environment';
import { AuthService } from './auth.service';
import { QrCodeService } from './qr-code.service';
import { EmailRequest, EmailResponse, Subscriber, ExportEmailsResponse, PrizeEmailRequest } from '../models';
 
@Injectable({
  providedIn: 'root'
})
export class EmailService {
  private readonly API_URL = `${environment.apiUrl}/email`;
 
  constructor(
    private http: HttpClient,
    private authService: AuthService,
    private qrCodeService: QrCodeService
  ) {}
 
  /**
   * Envoyer un email
   */
  sendEmail(request: EmailRequest): Observable<EmailResponse> {
    return this.http.post<EmailResponse>(`${this.API_URL}/send`, request, {
      headers: this.authService.getAuthHeaders()
    });
  }
 
  /**
   * Envoyer un email de victoire avec QR code
   */
  sendPrizeEmail(request: PrizeEmailRequest): Observable<EmailResponse> {
    // Générer le QR code
    const qrCodeUrl = this.qrCodeService.generateQrCodeUrl(request.codeValue, 300);
    
    // Créer le contenu HTML de l'email
    const htmlContent = this.generatePrizeEmailHtml(request, qrCodeUrl);
    
    // Créer la requête d'email avec isHtml = true
    const emailRequest: EmailRequest = {
      subject: `🎉 Félicitations ! Vous avez gagné : ${request.prizeName}`,
      message: htmlContent,
      recipients: [request.to],
      isHtml: true // Indiquer que le message est du HTML
    };
    
    return this.sendEmail(emailRequest);
  }
 
  /**
   * Génère le HTML de l'email de victoire
   */
  private generatePrizeEmailHtml(request: PrizeEmailRequest, qrCodeUrl: string): string {
    const deliveryInfo = request.deliveryType === 'home' 
      ? `<p style="color: #333; font-size: 16px; margin: 20px 0;">
           <strong>📦 Livraison à domicile</strong><br>
           ${request.address?.street}<br>
           ${request.address?.postalCode} ${request.address?.city}<br>
           ${request.address?.country}
         </p>`
      : `<p style="color: #333; font-size: 16px; margin: 20px 0;">
           <strong>🏪 Récupération en boutique</strong><br>
           ${request.storeAddress || 'Adresse de la boutique à confirmer'}
         </p>`;
 
    return `
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Félicitations ! Vous avez gagné</title>
</head>
<body style="margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f5f5f5;">
  <table width="100%" cellpadding="0" cellspacing="0" style="background-color: #f5f5f5; padding: 40px 20px;">
    <tr>
      <td align="center">
        <table width="600" cellpadding="0" cellspacing="0" style="background-color: #ffffff; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.1);">
          <!-- Header avec gradient -->
          <tr>
            <td style="background: linear-gradient(135deg, #4CAF50 0%, #81C784 100%); padding: 40px 30px; text-align: center;">
              <h1 style="color: #ffffff; margin: 0; font-size: 32px; font-weight: 700; text-shadow: 0 2px 4px rgba(0,0,0,0.2);">
                🎉 Félicitations !
              </h1>
              <p style="color: #ffffff; margin: 10px 0 0 0; font-size: 18px; opacity: 0.95;">
                Vous avez gagné un lot exceptionnel
              </p>
            </td>
          </tr>
          
          <!-- Contenu principal -->
          <tr>
            <td style="padding: 40px 30px;">
              <div style="text-align: center; margin-bottom: 30px;">
                <div style="font-size: 60px; margin-bottom: 20px;">🏆</div>
                <h2 style="color: #2E7D32; margin: 0 0 10px 0; font-size: 24px; font-weight: 600;">
                  Votre lot : ${request.prizeName}
                </h2>
                <p style="color: #666; font-size: 16px; line-height: 1.6; margin: 0;">
                  Votre code de participation : <strong style="color: #4CAF50; font-size: 18px; letter-spacing: 2px;">${request.codeValue}</strong>
                </p>
              </div>
              
              <!-- QR Code -->
              <div style="text-align: center; margin: 30px 0; padding: 20px; background-color: #f9f9f9; border-radius: 12px;">
                <p style="color: #333; font-size: 14px; margin: 0 0 15px 0; font-weight: 600;">
                  📱 Présentez ce QR code pour récupérer votre lot
                </p>
                <img src="${qrCodeUrl}" alt="QR Code" style="width: 250px; height: 250px; border: 4px solid #4CAF50; border-radius: 12px; background-color: #ffffff; padding: 10px;" />
                <p style="color: #666; font-size: 12px; margin: 15px 0 0 0;">
                  Code : ${request.codeValue}
                </p>
              </div>
              
              <!-- Informations de livraison -->
              <div style="background-color: #E8F5E9; border-left: 4px solid #4CAF50; padding: 20px; border-radius: 8px; margin: 30px 0;">
                <h3 style="color: #2E7D32; margin: 0 0 15px 0; font-size: 18px; font-weight: 600;">
                  📦 Informations de livraison
                </h3>
                ${deliveryInfo}
                <p style="color: #666; font-size: 14px; margin: 20px 0 0 0; line-height: 1.6;">
                  Vous recevrez un email de confirmation une fois votre lot expédié ou prêt à être récupéré.
                </p>
              </div>
              
              <!-- Instructions -->
              <div style="background-color: #FFF3E0; border-left: 4px solid #FF9800; padding: 20px; border-radius: 8px; margin: 30px 0;">
                <h3 style="color: #E65100; margin: 0 0 15px 0; font-size: 18px; font-weight: 600;">
                  ℹ️ Instructions importantes
                </h3>
                <ul style="color: #666; font-size: 14px; line-height: 1.8; margin: 0; padding-left: 20px;">
                  <li>Conservez cet email et votre QR code en sécurité</li>
                  <li>Présentez le QR code lors de la récupération en boutique</li>
                  <li>Pour la livraison à domicile, vous serez contacté sous 48h</li>
                  <li>En cas de question, contactez-nous à service@thetiptop.com</li>
                </ul>
              </div>
            </td>
          </tr>
          
          <!-- Footer -->
          <tr>
            <td style="background-color: #2E7D32; padding: 30px; text-align: center;">
              <p style="color: #ffffff; margin: 0 0 10px 0; font-size: 14px;">
                Thé Tip Top - Jeu Concours
              </p>
              <p style="color: #ffffff; margin: 0; font-size: 12px; opacity: 0.8;">
                Merci de votre participation !
              </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>
    `.trim();
  }
 
  /**
   * Lister les abonnés (utilisateurs avec consentGiven = true)
   */
  getSubscribers(): Observable<Subscriber[]> {
    return this.http.get<Subscriber[]>(`${this.API_URL}/subscribers`, {
      headers: this.authService.getAuthHeaders()
    });
  }
 
  /**
   * Exporter les emails opt-in (admin)
   */
  exportEmails(): Observable<ExportEmailsResponse> {
    return this.http.get<ExportEmailsResponse>(`${environment.apiUrl}/admin/export-emailing`, {
      headers: this.authService.getAuthHeaders()
    });
  }
}