import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Head from 'next/head'; import { toast } from 'react-hot-toast'; import { MagnifyingGlassIcon, UserIcon, StarIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline'; import { supabase, TABLES } from '@/lib/supabase'; import { getDemoData } from '@/lib/demo-data'; import { Interpreter } from '@/types'; import { formatTime } from '@/utils'; import Layout from '@/components/Layout'; interface InterpreterFilters { search: string; status: 'all' | 'online' | 'busy' | 'offline'; sortBy: 'created_at' | 'name' | 'rating'; sortOrder: 'asc' | 'desc'; } export default function InterpretersPage() { const [interpreters, setInterpreters] = useState([]); const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [totalCount, setTotalCount] = useState(0); const [isDemoMode, setIsDemoMode] = useState(false); const [filters, setFilters] = useState({ search: '', status: 'all', sortBy: 'created_at', sortOrder: 'desc' }); const router = useRouter(); const pageSize = 20; // 获取翻译员列表 const fetchInterpreters = async (page = 1) => { try { setLoading(true); // 检查是否为演示模式 const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const isDemo = !supabaseUrl || supabaseUrl === 'https://demo.supabase.co' || supabaseUrl === ''; setIsDemoMode(isDemo); if (isDemo) { // 使用演示数据 const result = await getDemoData.interpreters(); // 转换数据格式以匹配 Interpreter 类型 const formattedResult = result.map(item => ({ ...item, user_id: item.id, specializations: item.specialties || [], hourly_rate: 150, currency: 'CNY' as const, total_calls: Math.floor(Math.random() * 100), is_certified: Math.random() > 0.5, created_at: new Date().toISOString(), updated_at: new Date().toISOString() })); setInterpreters(formattedResult); setTotalCount(formattedResult.length); setTotalPages(Math.ceil(formattedResult.length / pageSize)); setCurrentPage(page); } else { // 使用真实数据 let query = supabase .from(TABLES.INTERPRETERS) .select('*', { count: 'exact' }); // 搜索过滤 if (filters.search) { query = query.or(`name.ilike.%${filters.search}%`); } // 状态过滤 if (filters.status !== 'all') { query = query.eq('status', filters.status); } // 排序 query = query.order(filters.sortBy, { ascending: filters.sortOrder === 'asc' }); // 分页 const from = (page - 1) * pageSize; const to = from + pageSize - 1; query = query.range(from, to); const { data, error, count } = await query; if (error) throw error; setInterpreters(data || []); setTotalCount(count || 0); setTotalPages(Math.ceil((count || 0) / pageSize)); setCurrentPage(page); } } catch (error) { console.error('Error fetching interpreters:', error); toast.error('获取翻译员列表失败'); // 如果真实数据获取失败,切换到演示模式 if (!isDemoMode) { setIsDemoMode(true); const result = await getDemoData.interpreters(); // 转换数据格式以匹配 Interpreter 类型 const formattedResult = result.map(item => ({ ...item, user_id: item.id, specializations: item.specialties || [], hourly_rate: 150, currency: 'CNY' as const, total_calls: Math.floor(Math.random() * 100), is_certified: Math.random() > 0.5, created_at: new Date().toISOString(), updated_at: new Date().toISOString() })); setInterpreters(formattedResult); setTotalCount(formattedResult.length); setTotalPages(Math.ceil(formattedResult.length / pageSize)); setCurrentPage(page); } } finally { setLoading(false); } }; // 处理筛选变更 const handleFilterChange = (key: keyof InterpreterFilters, value: any) => { setFilters(prev => ({ ...prev, [key]: value })); }; // 应用筛选 const applyFilters = () => { setCurrentPage(1); fetchInterpreters(1); }; // 重置筛选 const resetFilters = () => { setFilters({ search: '', status: 'all', sortBy: 'created_at', sortOrder: 'desc' }); setCurrentPage(1); fetchInterpreters(1); }; // 获取状态颜色 const getStatusColor = (status: string) => { switch (status) { case 'online': return 'bg-green-100 text-green-800'; case 'busy': return 'bg-yellow-100 text-yellow-800'; case 'offline': return 'bg-gray-100 text-gray-800'; default: return 'bg-gray-100 text-gray-800'; } }; // 获取状态文本 const getStatusText = (status: string) => { switch (status) { case 'online': return '在线'; case 'busy': return '忙碌'; case 'offline': return '离线'; default: return '未知'; } }; useEffect(() => { fetchInterpreters(); }, []); return ( 翻译员管理 - 口译服务管理后台
{/* 页面标题 */}

翻译员管理

{/* 搜索和筛选 */}
{/* 搜索框 */}
handleFilterChange('search', e.target.value)} className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-blue-500 focus:border-blue-500" />
{/* 状态筛选 */}
{/* 排序 */}
{/* 翻译员列表 */} {loading ? (
) : interpreters.length === 0 ? (

暂无翻译员

调整筛选条件或检查数据源

) : (

翻译员列表 ({totalCount} 个翻译员)

{interpreters.map((interpreter) => (
{interpreter.name}

{interpreter.name}

{interpreter.languages.join(', ')}

专业领域: {interpreter.specializations?.join(', ') || '无'}

{interpreter.rating || 0}/5
{getStatusText(interpreter.status)}
))}
{/* 分页 */} {totalPages > 1 && (

显示第 {(currentPage - 1) * pageSize + 1} 到{' '} {Math.min(currentPage * pageSize, totalCount)} {' '} 条,共 {totalCount} 条记录

)}
)}
); }