'use client'; import { useState, useEffect, useTransition } from 'react'; import Link from 'next/link'; import { useParams } from 'next/navigation'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Search, Edit, FileText, ChevronUp, ChevronDown } from 'lucide-react'; import { toast } from 'sonner'; import { getTemplatesAction, TemplateFile } from '@/lib/mail/service'; type Template = TemplateFile; interface MailTemplatesClientProps { initialData?: Template[]; } type SortField = 'name' | 'lastModified'; type SortDirection = 'asc' | 'desc'; export default function MailTemplatesClient({ initialData = [] }: MailTemplatesClientProps) { const params = useParams(); const lng = (params?.lng as string) || 'ko'; const [templates, setTemplates] = useState(initialData); const [loading, setLoading] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [sortField, setSortField] = useState('name'); const [sortDirection, setSortDirection] = useState('asc'); const [, startTransition] = useTransition(); // 템플릿 목록 조회 const fetchTemplates = async () => { try { setLoading(true); const search = searchQuery || undefined; startTransition(async () => { const result = await getTemplatesAction(search); if (result.success && result.data) { setTemplates(result.data); } else { toast.error(result.error || '템플릿 목록을 가져오는데 실패했습니다.'); } setLoading(false); }); } catch (error) { console.error('Error fetching templates:', error); toast.error('템플릿 목록을 가져오는데 실패했습니다.'); setLoading(false); } }; // 검색 핸들러 const handleSearch = () => { fetchTemplates(); }; // 정렬 함수 const sortTemplates = (templates: Template[]) => { return [...templates].sort((a, b) => { let aValue: string | Date; let bValue: string | Date; if (sortField === 'name') { aValue = a.name; bValue = b.name; } else { aValue = new Date(a.lastModified); bValue = new Date(b.lastModified); } if (aValue < bValue) { return sortDirection === 'asc' ? -1 : 1; } if (aValue > bValue) { return sortDirection === 'asc' ? 1 : -1; } return 0; }); }; // 정렬 핸들러 const handleSort = (field: SortField) => { if (sortField === field) { setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc'); } else { setSortField(field); setSortDirection('asc'); } }; // 정렬된 템플릿 목록 const sortedTemplates = sortTemplates(templates); useEffect(() => { if (searchQuery !== '') { fetchTemplates(); } else { setTemplates(initialData); } }, [searchQuery, initialData]); return (
{/* 검색 */}
setSearchQuery(e.target.value)} className="pl-10" onKeyPress={(e) => e.key === 'Enter' && handleSearch()} />
{/* 템플릿 테이블 */}
작업 {loading ? ( 로딩 중... ) : templates.length === 0 ? ( 템플릿이 없습니다. ) : ( sortedTemplates.map((template) => (
{template.name}
{new Date(template.lastModified).toLocaleString('ko-KR')}
)) )}
); }