Download backend/static/pages/login.html from TalimBot/talimbot: direct link, hf CLI and curl.
- Browser
- Download file 15 kB
-
https://huggingface.co/spaces/TalimBot/talimbot/resolve/main/backend/static/pages/login.html
- Command line
-
hf download hf://spaces/TalimBot/talimbot/backend/static/pages/login.html
-
curl -L -o login.html https://huggingface.co/spaces/TalimBot/talimbot/resolve/main/backend/static/pages/login.html
15 kB
| <html lang="fa" dir="rtl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ورود - سیستم گروهبندی دانش آموزان</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700;800&display=swap" rel="stylesheet"> | |
| <style> | |
| body { | |
| font-family: 'Vazirmatn', system-ui, -apple-system, sans-serif; | |
| } | |
| /* Hide browser's default password reveal button */ | |
| input[type="password"]::-ms-reveal, | |
| input[type="password"]::-ms-clear { | |
| display: none; | |
| } | |
| input[type="password"]::-webkit-credentials-auto-fill-button, | |
| input[type="password"]::-webkit-caps-lock-indicator { | |
| display: none; | |
| } | |
| </style> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| fontFamily: { | |
| 'vazir': ['Vazirmatn', 'system-ui', '-apple-system', 'sans-serif'], | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| </head> | |
| <body class="font-vazir bg-gray-50"> | |
| <!-- Split Layout --> | |
| <div class="min-h-screen flex flex-col md:flex-row"> | |
| <!-- Left: Illustration Section --> | |
| <div class="bg-gradient-to-br from-teal-600 via-cyan-500 to-blue-500 p-8 md:p-12 flex flex-col items-center justify-center md:w-2/5"> | |
| <div class="max-w-sm w-full"> | |
| <!-- Illustration Placeholder --> | |
| <div class="bg-white/20 backdrop-blur-sm rounded-3xl p-8 mb-8 shadow-2xl"> | |
| <div class="text-center text-white"> | |
| <img src="../Icons/logo/logo.png" alt="TalimBot Logo" class="w-32 h-32 mx-auto mb-4 rounded-2xl"> | |
| <h2 class="text-2xl font-bold mb-2">سیستم گروهبندی هوشمند</h2> | |
| <p class="text-teal-100 text-sm">مدیریت و گروهبندی دانش آموزان بر اساس شخصیت و سبک یادگیری</p> | |
| </div> | |
| </div> | |
| <h1 class="text-4xl font-extrabold text-white text-center drop-shadow-lg"> | |
| TalimBot | |
| </h1> | |
| </div> | |
| </div> | |
| <!-- Right: Form Section --> | |
| <div class="bg-white p-6 md:p-12 flex-1 flex items-center justify-center"> | |
| <div class="w-full max-w-md space-y-8"> | |
| <!-- Header --> | |
| <div class="text-center"> | |
| <h2 class="text-3xl font-bold text-gray-900 mb-2">سیستم گروهبندی دانش آموزان</h2> | |
| <p class="text-gray-600">لطفاً نقش خود را انتخاب کنید</p> | |
| </div> | |
| <!-- Role Selector --> | |
| <!-- Role Selector --> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <button type="button" id="studentRole" onclick="selectRole('student')" | |
| class="role-card p-6 border-2 border-gray-200 rounded-2xl hover:border-teal-500 hover:bg-teal-50 transition-all duration-300 group"> | |
| <img src="../Icons/studentIcon.png" alt="Student" class="w-24 h-24 mx-auto mb-3 object-cover"> | |
| <h3 class="text-lg font-bold text-gray-800 group-hover:text-teal-600">دانش آموز</h3> | |
| </button> | |
| <button type="button" id="teacherRole" onclick="selectRole('teacher')" | |
| class="role-card p-6 border-2 border-gray-200 rounded-2xl hover:border-cyan-500 hover:bg-cyan-50 transition-all duration-300 group"> | |
| <img src="../Icons/teacherIcon3.png" alt="Teacher" class="w-24 h-24 mx-auto mb-3 object-cover"> | |
| <h3 class="text-lg font-bold text-gray-800 group-hover:text-cyan-600">معلم</h3> | |
| </button> | |
| </div> | |
| <!-- Login Form --> | |
| <form id="loginForm" onsubmit="handleLogin(event)" class="space-y-6"> | |
| <!-- Student Login --> | |
| <div id="studentLogin" class="hidden space-y-4"> | |
| <div> | |
| <label for="nationalCode" class="block text-sm font-semibold text-gray-700 mb-2"> | |
| کد ملی | |
| </label> | |
| <input | |
| type="text" | |
| id="nationalCode" | |
| placeholder="کد ملی خود را وارد کنید" | |
| class="w-full p-4 border-2 border-gray-300 rounded-xl text-center text-lg focus:border-teal-500 focus:ring-2 focus:ring-teal-200 outline-none transition-all" | |
| dir="ltr" | |
| > | |
| <p class="text-xs text-gray-500 mt-2 text-center">کد ملی خود را بدون صفر ابتدایی وارد کنید</p> | |
| </div> | |
| </div> | |
| <!-- Teacher Login --> | |
| <div id="teacherLogin" class="hidden"> | |
| <label for="teacherPassword" class="block text-sm font-semibold text-gray-700 mb-2"> | |
| رمز عبور | |
| </label> | |
| <div class="relative"> | |
| <input | |
| type="password" | |
| id="teacherPassword" | |
| placeholder="رمز عبور خود را وارد کنید" | |
| class="w-full p-4 pl-12 border-2 border-gray-300 rounded-xl focus:border-blue-500 focus:ring-2 focus:ring-blue-200 outline-none transition-all" | |
| > | |
| <button type="button" onclick="togglePassword()" class="absolute left-4 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700 focus:outline-none"> | |
| <svg id="eyeIcon" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/> | |
| </svg> | |
| </button> | |
| </div> | |
| <!-- <p class="text-xs text-gray-500 mt-2 text-center flex items-center justify-center gap-1"> | |
| <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"> | |
| <path d="M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z"/> | |
| </svg> | |
| رمز عبور دمو: teacher123 | |
| </p> --> | |
| </div> | |
| <!-- Submit Button --> | |
| <button | |
| type="submit" | |
| id="loginButton" | |
| disabled | |
| class="w-full bg-gradient-to-r from-teal-600 to-cyan-600 text-white py-4 rounded-xl font-bold text-lg hover:from-teal-700 hover:to-cyan-700 disabled:from-gray-300 disabled:to-gray-400 disabled:cursor-not-allowed transform hover:scale-[1.02] active:scale-[0.98] transition-all duration-300 shadow-lg disabled:shadow-none" | |
| > | |
| ورود به سیستم | |
| </button> | |
| </form> | |
| <!-- Error Message --> | |
| <div id="errorMessage" class="hidden bg-red-50 border-r-4 border-red-500 text-red-700 p-4 rounded-lg"> | |
| <div class="flex items-center gap-2"> | |
| <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"> | |
| <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/> | |
| </svg> | |
| <span id="errorText" class="text-sm font-medium"></span> | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <div class="text-center text-sm text-gray-500"> | |
| <p>نسخه 1.0.0 | آبان 1404</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="../assets/js/data.js"></script> | |
| <script> | |
| let selectedRole = null; | |
| function selectRole(role) { | |
| selectedRole = role; | |
| // Update UI | |
| const studentBtn = document.getElementById('studentRole'); | |
| const teacherBtn = document.getElementById('teacherRole'); | |
| studentBtn.className = 'role-card p-6 border-2 rounded-2xl transition-all duration-300 group'; | |
| teacherBtn.className = 'role-card p-6 border-2 rounded-2xl transition-all duration-300 group'; | |
| if (role === 'student') { | |
| studentBtn.className += ' border-teal-500 bg-teal-50 shadow-lg scale-105'; | |
| document.getElementById('loginButton').className = document.getElementById('loginButton').className.replace('from-teal-600 to-cyan-600', 'from-teal-600 to-teal-700').replace('hover:from-teal-700 hover:to-cyan-700', 'hover:from-teal-700 hover:to-teal-800'); | |
| } else { | |
| teacherBtn.className += ' border-cyan-500 bg-cyan-50 shadow-lg scale-105'; | |
| document.getElementById('loginButton').className = document.getElementById('loginButton').className.replace('from-teal-600 to-teal-700', 'from-teal-600 to-cyan-600').replace('hover:from-teal-700 hover:to-teal-800', 'hover:from-teal-700 hover:to-cyan-700'); | |
| } | |
| // Show appropriate form | |
| document.getElementById('studentLogin').classList.toggle('hidden', role !== 'student'); | |
| document.getElementById('teacherLogin').classList.toggle('hidden', role !== 'teacher'); | |
| // Enable login button | |
| document.getElementById('loginButton').disabled = false; | |
| // Hide error | |
| document.getElementById('errorMessage').classList.add('hidden'); | |
| } | |
| function togglePassword() { | |
| const input = document.getElementById('teacherPassword'); | |
| const type = input.type === 'password' ? 'text' : 'password'; | |
| input.type = type; | |
| } | |
| async function handleLogin(event) { | |
| event.preventDefault(); | |
| const errorDiv = document.getElementById('errorMessage'); | |
| errorDiv.classList.add('hidden'); | |
| if (selectedRole === 'student') { | |
| let nationalCode = document.getElementById('nationalCode').value.trim(); | |
| if (!nationalCode) { | |
| showError('لطفاً کد ملی خود را وارد کنید'); | |
| return; | |
| } | |
| // Check if starts with zero and show warning | |
| if (nationalCode.startsWith('0')) { | |
| showError('لطفاً صفر ابتدایی را از کد ملی حذف کنید'); | |
| return; | |
| } | |
| // No length restriction - just check if it matches a student in database | |
| try { | |
| // Authenticate student with backend using national code only | |
| const response = await fetch('/api/auth/student-by-nationalcode', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ nationalCode }) | |
| }); | |
| if (!response.ok) { | |
| const error = await response.json(); | |
| showError(error.detail || 'خطا در ورود'); | |
| return; | |
| } | |
| const result = await response.json(); | |
| sessionStorage.setItem('currentStudent', result.student.studentNumber); | |
| sessionStorage.setItem('studentName', result.student.name); | |
| window.location.href = 'student-dashboard.html'; | |
| } catch (error) { | |
| showError('خطا در اتصال به سرور. لطفاً اطمینان حاصل کنید که سرور در حال اجرا است'); | |
| console.error('Login error:', error); | |
| } | |
| } else if (selectedRole === 'teacher') { | |
| const password = document.getElementById('teacherPassword').value; | |
| if (!password) { | |
| showError('لطفاً رمز عبور را وارد کنید'); | |
| return; | |
| } | |
| try { | |
| const isValid = await checkTeacherPassword(password); | |
| if (!isValid) { | |
| showError('رمز عبور نادرست است. دوباره تلاش کنید.'); | |
| return; | |
| } | |
| sessionStorage.setItem('isTeacher', 'true'); | |
| window.location.href = 'teacher-dashboard.html'; | |
| } catch (error) { | |
| showError('خطا در اتصال به سرور'); | |
| console.error('Login error:', error); | |
| } | |
| } | |
| } | |
| function showError(message) { | |
| const errorDiv = document.getElementById('errorMessage'); | |
| const errorText = document.getElementById('errorText'); | |
| errorText.textContent = message; | |
| errorDiv.classList.remove('hidden'); | |
| } | |
| </script> | |
| </body> | |
| </html> | |