d4d8d8a3b6
- Migrated monolithic main.py to feature-scoped routers in app/routers/ - Added GEMINI.md for project context and AI instructional guidelines - Updated README.md with a comprehensive modernization plan (SQL migration, robust scraping DSL, frontend modernization) - Improved authentication with cookie support and modular JS - Updated test suite and documentation
282 lines
9.6 KiB
HTML
282 lines
9.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Connexion - Ohm Stream Downloader</title>
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
<style>
|
|
.auth-container {
|
|
max-width: 400px;
|
|
margin: 50px auto;
|
|
padding: 30px;
|
|
background: linear-gradient(135deg, rgba(26, 26, 46, 0.95), rgba(22, 33, 62, 0.95));
|
|
border-radius: 20px;
|
|
box-shadow: 0 8px 32px rgba(0, 217, 255, 0.3);
|
|
}
|
|
.auth-title {
|
|
text-align: center;
|
|
color: #00d9ff;
|
|
margin-bottom: 30px;
|
|
font-size: 28px;
|
|
}
|
|
.auth-tabs {
|
|
display: flex;
|
|
margin-bottom: 30px;
|
|
border-bottom: 2px solid rgba(0, 217, 255, 0.2);
|
|
}
|
|
.auth-tab {
|
|
flex: 1;
|
|
padding: 15px;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
color: #aaa;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.auth-tab.active {
|
|
color: #00d9ff;
|
|
border-bottom: 2px solid #00d9ff;
|
|
}
|
|
.auth-tab:hover {
|
|
color: #00d9ff;
|
|
}
|
|
.auth-form {
|
|
display: none;
|
|
}
|
|
.auth-form.active {
|
|
display: block;
|
|
}
|
|
.form-group {
|
|
margin-bottom: 20px;
|
|
}
|
|
.form-group label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
color: #00d9ff;
|
|
font-size: 14px;
|
|
}
|
|
.form-group input {
|
|
width: 100%;
|
|
padding: 12px;
|
|
background: rgba(0, 217, 255, 0.1);
|
|
border: 1px solid rgba(0, 217, 255, 0.3);
|
|
border-radius: 8px;
|
|
color: #fff;
|
|
font-size: 14px;
|
|
box-sizing: border-box;
|
|
}
|
|
.form-group input:focus {
|
|
outline: none;
|
|
border-color: #00d9ff;
|
|
box-shadow: 0 0 10px rgba(0, 217, 255, 0.3);
|
|
}
|
|
.form-group input::placeholder {
|
|
color: #666;
|
|
}
|
|
.auth-error {
|
|
background: rgba(255, 107, 107, 0.2);
|
|
border: 1px solid #ff6b6b;
|
|
color: #ff6b6b;
|
|
padding: 12px;
|
|
border-radius: 8px;
|
|
margin-bottom: 20px;
|
|
font-size: 14px;
|
|
display: none;
|
|
}
|
|
.auth-error.show {
|
|
display: block;
|
|
}
|
|
.auth-success {
|
|
background: rgba(0, 217, 255, 0.2);
|
|
border: 1px solid #00d9ff;
|
|
color: #00d9ff;
|
|
padding: 12px;
|
|
border-radius: 8px;
|
|
margin-bottom: 20px;
|
|
font-size: 14px;
|
|
display: none;
|
|
}
|
|
.auth-success.show {
|
|
display: block;
|
|
}
|
|
.btn-block {
|
|
width: 100%;
|
|
}
|
|
.back-link {
|
|
text-align: center;
|
|
margin-top: 20px;
|
|
}
|
|
.back-link a {
|
|
color: #00d9ff;
|
|
text-decoration: none;
|
|
font-size: 14px;
|
|
}
|
|
.back-link a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="auth-container">
|
|
<h1 class="auth-title">🎬 Ohm Stream</h1>
|
|
|
|
<div class="auth-tabs">
|
|
<div class="auth-tab active" data-tab="login">Connexion</div>
|
|
<div class="auth-tab" data-tab="register">Inscription</div>
|
|
</div>
|
|
|
|
<div class="auth-error" id="authError" aria-live="polite"></div>
|
|
<div class="auth-success" id="authSuccess" aria-live="polite"></div>
|
|
|
|
<!-- Login Form -->
|
|
<form class="auth-form active" id="loginForm">
|
|
<div class="form-group">
|
|
<label for="loginUsername">Nom d'utilisateur</label>
|
|
<input
|
|
type="text"
|
|
id="loginUsername"
|
|
placeholder="Entrez votre nom d'utilisateur"
|
|
required
|
|
aria-required="true"
|
|
aria-describedby="loginUsernameHelp"
|
|
>
|
|
<span id="loginUsernameHelp" class="visually-hidden">Champ obligatoire</span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="loginPassword">Mot de passe</label>
|
|
<input
|
|
type="password"
|
|
id="loginPassword"
|
|
placeholder="Entrez votre mot de passe"
|
|
required
|
|
aria-required="true"
|
|
>
|
|
</div>
|
|
<button type="submit" id="loginSubmit" class="btn-primary btn-block">Se connecter</button>
|
|
</form>
|
|
|
|
<!-- Register Form -->
|
|
<form class="auth-form" id="registerForm">
|
|
<div class="form-group">
|
|
<label for="registerUsername">Nom d'utilisateur</label>
|
|
<input
|
|
type="text"
|
|
id="registerUsername"
|
|
placeholder="Choisissez un nom d'utilisateur"
|
|
minlength="3"
|
|
required
|
|
aria-required="true"
|
|
>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="registerEmail">Email (optionnel)</label>
|
|
<input
|
|
type="email"
|
|
id="registerEmail"
|
|
placeholder="votre@email.com"
|
|
>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="registerFullName">Nom complet (optionnel)</label>
|
|
<input
|
|
type="text"
|
|
id="registerFullName"
|
|
placeholder="Votre nom complet"
|
|
>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="registerPassword">Mot de passe</label>
|
|
<input
|
|
type="password"
|
|
id="registerPassword"
|
|
placeholder="Au moins 6 caractères"
|
|
minlength="6"
|
|
required
|
|
aria-required="true"
|
|
>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="registerPasswordConfirm">Confirmer le mot de passe</label>
|
|
<input
|
|
type="password"
|
|
id="registerPasswordConfirm"
|
|
placeholder="Confirmez votre mot de passe"
|
|
minlength="6"
|
|
required
|
|
aria-required="true"
|
|
>
|
|
</div>
|
|
<button type="submit" id="registerSubmit" class="btn-primary btn-block">S'inscrire</button>
|
|
</form>
|
|
|
|
<div class="back-link">
|
|
<a href="/web">← Retour à l'accueil</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Load auth modules in order -->
|
|
<script src="/static/js/auth-utils.js"></script>
|
|
<script src="/static/js/auth-api.js"></script>
|
|
<script src="/static/js/auth-ui.js"></script>
|
|
<script>
|
|
// Debug: Check what's loaded
|
|
console.log('Auth modules loaded:');
|
|
console.log('- window.safeJsonParse:', typeof window.safeJsonParse);
|
|
console.log('- window.authApi:', typeof window.authApi);
|
|
console.log('- window.authUi:', typeof window.authUi);
|
|
console.log('- window.authApi.login:', typeof window.authApi?.login);
|
|
console.log('- window.authUi.handleLogin:', typeof window.authUi?.handleLogin);
|
|
|
|
// Expose setToken from auth.js if available
|
|
if (typeof window.setToken === 'undefined') {
|
|
window.setToken = function(token) {
|
|
localStorage.setItem('auth_token', token);
|
|
document.cookie = 'auth_token=' + token + ';path=/;SameSite=Strict';
|
|
};
|
|
}
|
|
|
|
// Attach event listeners after all scripts are loaded
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
console.log('DOM Content Loaded');
|
|
console.log('window.authUi:', window.authUi);
|
|
|
|
const loginForm = document.getElementById('loginForm');
|
|
const registerForm = document.getElementById('registerForm');
|
|
|
|
if (loginForm && window.authUi && window.authUi.handleLogin) {
|
|
loginForm.addEventListener('submit', window.authUi.handleLogin);
|
|
console.log('✓ Login handler attached');
|
|
} else {
|
|
console.error('✗ authUi.handleLogin not available', {
|
|
hasLoginForm: !!loginForm,
|
|
hasAuthUi: !!window.authUi,
|
|
hasHandleLogin: !!window.authUi?.handleLogin
|
|
});
|
|
}
|
|
|
|
if (registerForm && window.authUi && window.authUi.handleRegister) {
|
|
registerForm.addEventListener('submit', window.authUi.handleRegister);
|
|
console.log('✓ Register handler attached');
|
|
} else {
|
|
console.error('✗ authUi.handleRegister not available');
|
|
}
|
|
|
|
// Attach tab click handlers
|
|
const tabs = document.querySelectorAll('.auth-tab');
|
|
console.log('Found tabs:', tabs.length);
|
|
tabs.forEach(tab => {
|
|
tab.addEventListener('click', function() {
|
|
console.log('Tab clicked:', this.dataset.tab);
|
|
if (window.authUi && window.authUi.switchTab) {
|
|
window.authUi.switchTab(this.dataset.tab);
|
|
} else {
|
|
console.error('✗ authUi.switchTab not available');
|
|
}
|
|
});
|
|
});
|
|
console.log('✓ Tab handlers attached');
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|