Skip to content

Interactive exam example implementation #16

Description

<title>اختبار قواعد الإنجليزية - الصف الثاني الثانوي</title> <style> :root { --bg-color: #f3f4f6; --card-bg: #ffffff; --text-color: #1f2937; --text-secondary: #4b5563; --primary: #2563eb; --success: #10b981; --success-bg: #ecfdf5; --error: #ef4444; --error-bg: #fef2f2; --border-color: #e5e7eb; --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); --header-bg: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%); --badge-bg: #e0e7ff; --badge-text: #3730a3; }
    [data-theme="dark"] {
        --bg-color: #0f172a;
        --card-bg: #1e293b;
        --text-color: #f8fafc;
        --text-secondary: #94a3b8;
        --primary: #3b82f6;
        --success: #34d399;
        --success-bg: #064e3b;
        --error: #f87171;
        --error-bg: #7f1d1d;
        --border-color: #334155;
        --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.5);
        --header-bg: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
        --badge-bg: #312e81;
        --badge-text: #c7d2fe;
    }

    * { box-sizing: border-box; margin: 0; padding: 0; transition: background-color 0.3s, color 0.3s; }

    body {
        font-family: 'Tajawal', sans-serif;
        background-color: var(--bg-color);
        color: var(--text-color);
        padding: 12px;
        padding-bottom: 80px;
        max-width: 650px;
        margin: 0 auto;
    }

    .top-bar {
        display: flex; justify-content: space-between; align-items: center;
        margin-bottom: 15px; padding: 10px 15px;
        background: var(--card-bg); border-radius: 12px; box-shadow: var(--shadow);
        position: sticky; top: 10px; z-index: 100;
    }

    .timer-box { font-weight: 700; font-size: 1.1rem; color: #f59e0b; }
    .theme-toggle-btn { background: none; border: none; font-size: 1.3rem; cursor: pointer; }

    .header-card {
        background: var(--header-bg); color: #ffffff;
        padding: 20px; border-radius: 16px; text-align: center; margin-bottom: 20px; box-shadow: var(--shadow);
    }
    .header-card h1 { font-size: 1.4rem; margin-bottom: 6px; }
    .header-card p { font-size: 0.9rem; opacity: 0.9; }

    .q-card {
        background-color: var(--card-bg); border: 1px solid var(--border-color);
        border-radius: 16px; padding: 18px; margin-bottom: 18px; box-shadow: var(--shadow);
    }

    .q-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
    .q-number { background-color: var(--badge-bg); color: var(--badge-text); font-weight: bold; padding: 4px 10px; border-radius: 20px; font-size: 0.85rem; }
    .creative-tag { background-color: #f59e0b; color: #ffffff; font-weight: bold; padding: 3px 8px; border-radius: 12px; font-size: 0.75rem; }

    .q-text { font-size: 1.05rem; font-weight: 700; margin-bottom: 15px; direction: ltr; text-align: left; line-height: 1.5; }
    .q-text.ar { direction: rtl; text-align: right; }

    .options-container { display: flex; flex-direction: column; gap: 10px; }

    .option-btn {
        background-color: var(--bg-color); border: 1.5px solid var(--border-color);
        color: var(--text-color); padding: 12px 15px; border-radius: 12px;
        font-size: 0.95rem; font-weight: 500; text-align: left; direction: ltr;
        cursor: pointer; display: flex; justify-content: space-between; align-items: center; width: 100%;
    }

    .option-btn.selected-correct { background-color: var(--success-bg) !important; border-color: var(--success) !important; color: var(--success) !important; font-weight: bold; }
    .option-btn.selected-wrong { background-color: var(--error-bg) !important; border-color: var(--error) !important; color: var(--error) !important; font-weight: bold; }
    .option-btn.show-correct { border-color: var(--success) !important; color: var(--success) !important; font-weight: bold; }

    .explanation-box {
        margin-top: 15px; padding: 12px 15px; border-radius: 12px;
        font-size: 0.9rem; line-height: 1.5; display: none; animation: fadeIn 0.4s ease;
    }
    .explanation-box.correct { background-color: var(--success-bg); border: 1px solid var(--success); }
    .explanation-box.wrong { background-color: var(--error-bg); border: 1px solid var(--error); }
    .explanation-title { font-weight: bold; margin-bottom: 4px; }

    .submit-container { text-align: center; margin-top: 25px; }
    .submit-btn {
        background: var(--header-bg); color: #ffffff; border: none; padding: 14px 35px;
        font-size: 1.1rem; font-weight: bold; border-radius: 30px; cursor: pointer; width: 100%; max-width: 300px;
    }

    .result-modal {
        position: fixed; top: 0; left: 0; right: 0; bottom: 0;
        background: rgba(0, 0, 0, 0.7); display: none; justify-content: center; align-items: center;
        z-index: 1000; padding: 20px;
    }
    .result-content { background: var(--card-bg); padding: 25px; border-radius: 20px; text-align: center; max-width: 400px; width: 100%; }
    .result-score { font-size: 2.2rem; font-weight: 800; color: var(--primary); margin: 15px 0; }

    @keyframes fadeIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: translateY(0); } }
