webmoney/frontend/src/pages/ActivateAccount.jsx
marcoitaloesp-ai 6292b62315
feat: complete email system redesign with corporate templates
- Redesigned all email templates with professional corporate style
- Created base layout with dark header, status cards, and footer
- Updated: subscription-cancelled, account-activation, welcome, welcome-new-user, due-payments-alert
- Removed emojis and gradients for cleaner look
- Added multi-language support (ES, PT-BR, EN)
- Fixed email delivery (sync instead of queue)
- Fixed PayPal already-cancelled subscription handling
- Cleaned orphan subscriptions from deleted users
2025-12-18 00:44:37 +00:00

126 lines
4.7 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { useSearchParams, useNavigate, Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import api from '../services/api';
import logo from '../assets/logo-white.png';
const ActivateAccount = () => {
const { t } = useTranslation();
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const [status, setStatus] = useState('loading'); // loading, success, error
const [message, setMessage] = useState('');
const [countdown, setCountdown] = useState(5);
useEffect(() => {
const token = searchParams.get('token');
if (!token) {
setStatus('error');
setMessage(t('activate.invalidLink'));
return;
}
activateAccount(token);
}, [searchParams]);
useEffect(() => {
if (status === 'success' && countdown > 0) {
const timer = setTimeout(() => setCountdown(countdown - 1), 1000);
return () => clearTimeout(timer);
} else if (status === 'success' && countdown === 0) {
navigate('/dashboard');
}
}, [status, countdown, navigate]);
const activateAccount = async (token) => {
try {
const response = await api.post('/activate', { token });
if (response.data.success) {
// Save token and user to localStorage
localStorage.setItem('token', response.data.data.token);
localStorage.setItem('user', JSON.stringify(response.data.data.user));
setStatus('success');
setMessage(t('activate.success'));
} else {
setStatus('error');
setMessage(response.data.message || t('activate.error'));
}
} catch (error) {
setStatus('error');
setMessage(error.response?.data?.message || t('activate.error'));
}
};
return (
<div className="min-vh-100 d-flex align-items-center justify-content-center"
style={{ background: 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)' }}>
<div className="container">
<div className="row justify-content-center">
<div className="col-md-6 col-lg-5">
<div className="card shadow-lg border-0">
<div className="card-body p-5 text-center">
<Link to="/">
<img src={logo} alt="WEBMoney" className="mb-4" style={{ height: '80px', width: 'auto' }} />
</Link>
{status === 'loading' && (
<>
<div className="spinner-border text-primary mb-4" role="status">
<span className="visually-hidden">{t('common.loading')}</span>
</div>
<h4 className="mb-3">{t('activate.activating')}</h4>
<p className="text-muted">{t('activate.pleaseWait')}</p>
</>
)}
{status === 'success' && (
<>
<div className="mb-4">
<i className="bi bi-check-circle-fill text-success" style={{ fontSize: '80px' }}></i>
</div>
<h4 className="mb-3 text-success">{t('activate.successTitle')}</h4>
<p className="text-muted mb-4">{message}</p>
<div className="alert alert-info">
<i className="bi bi-clock me-2"></i>
{t('activate.redirecting', { seconds: countdown })}
</div>
<Link to="/dashboard" className="btn btn-primary btn-lg w-100">
<i className="bi bi-speedometer2 me-2"></i>
{t('activate.goToDashboard')}
</Link>
</>
)}
{status === 'error' && (
<>
<div className="mb-4">
<i className="bi bi-x-circle-fill text-danger" style={{ fontSize: '80px' }}></i>
</div>
<h4 className="mb-3 text-danger">{t('activate.errorTitle')}</h4>
<p className="text-muted mb-4">{message}</p>
<div className="d-grid gap-2">
<Link to="/login" className="btn btn-primary btn-lg">
<i className="bi bi-box-arrow-in-right me-2"></i>
{t('auth.login')}
</Link>
<Link to="/" className="btn btn-outline-secondary">
<i className="bi bi-house me-2"></i>
{t('common.back')}
</Link>
</div>
</>
)}
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default ActivateAccount;