-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathwriting_part4.html
More file actions
642 lines (579 loc) · 33.4 KB
/
writing_part4.html
File metadata and controls
642 lines (579 loc) · 33.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Writing - Part 4</title>
<link rel="stylesheet" href="css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@400;500;700&display=swap" rel="stylesheet">
<link rel="icon" href="img/favicon.png" type="image/x-icon">
<!-- 1. Tích hợp CSS của Driver.js -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@1.0.1/dist/driver.css"/>
<style>
/* CSS cho nút Help/Tour */
.tour-btn {
position: fixed;
bottom: 20px;
right: 20px;
background-color: #fff;
border: 1px solid #ddd;
color: #333;
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
z-index: 999;
font-size: 24px;
transition: transform 0.2s, background-color 0.2s;
}
.tour-btn:hover {
transform: scale(1.1);
background-color: #f8f9fa;
}
/* Tùy chỉnh giao diện Driver.js */
.driver-popover.driverjs-theme {
background-color: #fff;
color: #333;
border-radius: 8px;
padding: 15px;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
max-width: 350px;
}
.driver-popover.driverjs-theme .driver-popover-title {
font-size: 18px;
font-weight: 700;
margin-bottom: 8px;
color: #007bff; /* Màu xanh Aptis Practice */
}
.driver-popover.driverjs-theme .driver-popover-description {
font-size: 14px;
line-height: 1.6;
color: #555;
}
.driver-popover.driverjs-theme button {
background-color: #007bff; /* Màu xanh Aptis Practice */
color: #fff;
text-shadow: none;
border: none;
border-radius: 4px;
padding: 6px 12px;
}
/* Highlight styles cho Driver.js */
.driver-active-element {
box-shadow: 0 0 0 4px rgba(0, 123, 255, 0.3) !important;
}
/* CSS cho Hints Wrapper */
.hints-wrapper {
margin-top: 15px;
padding: 15px;
background-color: #e3f2fd;
border-radius: 8px;
border-left: 4px solid #007bff; /* Đồng bộ màu xanh */
font-size: 0.95em;
}
.hints-wrapper h4 {
margin-top: 0;
color: #0056b3;
margin-bottom: 10px;
}
.hints-wrapper ul {
padding-left: 20px;
margin-bottom: 0;
}
/* CSS cho Sample Answer Wrapper */
.sample-answer-wrapper {
margin-top: 15px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 8px;
border-left: 4px solid #6c757d; /* Màu xám cho đáp án để phân biệt */
font-size: 0.95em;
}
.sample-answer-wrapper h4 {
margin-top: 0;
color: #495057;
margin-bottom: 10px;
}
/* Custom style cho nút trong JS */
.btn-primary-custom {
background-color: #007bff !important;
color: white !important;
border: 1px solid #007bff !important;
}
.btn-outline-custom {
background-color: white !important;
color: #007bff !important;
border: 1px solid #007bff !important;
}
.btn-outline-custom:hover {
background-color: #f0f8ff !important;
}
</style>
</head>
<body>
<header id="header-placeholder"></header>
<!-- 2. Nút kích hoạt lại Tour -->
<div class="tour-btn" id="restart-tour" title="Hướng dẫn sử dụng">❓</div>
<div class="content-pusher">
<div class="container">
<div class="page-intro">
<h1>Writing - Part 4</h1>
<p>Viết hai email phản hồi (Tổng thời gian: 30 phút)</p>
</div>
<div class="explanation-box">
<h3>💡 Sườn bài gợi ý cho Part 4</h3>
<p>Writing Part 4 yêu cầu bạn viết 2 email: một cho bạn bè (thân mật) và một cho quản lý (trang trọng).
Dưới đây là các sườn bài và gợi ý để bạn triển khai.</p>
<!-- Sườn bài cho bạn bè -->
<div class="method-step">
<h4>Sườn bài Email cho bạn bè (Thân mật - ~50 từ)</h4>
<div class="template-section">
<p><strong>1. Mở đầu (Greeting):</strong></p>
<ul>
<li><code>Hi [Tên bạn],</code> / <code>Hi Sara,</code></li>
<li><code>How's it going?</code> / <code>I hope you’re doing well.</code></li>
</ul>
<p><strong>2. Nêu vấn đề & Cảm xúc (Context & Feeling):</strong></p>
<ul>
<li><code>I just got an email from the club manager. He mentioned that...</code></li>
<li><code>To be honest, I was very excited/happy/surprised about this news.</code></li>
</ul>
<p><strong>3. Đưa ra gợi ý chính (Suggestion):</strong></p>
<ul>
<li><code>I think we should...</code> / <code>Maybe the club could...</code></li>
</ul>
<p><strong>4. Kết bài (Closing):</strong></p>
<ul>
<li><code>What do you think?</code> / <code>Let me know your thoughts.</code></li>
<li><code>Hope to hear from you soon.</code> / <code>Please reply soon.</code></li>
<li><code>Love,</code> / <code>Best,</code> / <code>All the best,</code></li>
</ul>
</div>
</div>
<!-- Sườn bài cho quản lý -->
<div class="method-step">
<h4>Sườn bài Email cho quản lý (Trang trọng - 120-150 từ)</h4>
<div class="template-section">
<p><strong>1. Mở đầu (Opening):</strong></p>
<ul>
<li><code>Dear Manager,</code> / <code>Dear Sir/Madam,</code></li>
<li><code>I hope this email finds you well.</code></li>
<li><strong>Giới thiệu bản thân (quan trọng):</strong>
<code>First, I would like to introduce myself. My name is [Tên của bạn] and I have been a club member for [số] years.</code>
</li>
<li><strong>Nêu mục đích viết thư:</strong>
<code>I am writing this email to express my opinion concerning the recent email.</code>
</li>
</ul>
<p><strong>2. Trình bày lại vấn đề (Context):</strong></p>
<ul>
<li><code>According to the email, you said that...</code></li>
<li><strong>Nêu cảm xúc (tùy chọn):</strong>
<code>To be honest, I was very happy / a little disappointed when I heard this news.</code>
</li>
</ul>
<p><strong>3. Thân bài - Đưa ra các gợi ý (Suggestions):</strong></p>
<ul>
<li>Sử dụng các từ nối để trình bày 2-3 gợi ý một cách logic:</li>
<li><code><strong>From my perspective,</strong> I think we should...</code></li>
<li><code><strong>Firstly,</strong> I suggest that the club could...</code></li>
<li><code><strong>Secondly,</strong> it would be a great idea if we...</code> /
<code><strong>In addition,</strong> we could also...</code> /
<code><strong>Besides,</strong> ...</code>
</li>
</ul>
<p><strong>4. Kết bài (Closing):</strong></p>
<ul>
<li><strong>Các câu kết thư gợi ý:</strong>
<ul>
<li><code>I have spoken to other club members, and they agree with my suggestions.</code>
</li>
<li><code>Thank you for considering my suggestions. I hope you will find them helpful.</code>
</li>
</ul>
</li>
<li><strong>Kêu gọi hành động:</strong>
<code>I look forward to hearing from you soon.</code>
</li>
<li><strong>Lời chào cuối thư:</strong> <code>Yours sincerely,</code> /
<code>Best regards,</code>
</li>
</ul>
</div>
</div>
</div>
<!-- THÊM CẨM NANG HƯỚNG DẪN VÀO ĐÂY -->
<div class="method-guide-card" style="margin-bottom: 30px;">
<h2>💡 Phân tích đề & Gợi ý ý tưởng cho Part 4</h2>
<p>Writing Part 4 thường có hai dạng đề chính. Việc xác định đúng dạng đề sẽ giúp bạn có cấu trúc bài
viết phù hợp.</p>
<div class="method-step">
<h4>Dạng 1: Lựa chọn đề xuất (Choose a Proposal)</h4>
<p><strong>Nhiệm vụ:</strong> Đề bài sẽ đưa ra 2 lựa chọn (ví dụ: trồng cây ở công viên HOẶC tổ chức
workshop làm vườn). Bạn cần chọn một và giải thích lý do.</p>
<p><strong>Chiến lược gợi ý:</strong></p>
<ul>
<li><strong>Chọn 1 đề xuất:</strong> Rõ ràng bày tỏ sự ủng hộ cho lựa chọn của bạn (ví dụ: "I
strongly support planting 500 trees...").</li>
<li><strong>Nêu lý do 1 (Ưu điểm của lựa chọn):</strong> Giải thích tại sao lựa chọn của bạn lại
tốt. (Ví dụ: "This initiative will provide a greener environment and improve air
quality...").</li>
<li><strong>Nêu lý do 2 (So sánh với lựa chọn còn lại):</strong> Giải thích tại sao lựa chọn của
bạn tốt HƠN lựa chọn kia. (Ví dụ: "While gardening workshops are valuable, I believe more
people will benefit from an improved park...").</li>
</ul>
</div>
<div class="method-step">
<h4>Dạng 2: Giải quyết vấn đề & Đưa ra gợi ý (Problem-Solving)</h4>
<p><strong>Nhiệm vụ:</strong> Đề bài nêu ra một vấn đề hoặc một kế hoạch cần ý kiến đóng góp (ví dụ:
làm sao để thu hút khách du lịch?). Bạn cần đề xuất giải pháp.</p>
<p><strong>Chiến lược gợi ý:</strong></p>
<ul>
<li><strong>Đưa ra 2-3 giải pháp:</strong> Cố gắng đề xuất những ý tưởng hợp lý và có tính
thuyết phục để gây ấn tượng với người quản lý.</li>
<li><strong>Sử dụng "Ngân hàng ý tưởng" sau:</strong>
<ul>
<li><strong>Tổ chức sự kiện:</strong> Chọn thời gian/địa điểm, đa dạng hoạt động, quảng
cáo...</li>
<li><strong>Chọn chủ đề thu hút:</strong> Miễn phí vé, chủ đề mới lạ, thu hút ở mọi lứa
tuổi...</li>
<li><strong>Tăng phí / Gây quỹ:</strong> Tăng phí nhẹ, kêu gọi tài trợ, đóng góp tự
nguyện...</li>
<li><strong>Mời khách mời:</strong> Mời chuyên gia, người nổi tiếng để tăng sức hút, các
tác phẩm của người đó truyền cảm hứng cho người yêu thích chủ đề nào đó,...
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- BẢNG ĐIỀU KHIỂN CHỌN CHỦ ĐỀ -->
<div id="topic-selector-grid" class="topic-grid">
<!-- Các nút chọn chủ đề sẽ được chèn vào đây -->
</div>
<main id="writing-container">
<!-- Chỉ một bài tập được hiển thị tại một thời điểm -->
</main>
</div>
<footer id="footer-placeholder"></footer>
</div>
<script src="js/main.js"></script>
<script src="js/data-writing-part4.js"></script>
<!-- 3. Tích hợp Script của Driver.js -->
<script src="https://cdn.jsdelivr.net/npm/driver.js@1.0.1/dist/driver.js.iife.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const selectorContainer = document.getElementById('topic-selector-grid');
const contentContainer = document.getElementById('writing-container');
const topics = writingPart4Data;
if (!topics || topics.length === 0) {
contentContainer.innerHTML = `<p class="error">Không có dữ liệu cho Writing Part 4.</p>`;
return;
}
topics.forEach((topic, index) => {
const button = document.createElement('button');
button.className = 'topic-selector-btn';
button.textContent = `Chủ đề ${index + 1}`;
button.dataset.target = `#${topic.id}`;
selectorContainer.appendChild(button);
const card = document.createElement('div');
card.className = 'quiz-card writing-part4-card';
card.id = topic.id;
let hints1HTML = topic.task1.hints ? '<ul>' + topic.task1.hints.map(h => `<li>${h}</li>`).join('') + '</ul>' : '<p>Không có gợi ý cho phần này.</p>';
let hints2HTML = topic.task2.hints ? '<ul>' + topic.task2.hints.map(h => `<li>${h}</li>`).join('') + '</ul>' : '<p>Không có gợi ý cho phần này.</p>';
// === CẬP NHẬT MÀU NÚT BẤM TẠI ĐÂY ===
card.innerHTML = `
<div class="card-header"><h2>${topic.title}</h2></div>
<div class="context-box">
<p>${topic.context}</p>
<div class="translation-controls">
<button class="action-btn-small show-translation-btn" style="background-color: #007bff; border:none; color:white;">🔍 Dịch & Từ khóa</button>
</div>
<div class="translation-content" style="display:none;">
<p><strong>Bản dịch:</strong> ${topic.context_vi || 'Chưa có bản dịch.'}</p>
<div class="keywords-list"></div>
</div>
</div>
<!-- Nhiệm vụ 1 -->
<div class="writing-task" data-task-id="1">
<div class="task-header"><h3>Nhiệm vụ 1: Email cho bạn (thân mật)</h3><p class="instruction">${topic.task1.instruction}</p></div>
<div class="writing-timer-bar"><button class="action-btn start-writing-btn" data-duration="600">Bắt đầu (10 phút)</button><div class="timer-display">10:00</div></div>
<textarea class="writing-textarea" data-limit="75" rows="8" placeholder="Viết email cho bạn của bạn ở đây..."></textarea>
<div class="word-count-container"><span class="word-count">0/75 words</span></div>
<div class="card-actions" style="display: flex; gap: 10px; justify-content: center; margin-top: 15px;">
<!-- NÚT GỢI Ý (Solid Blue) -->
<button class="action-btn show-hints-btn btn-primary-custom">💡 Xem Gợi ý</button>
<!-- NÚT ĐÁP ÁN (Outline Blue) -->
<button class="action-btn show-sample-btn btn-outline-custom">📖 Xem Đáp án</button>
</div>
<div class="hints-wrapper" style="display: none;">
<h4>Gợi ý dàn bài:</h4>${hints1HTML}
</div>
<div class="sample-answer-wrapper" style="display: none;">
<h4>Bài mẫu tham khảo:</h4>
<div class="sample-answer"><pre>${topic.task1.sampleAnswer}</pre></div>
</div>
</div>
<!-- Nhiệm vụ 2 -->
<div class="writing-task" data-task-id="2">
<div class="task-header"><h3>Nhiệm vụ 2: Email cho quản lý (trang trọng)</h3><p class="instruction">${topic.task2.instruction}</p></div>
<div class="writing-timer-bar"><button class="action-btn start-writing-btn" data-duration="1200">Bắt đầu (20 phút)</button><div class="timer-display">20:00</div></div>
<textarea class="writing-textarea" data-limit="250" rows="15" placeholder="Viết email cho quản lý ở đây..."></textarea>
<div class="word-count-container"><span class="word-count">0/250 words</span></div>
<div class="card-actions" style="display: flex; gap: 10px; justify-content: center; margin-top: 15px;">
<button class="action-btn show-hints-btn btn-primary-custom">💡 Xem Gợi ý</button>
<button class="action-btn show-sample-btn btn-outline-custom">📖 Xem Đáp án</button>
</div>
<div class="hints-wrapper" style="display: none;">
<h4>Gợi ý dàn bài:</h4>${hints2HTML}
</div>
<div class="sample-answer-wrapper" style="display: none;">
<h4>Bài mẫu tham khảo:</h4>
<div class="sample-answer"><pre>${topic.task2.sampleAnswer}</pre></div>
</div>
</div>`;
contentContainer.appendChild(card);
});
const allButtons = selectorContainer.querySelectorAll('.topic-selector-btn');
const allCards = contentContainer.querySelectorAll('.writing-part4-card');
let timers = {};
function showTopic(targetId) {
allCards.forEach(card => card.classList.remove('active'));
allButtons.forEach(btn => btn.classList.remove('active'));
const targetCard = document.querySelector(targetId);
const targetButton = selectorContainer.querySelector(`[data-target='${targetId}']`);
if (targetCard) targetCard.classList.add('active');
if (targetButton) targetButton.classList.add('active');
Object.values(timers).forEach(timer => clearInterval(timer));
allCards.forEach(c => {
c.querySelectorAll('.writing-timer-bar').forEach(bar => {
const btn = bar.querySelector('.start-writing-btn');
const display = bar.querySelector('.timer-display');
const duration = btn.dataset.duration;
const minutes = Math.floor(duration / 60);
display.textContent = `${minutes.toString().padStart(2, '0')}:00`;
btn.disabled = false;
btn.textContent = `Bắt đầu (${minutes} phút)`;
});
});
}
function loadAnswers(card) {
const storageKey = `writing_part4_${card.id}`;
const saved = JSON.parse(localStorage.getItem(storageKey));
if (saved) {
const task1Textarea = card.querySelector('[data-task-id="1"] textarea');
const task2Textarea = card.querySelector('[data-task-id="2"] textarea');
if (task1Textarea && saved.task1) {
task1Textarea.value = saved.task1;
task1Textarea.dispatchEvent(new Event('input'));
}
if (task2Textarea && saved.task2) {
task2Textarea.value = saved.task2;
task2Textarea.dispatchEvent(new Event('input'));
}
}
}
allCards.forEach(loadAnswers);
selectorContainer.addEventListener('click', function (e) { if (e.target.classList.contains('topic-selector-btn')) showTopic(e.target.dataset.target); });
// --- XỬ LÝ NHẬP LIỆU ---
contentContainer.addEventListener('input', function (e) {
if (e.target.classList.contains('writing-textarea')) {
const textarea = e.target;
// Auto Start Timer
const taskContainer = textarea.closest('.writing-task');
const startBtn = taskContainer.querySelector('.start-writing-btn');
if (startBtn && !startBtn.disabled) {
startBtn.click();
}
// Word Count & Hard Limit
const limit = parseInt(textarea.dataset.limit);
let val = textarea.value;
let words = val.trim().split(/\s+/).filter(word => word.length > 0);
if (words.length > limit) {
textarea.value = words.slice(0, limit).join(" ");
words = textarea.value.trim().split(/\s+/).filter(word => word.length > 0);
}
const wordCountSpan = textarea.nextElementSibling.querySelector('.word-count');
wordCountSpan.textContent = `${words.length}/${limit} words`;
wordCountSpan.classList.toggle('limit-exceeded', words.length >= limit);
if (words.length >= limit) {
wordCountSpan.style.color = '#dc3545';
wordCountSpan.style.fontWeight = 'bold';
} else {
wordCountSpan.style.color = '#666';
wordCountSpan.style.fontWeight = 'normal';
}
// Save
const card = e.target.closest('.writing-part4-card');
const storageKey = `writing_part4_${card.id}`;
const task1Value = card.querySelector('[data-task-id="1"] textarea').value;
const task2Value = card.querySelector('[data-task-id="2"] textarea').value;
localStorage.setItem(storageKey, JSON.stringify({ task1: task1Value, task2: task2Value }));
}
});
contentContainer.addEventListener('click', function (e) {
// Xử lý nút Dịch
if (e.target.classList.contains('show-translation-btn')) {
const button = e.target;
const card = button.closest('.writing-part4-card');
const topicData = topics.find(t => t.id === card.id);
const translationContent = card.querySelector('.translation-content');
const keywordsList = translationContent.querySelector('.keywords-list');
const isVisible = translationContent.style.display === 'block';
if (!isVisible) {
keywordsList.innerHTML = '';
if (topicData.keywords_vi) {
keywordsList.innerHTML = '<h4>Từ khóa chính:</h4>';
for (const [en, vi] of Object.entries(topicData.keywords_vi)) {
keywordsList.innerHTML += `<p><strong>${en}:</strong> ${vi}</p>`;
}
}
}
translationContent.style.display = isVisible ? 'none' : 'block';
button.textContent = isVisible ? '🔍 Dịch & Từ khóa' : '🙈 Ẩn';
}
// Xử lý Timer
if (e.target.classList.contains('start-writing-btn')) {
const button = e.target;
const timerBar = button.closest('.writing-timer-bar');
const timerDisplay = timerBar.querySelector('.timer-display');
const taskContainer = button.closest('.writing-task');
const textarea = taskContainer.querySelector('.writing-textarea');
const timerId = taskContainer.id || `timer-${Math.random()}`; // Đảm bảo ID duy nhất
taskContainer.id = timerId;
if (timers[timerId]) clearInterval(timers[timerId]);
button.disabled = true;
button.textContent = 'Đang tính giờ...';
let timeInSeconds = parseInt(button.dataset.duration, 10);
timers[timerId] = setInterval(() => {
timeInSeconds--;
const minutes = Math.floor(timeInSeconds / 60);
const seconds = timeInSeconds % 60;
timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
if (timeInSeconds <= 0) {
clearInterval(timers[timerId]);
timerDisplay.textContent = "Hết giờ!";
alert(`Hết giờ cho nhiệm vụ này!`);
textarea.disabled = true;
}
}, 1000);
}
// Xử lý nút Xem Gợi ý
if (e.target.classList.contains('show-hints-btn')) {
const button = e.target;
const taskContainer = button.closest('.writing-task');
const hintsWrapper = taskContainer.querySelector('.hints-wrapper');
const isVisible = hintsWrapper.style.display === 'block';
hintsWrapper.style.display = isVisible ? 'none' : 'block';
button.textContent = isVisible ? '💡 Xem Gợi ý' : '🙈 Ẩn Gợi ý';
}
// Xử lý nút Xem Đáp án
if (e.target.classList.contains('show-sample-btn')) {
const button = e.target;
const taskContainer = button.closest('.writing-task');
const sampleWrapper = taskContainer.querySelector('.sample-answer-wrapper');
const isVisible = sampleWrapper.style.display === 'block';
sampleWrapper.style.display = isVisible ? 'none' : 'block';
button.textContent = isVisible ? '📖 Xem Đáp án' : '🙈 Ẩn Đáp án';
}
});
if (allButtons.length > 0) showTopic(allButtons[0].dataset.target);
// --- KÍCH HOẠT TOUR HƯỚNG DẪN PART 4 ---
setTimeout(initWritingPart4Tour, 800);
});
function initWritingPart4Tour() {
const driver = window.driver.js.driver;
const driverObj = driver({
showProgress: true,
animate: true,
doneBtnText: 'Hoàn thành',
nextBtnText: 'Tiếp theo',
prevBtnText: 'Quay lại',
popoverClass: 'driverjs-theme',
steps: [
{
element: '.explanation-box',
popover: {
title: 'Cẩm nang Part 4',
description: 'Đây là phần thi quan trọng nhất. Hãy đọc kỹ 2 sườn bài mẫu: Email cho bạn bè (ngắn, thân mật) và Email cho quản lý (dài, trang trọng, cấu trúc 4 phần).',
side: "bottom",
align: 'center'
}
},
{
element: '.method-guide-card',
popover: {
title: 'Phân tích đề',
description: 'Xác định xem đề bài thuộc dạng "Lựa chọn phương án" hay "Giải quyết vấn đề" để có ý tưởng viết phù hợp.',
side: "bottom",
align: 'center'
}
},
{
element: '#topic-selector-grid',
popover: {
title: 'Chọn chủ đề',
description: 'Danh sách các chủ đề Part 4 được biên soạn sát với đề thi thật.',
side: "top",
align: 'center'
}
},
{
element: '.writing-part4-card.active .context-box',
popover: {
title: 'Ngữ cảnh (Context)',
description: 'Đây là email từ Câu lạc bộ. Bạn PHẢI đọc kỹ phần này để hiểu vấn đề. Nếu có từ mới, hãy dùng nút <strong>"Dịch & Từ khóa"</strong> bên dưới.',
side: "bottom",
align: 'center'
}
},
{
element: '.writing-part4-card.active [data-task-id="1"]',
popover: {
title: 'Nhiệm vụ 1: Email cho bạn',
description: 'Viết khoảng 50 từ trong 10 phút. Dùng ngôn ngữ thân mật ("Hi", "Love",...). Hãy kể lại cảm xúc của bạn về tin tức từ CLB.',
side: "top",
align: 'center'
}
},
{
element: '.writing-part4-card.active [data-task-id="2"]',
popover: {
title: 'Nhiệm vụ 2: Email cho quản lý',
description: 'Viết 120-150 từ trong 20 phút. Dùng ngôn ngữ trang trọng ("Dear Sir", "Sincerely"). Cấu trúc phải rõ ràng: Mở bài -> Lý do -> Gợi ý -> Kết bài.',
side: "top",
align: 'center'
}
},
{
element: '.writing-part4-card.active [data-task-id="2"] .card-actions',
popover: {
title: 'Công cụ hỗ trợ',
description: 'Sử dụng nút "Xem Gợi ý" để lấy ý tưởng dàn bài (nút xanh đậm) hoặc nút "Xem Đáp án" để tham khảo bài mẫu (nút trắng viền xanh).',
side: "top",
align: 'center'
}
},
{
element: '#restart-tour',
popover: {
title: 'Hỗ trợ',
description: 'Bất cứ lúc nào cần xem lại hướng dẫn này, hãy bấm vào đây.',
side: "left",
align: 'center'
}
}
]
});
showTourHint('hasSeenWritingPart4Tour', () => driverObj.drive());
document.getElementById('restart-tour').addEventListener('click', () => {
driverObj.drive();
});
}
</script>
</body>
</html>