'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import api from '@/lib/api'; import { Loader2, Search, MapPin, Filter, X, Globe } from 'lucide-react'; import Pagination from '@/components/common/Pagination'; import { useLanguage } from '@/lib/i18n/LanguageContext'; interface Product { id: number; title: string; price_amount: number; price_currency: string; description: string; country: string; city: string; visa_type: string; provider: string; } export default function ServiceList() { const router = useRouter(); const { t } = useLanguage(); const [products, setProducts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [keyword, setKeyword] = useState(''); const [selectedCountry, setSelectedCountry] = useState(''); const [selectedType, setSelectedType] = useState(''); const [page, setPage] = useState(1); const [pageSize] = useState(9); const [total, setTotal] = useState(0); const countries = ['Austria','Croatia','Denmark','Finland','France','Germany','Greece','Hungary','Iceland','Italy','Netherlands','Poland','Spain']; const visaTypes = ['Tourist','Business','Family','Student','Work','Transit','e-Visa']; useEffect(() => { fetchProducts(1); }, []); const fetchProducts = async (targetPage: number) => { setLoading(true); setError(''); try { const res = await api.get('/api/vas/product/list', { params: { page: targetPage, size: pageSize, keyword: keyword, country: selectedCountry, visa_type: selectedType } }); const data = res.data.data || {}; if (Array.isArray(data)) { let filtered = data; if (keyword) { const lowerKey = keyword.toLowerCase(); filtered = filtered.filter((p: any) => p.title.toLowerCase().includes(lowerKey) || p.city?.toLowerCase().includes(lowerKey) || p.country?.toLowerCase().includes(lowerKey) ); } if (selectedCountry) filtered = filtered.filter((p: any) => p.country === selectedCountry); if (selectedType) filtered = filtered.filter((p: any) => p.visa_type === selectedType); setProducts(filtered); setTotal(filtered.length); } else { setProducts(data.items || []); setTotal(data.total || 0); } setPage(targetPage); } catch (err) { console.warn("API Error, using mock data"); setProducts([]); setTotal(0); } finally { setLoading(false); } }; const handleSearch = () => fetchProducts(1); const handleReset = () => { setKeyword(''); setSelectedCountry(''); setSelectedType(''); fetchProducts(1); }; const handleOrderClick = (id: number) => { router.push(`/create-order/${id}`); }; return (
{/* === 筛选工具栏:响应式调整 === */}
{/* 搜索框 */}
setKeyword(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSearch()} />
{/* 国家筛选 */}
{/* 类型筛选 */}
{/* 按钮组 */}
{(keyword || selectedCountry || selectedType) && ( )}
{/* === 商品列表:响应式调整 === */} {loading ? (
) : error ? (
{error}
) : products.length === 0 ? (

{t('services.no_result_title')}

{t('services.no_result_desc')}

) : ( // 修改:移动端 grid-cols-1,平板 grid-cols-2,桌面 grid-cols-3
{products.map((item) => (
{item.country} {item.city && ( <> / {item.city} )}
{item.visa_type}

{item.title}

{item.description || t('services.no_desc')}

{t('services.service_fee')} {item.price_currency === 'CNY' ? '¥' : item.price_currency} {(item.price_amount / 100).toLocaleString()}
))}
)} fetchProducts(p)} />
); }