Tech Stack Advisor - Code Viewer

← Back to File Tree

register.html

Language: html | Path: backend/static/register.html | Lines: 316
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Register - Tech Stack Advisor</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 20px;
        }

        .auth-container {
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            padding: 40px;
            max-width: 450px;
            width: 100%;
        }

        .logo {
            text-align: center;
            margin-bottom: 30px;
        }

        .logo h1 {
            font-size: 2em;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }

        .logo p {
            color: #666;
            margin-top: 10px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        label {
            display: block;
            margin-bottom: 8px;
            color: #333;
            font-weight: 500;
        }

        input {
            width: 100%;
            padding: 12px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            transition: border-color 0.3s;
        }

        input:focus {
            outline: none;
            border-color: #667eea;
        }

        .btn {
            width: 100%;
            padding: 15px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: transform 0.2s;
        }

        .btn:hover:not(:disabled) {
            transform: translateY(-2px);
        }

        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
        }

        .alert {
            padding: 12px;
            border-radius: 8px;
            margin-bottom: 20px;
            display: none;
        }

        .alert.error {
            background: #fee;
            color: #c33;
            border: 1px solid #fcc;
        }

        .alert.success {
            background: #efe;
            color: #3c3;
            border: 1px solid #cfc;
        }

        .password-strength {
            margin-top: 5px;
            font-size: 14px;
            color: #666;
        }

        .password-strength.weak {
            color: #f00;
        }

        .password-strength.medium {
            color: #fa0;
        }

        .password-strength.strong {
            color: #0a0;
        }

        .footer-link {
            text-align: center;
            margin-top: 20px;
            color: #666;
        }

        .footer-link a {
            color: #667eea;
            text-decoration: none;
            font-weight: 600;
        }

        .footer-link a:hover {
            text-decoration: underline;
        }

        .loading {
            display: none;
            text-align: center;
            color: #667eea;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="auth-container">
        <div class="logo">
            <h1>🚀 Tech Stack Advisor</h1>
            <p>Create your account to get started</p>
        </div>

        <div id="alert" class="alert"></div>
        <div id="loading" class="loading">Loading...</div>

        <form id="registerForm">
            <div class="form-group">
                <label for="fullName">Full Name</label>
                <input type="text" id="fullName" name="fullName" required placeholder="John Doe">
            </div>

            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" id="email" name="email" required placeholder="you@example.com">
            </div>

            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" id="password" name="password" required placeholder="At least 8 characters" minlength="8">
                <div id="passwordStrength" class="password-strength"></div>
            </div>

            <div class="form-group">
                <label for="confirmPassword">Confirm Password</label>
                <input type="password" id="confirmPassword" name="confirmPassword" required placeholder="Re-enter your password">
            </div>

            <button type="submit" class="btn" id="registerBtn">Create Account</button>
        </form>

        <div class="footer-link">
            Already have an account? <a href="/login.html">Login</a>
        </div>
    </div>

    <script src="/auth.js"></script>
    <script>
        const registerForm = document.getElementById('registerForm');
        const registerBtn = document.getElementById('registerBtn');
        const alert = document.getElementById('alert');
        const loading = document.getElementById('loading');
        const passwordInput = document.getElementById('password');
        const confirmPasswordInput = document.getElementById('confirmPassword');
        const passwordStrength = document.getElementById('passwordStrength');

        // Check if already logged in
        if (isAuthenticated()) {
            window.location.href = '/';
        }

        // Password strength checker
        passwordInput.addEventListener('input', () => {
            const password = passwordInput.value;
            const strength = checkPasswordStrength(password);

            passwordStrength.textContent = strength.text;
            passwordStrength.className = `password-strength ${strength.class}`;
        });

        function checkPasswordStrength(password) {
            if (password.length < 8) {
                return { text: 'Too short', class: 'weak' };
            }

            let strength = 0;
            if (password.length >= 12) strength++;
            if (/[a-z]/.test(password) && /[A-Z]/.test(password)) strength++;
            if (/\d/.test(password)) strength++;
            if (/[^a-zA-Z\d]/.test(password)) strength++;

            if (strength <= 1) {
                return { text: 'Weak password', class: 'weak' };
            } else if (strength === 2) {
                return { text: 'Medium password', class: 'medium' };
            } else {
                return { text: 'Strong password', class: 'strong' };
            }
        }

        registerForm.addEventListener('submit', async (e) => {
            e.preventDefault();

            const fullName = document.getElementById('fullName').value;
            const email = document.getElementById('email').value;
            const password = passwordInput.value;
            const confirmPassword = confirmPasswordInput.value;

            // Validate passwords match
            if (password !== confirmPassword) {
                showAlert('Passwords do not match!', 'error');
                return;
            }

            // Validate password strength
            const strength = checkPasswordStrength(password);
            if (strength.class === 'weak') {
                showAlert('Please use a stronger password (at least 8 characters with mix of letters, numbers, and symbols)', 'error');
                return;
            }

            // Disable form
            registerBtn.disabled = true;
            loading.style.display = 'block';
            hideAlert();

            try {
                const response = await fetch('/auth/register', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        email,
                        password,
                        full_name: fullName
                    }),
                });

                const data = await response.json();

                if (response.ok) {
                    // Save token
                    saveToken(data.token);
                    showAlert('Registration successful! Redirecting...', 'success');

                    // Redirect to main page
                    setTimeout(() => {
                        window.location.href = '/';
                    }, 1000);
                } else {
                    showAlert(data.detail || 'Registration failed. Please try again.', 'error');
                }
            } catch (error) {
                console.error('Registration error:', error);
                showAlert('An error occurred. Please try again.', 'error');
            } finally {
                registerBtn.disabled = false;
                loading.style.display = 'none';
            }
        });

        function showAlert(message, type) {
            alert.textContent = message;
            alert.className = `alert ${type}`;
            alert.style.display = 'block';
        }

        function hideAlert() {
            alert.style.display = 'none';
        }
    </script>
</body>
</html>