جاري التحميل...

التحكم في الإصدارات HTML

التحكم في الإصدارات HTML (HTML Version Control) هو عملية إدارة وتتبع التغييرات التي تتم على ملفات HTML الخاصة بالمواقع الإلكترونية بمرور الوقت. هذه العملية تشبه تنظيم مكتبة كبيرة؛ حيث نقوم بتسجيل كل كتاب (صفحة HTML) وتحديثاته بدقة حتى نعرف من قام بتعديل ماذا ومتى. تخيل أنك تبني منزلاً (موقع إلكتروني): الجدران والأسقف تمثل هيكل HTML، وكل تعديل مثل فتح نافذة جديدة أو إعادة ترتيب غرفة يحتاج إلى توثيق حتى لا ينهار النظام أو يحدث ارتباك.
أهمية التحكم في الإصدارات لا تظهر فقط عند العمل ضمن فريق، بل أيضًا عند العمل الفردي. على سبيل المثال:

  • في موقع أخبار (News Site)، يساعد في استعادة النسخة القديمة من الصفحة عند حدوث خطأ في تحديث عاجل.
  • في متجر إلكتروني (E-commerce)، يحافظ على أمان التحديثات أثناء إضافة منتجات جديدة أو تغييرات في صفحات الدفع.
  • في الصفحة الشخصية (Personal Page)، يمكن تجربة تصميمات جديدة مع الحفاظ على نسخة مستقرة.
  • في بوابة حكومية (Government Portal)، يعتبر التتبع الدقيق للتغييرات ضروريًا لتدقيق الأمان والشفافية.
    سيتعلم القارئ في هذا الدرس كيفية إدارة نسخ صفحات HTML، فهم التعليقات الزمنية (Timestamps) وأسماء الإصدارات (Tags)، وكيفية استخدام تقنيات التحكم في الإصدارات مع أمثلة عملية واقعية.

مثال أساسي

html
HTML Code
<!DOCTYPE html>

<html lang="ar">
<head>
<meta charset="UTF-8">
<title>نسخة الصفحة 1.0</title> <!-- تعليق يوضح رقم الإصدار -->
</head>
<body>
<h1>مرحبا بكم في موقعي</h1> <!-- محتوى الإصدار الأول -->
<!-- الإصدار 1.0 - تاريخ 2025-07-29 -->
</body>
</html>

في هذا المثال البسيط، قمنا بإنشاء صفحة HTML تحمل عناصر أساسية. يبدأ الكود بسطر <!DOCTYPE html> لتحديد نوع المستند (Document Type)، وهو مهم جدًا لضمان توافق الصفحة مع جميع المتصفحات الحديثة. وسم يحدد لغة الصفحة بالعربية لتحسين الوصولية (Accessibility) وتحسين نتائج البحث.
في وسم ، لدينا لضمان دعم جميع الأحرف العربية بشكل صحيح. بعد ذلك، يأتي نسخة الصفحة 1.0، وهنا استخدمنا العنوان للإشارة إلى رقم الإصدار (Version Number) حتى يسهل التعرف على حالة الصفحة ضمن عملية التحكم في الإصدارات.
في قسم ، أضفنا

مرحبا بكم في موقعي

كمحتوى أولي يمثل الإصدار الأول. وأخيرًا، أضفنا تعليقًا في HTML لتوثيق تاريخ الإصدار. هذه الممارسة تشبه كتابة ملاحظات في هامش كتاب داخل مكتبة منظمة؛ تسهل عليك أو على فريقك تتبع كل تعديل تم على الصفحة مع مرور الوقت.

مثال عملي

html
HTML Code
<!DOCTYPE html>

<html lang="ar">
<head>
<meta charset="UTF-8">
<title>الأخبار العاجلة - الإصدار 2.1</title> <!-- تم تحديث الإصدار بعد إضافة شريط التنبيه -->
</head>
<body>
<div class="alert">خبر عاجل: افتتاح متجر إلكتروني جديد</div> <!-- تحديث جديد -->
<h1>أحدث الأخبار</h1>
<p>يمكنكم متابعة المزيد من الأخبار على موقعنا.</p>
<!-- الإصدار 2.1 - أضيف شريط التنبيه 2025-07-29 -->
</body>
</html>