</style>
<div class="top-bar">
    <div class="timer-box">⏰ <span id="timer">10:00</span></div>
    <div>
        <span style="font-size: 0.85rem; font-weight: bold;">الوضع: </span>
        <button class="theme-toggle-btn" id="themeBtn" onclick="toggleTheme()">🌙</button>
    </div>
</div>

<div class="header-card">
    <h1>اختبار قواعد الإنجليزية 📝</h1>
    <p>الصف الثاني الثانوي - (الحالة الشرطية الثانية وبدائلها)</p>
</div>

<div id="questions-wrapper"></div>

<div class="submit-container">
    <button class="submit-btn" id="submitBtn" onclick="finishQuiz()">إنهاء الاختبار وتسليم الإجابات 🚀</button>
</div>

<div class="result-modal" id="resultModal">
    <div class="result-content">
        <h2 id="resultEmoji">🎉</h2>
        <h2 style="margin-top: 10px;">نتيجة الاختبار</h2>
        <div class="result-score" id="scoreText">0 / 15</div>
        <p id="resultFeedback" style="color: var(--text-secondary); margin-bottom: 20px;"></p>
        <button class="submit-btn" style="width: auto; padding: 10px 25px;" onclick="closeModal()">إغلاق ومراجعة الإجابات 👁️</button>
    </div>
</div>

