import { useState } from 'react'; import { Copy, Plus, RefreshCw } from 'lucide-react'; import { api, errorText } from '../api'; import type { School } from '../types'; export function Schools({ schools, onChanged, onMessage }: { schools: School[]; onChanged: () => void; onMessage: (text: string) => void; }) { const [schoolId, setSchoolId] = useState(''); const [name, setName] = useState(''); const [issued, setIssued] = useState<{ school_id: string; token: string } | null>(null); const [busy, setBusy] = useState(false); async function register(id: string, label: string): Promise { if (!id.trim()) return; setBusy(true); try { const result = await api.post<{ school_id: string; token: string }>('/api/schools', { school_id: id.trim(), name: label.trim(), }); setIssued(result); setSchoolId(''); setName(''); onChanged(); } catch (error) { onMessage(errorText(error)); } finally { setBusy(false); } } return (

学校与上报凭证

每所学校的桌面端用自己的凭证上报草稿、拉取已发布的经验。凭证只在生成时显示一次,丢了就重新生成。

{ event.preventDefault(); void register(schoolId, name); }}> setSchoolId(event.target.value)} /> setName(event.target.value)} />
{issued && (
{issued.school_id} 的上报凭证
{issued.token}

写进那台机器的 .env:HUB_URL=http://本机地址:8801 和 HUB_TOKEN=上面这串,重启桌面端生效。 这串只显示这一次。

)} {schools.length === 0 && } {schools.map(school => ( ))}
学校已报条目最近上报最近拉取
还没有学校注册
{school.name || school.id}
{school.id}
{school.reported_entries} {school.last_report_at ?? '—'} {school.last_pull_at ?? '—'}
); }