# HƯỚNG DẪN TÍCH HỢP GÓI 70 SLIDE VÀO DỰ ÁN KHÁC

Tài liệu này hướng dẫn chi tiết các phương án tích hợp gói `GOI_70_SLIDES_HTML` vào bất kỳ nền tảng, website, ứng dụng Web hoặc ứng dụng di động nào.

---

## MỤC LỤC
1. [Tổng quan về tính tương thích](#1-tổng-quan-về-tính-tương-thích)
2. [Phương án 1: Nhúng toàn bộ Kho Slide bằng Iframe](#2-phương-án-1-nhúng-toàn-bộ-kho-slide-bằng-iframe)
3. [Phương án 2: Nhúng trực tiếp một bài Slide cụ thể](#3-phương-án-2-nhúng-trực-tiếp-một-bài-slide-cụ-thể)
4. [Phương án 3: Tích hợp vào dự án React / Next.js / Vue / Vite](#4-phương-án-3-tích-hợp-vào-dự-án-react--nextjs--vue--vite)
5. [Phương án 4: Tích hợp vào Backend (Node.js, Express, Python, PHP)](#5-phương-án-4-tích-hợp-vào-backend-nodejs-express-python-php)
6. [Phương án 5: Tích hợp vào Ứng dụng Di động (Flutter, React Native WebView)](#6-phương-án-5-tích-hợp-vào-ứng-dụng-di-động-flutter-react-native-webview)
7. [Phương án 6: Triển khai lên Web Server (Nginx, Apache, Vercel, Netlify)](#7-phương-án-6-triển-khai-lên-web-server-nginx-apache-vercel-netlify)
8. [Cấu trúc dữ liệu `slides_catalog.json`](#8-cấu-trúc-dữ-liệu-slides_catalogjson)

---

## 1. TỔNG QUAN VỀ TÍNH TƯƠNG THÍCH

- **Độc lập 100% (Zero External Dependencies):** Không yêu cầu Node.js, không cần build-step (Webpack/Vite), không cần cơ sở dữ liệu. Tất cả file HTML, CSS, JS và hình ảnh đều chạy trực tiếp trên trình duyệt.
- **Đường dẫn tương đối (Relative Paths):** Mọi tài nguyên đều sử dụng đường dẫn tương đối, do đó bạn có thể đặt thư mục gói ở bất kỳ thư mục con nào trong dự án mà không lo bị gãy liên kết (broken links).
- **Hỗ trợ chế độ Offline:** Chạy tốt ngay cả khi thiết bị không có kết nối mạng Internet.

---

## 2. PHƯƠNG ÁN 1: NHÚNG TOÀN BỘ KHO SLIDE BẰNG IFRAME

Nếu dự án của bạn đã có sẵn một website hoặc trang quản trị và bạn muốn nhúng nguyên vẹn cổng xem 70 slide:

### Bước 1:
Sao chép thư mục `GOI_70_SLIDES_HTML` vào thư mục chứa tài nguyên tĩnh của dự án mới (ví dụ đặt tên là `slides/` hoặc `truth-slides/`).

### Bước 2:
Trong trang HTML của dự án đích, thêm đoạn mã sau:

```html
<!-- Nhúng Kho Slide 70 Chủ Đề -->
<div style="width: 100%; height: 90vh; border-radius: 12px; overflow: hidden; box-shadow: 0 8px 30px rgba(0,0,0,0.15);">
  <iframe
    src="/slides/index.html"
    style="width: 100%; height: 100%; border: none;"
    allow="fullscreen; autoplay"
    loading="lazy"
    title="Kho Slide 70 Chủ Đề">
  </iframe>
</div>
```

---

## 3. PHƯƠNG ÁN 2: NHÚNG TRỰC TIẾP MỘT BÀI SLIDE CỤ THỂ

Nếu bạn chỉ muốn nhúng một bài thuyết giáo cụ thể vào trang chi tiết bài viết hoặc giáo trình:

```html
<!-- Ví dụ nhúng bài 1.1: Mầu nhiệm về sự tha tội và Đấng Cứu Chúa -->
<div style="width: 100%; max-width: 1200px; aspect-ratio: 16/9; margin: 0 auto; border-radius: 8px; overflow: hidden;">
  <iframe
    src="/slides/slides/sermon_01_01_1.html"
    style="width: 100%; height: 100%; border: none;"
    allow="fullscreen"
    title="Bài 1.1: Mầu nhiệm về sự tha tội và Đấng Cứu Chúa">
  </iframe>
</div>
```

Hoặc tạo nút bấm mở toàn màn hình bài giảng trong tab mới:
```html
<a href="/slides/slides/sermon_01_01_1.html" target="_blank" class="btn btn-primary">
  ▶ Trình chiếu bài 1.1 Toàn màn hình
</a>
```

---

## 4. PHƯƠNG ÁN 3: TÍCH HỢP VÀO DỰ ÁN REACT / NEXT.JS / VUE / VITE

### Đối với Next.js (App Router hoặc Pages Router):
1. Đặt thư mục `GOI_70_SLIDES_HTML` vào trong thư mục `public/`:
   ```text
   my-nextjs-app/
   ├── public/
   │   └── presentation-slides/   <-- Đặt toàn bộ nội dung gói vào đây
   ```
2. Tạo component xem slide trong React:

```tsx
// components/SlideViewer.tsx
'use client';

interface SlideViewerProps {
  slideFile: string; // ví dụ: "sermon_01_01_1.html" hoặc "moses_01_01_51.html"
}

export default function SlideViewer({ slideFile }: SlideViewerProps) {
  return (
    <div className="relative w-full aspect-video rounded-xl overflow-hidden shadow-2xl bg-slate-900">
      <iframe
        src={`/presentation-slides/slides/${slideFile}`}
        className="w-full h-full border-0"
        allow="fullscreen; autoplay"
        allowFullScreen
      />
    </div>
  );
}
```

3. Sử dụng file `public/presentation-slides/data/slides_catalog.json` để render danh sách thẻ bài giảng tùy biến theo giao diện riêng của dự án bạn:

```tsx
import slidesCatalog from '@/public/presentation-slides/data/slides_catalog.json';

export default function SlideCatalogPage() {
  return (
    <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
      {slidesCatalog.map((item) => (
        <div key={item.id} className="border rounded-lg p-4">
          <img src={`/presentation-slides/${item.thumbnail}`} alt={item.title} className="rounded" />
          <h3 className="font-bold mt-2">{item.title}</h3>
          <p className="text-sm text-gray-500">{item.korean_title} • {item.total_slides} trang</p>
          <a
            href={`/presentation-slides/${item.html_file}`}
            target="_blank"
            className="inline-block mt-3 px-4 py-2 bg-blue-600 text-white rounded"
          >
            Trình chiếu
          </a>
        </div>
      ))}
    </div>
  );
}
```

---

## 5. PHƯƠNG ÁN 4: TÍCH HỢP VÀO BACKEND (NODE.JS, EXPRESS, PYTHON, PHP)

### Với Node.js / Express:
Chỉ cần khai báo một thư mục tĩnh (Static Directory):
```javascript
const express = require('express');
const path = require('path');
const app = express();

// Khai báo phục vụ toàn bộ thư mục slide
app.use('/truth-slides', express.static(path.join(__dirname, 'GOI_70_SLIDES_HTML')));

app.listen(3000, () => {
  console.log('Kho slide đã sẵn sàng tại: http://localhost:3000/truth-slides');
});
```

### Với Python FastAPI:
```python
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

app = FastAPI()

app.mount("/slides", StaticFiles(directory="GOI_70_SLIDES_HTML", html=True), name="slides")
```

---

## 6. PHƯƠNG ÁN 5: TÍCH HỢP VÀO ỨNG DỤNG DI ĐỘNG (FLUTTER / REACT NATIVE)

### Trong Flutter (`webview_flutter`):
1. Đặt thư mục `GOI_70_SLIDES_HTML` vào `assets/slides/` và khai báo trong `pubspec.yaml`.
2. Sử dụng controller để mở file:
```dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class SlideScreen extends StatefulWidget {
  final String slideFileName;
  SlideScreen({required this.slideFileName});

  @override
  _SlideScreenState createState() => _SlideScreenState();
}

class _SlideScreenState extends State<SlideScreen> {
  late final WebViewController _controller;

  @override
  void initState() {
    super.initState();
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadFlutterAsset('assets/slides/slides/${widget.slideFileName}');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: WebViewWidget(controller: _controller),
      ),
    );
  }
}
```

---

## 7. PHƯƠNG ÁN 6: TRIỂN KHAI LÊN WEB SERVER (NGINX, APACHE, VERCEL, NETLIFY)

### Triển khai trên Nginx:
Thêm cấu hình vào file `nginx.conf`:
```nginx
server {
    listen 80;
    server_name slides.yourdomain.com;

    location / {
        root /var/www/GOI_70_SLIDES_HTML;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
}
```

### Triển khai lên Vercel hoặc Netlify:
- Đặt thư mục `GOI_70_SLIDES_HTML` làm thư mục gốc (Root Directory) của trang web tĩnh.
- Deploy trực tiếp mà không cần cấu hình build command nào.

---

## 8. CẤU TRÚC DỮ LIỆU `slides_catalog.json`

File `data/slides_catalog.json` chứa thông tin chuẩn hóa của toàn bộ 70 bài giảng dưới dạng mảng JSON. Mỗi phần tử có cấu trúc như sau:

```json
{
  "id": 1,
  "category": "sermon",
  "step": 1,
  "chapter": 1,
  "title": "Mầu nhiệm về sự tha tội và Đấng Cứu Chúa",
  "korean_title": "죄 사함의 비밀과 구원자",
  "total_slides": 71,
  "html_file": "slides/sermon_01_01_1.html",
  "thumbnail": "slides/assets/sermon_01_01_1/Step_1.jpg"
}
```

### Giải thích các trường:
- `id`: Mã số định danh duy nhất của bài giảng (1 đến 70).
- `category`: Thể loại bài giảng (`"sermon"` = Chân lý Thuyết giáo; `"moses"` = Cây gậy của Môi-se).
- `step`: Phân bước (từ 1 đến 5 cho Thuyết giáo; từ 1 đến 2 cho Môi-se).
- `chapter`: Số thứ tự chương trong bước.
- `title`: Tiêu đề tiếng Việt chuẩn của bài giảng.
- `korean_title`: Tiêu đề tiếng Hàn chuẩn đối chiếu.
- `total_slides`: Tổng số trang/bước trình chiếu trong bài.
- `html_file`: Đường dẫn tương đối đến file HTML trình chiếu.
- `thumbnail`: Đường dẫn tương đối đến ảnh đại diện thu nhỏ của bài.

---

Chúc bạn tích hợp thuận lợi và mang lại trải nghiệm trình chiếu lẽ thật tuyệt vời cho người học!
