در حال بارگذاری...

کدها و وضعیت‌های HTTP برای HTML

کدها و وضعیت‌های HTTP برای HTML مجموعه‌ای از اعداد و پیام‌هایی هستند که وب‌سرورها هنگام پاسخ به درخواست‌های مرورگر ارسال می‌کنند تا وضعیت پردازش درخواست را به ما نشان دهند. این کدها مانند تابلوهای راهنمای ساختمان‌سازی، نامه‌نگاری یا مرتب‌کردن کتابخانه عمل می‌کنند و به ما می‌گویند که درخواست موفق بوده، خطایی رخ داده یا کاربر باید اقدامات دیگری انجام دهد. در سایت‌هایی مانند فروشگاه‌های آنلاین، وب‌سایت‌های خبری، وبلاگ‌های شخصی و پورتال‌های دولتی، مدیریت صحیح این کدها اهمیت حیاتی دارد تا تجربه کاربری روان و قابل اعتمادی فراهم شود.
در این آموزش، شما با انواع اصلی کدهای HTTP آشنا می‌شوید، یاد می‌گیرید چگونه صفحات خطا یا اطلاع‌رسانی با HTML بسازید و این کدها را به شکل حرفه‌ای در پروژه‌های مختلف پیاده‌سازی کنید. مثل طراحی دقیق یک اتاق یا نامه‌ای واضح، درک صحیح و نمایش درست وضعیت‌ها به بازدیدکنندگان کمک می‌کند تا بدانند سایت در چه وضعیتی است و چگونه باید رفتار کنند.

مثال پایه

html
HTML Code
<!DOCTYPE html>

<html lang="fa">
<head>
<meta charset="UTF-8">
<title>خطای 404 - صفحه پیدا نشد</title>
</head>
<body>
<!-- نمایش پیام برای خطای HTTP 404 -->
<h1>خطا 404: صفحه پیدا نشد</h1>
<p>متأسفانه صفحه‌ای که دنبال آن هستید موجود نیست. لطفاً آدرس را بررسی کنید یا به <a href="index.html">صفحه اصلی</a> بازگردید.</p>
</body>
</html>

