diff --git a/packages/web/src/components/FederatedSearchCard.tsx b/packages/web/src/components/FederatedSearchCard.tsx index aec6531..f7d248d 100644 --- a/packages/web/src/components/FederatedSearchCard.tsx +++ b/packages/web/src/components/FederatedSearchCard.tsx @@ -1,4 +1,4 @@ -import { ExternalLink, Globe } from 'lucide-react'; +import { Dna, ExternalLink, Globe } from 'lucide-react'; import { Link } from 'react-router-dom'; import type { FederatedGeneItem } from '@/api/client'; import { Badge } from './ui/badge'; @@ -11,7 +11,7 @@ export default function FederatedSearchCard({ item }: { item: FederatedGeneItem
- 🧬 +

{item.clawhub_display_name || item.name}

diff --git a/packages/web/src/pages/Browse.tsx b/packages/web/src/pages/Browse.tsx index 894aa1f..733877e 100644 --- a/packages/web/src/pages/Browse.tsx +++ b/packages/web/src/pages/Browse.tsx @@ -50,6 +50,7 @@ export default function Browse() { const [loading, setLoading] = useState(true); const { isAdmin } = useAuth(); + const [listError, setListError] = useState(null); const [federatedMode, setFederatedMode] = useState(false); const [federatedItems, setFederatedItems] = useState([]); const [federatedSources, setFederatedSources] = useState<{ local: number; clawhub: number }>({ @@ -81,6 +82,7 @@ export default function Browse() { useEffect(() => { if (federatedMode && q.trim()) { setLoading(true); + setListError(null); federatedSearch({ q, category: category || undefined, limit: 20 }) .then((result) => { setFederatedItems(result.items); @@ -91,12 +93,14 @@ export default function Browse() { .catch(() => { setFederatedItems([]); setTotal(0); + setListError('搜索加载失败,请刷新重试'); }) .finally(() => setLoading(false)); return; } setLoading(true); + setListError(null); listGenes({ q: q || undefined, category: category || undefined, @@ -116,6 +120,7 @@ export default function Browse() { .catch(() => { setGenes([]); setTotal(0); + setListError('列表加载失败,请刷新重试'); }) .finally(() => setLoading(false)); }, [q, category, tag, compatibility, sort, page, federatedMode, isAdmin, reviewStatus]); @@ -258,10 +263,14 @@ export default function Browse() {
))}
+ ) : listError ? ( +
+

{listError}

+
) : showFederated ? ( federatedItems.length === 0 ? (
-
🔍
+

没有找到匹配的基因

) : ( @@ -273,7 +282,7 @@ export default function Browse() { ) ) : genes.length === 0 ? (
-
🔍
+

没有找到匹配的基因

) : ( diff --git a/packages/web/src/pages/GeneDetail.tsx b/packages/web/src/pages/GeneDetail.tsx index e2a02a0..3b0da70 100644 --- a/packages/web/src/pages/GeneDetail.tsx +++ b/packages/web/src/pages/GeneDetail.tsx @@ -1,4 +1,5 @@ import { + AlertCircle, Bot, Calendar, Check, @@ -185,6 +186,7 @@ export default function GeneDetail() { const { slug } = useParams<{ slug: string }>(); const [gene, setGene] = useState(null); const [versions, setVersions] = useState([]); + const [versionsError, setVersionsError] = useState(null); const [error, setError] = useState(''); useEffect(() => { @@ -192,15 +194,16 @@ export default function GeneDetail() { getGene(slug) .then(setGene) .catch(() => setError('找不到该基因')); + setVersionsError(null); getGeneVersions(slug) .then(setVersions) - .catch(() => {}); + .catch(() => setVersionsError('版本历史加载失败,请刷新重试')); }, [slug]); if (error) { return (
-
😵
+

{error}

返回浏览 @@ -390,7 +393,11 @@ export default function GeneDetail() { {slug && } - + {versionsError ? ( +

{versionsError}

+ ) : ( + + )}
diff --git a/packages/web/src/pages/GenomeBrowse.tsx b/packages/web/src/pages/GenomeBrowse.tsx index 745dacc..9c3a6a4 100644 --- a/packages/web/src/pages/GenomeBrowse.tsx +++ b/packages/web/src/pages/GenomeBrowse.tsx @@ -20,6 +20,7 @@ export default function GenomeBrowse() { const [total, setTotal] = useState(0); const [totalPages, setTotalPages] = useState(0); const [loading, setLoading] = useState(true); + const [listError, setListError] = useState(null); const { isAdmin } = useAuth(); const q = searchParams.get('q') || ''; @@ -42,6 +43,7 @@ export default function GenomeBrowse() { useEffect(() => { setLoading(true); + setListError(null); listGenomes({ q: q || undefined, category: category || undefined, @@ -58,6 +60,7 @@ export default function GenomeBrowse() { .catch(() => { setGenomes([]); setTotal(0); + setListError('列表加载失败,请刷新重试'); }) .finally(() => setLoading(false)); }, [q, category, sort, page, isAdmin]); @@ -119,6 +122,10 @@ export default function GenomeBrowse() { ))} + ) : listError ? ( +
+

{listError}

+
) : genomes.length === 0 ? (
🧫
diff --git a/packages/web/src/pages/GenomeDetail.tsx b/packages/web/src/pages/GenomeDetail.tsx index 35d39e7..367e92c 100644 --- a/packages/web/src/pages/GenomeDetail.tsx +++ b/packages/web/src/pages/GenomeDetail.tsx @@ -132,6 +132,7 @@ export default function GenomeDetail() { const { slug } = useParams<{ slug: string }>(); const [genome, setGenome] = useState(null); const [versions, setVersions] = useState([]); + const [versionsError, setVersionsError] = useState(null); const [error, setError] = useState(''); useEffect(() => { @@ -139,9 +140,10 @@ export default function GenomeDetail() { getGenome(slug) .then(setGenome) .catch(() => setError('找不到该基因组')); + setVersionsError(null); getGenomeVersions(slug) .then(setVersions) - .catch(() => {}); + .catch(() => setVersionsError('版本历史加载失败,请刷新重试')); }, [slug]); if (error) { @@ -263,7 +265,11 @@ export default function GenomeDetail() { - + {versionsError ? ( +

{versionsError}

+ ) : ( + + )}
diff --git a/packages/web/src/pages/Home.tsx b/packages/web/src/pages/Home.tsx index 90dd838..2c871cb 100644 --- a/packages/web/src/pages/Home.tsx +++ b/packages/web/src/pages/Home.tsx @@ -1,4 +1,4 @@ -import { ArrowRight, CheckCircle, Search } from 'lucide-react'; +import { ArrowRight, Bot, CheckCircle, Dna, Plug, Rocket, Search } from 'lucide-react'; import { useEffect, useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { type Gene, listGenes } from '@/api/client'; @@ -80,14 +80,26 @@ export default function Home() { -
- 🧬 {totalGenes > 0 ? `${totalGenes} 个基因` : '基因持续上新'} +
+ + + {totalGenes > 0 ? `${totalGenes} 个基因` : '基因持续上新'} + - 🚀 L0-L3 学习协议 + + + L0-L3 学习协议 + - 🔌 多平台兼容 + + + 多平台兼容 + - 🤖 AI Curator 自动审核 + + + AI Curator 自动审核 +
diff --git a/packages/web/src/pages/TemplateBrowse.tsx b/packages/web/src/pages/TemplateBrowse.tsx index 9e771a3..bd8d711 100644 --- a/packages/web/src/pages/TemplateBrowse.tsx +++ b/packages/web/src/pages/TemplateBrowse.tsx @@ -20,6 +20,7 @@ export default function TemplateBrowse() { const [total, setTotal] = useState(0); const [totalPages, setTotalPages] = useState(0); const [loading, setLoading] = useState(true); + const [listError, setListError] = useState(null); const { isAdmin } = useAuth(); const q = searchParams.get('q') || ''; @@ -42,6 +43,7 @@ export default function TemplateBrowse() { useEffect(() => { setLoading(true); + setListError(null); listTemplates({ q: q || undefined, category: category || undefined, @@ -58,6 +60,7 @@ export default function TemplateBrowse() { .catch(() => { setTemplates([]); setTotal(0); + setListError('列表加载失败,请刷新重试'); }) .finally(() => setLoading(false)); }, [q, category, sort, page, isAdmin]); @@ -117,6 +120,10 @@ export default function TemplateBrowse() { ))} + ) : listError ? ( +
+

{listError}

+
) : templates.length === 0 ? (

暂无 AI 员工模板

diff --git a/packages/web/src/pages/TemplateDetail.tsx b/packages/web/src/pages/TemplateDetail.tsx index 29207db..934a15b 100644 --- a/packages/web/src/pages/TemplateDetail.tsx +++ b/packages/web/src/pages/TemplateDetail.tsx @@ -142,6 +142,7 @@ export default function TemplateDetail() { const { slug } = useParams<{ slug: string }>(); const [template, setTemplate] = useState(null); const [versions, setVersions] = useState([]); + const [versionsError, setVersionsError] = useState(null); const [error, setError] = useState(''); useEffect(() => { @@ -149,9 +150,10 @@ export default function TemplateDetail() { getTemplate(slug) .then(setTemplate) .catch(() => setError('找不到该 AI 员工模板')); + setVersionsError(null); getTemplateVersions(slug) .then(setVersions) - .catch(() => {}); + .catch(() => setVersionsError('版本历史加载失败,请刷新重试')); }, [slug]); if (error) { @@ -322,7 +324,11 @@ export default function TemplateDetail() { - + {versionsError ? ( +

{versionsError}

+ ) : ( + + )}