import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { apiFetchWifiPool } from '../api'; import type { WifiPoolItem } from '../api'; function bssidKey(bssid: string): string { return bssid.toLowerCase().replace(/[^0-9a-f]/g, ''); } interface WifiPoolModalProps { open: boolean; onClose: () => void; onSelect: (ssid: string, bssid: string) => void; acceptedBssidKeys: string; } export const WifiPoolModal: React.FC = ({ open, onClose, onSelect, acceptedBssidKeys, }) => { const [search, setSearch] = useState(''); const [debouncedQ, setDebouncedQ] = useState(''); const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const acceptedSet = useMemo(() => { return new Set( acceptedBssidKeys.split(',').map(s => s.trim()).filter(s => s.length === 12) ); }, [acceptedBssidKeys]); useEffect(() => { if (!open) return; const t = setTimeout(() => setDebouncedQ(search.trim()), 300); return () => clearTimeout(t); }, [search, open]); const loadPool = useCallback(async (q: string) => { try { setLoading(true); setError(null); const res = await apiFetchWifiPool(q, 80); setItems(res.data || []); } catch (e: any) { setItems([]); setError(e?.message || 'Không tải được kho WiFi'); } finally { setLoading(false); } }, []); useEffect(() => { if (!open) return; loadPool(debouncedQ); const interval = setInterval(() => loadPool(debouncedQ), 20000); return () => clearInterval(interval); }, [open, debouncedQ, loadPool]); useEffect(() => { if (!open) { setSearch(''); setDebouncedQ(''); setItems([]); setError(null); } }, [open]); if (!open) return null; const handleSelect = (ssid: string, bssid: string) => { const key = bssidKey(bssid); if (!ssid.trim() || key.length !== 12 || acceptedSet.has(key)) return; onSelect(ssid, bssid); }; return (
e.stopPropagation()}>

Kho WiFi

Điểm phát thật từ máy sinh viên (SSID + BSSID). Chọn để thêm vào danh sách chấp nhận.

setSearch(e.target.value)} autoFocus />
{error ? (
{error}
) : loading && items.length === 0 ? (
Đang tải...
) : items.length === 0 ? (
{debouncedQ ? `Không tìm thấy "${debouncedQ}"` : 'Chưa có WiFi nào trong kho.'}
) : ( {items.map(item => { const key = bssidKey(item.bssid || ''); const added = key.length === 12 && acceptedSet.has(key); return ( ); })}
SSID BSSID (MAC) Lần ghi nhận Gần nhất
{item.ssid} {item.bssid || '—'} {item.hitCount}× {item.lastSeenAt ? new Date(item.lastSeenAt).toLocaleString('vi-VN') : '—'} {!item.bssid || key.length !== 12 ? ( Thiếu BSSID ) : added ? ( Đã có ) : ( )}
)}
Hiển thị {items.length} kết quả{debouncedQ ? ` cho "${debouncedQ}"` : ''}
); };