dramaling-vocab-learning/frontend/app/test-api/page.tsx

186 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useState } from 'react'
export default function TestApiPage() {
const [textInput, setTextInput] = useState('')
const [isLoading, setIsLoading] = useState(false)
const [result, setResult] = useState<any>(null)
const [error, setError] = useState<string | null>(null)
const handleTest = async () => {
if (!textInput.trim()) return
setIsLoading(true)
setError(null)
setResult(null)
try {
console.log('發送API請求到:', 'http://localhost:5000/api/ai/analyze-sentence')
console.log('請求數據:', { inputText: textInput, analysisMode: 'full' })
const response = await fetch('http://localhost:5000/api/ai/analyze-sentence', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
inputText: textInput,
analysisMode: 'full'
})
})
console.log('API響應狀態:', response.status, response.statusText)
if (!response.ok) {
throw new Error(`API 錯誤: ${response.status} ${response.statusText}`)
}
const result = await response.json()
console.log('API響應數據:', result)
setResult(result)
if (result.success) {
console.log('✅ API調用成功')
} else {
console.log('❌ API返回失敗:', result.error)
setError(result.error)
}
} catch (error) {
console.error('❌ API調用錯誤:', error)
setError(error instanceof Error ? error.message : '未知錯誤')
} finally {
setIsLoading(false)
}
}
return (
<div className="min-h-screen bg-gray-50 p-8">
<div className="max-w-4xl mx-auto">
<h1 className="text-3xl font-bold mb-8">API </h1>
{/* 輸入區域 */}
<div className="bg-white rounded-lg shadow p-6 mb-6">
<h2 className="text-lg font-semibold mb-4">API</h2>
<div className="space-y-4">
<textarea
value={textInput}
onChange={(e) => setTextInput(e.target.value)}
placeholder="輸入英文句子進行測試..."
className="w-full h-32 px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-transparent outline-none resize-none"
/>
<div className="flex gap-2">
<button
onClick={() => setTextInput("He brought this thing up during our meeting.")}
className="px-4 py-2 bg-green-100 text-green-700 rounded-lg text-sm hover:bg-green-200"
>
使
</button>
<button
onClick={() => setTextInput("I go to school yesterday and meet my friends.")}
className="px-4 py-2 bg-red-100 text-red-700 rounded-lg text-sm hover:bg-red-200"
>
使
</button>
</div>
<button
onClick={handleTest}
disabled={isLoading || !textInput.trim()}
className="w-full bg-blue-600 text-white py-3 rounded-lg font-semibold hover:bg-blue-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
{isLoading ? (
<span className="flex items-center justify-center">
<svg className="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
API連接...
</span>
) : (
'🔍 測試 API 連接'
)}
</button>
</div>
</div>
{/* 錯誤顯示 */}
{error && (
<div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
<h3 className="text-red-800 font-semibold mb-2"> </h3>
<p className="text-red-700">{error}</p>
</div>
)}
{/* 結果顯示 */}
{result && (
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold mb-4">📋 API </h3>
{result.success ? (
<div className="space-y-4">
<div className="flex items-center gap-2">
<span className="text-green-600 text-lg"></span>
<span className="font-medium">API 調</span>
{result.cached && <span className="text-blue-600 text-sm">(使)</span>}
{result.cacheHit && <span className="text-purple-600 text-sm">()</span>}
</div>
{/* 語法檢查結果 */}
{result.data?.grammarCorrection && (
<div className="p-3 bg-gray-50 rounded-lg">
<h4 className="font-medium mb-2"></h4>
{result.data.grammarCorrection.hasErrors ? (
<div className="text-red-600">
{result.data.grammarCorrection.corrections?.length || 0}
</div>
) : (
<div className="text-green-600"> </div>
)}
</div>
)}
{/* 句子意思 */}
{result.data?.sentenceMeaning && (
<div className="p-3 bg-blue-50 rounded-lg">
<h4 className="font-medium mb-2"></h4>
<p className="text-blue-800">{result.data.sentenceMeaning.translation}</p>
<p className="text-blue-600 text-sm mt-1">{result.data.sentenceMeaning.explanation}</p>
</div>
)}
{/* 高價值詞彙 */}
{result.data?.highValueWords && (
<div className="p-3 bg-green-50 rounded-lg">
<h4 className="font-medium mb-2"></h4>
<div className="flex flex-wrap gap-2">
{result.data.highValueWords.map((word: string, idx: number) => (
<span key={idx} className="bg-green-200 text-green-800 px-2 py-1 rounded text-sm">
{word}
</span>
))}
</div>
</div>
)}
{/* 原始響應(調試用) */}
<details className="mt-4">
<summary className="cursor-pointer text-gray-600 text-sm">JSON響應</summary>
<pre className="mt-2 p-3 bg-gray-100 rounded text-xs overflow-auto">
{JSON.stringify(result, null, 2)}
</pre>
</details>
</div>
) : (
<div className="text-red-600">
API : {result.error || '未知錯誤'}
</div>
)}
</div>
)}
</div>
</div>
)
}