Files
vida180/backend/app/services/email.py
Sergio Correa f50174f898 feat: Implementar funcionalidades de Tarefas e Saúde
- Criadas APIs para Health (métricas de saúde)
  * Registrar peso, altura, % gordura, medidas
  * Histórico completo de medições
  * Estatísticas e resumo

- Criadas APIs para Tasks (tarefas)
  * Criar, editar e deletar tarefas
  * Filtros por status e data
  * Estatísticas detalhadas
  * Prioridades (baixa, média, alta)

- Frontend implementado:
  * Página Health.tsx - registro de métricas
  * Página Tasks.tsx - gerenciamento de tarefas
  * Página Progress.tsx - visualização de progresso
  * Dashboard integrado com estatísticas reais

- Schemas e modelos atualizados
- Todas as funcionalidades testadas e operacionais
2025-11-22 02:33:15 +00:00

247 lines
8.5 KiB
Python

from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail, Email, To, Content
import logging
from app.core.config import settings
logger = logging.getLogger(__name__)
def send_verification_email(to_email: str, username: str, verification_token: str):
"""Envia email de verificação para novo usuário"""
verification_url = f"{settings.FRONTEND_URL}/verify-email/{verification_token}"
# Template do email
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{
font-family: 'Arial', sans-serif;
background-color: #f3f4f6;
padding: 20px;
}}
.container {{
max-width: 600px;
margin: 0 auto;
background: white;
border-radius: 16px;
padding: 40px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}}
.header {{
text-align: center;
margin-bottom: 30px;
}}
.logo {{
font-size: 2.5rem;
font-weight: 800;
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0;
}}
.content {{
color: #374151;
line-height: 1.6;
}}
.button {{
display: inline-block;
margin: 30px 0;
padding: 15px 40px;
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
color: white !important;
text-decoration: none;
border-radius: 12px;
font-weight: 700;
font-size: 16px;
}}
.footer {{
margin-top: 40px;
padding-top: 20px;
border-top: 2px solid #e5e7eb;
color: #6b7280;
font-size: 14px;
text-align: center;
}}
.highlight {{
color: #10b981;
font-weight: 700;
}}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1 class="logo">🚀 VIDA180</h1>
</div>
<div class="content">
<h2>Olá, <span class="highlight">{username}</span>! 👋</h2>
<p>Seja muito bem-vindo(a) ao <strong>Vida180</strong>! 🎉</p>
<p>Estamos muito felizes em ter você conosco nessa jornada de transformação!</p>
<p>Para ativar sua conta e começar a usar todas as funcionalidades, clique no botão abaixo:</p>
<div style="text-align: center;">
<a href="{verification_url}" class="button">
✅ Verificar Meu Email
</a>
</div>
<p style="color: #6b7280; font-size: 14px;">
Ou copie e cole este link no seu navegador:<br>
<a href="{verification_url}" style="color: #10b981;">{verification_url}</a>
</p>
<p>Após verificar seu email, você terá acesso completo a:</p>
<ul>
<li>🎯 <strong>Hábitos:</strong> Construa rotinas poderosas</li>
<li>📝 <strong>Tarefas:</strong> Organize seu dia</li>
<li>💪 <strong>Saúde:</strong> Acompanhe sua evolução física</li>
<li>📊 <strong>Progresso:</strong> Visualize sua transformação</li>
</ul>
<p><strong>A transformação acontece um dia de cada vez!</strong> 💪</p>
</div>
<div class="footer">
<p>
Este email foi enviado porque você se cadastrou no Vida180.<br>
Se você não criou esta conta, pode ignorar este email.
</p>
<p style="margin-top: 20px;">
<strong>Vida180</strong> - Transforme sua vida, um dia de cada vez 🚀
</p>
</div>
</div>
</body>
</html>
"""
try:
message = Mail(
from_email=Email(settings.SENDGRID_FROM_EMAIL, settings.SENDGRID_FROM_NAME),
to_emails=To(to_email),
subject=f"🚀 Bem-vindo ao Vida180! Confirme seu email",
html_content=Content("text/html", html_content)
)
sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
response = sg.send(message)
logger.info(f"Email enviado para {to_email} - Status: {response.status_code}")
return True
except Exception as e:
logger.error(f"Erro ao enviar email para {to_email}: {str(e)}")
return False
def send_password_reset_email(to_email: str, username: str, reset_token: str):
"""Envia email de reset de senha"""
reset_url = f"{settings.FRONTEND_URL}/reset-password/{reset_token}"
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{
font-family: 'Arial', sans-serif;
background-color: #f3f4f6;
padding: 20px;
}}
.container {{
max-width: 600px;
margin: 0 auto;
background: white;
border-radius: 16px;
padding: 40px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}}
.header {{
text-align: center;
margin-bottom: 30px;
}}
.logo {{
font-size: 2.5rem;
font-weight: 800;
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0;
}}
.button {{
display: inline-block;
margin: 30px 0;
padding: 15px 40px;
background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);
color: white !important;
text-decoration: none;
border-radius: 12px;
font-weight: 700;
}}
.alert {{
background: #fef3c7;
border-left: 4px solid #f59e0b;
padding: 15px;
margin: 20px 0;
border-radius: 8px;
}}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1 class="logo">🚀 VIDA180</h1>
</div>
<h2>Olá, {username}! 👋</h2>
<p>Recebemos uma solicitação para redefinir sua senha.</p>
<div class="alert">
⚠️ Se você não solicitou a alteração de senha, ignore este email e sua senha permanecerá a mesma.
</div>
<p>Para criar uma nova senha, clique no botão abaixo:</p>
<div style="text-align: center;">
<a href="{reset_url}" class="button">
🔑 Redefinir Minha Senha
</a>
</div>
<p style="color: #6b7280; font-size: 14px;">
Este link expira em 24 horas.
</p>
<div style="margin-top: 40px; padding-top: 20px; border-top: 2px solid #e5e7eb; color: #6b7280; font-size: 14px; text-align: center;">
<strong>Vida180</strong> - Transforme sua vida, um dia de cada vez 🚀
</div>
</div>
</body>
</html>
"""
try:
message = Mail(
from_email=Email(settings.SENDGRID_FROM_EMAIL, settings.SENDGRID_FROM_NAME),
to_emails=To(to_email),
subject="🔑 Redefinir senha - Vida180",
html_content=Content("text/html", html_content)
)
sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
response = sg.send(message)
logger.info(f"Email de reset enviado para {to_email}")
return True
except Exception as e:
logger.error(f"Erro ao enviar email de reset: {str(e)}")
return False