في هذا المثال العملي، طورنا صفحة HTML لموقع إخباري. هذه الصفحة تمثل الإصدار 2.1 بعد أن أضفنا شريط تنبيه (Alert Bar) باستخدام عنصر

مع صنف (Class) يسمى alert.
شرح تفصيلي للعناصر المهمة:

  • العنوان في يظهر الإصدار الجديد ويُستخدم أحيانًا داخليًا لمطابقة النسخ مع نظام التحكم في الإصدارات الخارجي مثل Git.</li> <li>عنصر <div class="alert"> يعكس تحديثًا حقيقيًا في المحتوى المرئي للمستخدمين، وهو جزء من الإصدار الجديد.</li> <li>التعليق الأخير في الكود <!-- الإصدار 2.1 - ... --> يحافظ على سجل واضح للتحديثات، وهو مهم عندما يتعاون عدة مطورين على موقع إخباري أو متجر إلكتروني لتفادي فقدان التغييرات.<br /> ربط هذا التطبيق الواقعي مع مشروع حكومي أو متجر إلكتروني يظهر كيف يمكن دمج التحكم في الإصدارات مع تجربة التصفح؛ كل إصدار جديد يتم توثيقه داخل الكود حتى لو كان هناك نظام خارجي يقوم بإدارة نسخ الملفات.</li> </ul> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>أفضل الممارسات والأخطاء الشائعة:<br /> أفضل الممارسات:</p> <ol> <li>استخدام تعليقات (Comments) واضحة داخل كود HTML للإشارة إلى أرقام الإصدارات وتواريخ التعديلات.</li> <li>اتباع هيكلة HTML دلالية (Semantic HTML) مثل استخدام <header>، <footer> لتسهيل قراءة الكود وصيانته.</li> <li>الحفاظ على ترتيب عناصر <head> نظيفًا ومنظمًا لضمان أن أي تغييرات مستقبلية لا تسبب مشاكل توافق.</li> <li> <p>حفظ نسخة احتياطية (Backup) لكل إصدار قبل الانتقال إلى الإصدار التالي.<br /> الأخطاء الشائعة:</p> </li> <li> <p>تجاهل التعليقات الخاصة بالإصدارات مما يصعّب تتبع التحديثات.</p> </li> <li>استخدام عناصر غير دلالية أو مكررة مما يربك عند العودة للإصدارات السابقة.</li> <li>حذف أو تعديل التعليقات القديمة دون أرشفتها.</li> <li>سوء تنظيم الملفات وعدم توافق أسماء الملفات مع أرقام الإصدارات.<br /> نصائح تصحيح الأخطاء:</li> </ol> <ul> <li>استخدم أداة مقارنة (Diff Tool) لمراجعة التغييرات بين الإصدارات.</li> <li>قم بفحص التوافق في المتصفحات بعد كل إصدار.</li> <li>حافظ على تنظيم المجلدات كما لو أنك تنظم كتبًا في مكتبة لضمان سهولة الرجوع لأي نسخة.</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">Property/Method</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">Description</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">Example</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"><!DOCTYPE></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">تعريف نوع مستند HTML لإصدار محدد</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><!DOCTYPE html></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><title></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"><title>موقعي 1.0</title></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><!-- Comment --></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"><!-- الإصدار 2.1 --></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">File Naming</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">index_v1.html</td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">Version Tag</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"><!-- v2.3 Release --></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">Date Tag</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"><!-- 2025-07-29 --></td> </tr> </tbody> </table> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>الملخص والخطوات التالية:<br /> في هذا الدرس تعلمت أن التحكم في الإصدارات HTML ليس مجرد عملية تقنية، بل هو وسيلة لإدارة موقعك مثل مكتبة منظمة؛ حيث كل نسخة من الصفحة عبارة عن كتاب له رقم وإصدار واضح. تعرفت على كيفية إضافة التعليقات الزمنية (Timestamps)، وأرقام الإصدارات (Version Numbers)، وكيفية استخدام هذه الطرق في مواقع الأخبار والمتاجر الإلكترونية والصفحات الشخصية والبوابات الحكومية.<br /> هذه الممارسات تساعد على الانتقال السلس بين الإصدارات، وتحافظ على تجربة مستخدم مستقرة عند دمجها مع أساليب تصميم <a href="/ar/css/" class="smart-link">CSS</a> وتفاعلات <a href="/ar/javascript/" class="smart-link">JavaScript</a>.<br /> الخطوة التالية هي دراسة كيفية دمج HTML Version Control مع أنظمة تحكم بالإصدارات أكثر تقدمًا مثل Git، والتعرف على آليات الاسترجاع (Rollback) واختبار التوافق بين الإصدارات.<br /> للاستمرار في التعلم، جرّب إنشاء مشروع صغير متعدد الإصدارات ثم دمجه مع نظام Git، وحاول مقارنة الفروق بين الإصدارات عمليًا. التكرار والمراجعة هما مفتاح الإتقان.</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="41"> <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="CjMntJzsiOJJEC34IcNtXCCEtn6n4XyucGdsWAFTC8TMPPbEWyMnWEINkEM20uKK"> <!-- 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">4</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(41)"> <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 = `/ar/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 = `/ar/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('/ar/api/smart-link-click/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': 'CjMntJzsiOJJEC34IcNtXCCEtn6n4XyucGdsWAFTC8TMPPbEWyMnWEINkEM20uKK' }, body: JSON.stringify({ keyword_id: keywordId, source_content_type: 'topic', source_content_id: 41, 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', 'CjMntJzsiOJJEC34IcNtXCCEtn6n4XyucGdsWAFTC8TMPPbEWyMnWEINkEM20uKK'); fetch('/ar/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('/ar/try-it/' + language + '/', '_blank'); } }) .catch(error => { console.error('Error:', error); window.open('/ar/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="/ar/html/" class="related-link"> <i class="fab fa-html5 text-orange-500"></i> <span>دروس HTML</span> </a> <a href="/ar/css/" class="related-link"> <i class="fab fa-css3-alt text-blue-500"></i> <span>الدليل الكامل لـ CSS</span> </a> <a href="/ar/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="/ar/html/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">HTML Tutorial</a></li> <li><a href="/ar/css/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">CSS Complete Guide</a></li> <li><a href="/ar/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="/ar/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="/ar/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="/ar/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="/ar/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="/ar/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="/ar/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 = `/ar/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 والخطافات وإدارة الحالة.' }, '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: 'بناء تطبيقات جوال أصلية جميلة لنظامي iOS وأندرويد بقاعدة كود واحدة.' }, 'react-native': { name: 'React Native Tutorial', description: 'إنشاء تطبيقات جوال أصلية باستخدام React وجافاسكريبت.' }, 'swift': { name: 'iOS Swift Tutorial', description: 'تطوير تطبيقات 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: 'بناء مواقع ويب متجاوبة بسرعة مع إطار عمل Bootstrap CSS.' }, 'jquery': { name: 'jQuery Library', description: 'تبسيط برمجة جافاسكريبت مع مكتبة jQuery لمعالجة DOM.' }, 'sass': { name: 'Sass & SCSS', description: 'كتابة CSS أكثر قابلية للصيانة مع معالج Sass المسبق والميزات المتقدمة.' }, 'graphql': { name: 'GraphQL Tutorial', description: 'بناء واجهات برمجة تطبيقات فعالة مع لغة استعلام GraphQL وتعريف المخطط.' }, '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: 'تصميم وبناء واجهات برمجة تطبيقات قوية لتطبيقات الويب والجوال.' }, 'rest-api': { name: 'REST API Tutorial', description: 'إنشاء خدمات ويب RESTful باتباع أفضل الممارسات والمعايير.' }, 'microservices': { name: 'Microservices', description: 'هندسة تطبيقات قابلة للتوسع باستخدام أنماط تصميم الخدمات المصغرة.' }, '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>