the-tip-top-frontend/public/fix-token.html
2025-11-17 23:38:02 +01:00

238 lines
8.1 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fix Token - Tirage au Sort</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.card {
background: white;
border-radius: 20px;
padding: 40px;
max-width: 600px;
width: 100%;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
h1 {
font-size: 32px;
color: #333;
margin-bottom: 10px;
text-align: center;
}
.emoji {
font-size: 48px;
text-align: center;
margin-bottom: 20px;
}
.status {
padding: 20px;
border-radius: 12px;
margin: 20px 0;
font-size: 16px;
text-align: center;
font-weight: 500;
}
.success { background: #d4edda; color: #155724; border: 2px solid #c3e6cb; }
.error { background: #f8d7da; color: #721c24; border: 2px solid #f5c6cb; }
.warning { background: #fff3cd; color: #856404; border: 2px solid #ffeeba; }
.info { background: #d1ecf1; color: #0c5460; border: 2px solid #bee5eb; }
button {
width: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 18px;
font-size: 18px;
font-weight: 700;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s;
text-transform: uppercase;
letter-spacing: 1px;
}
button:hover { transform: translateY(-2px); box-shadow: 0 10px 25px rgba(0,0,0,0.2); }
button:active { transform: translateY(0); }
button:disabled { opacity: 0.6; cursor: not-allowed; }
.steps {
background: #f8f9fa;
padding: 20px;
border-radius: 12px;
margin: 20px 0;
}
.step {
display: flex;
align-items: center;
padding: 10px 0;
font-size: 14px;
}
.step-num {
background: #667eea;
color: white;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
margin-right: 15px;
flex-shrink: 0;
}
.step.done .step-num { background: #28a745; }
.countdown {
font-size: 24px;
font-weight: bold;
color: #667eea;
text-align: center;
}
</style>
</head>
<body>
<div class="card">
<div class="emoji" id="emoji">🔑</div>
<h1 id="title">Mise à Jour du Token</h1>
<div id="status"></div>
<div class="steps">
<div class="step" id="step1">
<div class="step-num">1</div>
<div>Suppression de l'ancien token</div>
</div>
<div class="step" id="step2">
<div class="step-num">2</div>
<div>Installation du nouveau token</div>
</div>
<div class="step" id="step3">
<div class="step-num">3</div>
<div>Vérification du token</div>
</div>
<div class="step" id="step4">
<div class="step-num">4</div>
<div>Redirection vers la page de tirage</div>
</div>
</div>
<button id="fixBtn" onclick="fixToken()">
🚀 Corriger le Token Maintenant
</button>
</div>
<script>
const NEW_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1YTIzOThkZi00NWNiLTQyOGQtOWY1ZS04YzQwNzQxNzEyNGIiLCJpYXQiOjE3NjMwODM0NjksImV4cCI6MTc2MzY4ODI2OX0.fCxlIzy-RkCqvCwjatHmIZ5pjqC61Vs-RAnZwulNd_Q';
function showStatus(message, type) {
const status = document.getElementById('status');
status.className = 'status ' + type;
status.innerHTML = message;
}
function markStepDone(stepNum) {
document.getElementById('step' + stepNum).classList.add('done');
}
async function fixToken() {
const btn = document.getElementById('fixBtn');
btn.disabled = true;
btn.textContent = '⏳ Correction en cours...';
try {
// Étape 1
showStatus('🗑️ Suppression de l\'ancien token...', 'info');
await sleep(800);
localStorage.removeItem('token');
localStorage.removeItem('user');
sessionStorage.clear();
markStepDone(1);
// Étape 2
showStatus('✏️ Installation du nouveau token...', 'info');
await sleep(800);
localStorage.setItem('token', NEW_TOKEN);
markStepDone(2);
// Étape 3
showStatus('🔍 Vérification du token...', 'info');
await sleep(800);
const savedToken = localStorage.getItem('token');
if (savedToken !== NEW_TOKEN) {
throw new Error('Le token n\'a pas été enregistré correctement');
}
markStepDone(3);
// Test de connexion au backend
try {
const response = await fetch('http://localhost:4000/api/draw/eligible-participants?minTickets=1&verified=true', {
headers: {
'Authorization': 'Bearer ' + NEW_TOKEN
}
});
if (!response.ok) {
throw new Error('Erreur ' + response.status + ': ' + response.statusText);
}
const data = await response.json();
showStatus('✅ Token installé avec succès ! ' + data.data.total + ' participants trouvés', 'success');
document.getElementById('emoji').textContent = '✅';
} catch (err) {
showStatus('⚠️ Token installé mais serveur inaccessible. Vérifiez que le backend est lancé.', 'warning');
}
markStepDone(3);
// Étape 4 - Countdown
showStatus('✅ Token installé ! Redirection dans...', 'success');
for (let i = 3; i > 0; i--) {
document.getElementById('status').innerHTML =
`✅ Token installé avec succès !<br><div class="countdown">${i}</div>`;
await sleep(1000);
}
markStepDone(4);
window.location.href = 'http://localhost:3000/admin/tirages';
} catch (error) {
showStatus('❌ Erreur : ' + error.message, 'error');
document.getElementById('emoji').textContent = '❌';
btn.disabled = false;
btn.textContent = '🔄 Réessayer';
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Auto-démarrage si on est sur localhost:3000
window.addEventListener('load', () => {
if (window.location.hostname === 'localhost' && window.location.port === '3000') {
showStatus('📍 Détecté sur localhost:3000 - Prêt à corriger le token', 'info');
} else {
showStatus('⚠️ Cette page doit être ouverte depuis http://localhost:3000', 'warning');
}
});
</script>
</body>
</html>