در این مثال پایه، یک صفحه ساده HTML برای نمایش پیام خطای HTTP 404 ساخته شده است. ساختار صفحه شامل تگ‌های استاندارد ، و است که مطابق با استاندارد HTML5 می‌باشد. عنوان صفحه () در مرورگر نمایش داده می‌شود و به کاربر اطلاع می‌دهد که با یک خطا روبرو شده است. در داخل <body>، یک عنوان اصلی با تگ <h1> وضعیت خطا را واضح بیان می‌کند و پاراگراف <p> راهنمایی برای کاربر ارائه می‌دهد تا بتواند به صفحه اصلی بازگردد.<br /> کد وضعیت 404 وقتی ارسال می‌شود که سرور نتواند صفحه درخواستی را پیدا کند؛ معمولاً زمانی اتفاق می‌افتد که لینک اشتباه وارد شده یا صفحه حذف شده باشد. با طراحی چنین صفحه‌ای، کاربر به جای دیدن صفحه سفید یا خطای خام، پیامی روشن و قابل فهم دریافت می‌کند و می‌تواند به راحتی مسیر خود را پیدا کند. این روش در پروژه‌های فروشگاه آنلاین یا وبلاگ شخصی بسیار کاربردی است تا از سردرگمی کاربر جلوگیری شود.</p> </div> <!-- Enhanced Code Block --> <div class="code-editor-container"> <div class="code-editor-header"> <h3 class="code-title">مثال کاربردی</h3> <span class="code-language-badge html">html</span> </div> <div class="code-display"> <div class="code-display-header"> <span>HTML Code</span> <div class="flex flex-col sm:flex-row gap-2"> <button type="button" class="copy-button" onclick="copyStaticCode('code-1071', this)"> 📋 کپی </button> <button type="button" class="copy-button bg-green-600 hover:bg-green-700 text-white" onclick="openCodeRunner('html', 'مثال کاربردی', 1071)"> 🚀 اجرای زنده </button> </div> </div> <div class="code-block"> <pre><code id="code-1071" class="language-html"><!DOCTYPE html> <html lang="fa"> <head> <meta charset="UTF-8"> <title>سایت در حال تعمیر (خطای 503)</title> </head> <body> <!-- مثال کاربردی برای وضعیت HTTP 503 --> <header> <h1>سرویس در دسترس نیست (503)</h1> </header> <main> <p>سایت ما در حال به‌روزرسانی است. لطفاً چند دقیقه دیگر مراجعه کنید.</p> <nav> <ul> <li><a href="index.html">صفحه اصلی</a></li> <li><a href="contact.html">تماس با ما</a></li> <li><a href="faq.html">سؤالات متداول</a></li> </ul> </nav> </main> <footer> <small>&copy; 2025 فروشگاه آنلاین شما</small> </footer> </body> </html></code></pre> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>این مثال کاربردی، صفحه‌ای برای نمایش وضعیت HTTP 503 است که نشان می‌دهد سرویس یا سایت به طور موقت در دسترس نیست؛ مثلاً در زمان تعمیرات یا بارگذاری زیاد سرور. ساختار صفحه از تگ‌های معنایی مانند <header>، <main>، <nav> و <footer> استفاده می‌کند که به ساختار بهتر و دسترس‌پذیری بالاتر کمک می‌کنند.<br /> عنوان اصلی با <h1> به کاربر اطلاع می‌دهد که سایت در حال به‌روزرسانی است. پاراگراف زیر آن یک پیام مودبانه و روشن برای کاربران ارسال می‌کند تا متوجه شوند مشکل موقتی است. ناوبری در قالب فهرستی از لینک‌ها، به بازدیدکننده امکان می‌دهد به بخش‌های مهم سایت دسترسی پیدا کند و این باعث کاهش ناامیدی و ترک سایت می‌شود. این نوع صفحات برای پورتال‌های دولتی یا سایت‌های خبری نیز بسیار کاربردی است تا در مواقع بحرانی کاربر را در جریان قرار دهند.</p> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>بهترین روش‌ها و اشتباهات رایج:<br /> بهترین روش‌ها:</p> <ol> <li>استفاده از تگ‌های معنایی HTML (semantic HTML) مثل <header>، <main>، <nav> و <footer> برای ساختاردهی بهتر و افزایش دسترسی (accessibility).</li> <li>نمایش پیام‌های واضح و کاربرپسند همراه با راهنمایی‌های مفید برای ادامه مسیر کاربر.</li> <li>ساده و تمیز نگه داشتن کد و اجتناب از کدهای پیچیده یا تودرتو که نگهداری را سخت می‌کند.</li> <li> <p>اطمینان از اینکه سرور کد وضعیت (status code) درست را در هدر HTTP ارسال می‌کند تا مرورگر و موتورهای جستجو بتوانند به درستی واکنش نشان دهند.<br /> اشتباهات رایج:</p> </li> <li> <p>ارسال کد وضعیت اشتباه، مثلاً ارسال 200 OK برای صفحات خطا که باعث سردرگمی موتورهای جستجو می‌شود.</p> </li> <li>استفاده بیش از حد از تگ‌های <div> و <span> به جای تگ‌های معنایی.</li> <li>عدم ارائه لینک یا راهنمایی به کاربر که باعث می‌شود او در صفحه خطا سردرگم بماند.</li> <li>تودرتو شدن نامناسب یا عدم بسته شدن صحیح تگ‌ها که باعث خرابی نمایش صفحه می‌شود.<br /> نکات عیب‌یابی:</li> </ol> <ul> <li>از ابزارهای توسعه‌دهنده مرورگر برای بررسی هدرهای HTTP و کد وضعیت استفاده کنید.</li> <li>صفحات خطا را با ارسال کدهای مختلف تست کنید تا مطمئن شوید به درستی نمایش داده می‌شوند.</li> <li>کد HTML را با ویرایشگرهای استاندارد یا Validator بررسی کنید تا خطاهای نحوی نداشته باشید.</li> </ul> </div> <!-- Enhanced Reference Table --> <div class="table-responsive"> <div class="bg-white p-6"> <h3 class="text-xl font-semibold mb-4 text-gray-800">📊 مرجع سریع</h3> <div class="overflow-x-auto"> <table class="w-full table-auto border-collapse"> <thead> <tr class="bg-gradient-to-r from-gray-50 to-gray-100"> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">وضعیت کد</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">توضیح</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">مثال</th> </tr> </thead> <tbody> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">200 OK</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">درخواست با موفقیت انجام شده و صفحه بارگذاری شده</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">نمایش صفحه اصلی فروشگاه آنلاین</td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">301 Moved Permanently</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">انتقال دائمی به URL جدید</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">هدایت صفحات قدیمی وبلاگ به صفحات جدید</td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">404 Not Found</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">درخواست صفحه یا منبع یافت نشد</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">درخواست صفحه حذف شده در سایت خبری</td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">500 Internal Server Error</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">خطای سرور داخلی</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">خطا در پردازش سفارش در فروشگاه</td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">503 Service Unavailable</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">سرویس به طور موقت در دسترس نیست</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">نمایش صفحه تعمیرات سایت دولتی</td> </tr> </tbody> </table> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>خلاصه و مراحل بعدی:<br /> در این آموزش با کدها و وضعیت‌های HTTP آشنا شدید و یاد گرفتید چگونه با طراحی صفحات HTML مناسب، تجربه کاربری را در مواجهه با خطاها یا وضعیت‌های خاص بهبود دهید. شناخت دقیق این کدها همانند طراحی اصولی خانه یا نامه‌نگاری دقیق، به شما کمک می‌کند تا به درستی پیام مورد نظر را منتقل کنید.<br /> مرحله بعدی یادگیری، ترکیب این صفحات با <a href="/fa/css/" class="smart-link">CSS</a> برای زیباسازی و جاوااسکریپت برای افزودن تعاملات مانند ریدایرکت خودکار یا شمارش معکوس است. همچنین می‌توانید در سطح سرور، مثلاً با PHP یا Node.js، کنترل دقیق‌تری روی ارسال کدهای HTTP داشته باشید.<br /> مطالعه عمیق‌تر در زمینه روش‌های HTTP، طراحی RESTful API و بهینه‌سازی صفحات خطا برای موتورهای جستجو (SEO) می‌تواند به ارتقاء مهارت‌های شما کمک کند و تجربه وب‌سایت شما را حرفه‌ای‌تر نماید.</p> </div> </div> <!-- Keywords Section --> <!-- Content Reporting Widget --> <!-- Content Reporting Widget --> <div class="content-report-container" id="report-container" data-content-type-id="10" data-object-id="47"> <div class="report-dropdown" id="report-dropdown"> <button type="button" class="report-button" id="report-button"> <span>👋</span> <span>Report Issue</span> </button> <div class="dropdown-menu" id="dropdown-menu"> <!-- Categories will be loaded dynamically by JavaScript --> </div> </div> </div> <!-- Load Required CSS and JS --> <link rel="stylesheet" href="/static/css/content-reporting.3f7dc51ec48b.css"> <script src="/static/js/content-reporting.37a7bd46d1db.js" defer></script> <!-- Enhanced Quiz Section --> <div class="mb-8"> <h2 class="text-2xl md:text-3xl font-bold mb-6 bg-clip-text"> 🧠 دانش خود را بیازمایید </h2> <!-- Modern Quiz Container - Direct Display --> <div id="quiz-container" class="quiz-modern-container"> <!-- Hidden CSRF Token --> <input type="hidden" name="csrfmiddlewaretoken" value="OmLlpUyLtbt1DhxxXer6FbFLymomg8DueBzO9tEQV8WNxR6p8CMO0KcxIQqMU04B"> <!-- Quiz Header with Progress --> <div class="quiz-header"> <div class="quiz-progress-wrapper"> <div class="quiz-progress-track"> <div id="quiz-progress-fill" class="quiz-progress-fill"></div> </div> <div class="quiz-progress-info"> <span id="progress-text" class="progress-current">آماده شروع</span> <span id="progress-stats" class="progress-stats"></span> </div> </div> <!-- Timer (if applicable) --> <div id="quiz-timer-wrapper" class="quiz-timer-wrapper" style="display: none;"> <div class="timer-icon">⏱️</div> <span id="timer-display" class="timer-display">10:00</span> </div> </div> <!-- Quiz Content Area --> <div class="quiz-content-area"> <!-- Quiz Introduction - Now Always Visible --> <div id="quiz-intro" class="quiz-intro-section"> <div class="quiz-intro-icon"> <div class="icon-circle"> <svg class="brain-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/> </svg> </div> </div> <h3 class="quiz-intro-title">اختبر معرفتك</h3> <p class="quiz-intro-subtitle">اختبر فهمك لهذا الموضوع بأسئلة عملية.</p> <!-- Quiz Stats Grid --> <div id="quiz-stats-grid" class="quiz-stats-grid"> <div class="quiz-stat-card"> <span class="stat-icon">❓</span> <div class="stat-value">3</div> <div class="stat-label">سوالات</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">🎯</span> <div class="stat-value">70%</div> <div class="stat-label">برای قبولی</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">♾️</span> <div class="stat-value">∞</div> <div class="stat-label">زمان</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">🔄</span> <div class="stat-value">∞</div> <div class="stat-label">تلاش‌ها</div> </div> </div> <!-- Quiz Instructions --> <div class="quiz-instructions"> <h4 class="instructions-title">📝 دستورالعمل‌ها</h4> <ul class="instructions-list"> <li>هر سوال را با دقت بخوانید</li> <li>بهترین پاسخ را برای هر سوال انتخاب کنید</li> <li>می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید</li> <li>پیشرفت شما در بالا نمایش داده می‌شود</li> </ul> </div> <button id="start-quiz-btn" class="quiz-start-button" onclick="startQuiz(47)"> <span class="button-content"> <svg class="button-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1m-6 4h8"/> </svg> شروع آزمون </span> <div class="button-ripple"></div> </button> </div> <!-- Quiz Questions Section --> <div id="quiz-questions" class="quiz-questions-section" style="display: none;"> <!-- Question Header --> <div class="question-header"> <div class="question-meta"> <span id="question-number" class="question-counter">سوال 1</span> <div class="question-type-badge" id="question-type"> <span>📝</span> </div> </div> </div> <!-- Question Content --> <div id="current-question" class="question-content"> <!-- Question will be loaded here --> </div> <!-- Question Actions --> <div class="question-actions"> <button id="submit-answer" class="submit-answer-btn" onclick="submitAnswer()" disabled> <span class="btn-text">ارسال پاسخ</span> <div class="btn-loader" style="display: none;"> <div class="loader-spinner"></div> </div> </button> </div> </div> <!-- Quiz Results Section --> <div id="quiz-results" class="quiz-results-section" style="display: none;"> <!-- Results will be populated here --> </div> <!-- Loading State --> <div id="quiz-loading" class="quiz-loading-section" style="display: none;"> <div class="loading-animation"> <div class="loading-spinner"></div> <div class="loading-dots"> <span></span> <span></span> <span></span> </div> </div> <p class="loading-text">بارگذاری آزمون شما...</p> </div> </div> <!-- Error Display --> <div id="quiz-error" class="quiz-error-display" style="display: none;"> <div class="error-content"> <div class="error-icon">⚠️</div> <div class="error-message"></div> <button class="error-close" onclick="hideError()">✕</button> </div> </div> </div> <script> let currentQuiz = null; let currentQuestionIndex = 0; let selectedAnswer = null; let quizTimer = null; let timeRemaining = null; let currentQuestionData = null; let quizSessionData = null; // Store quiz session data for answer sheet function getCsrfToken() { let token = null; const quizContainer = document.getElementById('quiz-container'); if (quizContainer) { const tokenInput = quizContainer.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { token = tokenInput.value; } } if (!token) { const tokenInput = document.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { token = tokenInput.value; } } if (!token) { const cookieMatch = document.cookie.match(/csrftoken=([^;]+)/); if (cookieMatch) { token = cookieMatch[1]; } } return token; } function startQuiz(topicId) { console.log('Starting quiz for topic:', topicId); // Reset quiz session data quizSessionData = { questions: [], answers: {}, correctAnswers: {}, explanations: {}, startTime: new Date().toISOString() }; // Show loading showSection('quiz-loading'); updateProgress(0, 'راه‌اندازی آزمون...', ''); const csrfToken = getCsrfToken(); if (!csrfToken) { console.error('CSRF token not found'); showError('Security token not found. Please refresh the page.'); showSection('quiz-intro'); return; } const formData = new FormData(); formData.append('csrfmiddlewaretoken', csrfToken); const url = `/fa/quiz/${topicId}/start/`; fetch(url, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { if (data.success) { currentQuiz = data.quiz; currentQuestionIndex = 0; // Setup timer if quiz has time limit if (currentQuiz.time_limit) { setupTimer(currentQuiz.time_limit); } // Show quiz questions section showSection('quiz-questions'); // Load first question loadQuestion(data.current_question, data.question_number, data.total_questions); } else { console.error('Quiz start failed:', data.error); showError(data.error || 'Failed to start quiz'); showSection('quiz-intro'); } }) .catch(error => { console.error('Fetch error:', error); showError('شروع آزمون ناموفق بود. لطفاً دوباره تلاش کنید.'); showSection('quiz-intro'); }); } function loadQuestion(question, questionNumber, totalQuestions) { console.log('Loading question:', question); // Store current question data currentQuestionData = question; // Store question in session data quizSessionData.questions[questionNumber - 1] = question; // Update progress const progressPercent = (questionNumber / totalQuestions) * 100; updateProgress(progressPercent, `سوال ${questionNumber}`, `${questionNumber} از ${totalQuestions}`); // Update question number const questionNumberEl = document.getElementById('question-number'); if (questionNumberEl) { questionNumberEl.textContent = `سوال ${questionNumber}`; } // Update question type badge const questionTypeEl = document.getElementById('question-type'); if (questionTypeEl) { const typeIcons = { 'multiple_choice': '📝', 'true_false': '✅', 'fill_code': '💻' }; questionTypeEl.innerHTML = `<span>${typeIcons[question.type] || '📝'}</span>`; } // Reset selected answer selectedAnswer = null; const submitBtn = document.getElementById('submit-answer'); if (submitBtn) { submitBtn.disabled = true; submitBtn.querySelector('.btn-text').textContent = 'ارسال پاسخ'; } // Generate question HTML let questionHTML = ` <div class="question-text">${escapeHtml(question.text)}</div> `; // Add code template if exists if (question.code_template && question.code_template.trim()) { questionHTML += ` <div class="code-block"> <pre><code>${escapeHtml(question.code_template)}</code></pre> </div> `; } // Add options questionHTML += '<div class="options-container">'; if (question.options && question.options.length > 0) { question.options.forEach((option, index) => { questionHTML += ` <div class="option-item" onclick="selectOption(${option.id}, this)"> <input type="radio" name="quiz-option" value="${option.id}" style="display: none;"> <div class="option-content"> <div class="option-indicator"></div> <div class="option-text">${escapeHtml(option.text)}</div> </div> </div> `; }); } else { questionHTML += '<p class="error-message">No options available for this question.</p>'; } questionHTML += '</div>'; // Insert question content with animation const questionContainer = document.getElementById('current-question'); if (questionContainer) { questionContainer.style.opacity = '0'; questionContainer.innerHTML = questionHTML; // Animate in setTimeout(() => { questionContainer.style.transition = 'opacity 0.3s ease'; questionContainer.style.opacity = '1'; }, 100); } } function selectOption(optionId, element) { console.log('Option selected:', optionId); selectedAnswer = optionId; // Update visual feedback document.querySelectorAll('.option-item').forEach(item => { item.classList.remove('selected'); }); element.classList.add('selected'); // Enable submit button const submitBtn = document.getElementById('submit-answer'); if (submitBtn) { submitBtn.disabled = false; } } function submitAnswer() { if (!selectedAnswer || !currentQuestionData) { console.log('No answer selected or no question data'); return; } console.log('Submitting answer:', selectedAnswer, 'for question:', currentQuestionData.id); // Store user answer in session data quizSessionData.answers[currentQuestionData.id] = { selectedOptionId: selectedAnswer, selectedOptionText: getSelectedOptionText(selectedAnswer) }; const submitBtn = document.getElementById('submit-answer'); if (!submitBtn) return; // Show loading state submitBtn.disabled = true; submitBtn.querySelector('.btn-text').style.opacity = '0'; submitBtn.querySelector('.btn-loader').style.display = 'block'; const csrfToken = getCsrfToken(); if (!csrfToken) { console.error('CSRF token not found for submit'); showError('Security token not found. Please refresh the page.'); resetSubmitButton(submitBtn); return; } const formData = new FormData(); formData.append('question_id', currentQuestionData.id); formData.append('selected_option', selectedAnswer); formData.append('csrfmiddlewaretoken', csrfToken); const url = `/fa/quiz/${currentQuiz.id}/submit/`; fetch(url, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { if (data.success) { if (data.completed) { // Quiz completed - load results loadQuizResults(data.redirect_url); } else { // Load next question setTimeout(() => { loadQuestion(data.current_question, data.question_number, data.total_questions); resetSubmitButton(submitBtn); }, 500); } } else { console.error('Submit failed:', data.error); showError(data.error || 'Failed to submit answer'); resetSubmitButton(submitBtn); } }) .catch(error => { console.error('Submit fetch error:', error); showError('ارسال پاسخ ناموفق بود. لطفاً دوباره تلاش کنید.'); resetSubmitButton(submitBtn); }); } function getSelectedOptionText(optionId) { if (!currentQuestionData || !currentQuestionData.options) return ''; const option = currentQuestionData.options.find(opt => opt.id == optionId); return option ? option.text : ''; } function loadQuizResults(resultUrl) { console.log('Loading results from:', resultUrl); // Show loading while fetching results showSection('quiz-loading'); updateProgress(100, 'در حال محاسبه نتایج...', 'لطفاً منتظر بمانید'); fetch(resultUrl, { headers: { 'HX-Request': 'true' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.text(); }) .then(html => { // Parse the results and extract detailed information const tempDiv = document.createElement('div'); tempDiv.innerHTML = html; // Extract score data from the response const scoreElement = tempDiv.querySelector('.score-percentage') || tempDiv.querySelector('[data-score]'); let scoreValue = 0; if (scoreElement) { const scoreText = scoreElement.textContent || scoreElement.getAttribute('data-score') || '0'; scoreValue = parseInt(scoreText.replace('%', '')) || 0; } const correctElement = tempDiv.querySelector('.correct-answers') || tempDiv.querySelector('[data-correct]'); let correctAnswers = 0; if (correctElement) { const correctText = correctElement.textContent || correctElement.getAttribute('data-correct') || '0'; correctAnswers = parseInt(correctText) || 0; } const totalElement = tempDiv.querySelector('.total-questions') || tempDiv.querySelector('[data-total]'); let totalQuestions = currentQuiz.total_questions || 0; if (totalElement) { const totalText = totalElement.textContent || totalElement.getAttribute('data-total') || '0'; totalQuestions = parseInt(totalText) || totalQuestions; } // Extract detailed question results extractQuestionResults(tempDiv); // Save quiz result for authenticated users if (window.siteConfig && window.siteConfig.isAuthenticated && window.saveQuizResult) { const quizData = { quiz_id: currentQuiz.id, score: correctAnswers, total_questions: totalQuestions, correct_answers: correctAnswers, time_spent: calculateQuizTime(), answers: quizSessionData, passing_score: currentQuiz.passing_score || 70 }; window.saveQuizResult(quizData).catch(error => { console.error('Failed to save quiz result:', error); }); } displayResults(scoreValue, correctAnswers, totalQuestions); // Stop timer if running if (quizTimer) { clearInterval(quizTimer); hideTimer(); } }) .catch(error => { console.error('Results fetch error:', error); showError('بارگذاری نتایج ناموفق بود. لطفاً صفحه را تازه‌سازی کنید.'); showSection('quiz-questions'); }); } function calculateQuizTime() { // Calculate time spent from quiz session start if (quizSessionData && quizSessionData.startTime) { const startTime = new Date(quizSessionData.startTime); const endTime = new Date(); return Math.floor((endTime - startTime) / 1000); // Return seconds } return 0; } function extractQuestionResults(resultContainer) { // Extract detailed results from the Django-generated HTML const questionContainers = resultContainer.querySelectorAll('.border-b, .border'); questionContainers.forEach((container, index) => { try { // Extract question text const questionTextEl = container.querySelector('p.text-gray-700, .text-gray-700'); const questionText = questionTextEl ? questionTextEl.textContent.trim() : `Question ${index + 1}`; // Extract correct/incorrect status const correctSpan = container.querySelector('.bg-green-100'); const incorrectSpan = container.querySelector('.bg-red-100'); const isCorrect = correctSpan !== null; // Extract user's answer let userAnswer = ''; const userAnswerSpans = container.querySelectorAll('.text-red-600, .text-green-600'); for (let span of userAnswerSpans) { const text = span.textContent; if (text.includes('Your answer:')) { userAnswer = text.replace('Your answer:', '').trim(); break; } } // Extract correct answer let correctAnswer = ''; const greenSpans = container.querySelectorAll('.text-green-600'); for (let span of greenSpans) { const text = span.textContent.trim(); const parentText = span.parentElement ? span.parentElement.textContent : ''; // Check if this span contains "Correct answer:" in its parent context if (parentText.includes('Correct answer:') && !text.includes('Your answer:')) { // Extract only the answer part after "Correct answer:" const parts = parentText.split('Correct answer:'); if (parts.length > 1) { correctAnswer = parts[1].split('Explanation:')[0].trim(); break; } } } // Fallback: if still empty, use user answer for correct questions if (!correctAnswer && isCorrect) { correctAnswer = userAnswer; } // Extract explanation let explanation = ''; const explanationEl = container.querySelector('.bg-blue-50 p'); if (explanationEl) { explanation = explanationEl.textContent.replace('Explanation:', '').trim(); } // Store in session data const questionId = quizSessionData.questions[index] ? quizSessionData.questions[index].id : index + 1; quizSessionData.correctAnswers[questionId] = { isCorrect: isCorrect, correctAnswer: correctAnswer, explanation: explanation, questionText: questionText }; } catch (error) { console.error('Error extracting question result:', error); } }); } function displayResults(scoreValue, correctAnswers, totalQuestions) { const passed = scoreValue >= (currentQuiz.passing_score || 70); const resultsSection = document.getElementById('quiz-results'); if (!resultsSection) return; resultsSection.innerHTML = ` <div class="result-header"> <div class="result-status-icon ${passed ? 'passed' : 'failed'}"> ${passed ? '🎉' : '📚'} </div> <h3 class="result-title"> ${passed ? 'تبریک!' : 'به یادگیری ادامه دهید!'} </h3> <p class="result-subtitle"> ${passed ? 'در آزمون قبول شدید!' : 'می‌توانید بهتر عمل کنید. دوباره تلاش کنید!'} </p> </div> <div class="score-display"> <div class="score-percentage ${passed ? 'passed' : 'failed'}">${scoreValue}%</div> <div class="score-details"> ${correctAnswers} از ${totalQuestions} صحیح </div> <div class="score-bar"> <div class="score-fill" style="width: 0%"></div> </div> <div style="margin-top: 1rem; font-size: 0.875rem; opacity: 0.8;"> نمره قبولی: ${currentQuiz.passing_score || 70}% </div> </div> <div class="result-actions"> <button class="result-btn primary" onclick="retakeQuiz()"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/> </svg> تکرار آزمون </button> <button class="result-btn secondary" onclick="toggleAnswerSheet()" id="view-answers-btn"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> </svg> مشاهده پاسخ‌ها </button> <button class="result-btn secondary" onclick="closeQuiz()"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/> </svg> بستن </button> </div> <!-- Answer Sheet Section --> <div id="answer-sheet" class="answer-sheet-section" style="display: none;"> <div class="answer-sheet-header"> <h4>📋 برگه پاسخ‌ها</h4> <button class="close-answer-sheet" onclick="toggleAnswerSheet()">✕</button> </div> <div id="answer-sheet-content" class="answer-sheet-content"> بارگذاری پاسخ‌ها... </div> </div> `; // Show results section showSection('quiz-results'); updateProgress(100, 'آزمون تکمیل شد!', `${scoreValue}% امتیاز`); // Animate score bar setTimeout(() => { const scoreFill = resultsSection.querySelector('.score-fill'); if (scoreFill) { scoreFill.style.width = `${scoreValue}%`; } }, 500); } // Answer sheet functions function toggleAnswerSheet() { const answerSheet = document.getElementById('answer-sheet'); const btn = document.getElementById('view-answers-btn'); if (answerSheet.style.display === 'none' || answerSheet.style.display === '') { answerSheet.style.display = 'block'; loadAnswerSheet(); btn.innerHTML = ` <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/> </svg> مخفی کردن پاسخ‌ها `; } else { answerSheet.style.display = 'none'; btn.innerHTML = ` <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> </svg> مشاهده پاسخ‌ها `; } } function loadAnswerSheet() { const answerSheetContent = document.getElementById('answer-sheet-content'); if (!answerSheetContent || !quizSessionData) return; let correctCount = 0; let incorrectCount = 0; let answerSheetHTML = ` <div class="answer-summary"> <div class="summary-stat total"> <div class="number">${currentQuiz.total_questions || 0}</div> <div class="label">کل سوالات</div> </div> <div class="summary-stat correct"> <div class="number" id="correct-count">0</div> <div class="label">صحیح</div> </div> <div class="summary-stat incorrect"> <div class="number" id="incorrect-count">0</div> <div class="label">نادرست</div> </div> </div> <div class="answer-grid"> `; // Generate answer sheet for each question quizSessionData.questions.forEach((question, index) => { if (!question) return; const questionId = question.id; const userAnswer = quizSessionData.answers[questionId]; const correctInfo = quizSessionData.correctAnswers[questionId]; if (!userAnswer || !correctInfo) return; const isCorrect = correctInfo.isCorrect; if (isCorrect) { correctCount++; } else { incorrectCount++; } answerSheetHTML += ` <div class="answer-item ${isCorrect ? 'correct' : 'incorrect'}"> <div class="question-number">Q${index + 1}</div> <div class="question-details"> <div class="question-text">${escapeHtml(correctInfo.questionText || question.text)}</div> <div class="answer-comparison"> <div class="user-answer"> <span class="label">Your Answer:</span> <span class="value ${isCorrect ? 'correct' : 'incorrect'}">${escapeHtml(userAnswer.selectedOptionText)}</span> </div> ${!isCorrect ? ` <div class="correct-answer"> <span class="label">Correct Answer:</span> <span class="value correct">${escapeHtml(correctInfo.correctAnswer)}</span> </div> ` : ''} ${correctInfo.explanation ? ` <div class="explanation"> <span class="label">توضیح:</span> <span class="explanation-text">${escapeHtml(correctInfo.explanation)}</span> </div> ` : ''} </div> </div> <div class="result-icon"> ${isCorrect ? '✅' : '❌'} </div> </div> `; }); answerSheetHTML += '</div>'; answerSheetContent.innerHTML = answerSheetHTML; // Update summary counts document.getElementById('correct-count').textContent = correctCount; document.getElementById('incorrect-count').textContent = incorrectCount; } function retakeQuiz() { // Reset quiz state currentQuiz = null; currentQuestionIndex = 0; selectedAnswer = null; currentQuestionData = null; quizSessionData = null; if (quizTimer) { clearInterval(quizTimer); hideTimer(); } // Show intro section showSection('quiz-intro'); updateProgress(0, 'آماده شروع', ''); } function closeQuiz() { // Just reset and hide for now since we're directly displaying retakeQuiz(); } function showSection(sectionId) { const sections = ['quiz-intro', 'quiz-questions', 'quiz-results', 'quiz-loading']; sections.forEach(id => { const element = document.getElementById(id); if (element) { element.style.display = id === sectionId ? 'block' : 'none'; } }); } function updateProgress(percentage, currentText, statsText) { const progressFill = document.getElementById('quiz-progress-fill'); const progressText = document.getElementById('progress-text'); const progressStats = document.getElementById('progress-stats'); if (progressFill) { progressFill.style.width = `${percentage}%`; } if (progressText) { progressText.textContent = currentText; } if (progressStats) { progressStats.textContent = statsText; } } function setupTimer(timeLimit) { const timerWrapper = document.getElementById('quiz-timer-wrapper'); const timerDisplay = document.getElementById('timer-display'); if (!timerWrapper || !timerDisplay) return; timeRemaining = timeLimit * 60; // Convert to seconds timerWrapper.style.display = 'flex'; quizTimer = setInterval(() => { const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; timerDisplay.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; // Warning when time is running out if (timeRemaining <= 60) { timerWrapper.style.color = '#ef4444'; timerWrapper.style.animation = 'pulse 1s infinite'; } if (timeRemaining <= 0) { clearInterval(quizTimer); if (selectedAnswer) { submitAnswer(); } else { showError('زمان تمام شد! آزمون به صورت خودکار ارسال می‌شود.'); } } timeRemaining--; }, 1000); } function hideTimer() { const timerWrapper = document.getElementById('quiz-timer-wrapper'); if (timerWrapper) { timerWrapper.style.display = 'none'; } } function resetSubmitButton(button) { if (!button) return; button.disabled = false; button.querySelector('.btn-text').style.opacity = '1'; button.querySelector('.btn-loader').style.display = 'none'; } function showError(message) { console.log('Showing error:', message); const errorDisplay = document.getElementById('quiz-error'); if (!errorDisplay) return; const errorMessage = errorDisplay.querySelector('.error-message'); if (errorMessage) { errorMessage.textContent = message; } errorDisplay.style.display = 'block'; // Auto-hide after 5 seconds setTimeout(() => { hideError(); }, 5000); } function hideError() { const errorDisplay = document.getElementById('quiz-error'); if (errorDisplay) { errorDisplay.style.display = 'none'; } } function escapeHtml(unsafe) { if (typeof unsafe !== 'string') { return unsafe; } return unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // Initialize quiz when page loads document.addEventListener('DOMContentLoaded', function() { // Quiz is now directly visible, no need for showQuiz() function console.log('Quiz components loaded'); }); // HTMX after-swap event document.body.addEventListener('htmx:afterSwap', function() { // Reinitialize quiz if it exists on the swapped content console.log('Quiz components reloaded after HTMX swap'); }); </script> </div> <!-- Enhanced Navigation --> <div class="topic-navigation"> <div class="nav-links"> <div></div> <div class="nav-center"> <div class="text-sm font-semibold">موضوع 1 از 1</div> <div class="text-xs mt-1 opacity-75">Html آموزش</div> </div> <div></div> </div> </div> </div> <script> const sessionKey = `code_session_${codeExampleId}`; // Smart Link Click Tracking document.addEventListener('click', function(event) { const smartLink = event.target.closest('.smart-link'); if (smartLink) { const keywordId = smartLink.getAttribute('data-keyword-id'); if (keywordId) { // Track click asynchronously fetch('/fa/api/smart-link-click/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': 'OmLlpUyLtbt1DhxxXer6FbFLymomg8DueBzO9tEQV8WNxR6p8CMO0KcxIQqMU04B' }, body: JSON.stringify({ keyword_id: keywordId, source_content_type: 'topic', source_content_id: 47, user_agent: navigator.userAgent }) }).catch(error => { console.debug('Smart link tracking failed:', error); }); } } }); function openCodeRunner(language, title, codeExampleId) { const codeElement = document.getElementById('code-' + codeExampleId); const code = codeElement.textContent; const formData = new FormData(); formData.append('language', language); formData.append('title', title); formData.append('code', code); formData.append('source_example_id', codeExampleId); formData.append('csrfmiddlewaretoken', 'OmLlpUyLtbt1DhxxXer6FbFLymomg8DueBzO9tEQV8WNxR6p8CMO0KcxIQqMU04B'); fetch('/fa/create-code-session/', { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => response.json()) .then(data => { if (data.success) { window.open(data.url, '_blank'); } else { console.error('Error creating session:', data.error); window.open('/fa/try-it/' + language + '/', '_blank'); } }) .catch(error => { console.error('Error:', error); window.open('/fa/try-it/' + language + '/', '_blank'); }); } document.body.addEventListener('htmx:afterSwap', function() { window.scrollTo({ top: 0, behavior: 'smooth' }); if (typeof Prism !== 'undefined') { Prism.highlightAll(); } if (typeof populateQuizStats === 'function') { populateQuizStats(); } if (window.mobileMenu && window.mobileMenu.isMenuOpen && window.mobileMenu.isMenuOpen()) { window.mobileMenu.forceClose(); } initializeEnhancedFeatures(); }); function initializeEnhancedFeatures() { // Initialize topic tracking for authenticated users if (window.siteConfig && window.siteConfig.isAuthenticated) { initializeTopicTracking(); } document.querySelectorAll('.nav-link, .custom-sidebar-item').forEach(link => { link.addEventListener('click', function() { if (this.hasAttribute('hx-get')) { this.classList.add('loading'); setTimeout(() => { this.classList.remove('loading'); }, 1000); } }); }); document.querySelectorAll('.code-block pre').forEach(pre => { const code = pre.querySelector('code'); if (code && code.textContent.split('\n').length > 3) { pre.classList.add('line-numbers'); } }); } function initializeTopicTracking() { // Track topic view for authenticated users const topicId = getTopicIdFromCurrentUrl(); const categorySlug = getCategorySlugFromCurrentUrl(); if (topicId && categorySlug) { // Track initial view trackTopicView({ topic_id: topicId, category_slug: categorySlug }); // Track scroll percentage let maxScrollPercentage = 0; let timeSpent = 0; let startTime = Date.now(); window.addEventListener('scroll', throttle(function() { const scrollPercentage = calculateScrollPercentage(); if (scrollPercentage > maxScrollPercentage) { maxScrollPercentage = scrollPercentage; } }, 1000)); // Track time spent setInterval(() => { if (!document.hidden) { timeSpent += 5; // Add 5 seconds } }, 5000); // Send final data on page unload window.addEventListener('beforeunload', function() { if (maxScrollPercentage > 0 || timeSpent > 0) { trackTopicView({ topic_id: topicId, category_slug: categorySlug, scroll_percentage: maxScrollPercentage, time_spent: timeSpent, completed: maxScrollPercentage >= 80 // Consider 80% as completed }); } }); } } function getTopicIdFromCurrentUrl() { const pathParts = window.location.pathname.split('/').filter(Boolean); const languages = ['en', 'fa', 'ar', 'zh', 'hi', 'fr', 'de', 'ru', 'tr', 'pt', 'es']; let startIndex = 0; if (languages.includes(pathParts[0])) { startIndex = 1; } if (pathParts.length >= startIndex + 2) { return pathParts[startIndex + 1]; // Return topic slug } return null; } function getCategorySlugFromCurrentUrl() { const pathParts = window.location.pathname.split('/').filter(Boolean); const languages = ['en', 'fa', 'ar', 'zh', 'hi', 'fr', 'de', 'ru', 'tr', 'pt', 'es']; let startIndex = 0; if (languages.includes(pathParts[0])) { startIndex = 1; } if (pathParts.length >= startIndex + 1) { return pathParts[startIndex]; // Return category slug } return null; } function trackTopicView(data) { if (!window.siteConfig || !window.siteConfig.isAuthenticated) { return Promise.resolve(); } return fetch('/account/ajax/track-topic-view/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': window.siteConfig.csrfToken || getCsrfToken() }, body: JSON.stringify(data) }).catch(error => { console.debug('Topic view tracking failed:', error); }); } function calculateScrollPercentage() { const scrollTop = window.pageYOffset; const docHeight = document.documentElement.scrollHeight - window.innerHeight; return Math.min(100, Math.max(0, (scrollTop / docHeight) * 100)); } function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } function getCsrfToken() { const tokenInput = document.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { return tokenInput.value; } const cookieMatch = document.cookie.match(/csrftoken=([^;]+)/); return cookieMatch ? cookieMatch[1] : null; } document.addEventListener('DOMContentLoaded', function() { initializeEnhancedFeatures(); if (typeof Prism !== 'undefined') { Prism.highlightAll(); } document.body.addEventListener('htmx:beforeRequest', function(event) { const target = event.target; if (target.classList.contains('nav-link') || target.classList.contains('custom-sidebar-item')) { target.style.opacity = '0.7'; target.style.pointerEvents = 'none'; } }); document.body.addEventListener('htmx:afterRequest', function(event) { const target = event.target; if (target.classList.contains('nav-link') || target.classList.contains('custom-sidebar-item')) { target.style.opacity = '1'; target.style.pointerEvents = 'auto'; } }); }); window.addEventListener('error', function(event) { console.error('JavaScript error:', event.error); if (window.innerWidth <= 768) { const errorDiv = document.createElement('div'); errorDiv.className = 'fixed top-4 left-4 right-4 bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg z-50 shadow-lg'; errorDiv.innerHTML = ` <div class="flex items-center justify-between"> <div class="flex items-center"> <span class="text-red-500 mr-2">⚠️</span> <span><strong>خطا:</strong> مشکلی پیش آمد. لطفاً صفحه را تازه‌سازی کنید.</span> </div> <button onclick="this.parentElement.parentElement.remove()" class="text-red-500 hover:text-red-700 ml-2">✕</button> </div> `; document.body.appendChild(errorDiv); setTimeout(() => { if (errorDiv.parentElement) { errorDiv.remove(); } }, 5000); } }); const style = document.createElement('style'); style.textContent = ` @keyframes ripple { to { transform: scale(4); opacity: 0; } } .copy-button { position: relative; overflow: hidden; } `; document.head.appendChild(style); </script> </main> </div> <!-- Coming Soon Course Modal --> <div id="coming-soon-modal" class="coming-soon-modal hidden"> <div class="coming-soon-backdrop"></div> <div class="coming-soon-content"> <!-- Modal Header --> <div class="coming-soon-header"> <div class="flex items-center space-x-3 space-x-reverse"> <div class="coming-soon-icon"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path> </svg> </div> <h3 class="coming-soon-title"> 🚧 دوره به زودی </h3> </div> <button id="close-coming-soon-modal" class="coming-soon-close"> <svg 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="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> <!-- Modal Body --> <div class="coming-soon-body"> <div class="course-info-section"> <h4 id="course-name" class="course-name">Course Name</h4> <div class="course-status"> <span class="status-badge">در حال توسعه</span> </div> <p class="course-description"> این دوره جامع در حال حاضر با آخرین استانداردهای صنعت و بهترین شیوه‌ها در حال توسعه است. تیم متخصص ما محتوای باکیفیتی را ایجاد می‌کند تا بهترین تجربه یادگیری را برای شما فراهم کند. </p> </div> <div class="estimated-release"> <div class="flex items-center space-x-2 space-x-reverse"> <svg class="w-4 h-4 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path> </svg> <span class="text-sm text-gray-600 dark:text-gray-400"> زمان تخمینی انتشار: ۲-۴ هفته </span> </div> </div> <!-- Notify Me Section --> <div class="notify-section"> <h5 class="notify-title">هنگام در دسترس بودن اطلاع دهید</h5> <form id="notify-form" class="notify-form"> <div class="email-input-group"> <input type="email" id="notify-email" name="email" placeholder="آدرس ایمیل خود را وارد کنید" class="notify-email-input" required> <button type="submit" class="notify-submit-btn"> <span class="btn-text">به من اطلاع دهید</span> <svg class="btn-icon w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path> </svg> </button> </div> <p class="email-disclaimer"> زمانی که این دوره در دسترس قرار گیرد، یک اطلاعیه برای شما ارسال خواهیم کرد. بدون اسپم، قول می‌دهیم! </p> </form> </div> <!-- Related Courses --> <div class="related-courses"> <h5 class="related-title">اکنون در دسترس</h5> <div class="related-links"> <a href="/fa/html/" class="related-link"> <i class="fab fa-html5 text-orange-500"></i> <span>آموزش HTML</span> </a> <a href="/fa/css/" class="related-link"> <i class="fab fa-css3-alt text-blue-500"></i> <span>راهنمای کامل CSS</span> </a> <a href="/fa/javascript/" class="related-link"> <i class="fab fa-js-square text-yellow-500"></i> <span>مبانی JavaScript</span> </a> </div> </div> </div> </div> </div> <!-- Coming Soon Modal --> <div id="coming-soon-modal" class="coming-soon-modal"> <div class="coming-soon-backdrop"></div> <div class="coming-soon-content"> <div class="coming-soon-header"> <div class="coming-soon-icon"> <i class="fas fa-clock"></i> </div> <h3 class="coming-soon-title">Coming Soon</h3> <button class="coming-soon-close" id="close-coming-soon"> <svg 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="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> <div class="coming-soon-body"> <div class="course-info-section"> <h4 class="course-name" id="modal-course-name">Course Name</h4> <div class="course-status"> <span class="status-badge"> <i class="fas fa-hammer mr-1"></i> در حال توسعه </span> </div> <p class="course-description" id="modal-course-description"> This course is currently under development. We're working hard to bring you high-quality content. </p> </div> <div class="estimated-release"> <div class="flex items-center space-x-2 mb-2"> <i class="fas fa-calendar-alt text-blue-600"></i> <span class="font-semibold text-blue-600">Estimated Release</span> </div> <p class="text-sm text-blue-700" id="modal-release-date">Q2 2025</p> </div> </div> </div> </div> <!-- Include Footer --> <footer class="bg-gray-900 text-white"> <div class=""> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 grid grid-cols-2 md:grid-cols-6 gap-8"> <!-- Frontend Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">فرانت‌اند</h3> <ul class="space-y-1"> <li><a href="/fa/html/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">HTML Tutorial</a></li> <li><a href="/fa/css/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">CSS Complete Guide</a></li> <li><a href="/fa/javascript/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">JavaScript Fundamentals</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="react">React Development</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="vue">Vue.js Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="angular">Angular Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="typescript">TypeScript Guide</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="bootstrap">Bootstrap Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="tailwind">Tailwind CSS</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sass">Sass & SCSS</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="jquery">jQuery Library</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="webcomponents">Web Components</a></li> </ul> </div> <!-- Backend Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">بک‌اند</h3> <ul class="space-y-1"> <li><a href="/fa/python/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Python Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="django">Django Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="flask">Flask Framework</a></li> <li><a href="/fa/nodejs/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Node.js Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="express">Express.js Framework</a></li> <li><a href="/fa/php/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">PHP Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="laravel">Laravel Framework</a></li> <li><a href="/fa/java/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Java Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="spring">Spring Boot</a></li> <li><a href="/fa/c-sharp/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C# Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="dotnet">ASP.NET Core</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ruby">Ruby on Rails</a></li> </ul> </div> <!-- Database Programming --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">پایگاه داده</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sql">SQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mysql">MySQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="postgresql">PostgreSQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mongodb">MongoDB Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="redis">Redis Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sqlite">SQLite Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="database-design">Database Design</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sqlserver">SQL Server Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="oracle">Oracle Database</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mariadb">MariaDB Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="firebase">Firebase Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="elasticsearch">Elasticsearch Tutorial</a></li> </ul> </div> <!-- Mobile Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">موبایل</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="react-native">React Native Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="flutter">Flutter Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="dart">Dart Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="swift">iOS Swift Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="swiftui">SwiftUI Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="kotlin">Android Kotlin</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="android-java">Android Java</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="xamarin">Xamarin Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ionic">Ionic Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="phonegap">PhoneGap Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="pwa">Progressive Web Apps</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mobile-ui">Mobile UI Design</a></li> </ul> </div> <!-- Advanced Topics --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">پیشرفته</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="data-structures">Data Structures</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="algorithms">Algorithms Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="oop">Object Oriented Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="design-patterns">Design Patterns</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="api-development">API Development</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="rest-api">REST API Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="graphql">GraphQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="microservices">Microservices</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="machine-learning">Machine Learning</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ai">Artificial Intelligence</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="blockchain">Blockchain Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="game-dev">Game Development</a></li> </ul> </div> <!-- Programming Languages --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">زبان‌های برنامه‌نویسی</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="c">C Programming</a></li> <li><a href="/fa/c-plus-plus/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C++ Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="go">Go Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="rust">Rust Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ruby">Ruby Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="scala">Scala Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="kotlin">Kotlin Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="r">R Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="matlab">MATLAB Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="perl">Perl Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="assembly">Assembly Language</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="lua">Lua Programming</a></li> </ul> </div> </div> <!-- Brand Section --> <div class="border-t border-gray-800 mt-12 pt-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row justify-between items-center"> <div class="flex flex-col items-center text-center mb-6 md:mb-0"> <img src="/static/images/logo.6fecbe0a2cbf.png" alt="Mrebi Logo" class="h-12 w-auto object-contain mb-2"> <div> <p class="text-sm text-gray-400 mt-1">یاد بگیرید، تمرین کنید، تسلط پیدا کنید</p> </div> </div> <div class="text-center md:text-right"> <div class="flex flex-wrap justify-center md:justify-end gap-6 mb-4"> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">درباره ما</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">تماس</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">سیاست حفظ حریم خصوصی</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">شرایط خدمات</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">بلاگ</a> </div> <div class="text-gray-400"> <p class="text-sm mb-2"> برنامه‌نویسی را با آموزش‌های تعاملی و تمرین عملی تسلط پیدا کنید </p> <p class="text-xs"> © 2025 Mrebi. تمام حقوق محفوظ است. </p> </div> </div> </div> <!-- Social Links --> <div class="mt-8 pt-6 border-t border-gray-800 text-center"> <div class="flex justify-center gap-6 flex-wrap"> <a href="https://www.linkedin.com/in/mr-ebi/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="LinkedIn" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/> </svg> </a> <a href="https://www.youtube.com/@mrebi-com" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="YouTube" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/> </svg> </a> <a href="https://www.instagram.com/mrebicom/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="Instagram" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.148 3.227-1.691 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.148-4.771-1.691-4.919-4.919-.058-1.265-.069-1.645-.069-4.849 0-3.205.012-3.584.069-4.849.149-3.227 1.691-4.771 4.919-4.919 1.266-.058 1.644-.07 4.849-.07zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.667.072 4.947.2 4.36 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.667-.014 4.947-.072 4.358-.2 6.78-2.618 6.98-6.98.059-1.281.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.2-4.36-2.618-6.78-6.98-6.98-1.281-.058-1.689-.072-4.948-.072zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/> </svg> </a> <a href="#" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="TikTok" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 0 1-5.2 1.74 2.89 2.89 0 0 1 2.31-4.55 2.89 2.89 0 0 1 .88.13V9.65a6.34 6.34 0 0 0-1-.09A6.34 6.34 0 0 0 3 16a6.34 6.34 0 0 0 11.13 4.13 6.34 6.34 0 0 0 1.81-4.55V8.52a8.28 8.28 0 0 0 4.85 1.56V6.69z"/> </svg> </a> <a href="https://x.com/mrebicom" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="X" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/> </svg> </a> <a href="https://www.facebook.com/mrebicom/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="Facebook" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M22.675 0H1.325C.593 0 0 .593 0 1.325v21.351C0 23.407.593 24 1.325 24H12.82v-9.294H9.692v-3.622h3.128V8.413c0-3.1 1.893-4.788 4.659-4.788 1.325 0 2.463.099 2.795.143v3.24l-1.918.001c-1.504 0-1.795.715-1.795 1.763v2.313h3.587l-.467 3.622h-3.12V24h6.116c.73 0 1.323-.593 1.323-1.325V1.325C24 .593 23.407 0 22.675 0z"/> </svg> </a> </div> <p class="text-xs text-gray-500 mt-4"> Join our community and start your programming journey today! </p> </div> </div> </div> </footer> <script> // Handle Coming Soon links in footer document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.coming-soon-link').forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); const courseName = this.getAttribute('data-course') || 'default'; if (typeof window.showComingSoonModal === 'function') { window.showComingSoonModal(courseName); } }); }); }); </script> <!-- Prism.js for Syntax Highlighting --> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-html.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-css.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-python.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-php.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-sql.min.js"></script> <!-- Theme Switcher --> <script src="/static/js/theme-switcher.6107c7dde403.js"></script> <!-- Custom JavaScript --> <script src="/static/js/code-editor.744452e3251a.js"></script> <script src="/static/js/code-runner.0ff7847dbd6e.js"></script> <script src="/static/js/mobile-menu.b685f211e4ca.js"></script> <script> // Mobile menu toggle function toggleMobileMenu() { const menu = document.getElementById('mobile-menu'); menu.classList.toggle('hidden'); } // Enhanced language switcher function changeLanguage(languageCode) { const changeUrl = `/fa/change-language/?language=${languageCode}`; if (typeof htmx !== 'undefined') { htmx.ajax('GET', changeUrl, { headers: { 'HX-Request': 'true' } }).then(function(response) { if (response.redirect) { window.location.href = response.redirect; } }); } else { window.location.href = changeUrl; } } // HTMX event listeners document.body.addEventListener('htmx:beforeRequest', function(evt) { document.getElementById('loading-indicator').style.display = 'block'; }); document.body.addEventListener('htmx:afterRequest', function(evt) { document.getElementById('loading-indicator').style.display = 'none'; }); document.body.addEventListener('htmx:afterSwap', function(evt) { // Reinitialize Prism.js highlighting if (typeof Prism !== 'undefined') { Prism.highlightAll(); } // Close mobile menu const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenu && !mobileMenu.classList.contains('hidden')) { mobileMenu.classList.add('hidden'); } // Scroll to top for new content window.scrollTo({ top: 0, behavior: 'smooth' }); }); // Smooth scroll for anchor links document.addEventListener('click', function(e) { if (e.target.matches('a[href^="#"]')) { const href = e.target.getAttribute('href'); // Skip if just # if (href === '#') { return; } e.preventDefault(); const target = document.querySelector(href); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } }); // Coming Soon Modal functionality function initComingSoonModal() { const modal = document.getElementById('coming-soon-modal'); const closeBtn = document.getElementById('close-coming-soon-modal'); const backdrop = modal.querySelector('.coming-soon-backdrop'); const notifyForm = document.getElementById('notify-form'); // Course mapping for dynamic content const courseInfo = { 'python': { name: 'Python Programming', description: 'پایتون را از مبانی تا مفاهیم پیشرفته شامل توسعه وب، علم داده و اتوماسیون یاد بگیرید.' }, 'java': { name: 'Java Programming', description: 'برنامه‌نویسی جاوا را برای اپلیکیشن‌های سازمانی، توسعه اندروید و برنامه‌نویسی سمت سرور تسلط پیدا کنید.' }, 'nodejs': { name: 'Node.js Development', description: 'اپلیکیشن‌های مقیاس‌پذیر سمت سرور را با Node.js و فریمورک Express بسازید.' }, 'react': { name: 'React Development', description: 'رابط‌های کاربری مدرن را با React، hooks و مدیریت state ایجاد کنید.' }, 'typescript': { name: 'TypeScript Guide', description: 'جاوااسکریپت امن‌تری با بررسی نوع استاتیک و ویژگی‌های مدرن زبان بنویسید.' }, 'vue': { name: 'Vue.js Framework', description: 'اپلیکیشن‌های وب پیشرونده را با Vue.js و اکوسیستم آن بسازید.' }, 'angular': { name: 'Angular Framework', description: 'اپلیکیشن‌های تک‌صفحه‌ای سازمانی را با Angular توسعه دهید.' }, 'tailwind': { name: 'Tailwind CSS', description: 'طراحی‌های مدرن را به سرعت با فریمورک CSS ابزار-محور ایجاد کنید.' }, 'django': { name: 'Django Framework', description: 'اپلیکیشن‌های وب قدرتمند را با فریمورک کامل Django بسازید.' }, 'express': { name: 'Express.js Framework', description: 'اپلیکیشن‌های وب سریع و مینیمالیست را با Express.js ایجاد کنید.' }, 'spring': { name: 'Spring Boot', description: 'اپلیکیشن‌های جاوای سازمانی را با فریمورک Spring Boot توسعه دهید.' }, 'php': { name: 'PHP Programming', description: 'اسکریپت‌نویسی سمت سرور را با PHP برای توسعه وب پویا یاد بگیرید.' }, 'laravel': { name: 'Laravel Framework', description: 'اپلیکیشن‌های وب زیبا را با سینتکس بیان‌گر Laravel بسازید.' }, 'sql': { name: 'SQL Tutorial', description: 'کوئری‌های پایگاه داده و دستکاری داده‌ها را با SQL تسلط پیدا کنید.' }, 'mysql': { name: 'MySQL Tutorial', description: 'محبوب‌ترین پایگاه داده رابطه‌ای متن‌باز جهان را یاد بگیرید.' }, 'postgresql': { name: 'PostgreSQL Tutorial', description: 'ویژگی‌های پیشرفته سیستم پایگاه داده PostgreSQL را تسلط پیدا کنید.' }, 'mongodb': { name: 'MongoDB Tutorial', description: 'با پایگاه داده سند NoSQL انعطاف‌پذیر برای اپلیکیشن‌های مدرن کار کنید.' }, 'flutter': { name: 'Flutter Tutorial', description: 'اپلیکیشن‌های موبایل native زیبا برای iOS و Android با یک کدبیس بسازید.' }, 'react-native': { name: 'React Native Tutorial', description: 'اپلیکیشن‌های موبایل native را با React و JavaScript ایجاد کنید.' }, 'swift': { name: 'iOS Swift Tutorial', description: 'اپلیکیشن‌های native iOS را با زبان برنامه‌نویسی Swift توسعه دهید.' }, 'kotlin': { name: 'Android Kotlin', description: 'اپلیکیشن‌های اندروید مدرن را با زبان برنامه‌نویسی Kotlin بسازید.' }, 'docker': { name: 'Docker', description: 'اپلیکیشن‌ها را برای استقرار سازگار در محیط‌های مختلف کانتینری کنید.' }, 'git': { name: 'Git', description: 'کنترل نسخه و گردش‌کار همکاری را با Git تسلط پیدا کنید.' }, 'aws': { name: 'AWS', description: 'اپلیکیشن‌ها را روی پلتفرم ابری Amazon Web Services مستقر و مقیاس‌بندی کنید.' }, 'kubernetes': { name: 'Kubernetes', description: 'اپلیکیشن‌های کانتینری را در مقیاس بزرگ با Kubernetes هماهنگ کنید.' }, 'go': { name: 'Go Programming', description: 'نرم‌افزار سریع، قابل‌اعتماد و کارآمد را با زبان Go بسازید.' }, 'rust': { name: 'Rust Programming', description: 'برنامه‌نویسی سیستم‌ها را با ایمنی حافظه و انتزاعات بدون هزینه یاد بگیرید.' }, 'csharp': { name: 'C# Programming', description: 'اپلیکیشن‌های مدرن را با C# و اکوسیستم .NET توسعه دهید.' }, 'cpp': { name: 'C++ Programming', description: 'برنامه‌نویسی سیستم و اپلیکیشن‌های عملکرد بالا را با C++ تسلط پیدا کنید.' }, 'bootstrap': { name: 'Bootstrap Framework', description: 'وب‌سایت‌های واکنش‌گرا را به سرعت با فریمورک CSS Bootstrap بسازید.' }, 'jquery': { name: 'jQuery Library', description: 'برنامه‌نویسی جاوااسکریپت را با کتابخانه jQuery برای دستکاری DOM ساده کنید.' }, 'sass': { name: 'Sass & SCSS', description: 'CSS نگهداری‌پذیرتر را با پیش‌پردازنده Sass و ویژگی‌های پیشرفته بنویسید.' }, 'graphql': { name: 'GraphQL Tutorial', description: 'APIهای کارآمد را با زبان کوئری GraphQL و تعریف schema بسازید.' }, 'nextjs': { name: 'Next.js', description: 'اپلیکیشن‌های React تمام‌استک را با فریمورک Next.js ایجاد کنید.' }, 'nuxtjs': { name: 'Nuxt.js', description: 'اپلیکیشن‌های جهانی Vue.js را با فریمورک Nuxt.js بسازید.' }, 'redis': { name: 'Redis Tutorial', description: 'ذخیره‌سازی ساختار داده در حافظه را برای کش و اپلیکیشن‌های بلادرنگ یاد بگیرید.' }, 'firebase': { name: 'Firebase Tutorial', description: 'اپلیکیشن‌های وب و موبایل را با سرویس‌های بک‌اند Google Firebase بسازید.' }, 'elasticsearch': { name: 'Elasticsearch Tutorial', description: 'جستجو و آنالیز قدرتمند را با موتور Elasticsearch پیاده‌سازی کنید.' }, 'c': { name: 'C Programming', description: 'مبانی برنامه‌نویسی سیستم را با زبان C یاد بگیرید.' }, 'ruby': { name: 'Ruby Programming', description: 'کد زیبا را با زبان برنامه‌نویسی Ruby و فریمورک Rails بنویسید.' }, 'scala': { name: 'Scala Programming', description: 'برنامه‌نویسی شی‌گرا و تابعی را با Scala ترکیب کنید.' }, 'r': { name: 'R Programming', description: 'محاسبات آماری و تحلیل داده‌ها را با زبان R انجام دهید.' }, 'matlab': { name: 'MATLAB Programming', description: 'مسائل مهندسی و علمی را با برنامه‌نویسی MATLAB حل کنید.' }, 'perl': { name: 'Perl Programming', description: 'پردازش متن و مدیریت سیستم را با Perl تسلط پیدا کنید.' }, 'assembly': { name: 'Assembly Language', description: 'برنامه‌نویسی سطح پایین و معماری کامپیوتر را با Assembly درک کنید.' }, 'lua': { name: 'Lua Programming', description: 'زبان اسکریپت سبک را برای سیستم‌های نهفته و بازی‌ها یاد بگیرید.' }, 'xamarin': { name: 'Xamarin Tutorial', description: 'اپلیکیشن‌های موبایل چندپلتفرمه را با Xamarin و C# بسازید.' }, 'ionic': { name: 'Ionic Framework', description: 'اپلیکیشن‌های موبایل ترکیبی را با Ionic و تکنولوژی‌های وب ایجاد کنید.' }, 'phonegap': { name: 'PhoneGap Tutorial', description: 'اپلیکیشن‌های موبایل را با تکنولوژی‌های وب روی پلتفرم PhoneGap بسازید.' }, 'pwa': { name: 'Progressive Web Apps', description: 'تجربه‌های شبیه اپ را روی وب با تکنولوژی‌های Progressive Web App ایجاد کنید.' }, 'mobile-ui': { name: 'Mobile UI Design', description: 'رابط‌های کاربری زیبا و شهودی را برای اپلیکیشن‌های موبایل طراحی کنید.' }, 'data-structures': { name: 'Data Structures', description: 'ساختارهای داده بنیادی را برای پیاده‌سازی الگوریتم کارآمد تسلط پیدا کنید.' }, 'algorithms': { name: 'Algorithms Tutorial', description: 'تفکر الگوریتمی و تکنیک‌های حل مسئله را یاد بگیرید.' }, 'oop': { name: 'Object Oriented Programming', description: 'مفاهیم برنامه‌نویسی شی‌گرا و اصول طراحی را درک کنید.' }, 'design-patterns': { name: 'Design Patterns', description: 'الگوهای طراحی نرم‌افزار اثبات‌شده را برای حل مسائل رایج برنامه‌نویسی به کار بگیرید.' }, 'api-development': { name: 'API Development', description: 'APIهای قدرتمند را برای اپلیکیشن‌های وب و موبایل طراحی و ساخته کنید.' }, 'rest-api': { name: 'REST API Tutorial', description: 'سرویس‌های وب RESTful را با پیروی از بهترین شیوه‌ها و استانداردها ایجاد کنید.' }, 'microservices': { name: 'Microservices', description: 'اپلیکیشن‌های مقیاس‌پذیر را با الگوهای طراحی microservices معماری کنید.' }, 'machine-learning': { name: 'Machine Learning', description: 'سیستم‌های هوشمند را با الگوریتم‌ها و تکنیک‌های یادگیری ماشین بسازید.' }, 'ai': { name: 'Artificial Intelligence', description: 'مفاهیم هوش مصنوعی را کاوش کنید و اپلیکیشن‌های هوشمند را با فریمورک‌های مدرن بسازید.' }, 'blockchain': { name: 'Blockchain Programming', description: 'اپلیکیشن‌های غیرمتمرکز و قراردادهای هوشمند را روی پلتفرم‌های بلاک‌چین توسعه دهید.' }, 'game-dev': { name: 'Game Development', description: 'بازی‌های جذاب را با موتورهای بازی مدرن و تکنیک‌های برنامه‌نویسی ایجاد کنید.' }, 'webcomponents': { name: 'Web Components', description: 'عناصر سفارشی قابل استفاده مجدد را با استانداردهای Web Components بسازید.' }, 'database-design': { name: 'Database Design', description: 'طرحواره‌های پایگاه داده کارآمد و مقیاس‌پذیر و روابط را طراحی کنید.' }, 'sqlserver': { name: 'SQL Server Tutorial', description: 'با سیستم مدیریت پایگاه داده Microsoft SQL Server کار کنید.' }, 'oracle': { name: 'Oracle Database', description: 'تکنیک‌های مدیریت و توسعه پایگاه داده Oracle را تسلط پیدا کنید.' }, 'mariadb': { name: 'MariaDB Tutorial', description: 'ویژگی‌های پایگاه داده MariaDB و مدیریت آن را یاد بگیرید.' }, 'dotnet': { name: 'ASP.NET Core', description: 'اپلیکیشن‌های وب مدرن را با فریمورک ASP.NET Core بسازید.' }, 'flask': { name: 'Flask Framework', description: 'اپلیکیشن‌های وب سبک را با میکروفریمورک Python Flask ایجاد کنید.' }, 'android-java': { name: 'Android Java', description: 'اپلیکیشن‌های اندروید را با زبان برنامه‌نویسی Java توسعه دهید.' }, 'swiftui': { name: 'SwiftUI Tutorial', description: 'رابط‌های iOS مدرن را با فریمورک اعلانی SwiftUI بسازید.' }, 'prompt-engineering': { name: 'AI Prompt Engineering', description: 'هنر ارتباط مؤثر با سیستم‌های هوش مصنوعی و مدل‌های زبانی را تسلط پیدا کنید.' }, 'default': { name: 'دوره جدید', description: 'این دوره جامع با آخرین استانداردهای صنعت و بهترین شیوه‌ها در حال توسعه است.' } }; // Show modal function function showModal(courseName = 'default') { const info = courseInfo[courseName] || courseInfo['default']; const courseNameElement = document.getElementById('course-name'); const courseDescElement = modal.querySelector('.course-description'); if (courseNameElement) courseNameElement.textContent = info.name; if (courseDescElement) courseDescElement.textContent = info.description; modal.classList.remove('hidden'); modal.classList.add('active'); document.body.style.overflow = 'hidden'; } // Hide modal function function hideModal() { modal.classList.remove('active'); modal.classList.add('hidden'); document.body.style.overflow = 'auto'; // Reset form if (notifyForm) { notifyForm.reset(); } } // Event listeners if (closeBtn) { closeBtn.addEventListener('click', hideModal); } if (backdrop) { backdrop.addEventListener('click', hideModal); } // Escape key document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && modal.classList.contains('active')) { hideModal(); } }); // Handle notify form submission if (notifyForm) { notifyForm.addEventListener('submit', function(e) { e.preventDefault(); const email = document.getElementById('notify-email').value; if (email) { // Here you would typically send the email to your backend console.log('Notify email:', email); // Show success message alert('Thank you! We will notify you when this course becomes available.'); hideModal(); } }); } // Detect clicks on # links and show modal document.addEventListener('click', function(e) { if (e.target.matches('a[href="#"]') || e.target.closest('a[href="#"]')) { e.preventDefault(); // Try to extract course name from link text or data attribute const link = e.target.matches('a') ? e.target : e.target.closest('a'); const linkText = link.textContent.toLowerCase(); let courseName = 'default'; if (linkText.includes('python')) courseName = 'python'; else if (linkText.includes('java') && !linkText.includes('javascript')) courseName = 'java'; else if (linkText.includes('node')) courseName = 'nodejs'; else if (linkText.includes('react')) courseName = 'react'; else if (linkText.includes('typescript')) courseName = 'typescript'; else if (linkText.includes('vue')) courseName = 'vue'; else if (linkText.includes('angular')) courseName = 'angular'; else if (linkText.includes('tailwind')) courseName = 'tailwind'; else if (linkText.includes('django')) courseName = 'django'; else if (linkText.includes('express')) courseName = 'express'; else if (linkText.includes('spring')) courseName = 'spring'; else if (linkText.includes('php')) courseName = 'php'; else if (linkText.includes('laravel')) courseName = 'laravel'; else if (linkText.includes('sql') && !linkText.includes('mysql') && !linkText.includes('postgresql')) courseName = 'sql'; else if (linkText.includes('mysql')) courseName = 'mysql'; else if (linkText.includes('postgresql')) courseName = 'postgresql'; else if (linkText.includes('mongodb')) courseName = 'mongodb'; else if (linkText.includes('flutter')) courseName = 'flutter'; else if (linkText.includes('react native')) courseName = 'react-native'; else if (linkText.includes('swift')) courseName = 'swift'; else if (linkText.includes('kotlin')) courseName = 'kotlin'; else if (linkText.includes('docker')) courseName = 'docker'; else if (linkText.includes('git')) courseName = 'git'; else if (linkText.includes('aws')) courseName = 'aws'; else if (linkText.includes('kubernetes')) courseName = 'kubernetes'; else if (linkText.includes('go')) courseName = 'go'; else if (linkText.includes('rust')) courseName = 'rust'; else if (linkText.includes('c#')) courseName = 'csharp'; else if (linkText.includes('c++')) courseName = 'cpp'; else if (linkText.includes('bootstrap')) courseName = 'bootstrap'; else if (linkText.includes('jquery')) courseName = 'jquery'; else if (linkText.includes('sass')) courseName = 'sass'; else if (linkText.includes('graphql')) courseName = 'graphql'; else if (linkText.includes('next')) courseName = 'nextjs'; else if (linkText.includes('nuxt')) courseName = 'nuxtjs'; else if (linkText.includes('redis')) courseName = 'redis'; else if (linkText.includes('firebase')) courseName = 'firebase'; else if (linkText.includes('elasticsearch')) courseName = 'elasticsearch'; else if (linkText.includes('c programming')) courseName = 'c'; else if (linkText.includes('ruby')) courseName = 'ruby'; else if (linkText.includes('scala')) courseName = 'scala'; else if (linkText.includes('r programming')) courseName = 'r'; else if (linkText.includes('matlab')) courseName = 'matlab'; else if (linkText.includes('perl')) courseName = 'perl'; else if (linkText.includes('assembly')) courseName = 'assembly'; else if (linkText.includes('lua')) courseName = 'lua'; else if (linkText.includes('xamarin')) courseName = 'xamarin'; else if (linkText.includes('ionic')) courseName = 'ionic'; else if (linkText.includes('phonegap')) courseName = 'phonegap'; else if (linkText.includes('progressive web')) courseName = 'pwa'; else if (linkText.includes('mobile ui')) courseName = 'mobile-ui'; else if (linkText.includes('data structures')) courseName = 'data-structures'; else if (linkText.includes('algorithms')) courseName = 'algorithms'; else if (linkText.includes('object oriented')) courseName = 'oop'; else if (linkText.includes('design patterns')) courseName = 'design-patterns'; else if (linkText.includes('api development')) courseName = 'api-development'; else if (linkText.includes('rest api')) courseName = 'rest-api'; else if (linkText.includes('microservices')) courseName = 'microservices'; else if (linkText.includes('machine learning')) courseName = 'machine-learning'; else if (linkText.includes('artificial intelligence')) courseName = 'ai'; else if (linkText.includes('blockchain')) courseName = 'blockchain'; else if (linkText.includes('game development')) courseName = 'game-dev'; else if (linkText.includes('web components')) courseName = 'webcomponents'; else if (linkText.includes('database design')) courseName = 'database-design'; else if (linkText.includes('sql server')) courseName = 'sqlserver'; else if (linkText.includes('oracle')) courseName = 'oracle'; else if (linkText.includes('mariadb')) courseName = 'mariadb'; else if (linkText.includes('asp.net') || linkText.includes('dotnet')) courseName = 'dotnet'; else if (linkText.includes('flask')) courseName = 'flask'; else if (linkText.includes('android java')) courseName = 'android-java'; else if (linkText.includes('swiftui')) courseName = 'swiftui'; else if (linkText.includes('prompt engineering') || linkText.includes('ai prompt')) courseName = 'prompt-engineering'; showModal(courseName); } }); // Make showModal globally available window.showComingSoonModal = showModal; } // Initialize on page load document.addEventListener('DOMContentLoaded', function() { // Initialize Prism.js if (typeof Prism !== 'undefined') { Prism.highlightAll(); } // Hide loading indicator document.getElementById('loading-indicator').style.display = 'none'; // RTL adjustments if (window.siteConfig.isRTL) { document.body.classList.add('rtl'); } // Initialize Coming Soon Modal initComingSoonModal(); }); </script> <!-- Block for additional JavaScript --> <!-- Analytics (add your tracking code here) --> <!-- Add Google Analytics, Plausible, or other analytics scripts here --> </body> </html>