<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ôn thi Công chức Hải quan - Luật Tổ chức CQĐP 2025</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
background-color: #f3f4f6;
}
.custom-radio:checked + div {
border-color: #1e40af;
background-color: #eff6ff;
box-shadow: 0 0 0 1px #1e40af;
}
.custom-radio:checked + div .radio-dot {
background-color: #1e40af;
border-color: #1e40af;
}
.custom-radio:checked + div .radio-dot::after {
transform: scale(1);
}
/* Custom Scrollbar for Question Grid */
.grid-scroll::-webkit-scrollbar {
width: 6px;
}
.grid-scroll::-webkit-scrollbar-track {
background: #f1f1f1;
}
.grid-scroll::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 4px;
}
.grid-scroll::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
/* Status Colors */
.correct-answer {
background-color: #dcfce7 !important; /* Green 100 */
border-color: #22c55e !important; /* Green 500 */
}
.wrong-answer {
background-color: #fee2e2 !important; /* Red 100 */
border-color: #ef4444 !important; /* Red 500 */
}
</style>
</head>
<body class="h-screen flex flex-col overflow-hidden">
<!-- Header -->
<header class="bg-blue-900 text-white shadow-lg z-10">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="w-8 h-8 bg-yellow-500 rounded-full flex items-center justify-center text-blue-900 font-bold">
<i class="fa-solid fa-scale-balanced"></i>
</div>
<div>
<h1 class="font-bold text-lg leading-tight">ÔN THI HẢI QUAN</h1>
<p class="text-xs text-blue-200">Luật Tổ chức CQĐP 2025</p>
</div>
</div>
<div class="flex items-center space-x-4">
<div class="flex items-center bg-blue-800 px-3 py-1.5 rounded-lg border border-blue-700">
<i class="fa-regular fa-clock mr-2 text-yellow-400"></i>
<span id="timer" class="font-mono font-bold text-xl w-16 text-center">60:00</span>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-1 max-w-7xl w-full mx-auto p-4 flex gap-4 overflow-hidden">
<!-- Left Column: Question Area -->
<div class="flex-1 flex flex-col bg-white rounded-xl shadow-md overflow-hidden h-full">
<!-- Progress Bar -->
<div class="w-full bg-gray-200 h-1.5">
<div id="progress-bar" class="bg-yellow-500 h-1.5 transition-all duration-300" style="width: 0%"></div>
</div>
<!-- Question Content -->
<div id="question-container" class="flex-1 overflow-y-auto p-6 md:p-8">
<div class="mb-6">
<span class="inline-block bg-blue-100 text-blue-800 text-xs font-semibold px-2.5 py-0.5 rounded border border-blue-200 mb-2">
Câu <span id="current-question-num">1</span>
</span>
<h2 id="question-text" class="text-xl md:text-2xl font-bold text-gray-800 leading-snug">
<!-- Question text goes here -->
</h2>
</div>
<!-- Options -->
<div id="options-container" class="space-y-3">
<!-- Options will be injected here -->
</div>
<!-- Explanation (Hidden by default) -->
<div id="explanation-box" class="hidden mt-6 bg-green-50 border border-green-200 rounded-lg p-4">
<h3 class="flex items-center text-green-800 font-semibold mb-2">
<i class="fa-solid fa-check-circle mr-2"></i> Giải thích đáp án
</h3>
<p id="explanation-text" class="text-green-700 text-sm"></p>
</div>
</div>
<!-- Footer Controls -->
<div class="bg-gray-50 border-t border-gray-200 p-4 flex justify-between items-center">
<button id="btn-prev" onclick="changeQuestion(-1)" class="px-4 py-2 rounded-lg text-gray-600 hover:bg-gray-200 font-medium transition disabled:opacity-50 disabled:cursor-not-allowed">
<i class="fa-solid fa-arrow-left mr-1"></i> Trước
</button>
<button id="btn-submit" onclick="submitQuiz()" class="hidden bg-red-600 hover:bg-red-700 text-white px-6 py-2 rounded-lg font-bold shadow-lg shadow-red-200 transition transform hover:-translate-y-0.5">
Nộp Bài
</button>
<button id="btn-next" onclick="changeQuestion(1)" class="bg-blue-600 hover:bg-blue-700 text-white px-5 py-2 rounded-lg font-medium shadow-lg shadow-blue-200 transition transform hover:-translate-y-0.5">
Sau <i class="fa-solid fa-arrow-right ml-1"></i>
</button>
</div>
</div>
<!-- Right Column: Navigation Grid (Sidebar) -->
<div class="w-72 hidden lg:flex flex-col bg-white rounded-xl shadow-md overflow-hidden h-full">
<div class="p-4 border-b border-gray-200 bg-gray-50">
<h3 class="font-bold text-gray-700">Danh sách câu hỏi</h3>
<div class="flex items-center justify-between text-xs text-gray-500 mt-2">
<span class="flex items-center"><div class="w-3 h-3 bg-gray-100 border border-gray-300 rounded mr-1"></div> Chưa làm</span>
<span class="flex items-center"><div class="w-3 h-3 bg-blue-100 border border-blue-500 rounded mr-1"></div> Đã chọn</span>
</div>
</div>
<div class="flex-1 overflow-y-auto p-4 grid-scroll">
<div id="question-grid" class="grid grid-cols-4 gap-2">
<!-- Grid items injected here -->
</div>
</div>
<div class="p-4 border-t border-gray-200">
<button onclick="submitQuiz()" id="btn-submit-sidebar" class="w-full bg-blue-900 hover:bg-blue-800 text-white py-2.5 rounded-lg font-semibold transition shadow">
Nộp bài thi
</button>
</div>
</div>
</main>
<!-- Mobile Navigation Toggle (Visible on small screens) -->
<button onclick="toggleMobileGrid()" class="lg:hidden fixed bottom-20 right-4 bg-blue-900 text-white w-12 h-12 rounded-full shadow-xl flex items-center justify-center z-50">
<i class="fa-solid fa-list-ul"></i>
</button>
<!-- Mobile Grid Modal -->
<div id="mobile-grid-modal" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden lg:hidden" onclick="toggleMobileGrid()">
<div class="absolute right-0 top-0 bottom-0 w-64 bg-white shadow-xl flex flex-col" onclick="event.stopPropagation()">
<div class="p-4 border-b border-gray-200 flex justify-between items-center bg-gray-50">
<h3 class="font-bold text-gray-700">Danh sách câu hỏi</h3>
<button onclick="toggleMobileGrid()" class="text-gray-400 hover:text-gray-600"><i class="fa-solid fa-times"></i></button>
</div>
<div class="flex-1 overflow-y-auto p-4">
<div id="mobile-question-grid" class="grid grid-cols-4 gap-2"></div>
</div>
</div>
</div>
<!-- Result Modal -->
<div id="result-modal" class="fixed inset-0 bg-black bg-opacity-70 z-50 hidden flex items-center justify-center p-4">
<div class="bg-white rounded-2xl shadow-2xl max-w-md w-full p-6 transform transition-all scale-100">
<div class="text-center">
<div class="w-20 h-20 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
<i class="fa-solid fa-trophy text-3xl text-blue-600"></i>
</div>
<h2 class="text-2xl font-bold text-gray-800 mb-2">Kết quả bài thi</h2>
<p class="text-gray-500 mb-6">Bạn đã hoàn thành bài thi trắc nghiệm.</p>
<div class="bg-gray-50 rounded-xl p-4 mb-6 grid grid-cols-2 gap-4">
<div class="text-center p-2">
<div class="text-3xl font-bold text-blue-600" id="score-text">0/0</div>
<div class="text-xs text-gray-500 uppercase tracking-wide font-semibold mt-1">Số câu đúng</div>
</div>
<div class="text-center p-2 border-l border-gray-200">
<div class="text-3xl font-bold text-yellow-500" id="percent-text">0%</div>
<div class="text-xs text-gray-500 uppercase tracking-wide font-semibold mt-1">Điểm số</div>
</div>
</div>
<div class="flex space-x-3">
<button onclick="location.reload()" class="flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 font-medium transition">
Làm lại
</button>
<button onclick="closeResultModal()" class="flex-1 px-4 py-2 bg-blue-600 rounded-lg text-white hover:bg-blue-700 font-medium transition shadow-lg shadow-blue-200">
Xem đáp án
</button>
</div>
</div>
</div>
</div>
<script>
// --- DATA ---
// Dữ liệu câu hỏi được trích xuất từ file đính kèm
const quizData = [
{
id: 1,
question: "Luật Tổ chức chính quyền địa phương số 72/2025/QH15 được Quốc hội thông qua và ký bởi Chủ tịch Quốc hội Trần Thanh Mẫn ngày nào?",
options: ["Ngày 19 tháng 02 năm 2025", "Ngày 01 tháng 3 năm 2027", "Ngày 16 tháng 6 năm 2025", "Ngày 01 tháng 7 năm 2025"],
correct: 2,
explanation: "Đáp án đúng: C. Ngày 16 tháng 6 năm 2025."
},
{
id: 2,
question: "Luật Tổ chức chính quyền địa phương số 72/2025/QH15 có hiệu lực thi hành từ ngày nào?",
options: ["Ngày 16 tháng 6 năm 2025", "Ngày 01 tháng 7 năm 2025", "Ngày 01 tháng 3 năm 2027", "Kể từ ngày Luật được công bố trên Công báo điện tử"],
correct: 0,
explanation: "Đáp án đúng: A. Ngày 16 tháng 6 năm 2025."
},
{
id: 3,
question: "Luật Tổ chức chính quyền địa phương số 72/2025/QH15 thay thế Luật nào kể từ ngày Luật này có hiệu lực thi hành?",
options: ["Luật Tổ chức Chính phủ số 63/2025/QH15", "Luật Tổ chức chính quyền địa phương số 65/2025/QH15", "Luật Tổ chức chính quyền địa phương số 77/2015/QH13", "Nghị quyết số 203/2025/QH15"],
correct: 1,
explanation: "Đáp án đúng: B. Luật Tổ chức chính quyền địa phương số 65/2025/QH15."
},
{
id: 4,
question: "Theo Luật Tổ chức chính quyền địa phương số 72/2025/QH15, đơn vị hành chính của nước Cộng hòa xã hội chủ nghĩa Việt Nam được tổ chức thành mấy cấp?",
options: ["01 cấp", "02 cấp", "03 cấp", "04 cấp"],
correct: 1,
explanation: "Đáp án đúng: B. 02 cấp."
},
{
id: 5,
question: "Đơn vị hành chính cấp tỉnh bao gồm những loại đơn vị nào?",
options: ["Tỉnh, thành phố thuộc tỉnh, thị xã", "Tỉnh, thành phố trực thuộc trung ương", "Thành phố trực thuộc trung ương, quận, huyện", "Tỉnh, đặc khu trực thuộc cấp tỉnh"],
correct: 1,
explanation: "Đáp án đúng: B. Tỉnh, thành phố trực thuộc trung ương."
},
{
id: 6,
question: "Đơn vị hành chính cấp xã bao gồm những loại đơn vị nào?",
options: ["Xã, phường, thị trấn", "Xã, phường, thị xã", "Xã, phường, đặc khu trực thuộc cấp tỉnh", "Xã, thị trấn, đặc khu"],
correct: 2,
explanation: "Đáp án đúng: C. Xã, phường, đặc khu trực thuộc cấp tỉnh."
},
{
id: 7,
question: "Cơ quan nào có thẩm quyền quyết định thành lập đơn vị hành chính - kinh tế đặc biệt?",
options: ["Chính phủ", "Ủy ban Thường vụ Quốc hội", "Quốc hội", "Chủ tịch nước"],
correct: 2,
explanation: "Đáp án đúng: C. Quốc hội."
},
{
id: 8,
question: "Chính quyền địa phương ở các đơn vị hành chính thông thường (trừ đơn vị hành chính quy định tại Điều 28) gồm có những cơ quan nào?",
options: ["Chỉ có Hội đồng nhân dân", "Chỉ có Ủy ban nhân dân", "Hội đồng nhân dân và Ủy ban nhân dân", "Ủy ban nhân dân và Cơ quan chuyên môn"],
correct: 2,
explanation: "Đáp án đúng: C. Hội đồng nhân dân và Ủy ban nhân dân."
},
{
id: 9,
question: "Phân loại đơn vị hành chính là cơ sở để làm gì?",
options: ["Hoạch định chính sách phát triển kinh tế - xã hội", "Xây dựng tổ chức bộ máy, chế độ, chính sách đối với cán bộ, công chức", "Phù hợp với từng loại đơn vị hành chính", "Tất cả các phương án trên"],
correct: 3,
explanation: "Đáp án đúng: D. Tất cả các phương án trên."
},
{
id: 10,
question: "Việc phân loại đơn vị hành chính phải dựa trên các tiêu chí về quy mô dân số, diện tích tự nhiên, điều kiện phát triển kinh tế - xã hội và các yếu tố đặc thù theo quy định của cơ quan nào?",
options: ["Ủy ban Thường vụ Quốc hội", "Quốc hội", "Chính phủ", "Hội đồng nhân dân cấp tỉnh"],
correct: 2,
explanation: "Đáp án đúng: C. Chính phủ."
},
{
id: 11,
question: "Nguyên tắc làm việc của Hội đồng nhân dân là gì?",
options: ["Hoạt động theo chế độ thủ trưởng", "Hoạt động theo chế độ tập thể, quyết định theo đa số", "Hoạt động theo chế độ dân chủ, đề cao trách nhiệm của Chủ tịch", "Hoạt động theo chế độ tập trung dân chủ kết hợp với chế độ thủ trưởng"],
correct: 1,
explanation: "Đáp án đúng: B. Hoạt động theo chế độ tập thể, quyết định theo đa số."
},
{
id: 12,
question: "Nguyên tắc làm việc của Ủy ban nhân dân là gì?",
options: ["Hoạt động theo chế độ cá nhân, chịu trách nhiệm trước Nhân dân", "Hoạt động theo chế độ tập thể, quyết định theo đa số", "Hoạt động theo chế độ tập thể, quyết định theo đa số; đồng thời đề cao thẩm quyền và trách nhiệm của Chủ tịch Ủy ban nhân dân", "Hoạt động theo chế độ tập trung dân chủ"],
correct: 2,
explanation: "Đáp án đúng: C. Hoạt động theo chế độ tập thể, quyết định theo đa số; đồng thời đề cao thẩm quyền và trách nhiệm của Chủ tịch Ủy ban nhân dân."
},
{
id: 13,
question: "Tổ chức chính quyền địa phương phải đảm bảo trách nhiệm giải trình gắn với cơ chế nào?",
options: ["Cơ chế giám sát của Ủy ban Mặt trận Tổ quốc Việt Nam", "Cơ chế phản biện xã hội của các tổ chức chính trị - xã hội", "Cơ chế kiểm tra của cơ quan nhà nước cấp trên", "Cơ chế kiểm soát quyền lực"],
correct: 3,
explanation: "Đáp án đúng: D. Cơ chế kiểm soát quyền lực."
},
{
id: 14,
question: "Việc phân định thẩm quyền của chính quyền địa phương phải được phân định rõ thẩm quyền giữa các cơ quan nhà nước ở trung ương và chính quyền địa phương, và giữa các cấp nào?",
options: ["Giữa chính quyền địa phương cấp tỉnh và cấp huyện", "Giữa chính quyền địa phương cấp huyện và cấp xã", "Giữa chính quyền địa phương cấp tỉnh và chính quyền địa phương cấp xã", "Giữa các cơ quan thuộc chính quyền địa phương cấp tỉnh"],
correct: 2,
explanation: "Đáp án đúng: C. Giữa chính quyền địa phương cấp tỉnh và chính quyền địa phương cấp xã."
},
{
id: 15,
question: "Cơ quan nào có thẩm quyền quyết định thành lập, giải thể, nhập, chia đơn vị hành chính, điều chỉnh địa giới và đổi tên đơn vị hành chính cấp tỉnh?",
options: ["Chính phủ", "Ủy ban Thường vụ Quốc hội", "Quốc hội", "Hội đồng nhân dân cấp tỉnh"],
correct: 2,
explanation: "Đáp án đúng: C. Quốc hội."
},
{
id: 16,
question: "Cơ quan nào có thẩm quyền quyết định thành lập, giải thể, nhập, chia đơn vị hành chính, điều chỉnh địa giới và đổi tên đơn vị hành chính cấp xã?",
options: ["Quốc hội", "Chính phủ", "Ủy ban Thường vụ Quốc hội", "Hội đồng nhân dân cấp tỉnh"],
correct: 2,
explanation: "Đáp án đúng: C. Ủy ban Thường vụ Quốc hội."
},
{
id: 17,
question: "Cơ quan nào được Chính phủ phân công chủ trì xây dựng đề án thành lập, giải thể, nhập, chia đơn vị hành chính cấp tỉnh để trình Chính phủ, Quốc hội?",
options: ["Bộ Nội vụ", "Thường trực Hội đồng nhân dân cấp tỉnh", "Ủy ban nhân dân cấp tỉnh", "Văn phòng Chính phủ"],
correct: 2,
explanation: "Đáp án đúng: C. Ủy ban nhân dân cấp tỉnh."
},
{
id: 18,
question: "Việc thành lập, giải thể, nhập, chia đơn vị hành chính, điều chỉnh địa giới phải được lấy ý kiến Nhân dân ở những đơn vị hành chính cấp nào chịu ảnh hưởng trực tiếp?",
options: ["Cấp tỉnh", "Cấp huyện", "Cấp xã", "Tất cả các cấp hành chính"],
correct: 2,
explanation: "Đáp án đúng: C. Cấp xã."
},
{
id: 19,
question: "Việc tổ chức đơn vị hành chính phải bảo đảm các công việc, thủ tục hành chính liên quan đến người dân, doanh nghiệp và xã hội được tiếp nhận, giải quyết như thế nào?",
options: ["Theo quy định về cải cách hành chính", "Kịp thời, thuận lợi", "Minh bạch, công khai", "Theo quy trình thủ tục đơn giản nhất"],
correct: 1,
explanation: "Đáp án đúng: B. Kịp thời, thuận lợi."
},
{
id: 20,
question: "Hội đồng nhân dân, các cơ quan thuộc Hội đồng nhân dân, Ủy ban nhân dân, Chủ tịch Ủy ban nhân dân, các cơ quan chuyên môn thuộc Ủy ban nhân dân cấp huyện sẽ kết thúc hoạt động từ ngày nào?",
options: ["Ngày 16 tháng 6 năm 2025", "Ngày 01 tháng 7 năm 2025", "Ngày 01 tháng 3 năm 2027", "Ngày 30 tháng 6 năm 2025"],
correct: 1,
explanation: "Đáp án đúng: B. Ngày 01 tháng 7 năm 2025."
},
{
id: 21,
question: "Nhiệm vụ, quyền hạn của chính quyền địa phương các cấp được xác định trên cơ sở phân định thẩm quyền giữa các cơ quan nhà nước ở trung ương và địa phương, và của mỗi cấp chính quyền địa phương theo hình thức nào?",
options: ["Phân cấp và Ủy quyền", "Ủy quyền và Phân quyền", "Phân quyền và Phân cấp", "Tất cả các hình thức trên"],
correct: 2,
explanation: "Đáp án đúng: C. Phân quyền và Phân cấp."
},
{
id: 22,
question: "Việc phân quyền cho chính quyền địa phương các cấp phải được quy định trong văn bản nào?",
options: ["Nghị định của Chính phủ", "Nghị quyết của Hội đồng nhân dân cấp tỉnh", "Luật, nghị quyết của Quốc hội", "Quyết định của Thủ tướng Chính phủ"],
correct: 2,
explanation: "Đáp án đúng: C. Luật, nghị quyết của Quốc hội."
},
{
id: 23,
question: "Cơ quan nhà nước cấp trên có trách nhiệm kiểm tra, thanh tra, giám sát về tính hợp hiến, hợp pháp trong việc chính quyền địa phương các cấp thực hiện nhiệm vụ, quyền hạn được phân quyền hay không?",
options: ["Không, vì chính quyền địa phương tự chủ và tự chịu trách nhiệm", "Chỉ giám sát về tính hợp pháp", "Có, trong phạm vi nhiệm vụ, quyền hạn của mình", "Có, thông qua chế độ báo cáo thường xuyên"],
correct: 2,
explanation: "Đáp án đúng: C. Có, trong phạm vi nhiệm vụ, quyền hạn của mình."
},
{
id: 24,
question: "Ủy ban nhân dân cấp tỉnh, Chủ tịch Ủy ban nhân dân cấp tỉnh có thẩm quyền phân cấp cho cơ quan nào sau đây?",
options: ["Cơ quan chuyên môn, tổ chức hành chính khác thuộc Ủy ban nhân dân cấp mình", "Ủy ban nhân dân, Chủ tịch Ủy ban nhân dân cấp xã", "Đơn vị sự nghiệp công lập thuộc phạm vi quản lý", "Tất cả các cơ quan, đơn vị trên"],
correct: 3,
explanation: "Đáp án đúng: D. Tất cả các cơ quan, đơn vị trên."
},
{
id: 25,
question: "Cơ quan, tổ chức, đơn vị, cá nhân được phân cấp có được phân cấp tiếp nhiệm vụ, quyền hạn mà mình được phân cấp hay không?",
options: ["Có, nếu được cơ quan cấp trên đồng ý", "Có, nếu được quy định trong văn bản phân cấp", "Không được phân cấp tiếp nhiệm vụ, quyền hạn mà mình được phân cấp", "Tùy thuộc vào điều kiện tài chính và nguồn nhân lực"],
correct: 2,
explanation: "Đáp án đúng: C. Không được phân cấp tiếp nhiệm vụ, quyền hạn mà mình được phân cấp."
},
{
id: 26,
question: "Cơ quan, cá nhân phân cấp chịu trách nhiệm về kết quả thực hiện nhiệm vụ, quyền hạn mà mình phân cấp trong trường hợp nào?",
options: ["Cơ quan phân cấp không theo dõi, hướng dẫn, kiểm tra việc thực hiện", "Không bảo đảm các điều kiện cần thiết để thực hiện nhiệm vụ, quyền hạn phân cấp", "Cơ quan được phân cấp không thực hiện đúng trình tự, thủ tục hành chính", "Cơ quan được phân cấp đề nghị điều chỉnh nội dung phân cấp"],
correct: 1,
explanation: "Đáp án đúng: B. Không bảo đảm các điều kiện cần thiết để thực hiện nhiệm vụ, quyền hạn phân cấp."
},
{
id: 27,
question: "Việc ủy quyền nhiệm vụ, quyền hạn giữa các cơ quan, cá nhân phải được thực hiện bằng hình thức nào?",
options: ["Bằng quyết định hành chính", "Bằng lời nói (miệng)", "Bằng văn bản quy phạm pháp luật", "Bằng văn bản của cơ quan, tổ chức, cá nhân ủy quyền"],
correct: 3,
explanation: "Đáp án đúng: D. Bằng văn bản của cơ quan, tổ chức, cá nhân ủy quyền."
},
{
id: 28,
question: "Cơ quan, tổ chức, cá nhân ủy quyền có trách nhiệm chịu trách nhiệm trước pháp luật về tính hợp pháp của việc ủy quyền và kết quả thực hiện nhiệm vụ, quyền hạn mà mình ủy quyền, trừ trường hợp nào sau đây?",
options: ["Cơ quan nhận ủy quyền thay đổi trình tự, thủ tục ủy quyền", "Cơ quan, tổ chức, đơn vị, cá nhân nhận ủy quyền thực hiện không đúng nội dung, phạm vi, thời hạn đã được ủy quyền", "Cơ quan nhận ủy quyền sử dụng con dấu của mình", "Cơ quan nhận ủy quyền báo cáo kết quả không đúng hạn"],
correct: 1,
explanation: "Đáp án đúng: B. Cơ quan, tổ chức, đơn vị, cá nhân nhận ủy quyền thực hiện không đúng nội dung, phạm vi, thời hạn đã được ủy quyền."
},
{
id: 29,
question: "Công chức thuộc Ủy ban nhân dân cấp xã được Chủ tịch Ủy ban nhân dân cấp xã ủy quyền thực hiện một số nhiệm vụ, quyền hạn và được giao ký thừa ủy quyền thì được sử dụng con dấu của cơ quan nào?",
options: ["Con dấu của Chủ tịch Ủy ban nhân dân cấp xã", "Con dấu của cơ quan chuyên môn thuộc UBND cấp xã", "Con dấu của Ủy ban nhân dân cấp xã", "Con dấu của cơ quan, tổ chức, đơn vị mình"],
correct: 2,
explanation: "Đáp án đúng: C. Con dấu của Ủy ban nhân dân cấp xã."
},
{
id: 30,
question: "Cơ quan nào có thẩm quyền quy định chi tiết phạm vi nhiệm vụ, quyền hạn được ủy quyền cho công chức thuộc Ủy ban nhân dân cấp xã?",
options: ["Chính phủ", "Ủy ban Thường vụ Quốc hội", "Hội đồng nhân dân cấp tỉnh", "Chủ tịch Ủy ban nhân dân cấp tỉnh"],
correct: 2,
explanation: "Đáp án đúng: C. Hội đồng nhân dân cấp tỉnh."
}
// Để giữ file gọn nhẹ, tôi đã tích hợp 30 câu hỏi đầu tiên.
// Bạn có thể dễ dàng thêm các câu hỏi còn lại theo đúng format trên.
];
// --- STATE VARIABLES ---
let currentQuestionIndex = 0;
let userAnswers = {}; // { questionId: optionIndex }
let isSubmitted = false;
let timeLeft = 60 * 60; // 60 minutes in seconds
let timerInterval;
// --- ELEMENTS ---
const questionTextEl = document.getElementById('question-text');
const optionsContainerEl = document.getElementById('options-container');
const questionNumEl = document.getElementById('current-question-num');
const progressBarEl = document.getElementById('progress-bar');
const timerEl = document.getElementById('timer');
const btnPrev = document.getElementById('btn-prev');
const btnNext = document.getElementById('btn-next');
const btnSubmit = document.getElementById('btn-submit');
const gridContainer = document.getElementById('question-grid');
const mobileGridContainer = document.getElementById('mobile-question-grid');
const explanationBox = document.getElementById('explanation-box');
const explanationText = document.getElementById('explanation-text');
// --- INITIALIZATION ---
function initQuiz() {
renderGrid();
renderQuestion(0);
startTimer();
// Prevent accidental leave
window.onbeforeunload = function() {
if(!isSubmitted) return "Bạn có chắc muốn rời khỏi bài thi?";
};
}
// --- CORE FUNCTIONS ---
function startTimer() {
timerInterval = setInterval(() => {
if (timeLeft <= 0) {
clearInterval(timerInterval);
submitQuiz();
return;
}
timeLeft--;
const minutes = Math.floor(timeLeft / 60);
const seconds = timeLeft % 60;
timerEl.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
// Alert when running out of time
if (timeLeft < 300) { // 5 minutes
timerEl.parentElement.classList.add('animate-pulse', 'bg-red-800', 'border-red-600');
timerEl.classList.add('text-red-300');
document.querySelector('.fa-clock').classList.remove('text-yellow-400');
document.querySelector('.fa-clock').classList.add('text-red-500');
}
}, 1000);
}
function renderGrid() {
gridContainer.innerHTML = '';
mobileGridContainer.innerHTML = '';
quizData.forEach((q, index) => {
// Determine status class
let statusClass = "bg-gray-100 text-gray-700 border-gray-200 hover:bg-gray-200";
if (userAnswers[q.id] !== undefined) {
statusClass = "bg-blue-100 text-blue-700 border-blue-400 font-semibold";
}
if (isSubmitted) {
if (userAnswers[q.id] === q.correct) {
statusClass = "bg-green-100 text-green-700 border-green-500";
} else {
statusClass = "bg-red-100 text-red-700 border-red-500";
}
}
// Highlight current
if (index === currentQuestionIndex) {
statusClass += " ring-2 ring-blue-500 ring-offset-1";
}
const btn = document.createElement('button');
btn.className = `w-full aspect-square flex items-center justify-center rounded border text-sm transition ${statusClass}`;
btn.innerText = index + 1;
btn.onclick = () => {
renderQuestion(index);
toggleMobileGrid(false); // Close mobile menu if open
};
gridContainer.appendChild(btn);
mobileGridContainer.appendChild(btn.cloneNode(true)); // Copy to mobile menu
});
// Re-attach events for cloned mobile buttons
Array.from(mobileGridContainer.children).forEach((btn, index) => {
btn.onclick = () => {
renderQuestion(index);
toggleMobileGrid(false);
};
});
}
function renderQuestion(index) {
currentQuestionIndex = index;
const q = quizData[index];
// Update UI Text
questionNumEl.textContent = index + 1;
questionTextEl.textContent = q.question;
// Update Progress Bar
const progress = ((index + 1) / quizData.length) * 100;
progressBarEl.style.width = `${progress}%`;
// Clear previous options
optionsContainerEl.innerHTML = '';
// Generate Options
const letters = ['A', 'B', 'C', 'D'];
q.options.forEach((opt, optIndex) => {
const label = document.createElement('label');
label.className = 'cursor-pointer group block relative';
let optionStyle = 'border-gray-200 hover:bg-gray-50';
let dotStyle = 'bg-white border-gray-400';
let icon = '';
// Style Logic
const isSelected = userAnswers[q.id] === optIndex;
const isCorrect = q.correct === optIndex;
if (isSubmitted) {
if (isCorrect) {
optionStyle = 'correct-answer'; // Green
icon = '<i class="fa-solid fa-check text-green-600 ml-auto"></i>';
} else if (isSelected && !isCorrect) {
optionStyle = 'wrong-answer'; // Red
icon = '<i class="fa-solid fa-xmark text-red-600 ml-auto"></i>';
} else {
optionStyle = 'opacity-50 grayscale';
}
} else {
if (isSelected) {
optionStyle = 'border-blue-600 bg-blue-50 ring-1 ring-blue-600';
dotStyle = 'bg-blue-600 border-blue-600';
}
}
label.innerHTML = `
<input type="radio" name="q${q.id}" class="custom-radio sr-only" value="${optIndex}"
${isSelected ? 'checked' : ''}
${isSubmitted ? 'disabled' : ''}
onchange="selectAnswer(${q.id}, ${optIndex})">
<div class="flex p-4 rounded-lg border-2 transition-all duration-200 items-start ${optionStyle}">
<div class="flex-shrink-0 w-6 h-6 rounded-full border-2 mr-3 flex items-center justify-center mt-0.5 radio-dot transition-colors ${dotStyle}">
<div class="w-2.5 h-2.5 bg-white rounded-full transform scale-0 transition-transform ${isSelected ? 'scale-100' : ''}"></div>
</div>
<span class="flex-1 text-gray-700 font-medium text-sm md:text-base">
<span class="font-bold mr-1">${letters[optIndex]}.</span> ${opt}
</span>
${icon}
</div>
`;
optionsContainerEl.appendChild(label);
});
// Handle Explanation
if (isSubmitted) {
explanationBox.classList.remove('hidden');
explanationText.textContent = q.explanation;
} else {
explanationBox.classList.add('hidden');
}
// Update Navigation Buttons
btnPrev.disabled = index === 0;
if (index === quizData.length - 1) {
btnNext.classList.add('hidden');
btnSubmit.classList.remove('hidden');
} else {
btnNext.classList.remove('hidden');
btnSubmit.classList.add('hidden');
}
// Refresh Grid Highlight
renderGrid();
}
function selectAnswer(qId, optIndex) {
if (isSubmitted) return;
userAnswers[qId] = optIndex;
renderGrid(); // Update grid status
renderQuestion(currentQuestionIndex); // Re-render to show selected state styling
}
function changeQuestion(delta) {
const newIndex = currentQuestionIndex + delta;
if (newIndex >= 0 && newIndex < quizData.length) {
renderQuestion(newIndex);
}
}
function submitQuiz() {
if (isSubmitted) return;
// Stop Timer
clearInterval(timerInterval);
isSubmitted = true;
window.onbeforeunload = null;
// Calculate Score
let correctCount = 0;
quizData.forEach(q => {
if (userAnswers[q.id] === q.correct) {
correctCount++;
}
});
const score = Math.round((correctCount / quizData.length) * 10);
const percentage = Math.round((correctCount / quizData.length) * 100);
// Update Result Modal
document.getElementById('score-text').textContent = `${correctCount}/${quizData.length}`;
document.getElementById('percent-text').textContent = `${score} điểm`;
// Show Modal
document.getElementById('result-modal').classList.remove('hidden');
// Hide sidebar submit button
document.getElementById('btn-submit-sidebar').style.display = 'none';
// Re-render current question to show answers/explanations immediately
renderQuestion(currentQuestionIndex);
}
function closeResultModal() {
document.getElementById('result-modal').classList.add('hidden');
}
function toggleMobileGrid(forceState) {
const modal = document.getElementById('mobile-grid-modal');
if (typeof forceState !== 'undefined') {
if (forceState) modal.classList.remove('hidden');
else modal.classList.add('hidden');
} else {
modal.classList.toggle('hidden');
}
}
// Run
initQuiz();
</script>
</body>
</html>