<script>
    const questionsData = [
        {
            id: 1, creative: false, text: "1. If he played well, he __________ the match.", isAr: false,
            options: ["A) will win", "B) would win", "C) would have won", "D) wins"], correct: 1,
            expCorrect: "إجابة صحيحة! 👏 حالة شرطية ثانية (If + past simple -> would + inf).",
            expWrong: "إجابة خاطئة! ❌ فعل الشرط ماضي بسيط (played) فتكون النتيجة (would + المصدر)."
        },
        {
            id: 2, creative: false, text: "2. In case of __________ well, he would win the match.", isAr: false,
            options: ["A) play", "B) played", "C) playing", "D) to play"], correct: 2,
            expCorrect: "ممتاز! 🌟 التركيب الصحيح هو (In case of + V-ing).",
            expWrong: "خاطئة! ❌ حرف الجر In case of يليه دائماً اسم أو V-ing."
        },
        {
            id: 3, creative: false, text: "3. Should he __________ well, he would win the match.", isAr: false,
            options: ["A) play", "B) played", "C) plays", "D) playing"], correct: 0,
            expCorrect: "بطل! 🌟 التركيب البديل لـ If بـ Should يأتي بعده (فاعل + المصدر مجرد).",
            expWrong: "غير صحيحة ❌ مع Should البديلة لـ If نستخدم المصدر مجرداً بدون إضافة."
        },
        {
            id: 4, creative: false, text: "4. Were he __________ well, he would win the match.", isAr: false,
            options: ["A) play", "B) to play", "C) played", "D) playing"], correct: 1,
            expCorrect: "رائع! ✨ القاعدة هنا عند استخدام Were بدلاً من If مع فعل أساسي: (Were + subject + to + inf).",
            expWrong: "خاطئة! ❌ البديل الصحيح مع Were والفعل العادي هو (to + المصدر)."
        },
        {
            id: 5, creative: false, text: "5. If he had money, he __________ a car.", isAr: false,
            options: ["A) will buy", "B) would buy", "C) would have bought", "D) buys"], correct: 1,
            expCorrect: "مضبوط! 🎯 (had) هنا فعل أساسي ماضي بسيط، وبالتالي تعامل كحالة ثانية (would + inf).",
            expWrong: "خطأ! ❌ (had) جاءت بمفردها كـ ماضي بسيط وليست ماضي تام، لذلك الجواب (would buy)."
        },
        {
            id: 6, creative: true, text: "6. \"__________ he money, he would buy a car.\" Choose the correct word:", isAr: true,
            options: ["A) Were", "B) Should", "C) Had", "D) If"], correct: 2,
            expCorrect: "فكر ذكي! 🧠 تقدم (Had) على الفاعل للتعبير عن الملكية بالحالة الثانية (Had he money = If he had money).",
            expWrong: "خاطئة! ❌ الكلمة المناسبة هي Had لتحل محل If في التعبير عن الملكية."
        },
        {
            id: 7, creative: true, text: "7. \"Were he __________ a doctor, he would help us.\" Choose the correct form:", isAr: true,
            options: ["A) to be", "B) be", "C) Ø (no word needed)", "D) being"], correct: 2,
            expCorrect: "عبقري! 🎯 عندما تكون Were هي الفعل الأساسي (بمعنى كان)، تأتي مباشرة قبل الفاعل ولا نحتاج لأي فعل آخر.",
            expWrong: "خاطئة! ❌ الجملة أصلها (If he were a doctor)، فلا نحتاج لضافة كلمة أخرى."
        },
        {
            id: 8, creative: true, text: "8. \"Were he invited, he would attend the party.\" This sentence is equivalent to:", isAr: true,
            options: ["A) If he was inviting, he would attend.", "B) If he were invited, he would attend.", "C) If he invited, he would attend.", "D) Had he invited, he would attend."], correct: 1,
            expCorrect: "ممتاز! 🔥 جملة المبني للمجهول في الحالة الثانية تختصر بتقديم Were لتصبح (Were he invited).",
            expWrong: "غير صحيحة ❌ الجملة مكافئة لـ (If he were invited)."
        },
        {
            id: 9, creative: true, text: "9. \"He doesn't have money, so he doesn't buy a car.\" Which conditional sentence is correct?", isAr: true,
            options: ["A) If he has money, he buys a car.", "B) Had he money, he would have bought a car.", "C) If he had money, he would buy a car.", "D) Unless he had money, he wouldn't buy a car."], correct: 2,
            expCorrect: "إجابة صحيحة! 💡 الواقع المضارع المنفي نعبر عنه بافتراض خيالي في الحالة الثانية.",
            expWrong: "خاطئة! ❌ للتعبير عن عكس الواقع الحاضر نستخدم الحالة الثانية (If + past simple -> would + inf)."
        },
        {
            id: 10, creative: true, text: "10. \"__________ studying hard, he would fail.\" Choose the correct phrase:", isAr: true,
            options: ["A) In case of", "B) If it weren't for", "C) Provided that", "D) Unless"], correct: 1,
            expCorrect: "تركيز رائع! 🏅 (If it weren't for) يتبعها V-ing وتعطي معنى لولا (الشرط المنفي).",
            expWrong: "خطأ! ❌ اختارنا (If it weren't for) لأنها تأخذ V-ing وتعبر عن الشرط المنفي."
        },
        {
            id: 11, creative: false, text: "11. If it __________ for hard study, he would fail.", isAr: false,
            options: ["A) isn't", "B) haven't been", "C) weren't", "D) hadn't been"], correct: 2,
            expCorrect: "صحيحة! 🏆 التركيب الاصطلاحي للحالة الثانية هو (If it weren't for).",
            expWrong: "خاطئة! ❌ بوجود would fail نستخدم تركيب الحالة الثانية (If it weren't for)."
        },
        {
            id: 12, creative: false, text: "12. Suppose you __________ a millionaire, would you travel to space?", isAr: false,
            options: ["A) are", "B) were", "C) had been", "D) have been"], correct: 1,
            expCorrect: "أحسنت! 🚀 Suppose تُعامل معاملة If وتأخذ ماضي بسيط (were) للحالة الثانية.",
            expWrong: "خاطئة! ❌ Suppose للشرط والتخيل في الحالة الثانية تأخذ ماضي بسيط (were)."
        },
        {
            id: 13, creative: false, text: "13. Should he __________ rich, he would buy a villa.", isAr: false,
            options: ["A) is", "B) to be", "C) be", "D) were"], correct: 2,
            expCorrect: "ممتاز! 👏 Should يلزمها مصدر مجرد، ومصدر verb to be هو (be).",
            expWrong: "خطأ! ❌ بعد Should نضع المصدر (be) مجرداً بدون to."
        },
        {
            id: 14, creative: false, text: "14. Were he __________ rich, he would buy a villa.", isAr: false,
            options: ["A) to be", "B) rich", "C) being", "D) be"], correct: 1,
            expCorrect: "بطل! 🎉 مع الصفات (rich) تكون Were هي الفعل الأساسي ولا نضع be ثانية.",
            expWrong: "خاطئة! ❌ الصفة تأتي بعد الفاعل مباشرة دون الحاجة لـ to be."
        },
        {
            id: 15, creative: false, text: "15. Unless he studied hard, he __________ fail.", isAr: false,
            options: ["A) will", "B) would", "C) would have", "D) can"], correct: 1,
            expCorrect: "ممتاز! 👍 Unless مثل If تماماً، الفعل ماضي بسيط (studied) فالجواب (would).",
            expWrong: "خاطئة! ❌ مع الماضي البسيط تكون الإجابة (would + inf)."
        }
    ];

    let userAnswers = {};
    let timerSeconds = 600;
    let timerInterval;

    function renderQuestions() {
        const container = document.getElementById('questions-wrapper');
        container.innerHTML = '';
        questionsData.forEach((q) => {
            const card = document.createElement('div');
            card.className = 'q-card';
            let creativeBadge = q.creative ? `<span class="creative-tag">سؤال إبداعي ✨</span>` : '';
            let optionsHTML = '';
            q.options.forEach((opt, optIdx) => {
                optionsHTML += `
                    <button class="option-btn" id="opt-${q.id}-${optIdx}" onclick="selectAnswer(${q.id}, ${optIdx})">
                        <span>${opt}</span>
                        <span id="icon-${q.id}-${optIdx}"></span>
                    </button>
                `;
            });
            card.innerHTML = `
                <div class="q-header">
                    <span class="q-number">سؤال ${q.id} من 15</span>
                    ${creativeBadge}
                </div>
                <div class="q-text ${q.isAr ? 'ar' : ''}">${q.text}</div>
                <div class="options-container">${optionsHTML}</div>
                <div class="explanation-box" id="exp-${q.id}"></div>
            `;
            container.appendChild(card);
        });
    }

    function selectAnswer(qId, selectedOptIdx) {
        if (userAnswers[qId] !== undefined) return;
        userAnswers[qId] = selectedOptIdx;
        const qData = questionsData.find(q => q.id === qId);
        const isCorrect = selectedOptIdx === qData.correct;

        qData.options.forEach((_, optIdx) => {
            const btn = document.getElementById(`opt-${qId}-${optIdx}`);
            btn.disabled = true;
            if (optIdx === qData.correct) {
                btn.classList.add('show-correct');
                document.getElementById(`icon-${qId}-${optIdx}`).innerText = '✅';
            }
        });

        const selectedBtn = document.getElementById(`opt-${qId}-${selectedOptIdx}`);
        const expBox = document.getElementById(`exp-${qId}`);

        if (isCorrect) {
            selectedBtn.classList.add('selected-correct');
            expBox.className = 'explanation-box correct';
            expBox.innerHTML = `<div class="explanation-title">🎉 إجابة صحيحة!</div>${qData.expCorrect}`;
        } else {
            selectedBtn.classList.add('selected-wrong');
            document.getElementById(`icon-${qId}-${selectedOptIdx}`).innerText = '❌';
            expBox.className = 'explanation-box wrong';
            expBox.innerHTML = `<div class="explanation-title">⚠️ إجابة خاطئة!</div>${qData.expWrong}`;
        }
        expBox.style.display = 'block';
    }

    function startTimer() {
        timerInterval = setInterval(() => {
            timerSeconds--;
            let mins = Math.floor(timerSeconds / 60);
            let secs = timerSeconds % 60;
            document.getElementById('timer').innerText = `${mins < 10 ? '0' : ''}${mins}:${secs < 10 ? '0' : ''}${secs}`;
            if (timerSeconds <= 0) {
                clearInterval(timerInterval);
                finishQuiz();
            }
        }, 1000);
    }

    function finishQuiz() {
        clearInterval(timerInterval);
        let score = 0;
        questionsData.forEach(q => {
            if (userAnswers[q.id] === q.correct) score++;
        });
        document.getElementById('scoreText').innerText = `${score} / 15`;
        const resultEmoji = document.getElementById('resultEmoji');
        const resultFeedback = document.getElementById('resultFeedback');

        if (score >= 13) {
            resultEmoji.innerText = '🏆';
            resultFeedback.innerText = 'أداء أسطوري ممتاز! متقن للقواعد بامتياز!';
        } else if (score >= 9) {
            resultEmoji.innerText = '👏';
            resultFeedback.innerText = 'أداء جيد جداً!';
        } else {
            resultEmoji.innerText = '💪';
            resultFeedback.innerText = 'محاولة جيدة! راجع الشرح أسفل كل سؤال لتتحسن أكثر.';
        }
        document.getElementById('resultModal').style.display = 'flex';
    }

    function closeModal() { document.getElementById('resultModal').style.display = 'none'; }

    function toggleTheme() {
        const body = document.body;
        const themeBtn = document.getElementById('themeBtn');
        if (body.getAttribute('data-theme') === 'dark') {
            body.removeAttribute('data-theme');
            themeBtn.innerText = '🌙';
        } else {
            body.setAttribute('data-theme', 'dark');
            themeBtn.innerText = '☀️';
        }
    }

    window.onload = () => { renderQuestions(); startTimer(); };
</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions