# คู่มือนักพัฒนา - Documentation System
## ภาพรวมระบบ
ระบบเอกสารนี้เป็น Single Page Application (SPA) ที่ใช้ JavaScript ในการโหลดและแสดงผลไฟล์ Markdown แบบเรียลไทม์
## สถาปัตยกรรมระบบ
### โครงสร้างไฟล์
```
documentation/
├── index.html # หน้าหลัก (SPA)
├── docs/ # เอกสาร Markdown
│ ├── th/ # ภาษาไทย
│ └── en/ # ภาษาอังกฤษ
└── README.md # คู่มือโปรเจ็ค
```
### เทคโนโลยีที่ใช้
- **HTML5** - โครงสร้างหน้าเว็บ
- **CSS3** - การจัดรูปแบบ (CSS Variables, Flexbox, Grid)
- **JavaScript ES6+** - ตรรกะการทำงาน
- **Marked.js** - แปลง Markdown เป็น HTML
- **Highlight.js** - เน้นสีโค้ด
## โครงสร้างโค้ด
### HTML Structure
```html
```
### CSS Architecture
#### CSS Variables
```css
:root {
--bg-primary: #ffffff;
--bg-secondary: #f8f9fa;
--text-primary: #212529;
--accent: #0d6efd;
}
[data-theme="dark"] {
--bg-primary: #1a1d23;
--bg-secondary: #22252b;
--text-primary: #e9ecef;
--accent: #4dabf7;
}
```
#### Component-based CSS
```css
/* Header */
.header { /* styles */ }
.logo { /* styles */ }
.btn { /* styles */ }
/* Sidebar */
.sidebar { /* styles */ }
.file-item { /* styles */ }
/* Main Content */
.main-content { /* styles */ }
.markdown-content { /* styles */ }
```
### JavaScript Architecture
#### State Management
```javascript
// Global state
let currentLang = 'th';
let currentTheme = 'light';
let docs = {};
let currentDoc = null;
```
#### Core Functions
##### 1. Document Loading
```javascript
async function loadDocsFromFolder() {
try {
const thFiles = await loadMarkdownFiles('docs/th/');
const enFiles = await loadMarkdownFiles('docs/en/');
docs = {};
// Process Thai files
Object.keys(thFiles).forEach(fileName => {
if (!docs[fileName]) docs[fileName] = {};
docs[fileName]['th'] = thFiles[fileName];
});
// Process English files
Object.keys(enFiles).forEach(fileName => {
if (!docs[fileName]) docs[fileName] = {};
docs[fileName]['en'] = enFiles[fileName];
});
renderFileTree();
loadFirstDocument();
} catch (error) {
showNoDocsError();
}
}
```
##### 2. Markdown Processing
```javascript
function loadDocument(docName) {
currentDoc = docName;
const docContent = docs[docName][currentLang] ||
docs[docName]['en'] ||
docs[docName]['th'];
if (!docContent) {
showDocumentNotFound();
return;
}
// Convert markdown to HTML
const html = marked.parse(docContent);
content.innerHTML = html;
// Highlight code blocks
content.querySelectorAll('pre code').forEach((block) => {
hljs.highlightElement(block);
});
updateActiveState();
}
```
##### 3. Theme Management
```javascript
function toggleTheme() {
currentTheme = currentTheme === 'light' ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', currentTheme);
localStorage.setItem('theme', currentTheme);
}
// Load saved theme
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
currentTheme = savedTheme;
document.documentElement.setAttribute('data-theme', currentTheme);
}
```
##### 4. Language Management
```javascript
function toggleLanguage() {
currentLang = currentLang === 'th' ? 'en' : 'th';
localStorage.setItem('language', currentLang);
if (currentDoc) {
loadDocument(currentDoc);
}
}
// Load saved language
const savedLang = localStorage.getItem('language');
if (savedLang) {
currentLang = savedLang;
}
```
## การพัฒนาฟีเจอร์ใหม่
### 1. เพิ่มปุ่มใหม่
```javascript
// สร้างปุ่มใหม่
function createNewButton() {
const button = document.createElement('button');
button.className = 'btn';
button.innerHTML = '🆕 ฟีเจอร์ใหม่';
button.id = 'newFeatureBtn';
// เพิ่ม event listener
button.addEventListener('click', handleNewFeature);
// เพิ่มเข้า header
document.querySelector('.header-controls').appendChild(button);
}
function handleNewFeature() {
// ตรรกะการทำงาน
console.log('New feature activated');
}
```
### 2. เพิ่มเมนูใหม่
```javascript
// เพิ่มเมนูใน sidebar
function addCustomMenu() {
const menu = document.getElementById('fileTree');
const menuItem = document.createElement('div');
menuItem.className = 'file-item';
menuItem.innerHTML = '📄เมนูใหม่';
menuItem.onclick = () => loadCustomContent();
menu.appendChild(menuItem);
}
function loadCustomContent() {
const content = `
เมนูใหม่
เนื้อหาของเมนูใหม่
`;
document.getElementById('content').innerHTML = content;
}
```
### 3. เพิ่มฟีเจอร์ค้นหา
```javascript
// สร้าง search input
function addSearchFeature() {
const searchContainer = document.createElement('div');
searchContainer.className = 'search-container';
const searchInput = document.createElement('input');
searchInput.type = 'text';
searchInput.placeholder = 'ค้นหาเอกสาร...';
searchInput.className = 'search-input';
searchInput.addEventListener('input', handleSearch);
searchContainer.appendChild(searchInput);
document.querySelector('.header-controls').appendChild(searchContainer);
}
function handleSearch(event) {
const query = event.target.value.toLowerCase();
const fileItems = document.querySelectorAll('.file-item');
fileItems.forEach(item => {
const text = item.textContent.toLowerCase();
if (text.includes(query)) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
});
}
```
### 4. เพิ่มฟีเจอร์พิมพ์
```javascript
// เพิ่มปุ่มพิมพ์
function addPrintFeature() {
const printBtn = document.createElement('button');
printBtn.className = 'btn';
printBtn.innerHTML = '🖨️ พิมพ์';
printBtn.onclick = () => {
window.print();
};
document.querySelector('.header-controls').appendChild(printBtn);
}
// CSS สำหรับการพิมพ์
const printStyles = `
@media print {
.header, .sidebar {
display: none;
}
.main-content {
margin: 0;
padding: 0;
}
}
`;
```
## การปรับแต่ง UI
### 1. เปลี่ยนสี
```css
/* เพิ่มสีใหม่ */
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--success-color: #28a745;
--warning-color: #ffc107;
--danger-color: #dc3545;
}
/* ใช้สีใหม่ */
.btn-primary {
background-color: var(--primary-color);
}
.btn-secondary {
background-color: var(--secondary-color);
}
```
### 2. เปลี่ยนฟอนต์
```css
/* เพิ่มฟอนต์ใหม่ */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}
/* ฟอนต์สำหรับโค้ด */
code, pre {
font-family: 'Fira Code', 'Monaco', 'Consolas', monospace;
}
```
### 3. เพิ่ม Animation
```css
/* เพิ่ม transition */
.file-item {
transition: all 0.3s ease;
}
.file-item:hover {
transform: translateX(4px);
background-color: var(--accent);
}
/* Loading animation */
.loading {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
```
## การจัดการ State
### 1. Local Storage
```javascript
// บันทึก state
function saveState() {
localStorage.setItem('currentLang', currentLang);
localStorage.setItem('currentTheme', currentTheme);
localStorage.setItem('currentDoc', currentDoc);
}
// โหลด state
function loadState() {
currentLang = localStorage.getItem('currentLang') || 'th';
currentTheme = localStorage.getItem('currentTheme') || 'light';
currentDoc = localStorage.getItem('currentDoc');
// ใช้ state ที่โหลดมา
document.documentElement.setAttribute('data-theme', currentTheme);
if (currentDoc) {
loadDocument(currentDoc);
}
}
```
### 2. Session Storage
```javascript
// บันทึก session data
function saveSessionData() {
sessionStorage.setItem('lastVisit', new Date().toISOString());
sessionStorage.setItem('visitedDocs', JSON.stringify(visitedDocs));
}
// โหลด session data
function loadSessionData() {
const lastVisit = sessionStorage.getItem('lastVisit');
const visitedDocs = JSON.parse(sessionStorage.getItem('visitedDocs') || '[]');
console.log('Last visit:', lastVisit);
console.log('Visited docs:', visitedDocs);
}
```
## การจัดการ Error
### 1. Error Handling
```javascript
// Global error handler
window.addEventListener('error', (event) => {
console.error('Global error:', event.error);
showErrorMessage('เกิดข้อผิดพลาดในระบบ');
});
// Promise error handling
async function loadDocument(docName) {
try {
const docContent = docs[docName][currentLang];
if (!docContent) {
throw new Error(`Document not found: ${docName}`);
}
const html = marked.parse(docContent);
content.innerHTML = html;
} catch (error) {
console.error('Error loading document:', error);
showErrorMessage(`ไม่สามารถโหลดเอกสาร: ${error.message}`);
}
}
```
### 2. Loading States
```javascript
// แสดง loading state
function showLoading() {
content.innerHTML = `
`;
}
// ซ่อน loading state
function hideLoading() {
const loadingState = document.querySelector('.loading-state');
if (loadingState) {
loadingState.remove();
}
}
```
## การทดสอบ
### 1. Unit Testing
```javascript
// ตัวอย่าง unit test
function testLoadDocument() {
const mockDocs = {
'test': {
'th': '# ทดสอบ\nเนื้อหาทดสอบ',
'en': '# Test\nTest content'
}
};
docs = mockDocs;
currentLang = 'th';
loadDocument('test');
const content = document.getElementById('content');
assert(content.innerHTML.includes('ทดสอบ'));
}
function testThemeToggle() {
currentTheme = 'light';
toggleTheme();
assert(currentTheme === 'dark');
assert(document.documentElement.getAttribute('data-theme') === 'dark');
}
```
### 2. Integration Testing
```javascript
// ตัวอย่าง integration test
async function testFullWorkflow() {
// 1. โหลดเอกสาร
await loadDocsFromFolder();
// 2. เปลี่ยนภาษา
toggleLanguage();
// 3. เปลี่ยนธีม
toggleTheme();
// 4. ตรวจสอบผลลัพธ์
assert(document.documentElement.getAttribute('data-theme') === 'dark');
assert(currentLang === 'en');
}
```
## การ Deploy
### 1. Build Process
```bash
#!/bin/bash
# build.sh
# สร้าง production build
echo "Building production version..."
# Copy files
cp -r docs/ dist/
cp index.html dist/
cp README.md dist/
# Minify CSS (optional)
# npx clean-css-cli -o dist/styles.min.css styles.css
# Minify JS (optional)
# npx terser dist/script.js -o dist/script.min.js
echo "Build completed!"
```
### 2. Docker Deployment
```dockerfile
# Dockerfile
FROM nginx:alpine
COPY . /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
```bash
# Build and run
docker build -t documentation-system .
docker run -p 80:80 documentation-system
```
### 3. CI/CD Pipeline
```yaml
# .github/workflows/deploy.yml
name: Deploy Documentation
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to server
run: |
rsync -avz --delete . user@server:/var/www/docs/
```
## การบำรุงรักษา
### 1. Performance Monitoring
```javascript
// วัดประสิทธิภาพ
function measurePerformance() {
const startTime = performance.now();
loadDocument('index');
const endTime = performance.now();
console.log(`Document load time: ${endTime - startTime}ms`);
}
// ตรวจสอบ memory usage
function checkMemoryUsage() {
if (performance.memory) {
console.log('Memory usage:', {
used: performance.memory.usedJSHeapSize,
total: performance.memory.totalJSHeapSize,
limit: performance.memory.jsHeapSizeLimit
});
}
}
```
### 2. Analytics
```javascript
// ติดตามการใช้งาน
function trackUsage(action, data) {
// Google Analytics
if (typeof gtag !== 'undefined') {
gtag('event', action, data);
}
// Custom analytics
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action, data, timestamp: Date.now() })
});
}
// ติดตามการเปลี่ยนภาษา
function trackLanguageChange(lang) {
trackUsage('language_change', { language: lang });
}
// ติดตามการเปลี่ยนธีม
function trackThemeChange(theme) {
trackUsage('theme_change', { theme: theme });
}
```
## การพัฒนาต่อ
### 1. เพิ่ม PWA Support
```javascript
// Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => console.log('SW registered'))
.catch(error => console.log('SW registration failed'));
}
// Manifest
const manifest = {
"name": "Kotchasan Documentation",
"short_name": "Docs",
"start_url": "/",
"display": "standalone",
"theme_color": "#0d6efd",
"background_color": "#ffffff"
};
```
### 2. เพิ่ม Offline Support
```javascript
// Cache resources
const CACHE_NAME = 'docs-v1';
const urlsToCache = [
'/',
'/index.html',
'/docs/th/index.md',
'/docs/en/index.md'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
);
});
```
---
**หมายเหตุ**: คู่มือนี้ครอบคลุมการพัฒนาระบบเอกสาร สำหรับข้อมูลเพิ่มเติมโปรดดูที่ [Usage Guide](usage-guide.md)