Spaces:
Running
Running
| <html lang="fa" dir="rtl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ورود و ثبت نام | سیستم امن</title> | |
| <!-- ایمپورت فونت وزیرمتن برای ظاهر زیبای فارسی --> | |
| <link href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css" rel="stylesheet" | |
| type="text/css" /> | |
| <!-- ایمپورت آیکونها --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| /* تغییرات: پسزمینه روشنتر (Slate 800 به جای Slate 900) */ | |
| --bg-color: #1e293b; | |
| /* تغییرات: کارت شیشهای با حالت روشنتر */ | |
| --card-bg: rgba(255, 255, 255, 0.03); | |
| --primary: #6366f1; | |
| --primary-hover: #4f46e5; | |
| --text-main: #f1f5f9; | |
| --text-muted: #cbd5e1; | |
| /* تغییرات: ورودیها با پسزمینه روشنتر */ | |
| --input-bg: rgba(0, 0, 0, 0.2); | |
| --border-color: rgba(255, 255, 255, 0.1); | |
| --error: #ef4444; | |
| --success: #10b981; | |
| --glass-border: 1px solid rgba(255, 255, 255, 0.15); | |
| } | |
| * { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| font-family: 'Vazirmatn', sans-serif; | |
| } | |
| body { | |
| background-color: var(--bg-color); | |
| /* تغییرات: گرادینتها با نورانیته بیشتر برای ایجاد حالت کمتر تاریک */ | |
| background-image: | |
| radial-gradient(at 0% 0%, hsla(253, 16%, 15%, 1) 0, transparent 50%), | |
| radial-gradient(at 50% 0%, hsla(225, 39%, 40%, 1) 0, transparent 50%), | |
| radial-gradient(at 100% 0%, hsla(339, 49%, 40%, 1) 0, transparent 50%); | |
| color: var(--text-main); | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| overflow-x: hidden; | |
| } | |
| /* هدر */ | |
| header { | |
| position: absolute; | |
| top: 20px; | |
| width: 100%; | |
| text-align: center; | |
| z-index: 10; | |
| } | |
| .brand-link { | |
| color: var(--text-muted); | |
| text-decoration: none; | |
| font-size: 0.9rem; | |
| transition: color 0.3s; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 8px; | |
| padding: 8px 16px; | |
| background: rgba(255, 255, 255, 0.08); | |
| border-radius: 20px; | |
| backdrop-filter: blur(5px); | |
| border: 1px solid rgba(255,255,255,0.05); | |
| } | |
| .brand-link:hover { | |
| color: var(--primary); | |
| background: rgba(255, 255, 255, 0.15); | |
| } | |
| /* کارت اصلی */ | |
| .auth-container { | |
| width: 90%; | |
| max-width: 420px; | |
| background: var(--card-bg); | |
| backdrop-filter: blur(20px); | |
| -webkit-backdrop-filter: blur(20px); | |
| border: var(--glass-border); | |
| border-radius: 24px; | |
| padding: 40px 30px; | |
| box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); /* سایه کمتر */ | |
| position: relative; | |
| overflow: hidden; | |
| transition: all 0.4s ease; | |
| } | |
| /* تبهای تغییر وضعیت */ | |
| .tabs { | |
| display: flex; | |
| justify-content: center; | |
| margin-bottom: 30px; | |
| background: var(--input-bg); | |
| padding: 5px; | |
| border-radius: 12px; | |
| position: relative; | |
| } | |
| .tab-btn { | |
| flex: 1; | |
| padding: 12px; | |
| border: none; | |
| background: transparent; | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| border-radius: 8px; | |
| font-size: 1rem; | |
| font-weight: 500; | |
| transition: all 0.3s ease; | |
| z-index: 2; | |
| } | |
| .tab-btn.active { | |
| color: #fff; | |
| background: var(--primary); | |
| box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4); | |
| } | |
| /* فرمها */ | |
| .form-wrapper { | |
| position: relative; | |
| } | |
| .auth-form { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 20px; | |
| transition: opacity 0.3s ease, transform 0.3s ease; | |
| } | |
| .hidden { | |
| display: none; | |
| opacity: 0; | |
| transform: translateX(20px); | |
| } | |
| .visible { | |
| display: flex; | |
| opacity: 1; | |
| transform: translateX(0); | |
| animation: fadeIn 0.4s ease-out; | |
| } | |
| @keyframes fadeIn { | |
| from { | |
| opacity: 0; | |
| transform: translateY(10px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| /* گروه ورودی */ | |
| .input-group { | |
| position: relative; | |
| } | |
| .input-group label { | |
| display: block; | |
| margin-bottom: 8px; | |
| color: var(--text-muted); | |
| font-size: 0.9rem; | |
| } | |
| .input-wrapper { | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| } | |
| .input-wrapper i { | |
| position: absolute; | |
| right: 15px; | |
| color: var(--text-muted); | |
| transition: color 0.3s; | |
| } | |
| .form-input { | |
| width: 100%; | |
| padding: 14px 45px 14px 15px; | |
| background: var(--input-bg); | |
| border: 1px solid var(--border-color); | |
| border-radius: 12px; | |
| color: #fff; | |
| font-size: 1rem; | |
| outline: none; | |
| transition: all 0.3s; | |
| } | |
| .form-input:focus { | |
| border-color: var(--primary); | |
| box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2); | |
| background: rgba(0, 0, 0, 0.3); | |
| } | |
| .form-input:focus+i { | |
| color: var(--primary); | |
| } | |
| /* کپچا */ | |
| .captcha-container { | |
| display: flex; | |
| gap: 10px; | |
| align-items: center; | |
| } | |
| .captcha-canvas { | |
| background: #fff; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| flex-shrink: 0; | |
| } | |
| .captcha-input { | |
| flex-grow: 1; | |
| } | |
| /* دکمه اصلی */ | |
| .submit-btn { | |
| background: linear-gradient(135deg, var(--primary), #818cf8); | |
| color: white; | |
| border: none; | |
| padding: 14px; | |
| border-radius: 12px; | |
| font-size: 1rem; | |
| font-weight: bold; | |
| cursor: pointer; | |
| transition: transform 0.2s, box-shadow 0.2s; | |
| margin-top: 10px; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .submit-btn:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 20px -10px rgba(99, 102, 241, 0.6); | |
| } | |
| .submit-btn:active { | |
| transform: translateY(0); | |
| } | |
| .submit-btn.loading { | |
| opacity: 0.8; | |
| pointer-events: none; | |
| } | |
| .submit-btn.loading i { | |
| animation: spin 1s linear infinite; | |
| } | |
| @keyframes spin { | |
| 100% { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| /* لینک فراموشی رمز */ | |
| .forgot-pass { | |
| text-align: left; | |
| margin-top: -10px; | |
| } | |
| .forgot-pass a { | |
| color: var(--text-muted); | |
| font-size: 0.85rem; | |
| text-decoration: none; | |
| transition: color 0.3s; | |
| } | |
| .forgot-pass a:hover { | |
| color: var(--primary); | |
| } | |
| /* سیستم نوتیفیکیشن (Toast) */ | |
| .toast-container { | |
| position: fixed; | |
| bottom: 20px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| display: flex; | |
| flex-direction: column; | |
| gap: 10px; | |
| z-index: 100; | |
| } | |
| .toast { | |
| background: rgba(30, 41, 59, 0.95); | |
| color: #fff; | |
| padding: 12px 24px; | |
| border-radius: 50px; | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| font-size: 0.9rem; | |
| animation: slideUp 0.3s ease-out; | |
| border: 1px solid var(--border-color); | |
| min-width: 280px; | |
| justify-content: center; | |
| } | |
| .toast.success { | |
| border-color: var(--success); | |
| color: var(--success); | |
| } | |
| .toast.error { | |
| border-color: var(--error); | |
| color: var(--error); | |
| } | |
| @keyframes slideUp { | |
| from { | |
| transform: translateY(20px); | |
| opacity: 0; | |
| } | |
| to { | |
| transform: translateY(0); | |
| opacity: 1; | |
| } | |
| } | |
| /* رسپانسیو */ | |
| @media (max-width: 480px) { | |
| .auth-container { | |
| width: 95%; | |
| padding: 30px 20px; | |
| } | |
| .submit-btn { | |
| padding: 12px; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- هدر و لینک اجباری --> | |
| <header> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="brand-link"> | |
| <i class="fas fa-code"></i> | |
| Built with anycoder | |
| </a> | |
| </header> | |
| <main class="auth-container"> | |
| <!-- تبهای بالا --> | |
| <div class="tabs"> | |
| <button class="tab-btn active" onclick="switchTab('login')">ورود</button> | |
| <button class="tab-btn" onclick="switchTab('register')">ثبتنام</button> | |
| </div> | |
| <!-- فرم ورود --> | |
| <div id="login-form" class="auth-form visible"> | |
| <div class="input-group"> | |
| <label>شماره موبایل</label> | |
| <div class="input-wrapper"> | |
| <input type="tel" id="login-phone" class="form-input" placeholder="مثلا: 09123456789" maxlength="11"> | |
| <i class="fas fa-mobile-alt"></i> | |
| </div> | |
| </div> | |
| <div class="input-group"> | |
| <label>رمز عبور</label> | |
| <div class="input-wrapper"> | |
| <input type="password" id="login-pass" class="form-input" placeholder="رمز عبور خود را وارد کنید"> | |
| <i class="fas fa-lock"></i> | |
| </div> | |
| </div> | |
| <div class="input-group"> | |
| <label>کد امنیتی</label> | |
| <div class="captcha-container"> | |
| <canvas id="login-canvas" width="100" height="44" class="captcha-canvas" | |
| title="برای تغییر کلیک کنید"></canvas> | |
| <input type="text" id="login-captcha-input" class="form-input captcha-input" placeholder="کد تصویر" maxlength="4"> | |
| </div> | |
| </div> | |
| <div class="forgot-pass"> | |
| <a href="#">رمز عبور را فراموش کردهاید؟</a> | |
| </div> | |
| <button class="submit-btn" onclick="handleLogin()"> | |
| <span>ورود به حساب</span> | |
| <i class="fas fa-arrow-left"></i> | |
| </button> | |
| </div> | |
| <!-- فرم ثبت نام --> | |
| <div id="register-form" class="auth-form hidden"> | |
| <div class="input-group"> | |
| <label>شماره موبایل</label> | |
| <div class="input-wrapper"> | |
| <input type="tel" id="reg-phone" class="form-input" placeholder="مثلا: 09123456789" maxlength="11"> | |
| <i class="fas fa-mobile-alt"></i> | |
| </div> | |
| </div> | |
| <div class="input-group"> | |
| <label>رمز عبور</label> | |
| <div class="input-wrapper"> | |
| <input type="password" id="reg-pass" class="form-input" placeholder="حداقل ۸ کاراکتر"> | |
| <i class="fas fa-lock"></i> | |
| </div> | |
| </div> | |
| <div class="input-group"> | |
| <label>تکرار رمز عبور</label> | |
| <div class="input-wrapper"> | |
| <input type="password" id="reg-pass-conf" class="form-input" placeholder="تکرار رمز عبور"> | |
| <i class="fas fa-check-double"></i> | |
| </div> | |
| </div> | |
| <div class="input-group"> | |
| <label>کد امنیتی</label> | |
| <div class="captcha-container"> | |
| <canvas id="reg-canvas" width="100" height="44" class="captcha-captcha" title="برای تغییر کلیک کنید"></canvas> | |
| <input type="text" id="reg-captcha-input" class="form-input captcha-input" placeholder="کد تصویر" maxlength="4"> | |
| </div> | |
| </div> | |
| <button class="submit-btn" onclick="handleRegister()"> | |
| <span>ثبتنام کنید</span> | |
| <i class="fas fa-user-plus"></i> | |
| </button> | |
| </div> | |
| </main> | |
| <!-- کانتینر پیامها --> | |
| <div class="toast-container" id="toast-container"></div> | |
| <script> | |
| // متغیرهای سراسری برای کد کپچا | |
| let loginCaptchaCode = ''; | |
| let regCaptchaCode = ''; | |
| // --- توابع کمکی --- | |
| // تابع نمایش پیام (Toast) | |
| function showToast(message, type = 'success') { | |
| const container = document.getElementById('toast-container'); | |
| const toast = document.createElement('div'); | |
| toast.className = `toast ${type}`; | |
| const icon = type === 'success' ? '<i class="fas fa-check-circle"></i>' : '<i class="fas fa-exclamation-circle"></i>'; | |
| toast.innerHTML = `${icon} <span>${message}</span>`; | |
| container.appendChild(toast); | |
| // حذف پیام بعد از ۳ ثانیه | |
| setTimeout(() => { | |
| toast.style.opacity = '0'; | |
| toast.style.transform = 'translateY(20px)'; | |
| setTimeout(() => toast.remove(), 300); | |
| }, 3000); | |
| } | |
| // تابع اعتبارسنجی شماره موبایل ایران | |
| function isValidPhone(phone) { | |
| const regex = /^09[0-9]{9}$/; | |
| return regex.test(phone); | |
| } | |
| // تولید کپچا تصادفی | |
| function generateCaptcha(canvasId, codeVariable) { | |
| const canvas = document.getElementById(canvasId); | |
| const ctx = canvas.getContext('2d'); | |
| const chars = '0123456789'; | |
| let code = ''; | |
| // پاک کردن بوم | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| // پسزمینه نویز | |
| ctx.fillStyle = '#f0f0f0'; | |
| ctx.fillRect(0, 0, canvas.width, canvas.height); | |
| // رسم خطوط تصادفی | |
| for (let i = 0; i < 7; i++) { | |
| ctx.strokeStyle = `rgba(${Math.random()*255},${Math.random()*255},${Math.random()*255},0.5)`; | |
| ctx.beginPath(); | |
| ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height); | |
| ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height); | |
| ctx.stroke(); | |
| } | |
| // رسم متن | |
| ctx.font = 'bold 24px Vazirmatn, Arial'; | |
| ctx.textBaseline = 'middle'; | |
| for (let i = 0; i < 4; i++) { | |
| const char = chars[Math.floor(Math.random() * chars.length)]; | |
| code += char; | |
| ctx.save(); | |
| // جابجایی و چرخش تصادفی | |
| const x = 20 * i + 15; | |
| const y = canvas.height / 2; | |
| ctx.translate(x, y); | |
| ctx.rotate((Math.random() - 0.5) * 0.4); | |
| ctx.fillStyle = `rgb(${Math.random()*100},${Math.random()*100},${Math.random()*100})`; | |
| ctx.fillText(char, 0, 0); | |
| ctx.restore(); | |
| } | |
| // ذخیره کد در متغیر مناسب | |
| if (canvasId === 'login-canvas') loginCaptchaCode = code; | |
| if (canvasId === 'reg-canvas') regCaptchaCode = code; | |
| } | |
| // --- مدیریت تبها --- | |
| function switchTab(tab) { | |
| const loginForm = document.getElementById('login-form'); | |
| const registerForm = document.getElementById('register-form'); | |
| const btns = document.querySelectorAll('.tab-btn'); | |
| if (tab === 'login') { | |
| loginForm.classList.remove('hidden'); | |
| loginForm.classList.add('visible'); | |
| registerForm.classList.remove('visible'); | |
| registerForm.classList.add('hidden'); | |
| btns[0].classList.add('active'); | |
| btns[1].classList.remove('active'); | |
| generateCaptcha('login-canvas'); // رفرش کپچا هنگام باز شدن | |
| } else { | |
| registerForm.classList.remove('hidden'); | |
| registerForm.classList.add('visible'); | |
| loginForm.classList.remove('visible'); | |
| loginForm.classList.add('hidden'); | |
| btns[0].classList.remove('active'); | |
| btns[1].classList.add('active'); | |
| generateCaptcha('reg-canvas'); // رفرش کپچا هنگام باز شدن | |
| } | |
| } | |
| // --- مدیریت لاگین --- | |
| function handleLogin() { | |
| const phone = document.getElementById('login-phone').value; | |
| const pass = document.getElementById('login-pass').value; | |
| const captcha = document.getElementById('login-captcha-input').value; | |
| const btn = document.querySelector('#login-form .submit-btn'); | |
| // اعتبارسنجی | |
| if (!isValidPhone(phone)) { | |
| showToast('لطفاً شماره موبایل معتبر وارد کنید', 'error'); | |
| return; | |
| } | |
| if (pass.length < 4) { | |
| showToast('رمز عبور اشتباه است', 'error'); | |
| return; | |
| } | |
| if (captcha.toLowerCase() !== loginCaptchaCode) { | |
| showToast('کد امنیتی اشتباه است', 'error'); | |
| generateCaptcha('login-canvas'); | |
| document.getElementById('login-captcha-input').value = ''; | |
| return; | |
| } | |
| // شبیهسازی ارسال به سرور | |
| btn.classList.add('loading'); | |
| btn.innerHTML = '<i class="fas fa-spinner"></i> در حال پردازش...'; | |
| setTimeout(() => { | |
| btn.classList.remove('loading'); | |
| btn.innerHTML = '<span>ورود به حساب</span><i class="fas fa-arrow-left"></i>'; | |
| showToast('خوش آمدید! ورود موفقیت آمیز بود.', 'success'); | |
| // اینجا میتوانید کاربر را ریدایرکت کنید | |
| }, 2000); | |
| } | |
| // --- مدیریت ثبت نام --- | |
| function handleRegister() { | |
| const phone = document.getElementById('reg-phone').value; | |
| const pass = document.getElementById('reg-pass').value; | |
| const passConf = document.getElementById('reg-pass-conf').value; | |
| const captcha = document.getElementById('reg-captcha-input').value; | |
| const btn = document.querySelector('#register-form .submit-btn'); | |
| // اعتبارسنجی | |
| if (!isValidPhone(phone)) { | |
| showToast('شماره موبایل نامعتبر است', 'error'); | |
| return; | |
| } | |
| if (pass.length < 8) { | |
| showToast('رمز عبور باید حداقل ۸ کاراکتر باشد', 'error'); | |
| return; | |
| } | |
| if (pass !== passConf) { | |
| showToast('تکرار رمز عبور مطابقت ندارد', 'error'); | |
| return; | |
| } | |
| if (captcha.toLowerCase() !== regCaptchaCode) { | |
| showToast('کد امنیتی اشتباه است', 'error'); | |
| generateCaptcha('reg-canvas'); | |
| document.getElementById('reg-captcha-input').value = ''; | |
| return; | |
| } | |
| // شبیهسازی ارسال به سرور | |
| btn.classList.add('loading'); | |
| btn.innerHTML = '<i class="fas fa-spinner"></i> در حال ثبت...'; | |
| setTimeout(() => { | |
| btn.classList.remove('loading'); | |
| btn.innerHTML = '<span>ثبتنام کنید</span><i class="fas fa-user-plus"></i>'; | |
| showToast('حساب کاربری با موفقیت ساخته شد.', 'success'); | |
| // سوئیچ به تب لاگین بعد از ثبت نام موفق | |
| setTimeout(() => switchTab('login'), 1500); | |
| }, 2000); | |
| } | |
| // --- رویدادها --- | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // تولید کپچای اولیه | |
| generateCaptcha('login-canvas'); | |
| // قابلیت کلیک روی کپچا برای تغییر | |
| document.getElementById('login-canvas').addEventListener('click', () => generateCaptcha('login-canvas')); | |
| document.getElementById('reg-canvas').addEventListener('click', () => generateCaptcha('reg-canvas')); | |
| // جلوگیری از ورود اعداد انگلیسی/فارسی نامنظم در شماره موبایل (اختیاری) | |
| const phoneInputs = document.querySelectorAll('input[type="tel"]'); | |
| phoneInputs.forEach(input => { | |
| input.addEventListener('input', function(e) { | |
| this.value = this.value.replace(/[^0-9]/g, ''); | |
| }); | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |