| <!DOCTYPE html>
|
| <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;
|
| }
|
|
|
| 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">
|
|
|
| <div class="min-h-screen flex flex-col md:flex-row">
|
|
|
| <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">
|
|
|
| <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>
|
|
|
|
|
| <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">
|
|
|
| <div class="text-center">
|
| <h2 class="text-3xl font-bold text-gray-900 mb-2">سیستم گروهبندی دانش آموزان</h2>
|
| <p class="text-gray-600">لطفاً نقش خود را انتخاب کنید</p>
|
| </div>
|
|
|
|
|
|
|
| <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>
|
|
|
|
|
| <form id="loginForm" onsubmit="handleLogin(event)" class="space-y-6">
|
|
|
| <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>
|
|
|
|
|
| <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>
|
| |
| |
| |
| |
| |
|
|
| </div>
|
|
|
|
|
| <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>
|
|
|
|
|
| <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>
|
|
|
|
|
| <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;
|
|
|
|
|
| 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');
|
| }
|
|
|
|
|
| document.getElementById('studentLogin').classList.toggle('hidden', role !== 'student');
|
| document.getElementById('teacherLogin').classList.toggle('hidden', role !== 'teacher');
|
|
|
|
|
| document.getElementById('loginButton').disabled = false;
|
|
|
|
|
| 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;
|
| }
|
|
|
|
|
| if (nationalCode.startsWith('0')) {
|
| showError('لطفاً صفر ابتدایی را از کد ملی حذف کنید');
|
| return;
|
| }
|
|
|
|
|
|
|
| try {
|
|
|
| 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>
|
|
|