# คู่มือนักพัฒนา - 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)