Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Login | Learning Path</title> | |
| <!-- Tailwind CSS via CDN --> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script> | |
| (function () { | |
| const storedTheme = localStorage.getItem('theme'); | |
| if (storedTheme === 'light') { | |
| document.documentElement.classList.remove('dark'); | |
| } else { | |
| document.documentElement.classList.add('dark'); | |
| } | |
| })(); | |
| </script> | |
| <!-- Glassmorphic CSS --> | |
| <link rel="stylesheet" href="{{ url_for('static', filename='css/glassmorphic.css') }}"> | |
| </head> | |
| <body class="grid-background min-h-screen flex items-center justify-center px-6"> | |
| <button id="theme-toggle" class="fixed top-6 right-6 inline-flex items-center justify-center w-10 h-10 rounded-full bg-gray-200 dark:bg-gray-700 text-secondary dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-magenta transition" aria-label="Toggle dark mode"> | |
| <svg id="theme-toggle-light-icon" class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> | |
| <path d="M10 15a5 5 0 100-10 5 5 0 000 10zM10 1a1 1 0 011 1v1a1 1 0 11-2 0V2a1 1 0 011-1zm0 14a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zm9-5a1 1 0 01-1 1h-1a1 1 0 110-2h1a1 1 0 011 1zM3 10a1 1 0 01-1 1H1a1 1 0 110-2h1a1 1 0 011 1zm12.364-6.364a1 1 0 010 1.414L14.95 6.464a1 1 0 01-1.414-1.414l1.414-1.414a1 1 0 011.414 0zM5.05 14.95a1 1 0 011.414 0l1.414-1.414a1 1 0 10-1.414-1.414L5.05 13.536a1 1 0 010 1.414zm9.9 0a1 1 0 10-1.414-1.414l-1.414 1.414a1 1 0 101.414 1.414l1.414-1.414zM5.05 5.05a1 1 0 011.414 0L7.878 6.464A1 1 0 116.464 7.878L5.05 6.464A1 1 0 015.05 5.05z" clip-rule="evenodd"></path> | |
| </svg> | |
| <svg id="theme-toggle-dark-icon" class="w-6 h-6 hidden" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> | |
| <path d="M17.293 13.293A8 8 0 016.707 2.707a8 8 0 1010.586 10.586z"></path> | |
| </svg> | |
| </button> | |
| <!-- Login Card --> | |
| <div class="glass-card p-8 w-full max-w-md z-10 fade-in"> | |
| <h2 class="text-4xl font-bold text-gray-900 dark:text-white mb-8 text-center"> | |
| Welcome Back | |
| </h2> | |
| {% with messages = get_flashed_messages(with_categories=true) %} | |
| {% if messages %} | |
| {% for category, message in messages %} | |
| <div class="mb-6 p-4 rounded-lg {% if category == 'success' %}bg-neon-green bg-opacity-20 border border-neon-green text-neon-green{% else %}bg-status-error bg-opacity-20 border border-status-error text-status-error{% endif %}"> | |
| {{ message }} | |
| </div> | |
| {% endfor %} | |
| {% endif %} | |
| {% endwith %} | |
| <form method="POST" action="{{ url_for('auth.login') }}" class="space-y-6"> | |
| {{ form.hidden_tag() }} | |
| <div> | |
| {{ form.email.label(class="block text-sm font-medium text-secondary mb-2") }} | |
| {{ form.email(class="glass-input", placeholder="you@example.com") }} | |
| {% for error in form.email.errors %} | |
| <p class="text-status-error text-xs mt-1">{{ error }}</p> | |
| {% endfor %} | |
| </div> | |
| <div> | |
| {{ form.password.label(class="block text-sm font-medium text-secondary mb-2") }} | |
| {{ form.password(class="glass-input", placeholder="••••••••") }} | |
| {% for error in form.password.errors %} | |
| <p class="text-status-error text-xs mt-1">{{ error }}</p> | |
| {% endfor %} | |
| </div> | |
| <div class="flex items-center"> | |
| {{ form.remember_me(class="mr-2") }} | |
| {{ form.remember_me.label(class="text-sm text-secondary") }} | |
| </div> | |
| {{ form.submit(class="neon-btn w-full") }} | |
| </form> | |
| <p class="text-center text-muted mt-6"> | |
| Don't have an account? | |
| <a href="{{ url_for('auth.register') }}" class="text-neon-cyan hover:underline"> | |
| Register | |
| </a> | |
| </p> | |
| </div> | |
| <script src="{{ url_for('static', filename='js/theme.js') }}"></script> | |
| </body> | |
| </html> | |