import { useState } from "react"; import { ProgressBar, Label, Tabs } from "@heroui/react"; import Card from "./components/Card"; import Guodegang from "./components/Guodegang"; import Mermaid from "./components/Mermaid"; import Topic from "./components/Topic"; /* eslint-disable @typescript-eslint/no-explicit-any */ function App() { const [topic, setTopic] = useState(''); const [cardData, setCardData]: any = useState(null); const [cardLoading, setCardLoading] = useState(false); const [cardError, setCardError] = useState(null); const [guodegangData, setGuodegangData]: any = useState(null); const [guodegangLoading, setGuodegangLoading] = useState(false); const [guodegangError, setGuodegangError] = useState(null); const [mermaidData, setMermaidData]: any = useState(null); const [mermaidLoading, setMermaidLoading] = useState(false); const [mermaidError, setMermaidError] = useState(null); const fetchData = async (topicToFetch: string) => { setCardLoading(true); setGuodegangLoading(true); setMermaidLoading(true); setCardError(null); setGuodegangError(null); setMermaidError(null); const cardUrl = `http://localhost:8080/card/${encodeURIComponent(topicToFetch)}`; const guodegangUrl = `http://localhost:8080/guodegang/${encodeURIComponent(topicToFetch)}`; const mermaidUrl = `http://localhost:8080/mermaid/${encodeURIComponent(topicToFetch)}`; const abortController = new AbortController(); const timeoutId = setTimeout(() => abortController.abort(), 300000); const fetchCard = async () => { try { const response = await fetch(cardUrl, { signal: abortController.signal }); if (!response.ok) throw new Error(`Card API failed: ${response.status}`); const result = await response.json(); setCardData(result.message); } catch (error) { console.error("Error fetching card data:", error); setCardError("Failed to load card data"); } finally { setCardLoading(false); } }; const fetchGuodegang = async () => { try { const response = await fetch(guodegangUrl, { signal: abortController.signal }); if (!response.ok) throw new Error(`Guodegang API failed: ${response.status}`); const result = await response.json(); setGuodegangData(result.message); } catch (error) { console.error("Error fetching guodegang data:", error); setGuodegangError("Failed to load guodegang data"); } finally { setGuodegangLoading(false); } }; const fetchMermaid = async () => { try { const response = await fetch(mermaidUrl, { signal: abortController.signal }); if (!response.ok) throw new Error(`Mermaid API failed: ${response.status}`); const result = await response.json(); setMermaidData(result.message); } catch (error) { console.error("Error fetching mermaid data:", error); setMermaidError("Failed to load mermaid data"); } finally { setMermaidLoading(false); } }; Promise.allSettled([fetchCard(), fetchGuodegang(), fetchMermaid()]).finally(() => { clearTimeout(timeoutId); }); }; const handleTopicSubmit = (newTopic: string) => { setTopic(newTopic); if (newTopic) { fetchData(newTopic); } }; const cardLoaded = !cardLoading && !!cardData; const guodegangLoaded = !guodegangLoading && !!guodegangData; const mermaidLoaded = !mermaidLoading && !!mermaidData; const progress = (() => { if (!topic) return 0; if (cardLoaded && guodegangLoaded && mermaidLoaded) return 100; if (cardLoaded && guodegangLoaded) return 67; if (cardLoaded && mermaidLoaded) return 67; if (guodegangLoaded && mermaidLoaded) return 67; if (cardLoaded || guodegangLoaded || mermaidLoaded) return 33; return 10; })(); return (
{topic && (
)}
📚 学习卡片 🎭 德云社讲解 📊 Mermaid 图表
); } export default App;