import React, { useState, useEffect } from 'react'; interface CustomPath { ge_id: string; lang: string; custom_path: string; created_at?: string; updated_at?: string; } interface CustomPathManagerModalProps { isOpen: boolean; onClose: () => void; onPathUpdated?: () => void; // Callback khi có thay đổi } const CustomPathManagerModal: React.FC = ({ isOpen, onClose, onPathUpdated }) => { const [searchTerm, setSearchTerm] = useState(''); const [allPaths, setAllPaths] = useState([]); const [filteredPaths, setFilteredPaths] = useState([]); const [visibleCount, setVisibleCount] = useState(10); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [editingPath, setEditingPath] = useState(null); const [editForm, setEditForm] = useState({ ge_id: '', lang: '', custom_path: '' }); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [deleteTarget, setDeleteTarget] = useState(null); useEffect(() => { if (isOpen) { document.body.style.overflow = 'hidden'; loadPaths(); } else { document.body.style.overflow = 'auto'; } return () => { document.body.style.overflow = 'auto'; }; }, [isOpen]); useEffect(() => { // Filter paths when search term changes if (searchTerm.trim() === '') { setFilteredPaths(allPaths.slice(0, visibleCount)); } else { const filtered = allPaths .filter(path => path.ge_id.toLowerCase().includes(searchTerm.toLowerCase()) || path.lang.toLowerCase().includes(searchTerm.toLowerCase()) || path.custom_path.toLowerCase().includes(searchTerm.toLowerCase()) ) .slice(0, visibleCount); setFilteredPaths(filtered); } }, [searchTerm, allPaths, visibleCount]); const loadPaths = async () => { setIsLoading(true); setError(null); try { const response = await fetch('/api/custom-paths'); const data = await response.json(); if (data.success && Array.isArray(data.custom_paths)) { setAllPaths(data.custom_paths); setFilteredPaths(data.custom_paths.slice(0, 10)); } else { setError('Không thể tải danh sách custom paths'); } } catch (err) { console.error('Error loading custom paths:', err); setError('Lỗi khi tải danh sách custom paths'); } finally { setIsLoading(false); } }; if (!isOpen) { return null; } const handleSearch = () => { setVisibleCount(10); const filtered = allPaths .filter(path => path.ge_id.toLowerCase().includes(searchTerm.toLowerCase()) || path.lang.toLowerCase().includes(searchTerm.toLowerCase()) || path.custom_path.toLowerCase().includes(searchTerm.toLowerCase()) ) .slice(0, 10); setFilteredPaths(filtered); }; const handleInputKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { e.preventDefault(); handleSearch(); } }; const handleLoadMore = () => { const newCount = visibleCount + 10; setVisibleCount(newCount); if (searchTerm.trim() === '') { setFilteredPaths(allPaths.slice(0, newCount)); } else { const filtered = allPaths .filter(path => path.ge_id.toLowerCase().includes(searchTerm.toLowerCase()) || path.lang.toLowerCase().includes(searchTerm.toLowerCase()) || path.custom_path.toLowerCase().includes(searchTerm.toLowerCase()) ) .slice(0, newCount); setFilteredPaths(filtered); } }; const handleEdit = (path: CustomPath) => { setEditingPath(path); setEditForm({ ge_id: path.ge_id, lang: path.lang, custom_path: path.custom_path }); }; const handleCancelEdit = () => { setEditingPath(null); setEditForm({ ge_id: '', lang: '', custom_path: '' }); }; const handleSaveEdit = async () => { if (!editForm.ge_id || !editForm.lang || !editForm.custom_path) { setError('Vui lòng điền đầy đủ thông tin'); return; } setIsLoading(true); setError(null); try { // Delete old record if ge_id changed if (editingPath && editingPath.ge_id !== editForm.ge_id) { await fetch(`/api/custom-paths/${editingPath.ge_id}`, { method: 'DELETE' }); } // Create/update new record const response = await fetch('/api/custom-paths', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(editForm) }); const data = await response.json(); if (data.success) { await loadPaths(); handleCancelEdit(); if (onPathUpdated) onPathUpdated(); } else { setError(data.message || 'Không thể lưu custom path'); } } catch (err) { console.error('Error saving custom path:', err); setError('Lỗi khi lưu custom path'); } finally { setIsLoading(false); } }; const handleDeleteClick = (geId: string) => { setDeleteTarget(geId); setShowDeleteConfirm(true); }; const handleConfirmDelete = async () => { if (!deleteTarget) return; setIsLoading(true); setError(null); try { const response = await fetch(`/api/custom-paths/${deleteTarget}`, { method: 'DELETE' }); const data = await response.json(); if (data.success) { await loadPaths(); setShowDeleteConfirm(false); setDeleteTarget(null); if (onPathUpdated) onPathUpdated(); } else { setError(data.message || 'Không thể xóa custom path'); } } catch (err) { console.error('Error deleting custom path:', err); setError('Lỗi khi xóa custom path'); } finally { setIsLoading(false); } }; const handleCancelDelete = () => { setShowDeleteConfirm(false); setDeleteTarget(null); }; return (
{/* Header */}

Quản lý Custom Paths

{/* Search Bar */}
setSearchTerm(e.target.value)} onKeyDown={handleInputKeyDown} placeholder="Tìm kiếm GE ID, Lang, hoặc Path..." className="flex-1 bg-slate-900/50 border border-slate-600 text-white text-sm rounded-lg focus:ring-indigo-500 focus:border-indigo-500 px-4 py-2.5" />
{/* Error Message */} {error && (

{error}

)} {/* Content */}
{isLoading && filteredPaths.length === 0 ? (
) : filteredPaths.length === 0 ? (

Không tìm thấy custom path nào

) : (
{filteredPaths.map((path) => (
{editingPath?.ge_id === path.ge_id ? ( /* Edit Mode */
setEditForm({ ...editForm, ge_id: e.target.value })} placeholder="GE ID" className="bg-slate-800 border border-slate-600 text-white text-sm rounded-lg px-3 py-2" /> setEditForm({ ...editForm, lang: e.target.value.toUpperCase() })} placeholder="Lang" className="bg-slate-800 border border-slate-600 text-white text-sm rounded-lg px-3 py-2" /> setEditForm({ ...editForm, custom_path: e.target.value })} placeholder="Custom Path" className="bg-slate-800 border border-slate-600 text-white text-sm rounded-lg px-3 py-2" />
) : ( /* View Mode */
{path.ge_id} {path.lang}

{path.custom_path}

)}
))}
)} {/* Load More Button */} {filteredPaths.length < allPaths.length && (
)}
{/* Footer Info */}

Tổng số: {allPaths.length} custom paths

{/* Delete Confirmation Modal */} {showDeleteConfirm && (

Xác nhận xóa

Bạn có chắc chắn muốn xóa custom path cho {deleteTarget}?

)}
); }; export default CustomPathManagerModal;