import { useEffect, useMemo, useState } from "react"; import { adminFetch } from "./adminApi"; import PageHeader, { LoadingBlock } from "./PageHeader"; import { TableCard, TableHeadRow } from "./StampList"; type User = { id: string; username: string; phone: string; createdAt: string; collectionCount: number; redemptionCount: number; }; export default function UsersList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [query, setQuery] = useState(""); useEffect(() => { adminFetch("/users") .then(setUsers) .finally(() => setLoading(false)); }, []); const filtered = useMemo(() => { const q = query.trim().toLowerCase(); if (!q) return users; return users.filter( (u) => u.username.toLowerCase().includes(q) || u.phone.includes(q), ); }, [users, query]); return ( <> setQuery(e.target.value)} placeholder="搜索用户名或手机号" className="pl-9 pr-4 py-2.5 bg-white border border-[var(--border-default)] rounded-lg text-sm text-[var(--text-primary)] placeholder:text-[var(--text-muted)]/60 focus:outline-none focus:border-[var(--gold)] focus:ring-2 focus:ring-[var(--gold)]/15 transition-all w-64" /> } /> {loading ? ( ) : ( {filtered.length === 0 ? (

{query ? `没有匹配「${query}」的用户` : "尚无注册用户"}

) : ( {filtered.map((u, i) => ( ))}
{u.username.slice(0, 1).toUpperCase()}
{u.username}
{u.phone} {new Date(u.createdAt).toLocaleString("zh-CN")}
)}
)} ); } function CountBadge({ value, accent, suffix }: { value: number; accent: string; suffix: string }) { const isZero = value === 0; return ( {value} {suffix} ); }