209 lines
7.0 KiB
TypeScript
209 lines
7.0 KiB
TypeScript
'use client'
|
||
import { useState, useEffect } from 'react'
|
||
|
||
interface LanguageLevel {
|
||
value: string;
|
||
label: string;
|
||
description: string;
|
||
examples: string[];
|
||
}
|
||
|
||
export default function SettingsPage() {
|
||
const [userLevel, setUserLevel] = useState('A2');
|
||
const [isLoading, setIsLoading] = useState(false);
|
||
|
||
const levels: LanguageLevel[] = [
|
||
{
|
||
value: 'A1',
|
||
label: 'A1 - 初學者',
|
||
description: '能理解基本詞彙和簡單句子',
|
||
examples: ['hello', 'good', 'house', 'eat', 'happy']
|
||
},
|
||
{
|
||
value: 'A2',
|
||
label: 'A2 - 基礎',
|
||
description: '能處理日常對話和常見主題',
|
||
examples: ['important', 'difficult', 'interesting', 'beautiful', 'understand']
|
||
},
|
||
{
|
||
value: 'B1',
|
||
label: 'B1 - 中級',
|
||
description: '能理解清楚標準語言的要點',
|
||
examples: ['analyze', 'opportunity', 'environment', 'responsibility', 'development']
|
||
},
|
||
{
|
||
value: 'B2',
|
||
label: 'B2 - 中高級',
|
||
description: '能理解複雜文本的主要內容',
|
||
examples: ['sophisticated', 'implications', 'comprehensive', 'substantial', 'methodology']
|
||
},
|
||
{
|
||
value: 'C1',
|
||
label: 'C1 - 高級',
|
||
description: '能流利表達,理解含蓄意思',
|
||
examples: ['meticulous', 'predominantly', 'intricate', 'corroborate', 'paradigm']
|
||
},
|
||
{
|
||
value: 'C2',
|
||
label: 'C2 - 精通',
|
||
description: '接近母語水平',
|
||
examples: ['ubiquitous', 'ephemeral', 'perspicacious', 'multifarious', 'idiosyncratic']
|
||
}
|
||
];
|
||
|
||
// 載入用戶已設定的程度
|
||
useEffect(() => {
|
||
const savedLevel = localStorage.getItem('userEnglishLevel');
|
||
if (savedLevel) {
|
||
setUserLevel(savedLevel);
|
||
}
|
||
}, []);
|
||
|
||
const saveUserLevel = async () => {
|
||
setIsLoading(true);
|
||
try {
|
||
// 保存到本地存儲
|
||
localStorage.setItem('userEnglishLevel', userLevel);
|
||
|
||
// TODO: 如果用戶已登入,也保存到伺服器
|
||
// const token = localStorage.getItem('authToken');
|
||
// if (token) {
|
||
// await fetch('/api/user/update-level', {
|
||
// method: 'POST',
|
||
// headers: {
|
||
// 'Content-Type': 'application/json',
|
||
// 'Authorization': `Bearer ${token}`
|
||
// },
|
||
// body: JSON.stringify({ englishLevel: userLevel })
|
||
// });
|
||
// }
|
||
|
||
alert('✅ 程度設定已保存!系統將為您提供個人化的詞彙標記。');
|
||
} catch (error) {
|
||
console.error('Error saving user level:', error);
|
||
alert('❌ 保存失敗,請稍後再試');
|
||
} finally {
|
||
setIsLoading(false);
|
||
}
|
||
};
|
||
|
||
const getHighValueRange = (level: string) => {
|
||
const ranges = {
|
||
'A1': 'A2-B1',
|
||
'A2': 'B1-B2',
|
||
'B1': 'B2-C1',
|
||
'B2': 'C1-C2',
|
||
'C1': 'C2',
|
||
'C2': 'C2'
|
||
};
|
||
return ranges[level as keyof typeof ranges] || 'B1-B2';
|
||
};
|
||
|
||
return (
|
||
<div className="max-w-4xl mx-auto p-6">
|
||
<div className="mb-8">
|
||
<h1 className="text-3xl font-bold mb-4">🎯 英語程度設定</h1>
|
||
<p className="text-gray-600">
|
||
設定您的英語程度,系統將為您提供個人化的詞彙學習建議。
|
||
設定後,我們會重點標記比您目前程度高1-2級的詞彙。
|
||
</p>
|
||
</div>
|
||
|
||
<div className="grid gap-4 mb-8">
|
||
{levels.map(level => (
|
||
<label
|
||
key={level.value}
|
||
className={`
|
||
p-6 border-2 rounded-xl cursor-pointer transition-all hover:shadow-md
|
||
${userLevel === level.value
|
||
? 'border-blue-500 bg-blue-50 shadow-md'
|
||
: 'border-gray-200 hover:border-gray-300'
|
||
}
|
||
`}
|
||
>
|
||
<input
|
||
type="radio"
|
||
name="level"
|
||
value={level.value}
|
||
checked={userLevel === level.value}
|
||
onChange={(e) => setUserLevel(e.target.value)}
|
||
className="sr-only"
|
||
/>
|
||
|
||
<div className="flex items-start justify-between">
|
||
<div className="flex-1">
|
||
<div className="font-bold text-xl text-gray-800 mb-2">
|
||
{level.label}
|
||
</div>
|
||
<div className="text-gray-600 mb-3">
|
||
{level.description}
|
||
</div>
|
||
<div className="flex flex-wrap gap-2">
|
||
{level.examples.map(example => (
|
||
<span
|
||
key={example}
|
||
className="px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm"
|
||
>
|
||
{example}
|
||
</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{userLevel === level.value && (
|
||
<div className="ml-4">
|
||
<div className="w-6 h-6 bg-blue-500 rounded-full flex items-center justify-center">
|
||
<svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</label>
|
||
))}
|
||
</div>
|
||
|
||
{/* 個人化效果預覽 */}
|
||
<div className="bg-gradient-to-r from-blue-50 to-indigo-50 p-6 rounded-xl mb-8">
|
||
<h3 className="font-bold text-lg text-blue-800 mb-3">
|
||
💡 您的個人化學習效果預覽
|
||
</h3>
|
||
<div className="grid md:grid-cols-2 gap-4">
|
||
<div>
|
||
<h4 className="font-semibold text-blue-700 mb-2">高價值詞彙範圍</h4>
|
||
<p className="text-blue-600">
|
||
系統將重點標記 <span className="font-bold">{getHighValueRange(userLevel)}</span> 等級的詞彙
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<h4 className="font-semibold text-blue-700 mb-2">學習建議</h4>
|
||
<p className="text-blue-600 text-sm">
|
||
專注於比您目前程度({userLevel})高1-2級的詞彙,既有挑戰性又不會太困難
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button
|
||
onClick={saveUserLevel}
|
||
disabled={isLoading}
|
||
className={`
|
||
w-full py-4 rounded-xl font-semibold text-lg transition-all
|
||
${isLoading
|
||
? 'bg-gray-300 text-gray-500 cursor-not-allowed'
|
||
: 'bg-blue-500 text-white hover:bg-blue-600 shadow-lg hover:shadow-xl'
|
||
}
|
||
`}
|
||
>
|
||
{isLoading ? '⏳ 保存中...' : '✅ 保存程度設定'}
|
||
</button>
|
||
|
||
<div className="mt-4 text-center">
|
||
<p className="text-sm text-gray-500">
|
||
💡 提示: 您隨時可以回到這裡調整程度設定
|
||
</p>
|
||
</div>
|
||
</div>
|
||
);
|
||
} |