634 lines
25 KiB
TypeScript
634 lines
25 KiB
TypeScript
'use client'
|
||
|
||
import { useState } from 'react'
|
||
import { Navigation } from '@/components/Navigation'
|
||
import { ProtectedRoute } from '@/components/ProtectedRoute'
|
||
|
||
export default function VocabDesignsPage() {
|
||
return (
|
||
<ProtectedRoute>
|
||
<VocabDesignsContent />
|
||
</ProtectedRoute>
|
||
)
|
||
}
|
||
|
||
function VocabDesignsContent() {
|
||
const [selectedDesign, setSelectedDesign] = useState('modern')
|
||
const [showPopup, setShowPopup] = useState(false)
|
||
|
||
// 假詞彙數據
|
||
const mockWord = {
|
||
word: 'elaborate',
|
||
pronunciation: '/ɪˈlæbərət/',
|
||
partOfSpeech: 'verb',
|
||
translation: '詳細說明',
|
||
definition: 'To explain something in more detail; to develop or present a theory, policy, or system in further detail',
|
||
synonyms: ['explain', 'detail', 'expand', 'clarify'],
|
||
difficultyLevel: 'B2',
|
||
isHighValue: true,
|
||
example: 'Could you elaborate on your proposal?',
|
||
exampleTranslation: '你能詳細說明一下你的提案嗎?'
|
||
}
|
||
|
||
const designs = [
|
||
{ id: 'modern', name: '現代玻璃', description: '毛玻璃效果,現代感設計' },
|
||
{ id: 'classic', name: '經典卡片', description: '傳統卡片風格,清晰分區' },
|
||
{ id: 'minimal', name: '極簡風格', description: '簡潔乾淨,突出重點' },
|
||
{ id: 'magazine', name: '雜誌排版', description: '類似雜誌的排版風格' },
|
||
{ id: 'mobile', name: '移動應用', description: 'iOS/Android應用風格' },
|
||
{ id: 'learning', name: '學習卡片', description: '與學習功能一致的風格' }
|
||
]
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gray-50">
|
||
<Navigation />
|
||
|
||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||
{/* 頁面標題 */}
|
||
<div className="text-center mb-8">
|
||
<h1 className="text-4xl font-bold text-gray-900 mb-4">詞彙明細版型展示</h1>
|
||
<p className="text-xl text-gray-600 mb-6">6種不同風格的詞彙彈窗設計</p>
|
||
|
||
{/* 測試詞彙 */}
|
||
<div className="inline-block bg-white rounded-lg shadow-sm p-4 border border-gray-200">
|
||
<span className="text-gray-600 text-sm">測試詞彙:</span>
|
||
<button
|
||
onClick={() => setShowPopup(true)}
|
||
className="ml-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium"
|
||
>
|
||
點擊查看 "elaborate"
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 版型選擇器 */}
|
||
<div className="flex justify-center mb-8">
|
||
<div className="bg-white rounded-xl shadow-sm p-2 inline-flex flex-wrap gap-2">
|
||
{designs.map((design) => (
|
||
<button
|
||
key={design.id}
|
||
onClick={() => setSelectedDesign(design.id)}
|
||
className={`px-4 py-2 rounded-lg transition-all ${
|
||
selectedDesign === design.id
|
||
? 'bg-primary text-white shadow-md'
|
||
: 'text-gray-600 hover:text-gray-900 hover:bg-gray-100'
|
||
}`}
|
||
>
|
||
{design.name}
|
||
</button>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* 版型預覽 */}
|
||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||
{/* 左側:版型說明 */}
|
||
<div className="bg-white rounded-xl shadow-lg p-6">
|
||
<h2 className="text-2xl font-bold text-gray-900 mb-4">
|
||
{designs.find(d => d.id === selectedDesign)?.name}
|
||
</h2>
|
||
<p className="text-gray-600 mb-6">
|
||
{designs.find(d => d.id === selectedDesign)?.description}
|
||
</p>
|
||
|
||
<div className="space-y-4">
|
||
<div>
|
||
<h3 className="font-semibold text-gray-900 mb-2">設計特色</h3>
|
||
<ul className="text-sm text-gray-700 space-y-1">
|
||
{getDesignFeatures(selectedDesign).map((feature, idx) => (
|
||
<li key={idx} className="flex items-center gap-2">
|
||
<span className="text-blue-500">•</span>
|
||
{feature}
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="font-semibold text-gray-900 mb-2">適用場景</h3>
|
||
<p className="text-sm text-gray-700">
|
||
{getDesignScenario(selectedDesign)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 右側:版型預覽 */}
|
||
<div className="bg-gradient-to-br from-gray-100 to-gray-200 rounded-xl p-8 flex items-center justify-center min-h-[600px] relative">
|
||
<div className="text-center">
|
||
<p className="text-gray-600 mb-4">點擊下方按鈕預覽版型效果</p>
|
||
<button
|
||
onClick={() => setShowPopup(true)}
|
||
className="px-6 py-3 bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors font-medium shadow-lg"
|
||
>
|
||
預覽 "{mockWord.word}" 詞彙詳情
|
||
</button>
|
||
</div>
|
||
|
||
{/* 模擬背景文字 */}
|
||
<div className="absolute inset-4 opacity-10 text-gray-500 text-lg leading-relaxed pointer-events-none">
|
||
This is a sample sentence where you can click on any word to see the elaborate definition and detailed explanation.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 詞彙彈窗 - 根據選擇的設計風格渲染 */}
|
||
{showPopup && (
|
||
<>
|
||
{/* 背景遮罩 */}
|
||
<div
|
||
className="fixed inset-0 bg-black bg-opacity-50 z-40"
|
||
onClick={() => setShowPopup(false)}
|
||
/>
|
||
|
||
{/* 彈窗內容 */}
|
||
<div className="fixed inset-0 flex items-center justify-center z-50 p-4">
|
||
{renderVocabPopup(selectedDesign, mockWord, () => setShowPopup(false))}
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// 渲染不同風格的詞彙彈窗
|
||
function renderVocabPopup(design: string, word: any, onClose: () => void) {
|
||
const handleSave = () => {
|
||
alert(`✅ 已將「${word.word}」保存到詞卡!`)
|
||
onClose()
|
||
}
|
||
|
||
switch (design) {
|
||
case 'modern':
|
||
return <ModernGlassDesign word={word} onClose={onClose} onSave={handleSave} />
|
||
case 'classic':
|
||
return <ClassicCardDesign word={word} onClose={onClose} onSave={handleSave} />
|
||
case 'minimal':
|
||
return <MinimalDesign word={word} onClose={onClose} onSave={handleSave} />
|
||
case 'magazine':
|
||
return <MagazineDesign word={word} onClose={onClose} onSave={handleSave} />
|
||
case 'mobile':
|
||
return <MobileAppDesign word={word} onClose={onClose} onSave={handleSave} />
|
||
case 'learning':
|
||
return <LearningCardDesign word={word} onClose={onClose} onSave={handleSave} />
|
||
default:
|
||
return <ModernGlassDesign word={word} onClose={onClose} onSave={handleSave} />
|
||
}
|
||
}
|
||
|
||
// 1. 現代玻璃風格
|
||
function ModernGlassDesign({ word, onClose, onSave }: any) {
|
||
return (
|
||
<div
|
||
className="bg-white rounded-2xl shadow-2xl border-0 w-80 backdrop-blur-sm"
|
||
style={{
|
||
background: 'rgba(255, 255, 255, 0.98)',
|
||
backdropFilter: 'blur(12px)',
|
||
boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.8)'
|
||
}}
|
||
>
|
||
<div className="relative p-5 pb-0">
|
||
<button
|
||
onClick={onClose}
|
||
className="absolute top-3 right-3 w-6 h-6 rounded-full bg-gray-100 hover:bg-gray-200 transition-colors flex items-center justify-center text-gray-500"
|
||
>
|
||
✕
|
||
</button>
|
||
|
||
<div className="pr-8">
|
||
<div className="flex items-baseline gap-3 mb-1">
|
||
<h3 className="text-2xl font-bold text-gray-900">{word.word}</h3>
|
||
{word.isHighValue && <span className="text-yellow-500 text-lg">⭐</span>}
|
||
</div>
|
||
<div className="flex items-center gap-3 text-gray-600">
|
||
<span className="text-sm font-medium">{word.pronunciation}</span>
|
||
<span className="text-xs px-2 py-1 rounded-full font-medium bg-blue-100 text-blue-700">
|
||
{word.difficultyLevel}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="px-5 py-4 space-y-4">
|
||
<div>
|
||
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">翻譯</div>
|
||
<div className="text-lg font-semibold text-gray-900">{word.translation}</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">定義</div>
|
||
<div className="text-sm text-gray-700 leading-relaxed">{word.definition}</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">同義詞</div>
|
||
<div className="flex flex-wrap gap-1">
|
||
{word.synonyms.map((synonym: string, idx: number) => (
|
||
<span key={idx} className="bg-blue-50 text-blue-700 px-2 py-1 rounded text-xs font-medium border border-blue-200">
|
||
{synonym}
|
||
</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="p-5 pt-2 border-t border-gray-100">
|
||
<button
|
||
onClick={onSave}
|
||
className="w-full bg-gradient-to-r from-blue-600 to-blue-700 text-white py-3 px-4 rounded-xl font-medium hover:from-blue-700 hover:to-blue-800 transition-all duration-200 transform hover:scale-105 active:scale-95 flex items-center justify-center gap-2 shadow-lg"
|
||
>
|
||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
|
||
</svg>
|
||
<span className="text-sm font-medium">加入詞卡</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// 2. 經典卡片風格
|
||
function ClassicCardDesign({ word, onClose, onSave }: any) {
|
||
return (
|
||
<div className="bg-white rounded-lg shadow-lg border border-gray-200 w-96 max-w-md">
|
||
<div className="bg-gradient-to-r from-blue-600 to-blue-700 text-white p-4 rounded-t-lg">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<h3 className="text-xl font-bold">{word.word}</h3>
|
||
<p className="text-blue-100 text-sm">{word.pronunciation}</p>
|
||
</div>
|
||
<button
|
||
onClick={onClose}
|
||
className="text-blue-100 hover:text-white w-8 h-8 rounded-full hover:bg-blue-800 transition-colors flex items-center justify-center"
|
||
>
|
||
✕
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="p-4 space-y-4">
|
||
<div className="flex items-center gap-3">
|
||
<span className="bg-gray-100 text-gray-700 px-3 py-1 rounded-full text-sm font-medium">
|
||
{word.partOfSpeech}
|
||
</span>
|
||
<span className={`px-3 py-1 rounded-full text-sm font-medium ${
|
||
word.difficultyLevel === 'A1' || word.difficultyLevel === 'A2' ? 'bg-green-100 text-green-700' :
|
||
word.difficultyLevel === 'B1' || word.difficultyLevel === 'B2' ? 'bg-yellow-100 text-yellow-700' :
|
||
'bg-red-100 text-red-700'
|
||
}`}>
|
||
{word.difficultyLevel}
|
||
</span>
|
||
{word.isHighValue && (
|
||
<span className="bg-yellow-100 text-yellow-700 px-2 py-1 rounded-full text-xs font-medium">
|
||
⭐ 高價值
|
||
</span>
|
||
)}
|
||
</div>
|
||
|
||
<div className="bg-blue-50 rounded-lg p-3 border-l-4 border-blue-400">
|
||
<h4 className="font-semibold text-blue-900 mb-1">中文翻譯</h4>
|
||
<p className="text-blue-800 font-medium">{word.translation}</p>
|
||
</div>
|
||
|
||
<div className="bg-gray-50 rounded-lg p-3">
|
||
<h4 className="font-semibold text-gray-900 mb-2">英文定義</h4>
|
||
<p className="text-gray-700 text-sm leading-relaxed">{word.definition}</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h4 className="font-semibold text-gray-900 mb-2">同義詞</h4>
|
||
<div className="flex flex-wrap gap-2">
|
||
{word.synonyms.map((synonym: string, idx: number) => (
|
||
<span key={idx} className="bg-gray-100 text-gray-700 px-3 py-1 rounded-full text-sm">
|
||
{synonym}
|
||
</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<button
|
||
onClick={onSave}
|
||
className="w-full bg-blue-600 text-white py-3 rounded-lg font-medium hover:bg-blue-700 transition-colors flex items-center justify-center gap-2"
|
||
>
|
||
<span>💾</span>
|
||
<span>保存到詞卡</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// 3. 極簡風格
|
||
function MinimalDesign({ word, onClose, onSave }: any) {
|
||
return (
|
||
<div className="bg-white rounded-lg shadow-lg w-72 border border-gray-100">
|
||
<div className="p-4 border-b border-gray-100">
|
||
<div className="flex items-center justify-between">
|
||
<h3 className="text-xl font-bold text-gray-900">{word.word}</h3>
|
||
<button
|
||
onClick={onClose}
|
||
className="text-gray-400 hover:text-gray-600 w-5 h-5 flex items-center justify-center"
|
||
>
|
||
✕
|
||
</button>
|
||
</div>
|
||
<p className="text-sm text-gray-500 mt-1">{word.pronunciation}</p>
|
||
</div>
|
||
|
||
<div className="p-4 space-y-3">
|
||
<div>
|
||
<span className="text-lg font-medium text-gray-900">{word.translation}</span>
|
||
<span className="ml-2 text-xs text-gray-500">({word.partOfSpeech})</span>
|
||
</div>
|
||
|
||
<p className="text-sm text-gray-600 leading-relaxed">{word.definition}</p>
|
||
|
||
<div className="flex flex-wrap gap-1 pt-2">
|
||
{word.synonyms.slice(0, 3).map((synonym: string, idx: number) => (
|
||
<span key={idx} className="text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded">
|
||
{synonym}
|
||
</span>
|
||
))}
|
||
</div>
|
||
|
||
<button
|
||
onClick={onSave}
|
||
className="w-full mt-4 bg-gray-900 text-white py-2 rounded text-sm font-medium hover:bg-gray-800 transition-colors"
|
||
>
|
||
加入學習
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// 4. 雜誌排版風格
|
||
function MagazineDesign({ word, onClose, onSave }: any) {
|
||
return (
|
||
<div className="bg-white shadow-xl w-96 max-w-md" style={{ fontFamily: 'Georgia, serif' }}>
|
||
<div className="p-6 border-b-2 border-gray-900">
|
||
<div className="flex items-start justify-between">
|
||
<div>
|
||
<h3 className="text-3xl font-bold text-gray-900 mb-1" style={{ fontFamily: 'Georgia, serif' }}>
|
||
{word.word}
|
||
</h3>
|
||
<div className="flex items-center gap-4 text-sm text-gray-600">
|
||
<span className="italic">{word.pronunciation}</span>
|
||
<span className="font-semibold">{word.partOfSpeech}</span>
|
||
<span className="bg-gray-900 text-white px-2 py-1 text-xs">{word.difficultyLevel}</span>
|
||
</div>
|
||
</div>
|
||
<button
|
||
onClick={onClose}
|
||
className="text-gray-400 hover:text-gray-600 text-xl"
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="p-6">
|
||
<div className="mb-4">
|
||
<h4 className="text-xs font-bold text-gray-500 uppercase tracking-widest mb-2 border-b border-gray-200 pb-1">
|
||
Translation
|
||
</h4>
|
||
<p className="text-xl font-semibold text-gray-900" style={{ fontFamily: 'Georgia, serif' }}>
|
||
{word.translation}
|
||
</p>
|
||
</div>
|
||
|
||
<div className="mb-4">
|
||
<h4 className="text-xs font-bold text-gray-500 uppercase tracking-widest mb-2">Definition</h4>
|
||
<p className="text-sm text-gray-700 leading-relaxed" style={{ textAlign: 'justify' }}>
|
||
{word.definition}
|
||
</p>
|
||
</div>
|
||
|
||
<div className="mb-6">
|
||
<h4 className="text-xs font-bold text-gray-500 uppercase tracking-widest mb-2">Synonyms</h4>
|
||
<p className="text-sm text-gray-700 italic">
|
||
{word.synonyms.join(', ')}
|
||
</p>
|
||
</div>
|
||
|
||
<button
|
||
onClick={onSave}
|
||
className="w-full bg-gray-900 text-white py-3 font-semibold uppercase tracking-wider text-sm hover:bg-gray-800 transition-colors"
|
||
>
|
||
Add to Collection
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// 5. 移動應用風格
|
||
function MobileAppDesign({ word, onClose, onSave }: any) {
|
||
return (
|
||
<div className="bg-white rounded-3xl shadow-xl w-80 overflow-hidden">
|
||
<div className="bg-gray-50 px-4 py-3 border-b border-gray-200">
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white font-bold text-sm">
|
||
{word.word[0].toUpperCase()}
|
||
</div>
|
||
<span className="font-medium text-gray-900">詞彙詳情</span>
|
||
</div>
|
||
<button
|
||
onClick={onClose}
|
||
className="text-blue-500 font-medium text-sm"
|
||
>
|
||
完成
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="p-4">
|
||
<div className="text-center mb-4">
|
||
<h3 className="text-2xl font-bold text-gray-900 mb-1">{word.word}</h3>
|
||
<p className="text-gray-500 text-sm">{word.pronunciation}</p>
|
||
<div className="flex items-center justify-center gap-2 mt-2">
|
||
<span className="bg-gray-100 text-gray-700 px-2 py-1 rounded-full text-xs">
|
||
{word.partOfSpeech}
|
||
</span>
|
||
<span className={`px-2 py-1 rounded-full text-xs ${
|
||
word.difficultyLevel === 'A1' || word.difficultyLevel === 'A2' ? 'bg-green-100 text-green-700' :
|
||
word.difficultyLevel === 'B1' || word.difficultyLevel === 'B2' ? 'bg-yellow-100 text-yellow-700' :
|
||
'bg-red-100 text-red-700'
|
||
}`}>
|
||
{word.difficultyLevel}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="space-y-3">
|
||
<div className="flex items-start gap-3 py-2">
|
||
<div className="w-8 text-center">🌏</div>
|
||
<div className="flex-1">
|
||
<div className="font-medium text-gray-900">{word.translation}</div>
|
||
<div className="text-xs text-gray-500">中文翻譯</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex items-start gap-3 py-2 border-t border-gray-100">
|
||
<div className="w-8 text-center">📝</div>
|
||
<div className="flex-1">
|
||
<div className="text-sm text-gray-700 leading-relaxed">{word.definition}</div>
|
||
<div className="text-xs text-gray-500 mt-1">英文定義</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex items-start gap-3 py-2 border-t border-gray-100">
|
||
<div className="w-8 text-center">🔗</div>
|
||
<div className="flex-1">
|
||
<div className="flex flex-wrap gap-1">
|
||
{word.synonyms.slice(0, 3).map((synonym: string, idx: number) => (
|
||
<span key={idx} className="bg-gray-100 text-gray-700 px-2 py-1 rounded-full text-xs">
|
||
{synonym}
|
||
</span>
|
||
))}
|
||
</div>
|
||
<div className="text-xs text-gray-500 mt-1">同義詞</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button
|
||
onClick={onSave}
|
||
className="w-full mt-6 bg-blue-500 text-white py-3 rounded-xl font-medium text-base hover:bg-blue-600 transition-colors active:bg-blue-700"
|
||
>
|
||
加入詞卡
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// 6. 學習卡片風格
|
||
function LearningCardDesign({ word, onClose, onSave }: any) {
|
||
return (
|
||
<div className="bg-white rounded-xl shadow-lg w-96 max-w-md overflow-hidden">
|
||
<div className="bg-gradient-to-br from-blue-50 to-indigo-50 p-5 border-b border-blue-200">
|
||
<div className="flex items-center justify-between mb-3">
|
||
<div className="flex items-center gap-3">
|
||
<div className="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center text-white font-bold">
|
||
{word.word[0].toUpperCase()}
|
||
</div>
|
||
<div>
|
||
<h3 className="text-lg font-bold text-gray-900">{word.word}</h3>
|
||
<p className="text-sm text-gray-600">{word.partOfSpeech}</p>
|
||
</div>
|
||
</div>
|
||
<button
|
||
onClick={onClose}
|
||
className="text-gray-400 hover:text-gray-600"
|
||
>
|
||
✕
|
||
</button>
|
||
</div>
|
||
|
||
<div className="flex items-center gap-3">
|
||
<span className="text-sm font-medium text-gray-700">{word.pronunciation}</span>
|
||
<button className="text-blue-600 hover:text-blue-700 p-1 rounded-full hover:bg-blue-50 transition-colors">
|
||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M8 5v14l11-7z"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="p-5 space-y-4">
|
||
<div className="bg-green-50 rounded-lg p-4">
|
||
<h4 className="font-semibold text-green-900 mb-2 text-left">翻譯</h4>
|
||
<p className="text-green-800 font-medium text-left">{word.translation}</p>
|
||
</div>
|
||
|
||
<div className="bg-gray-50 rounded-lg p-4">
|
||
<h4 className="font-semibold text-gray-900 mb-2 text-left">定義</h4>
|
||
<p className="text-gray-700 text-sm text-left leading-relaxed">{word.definition}</p>
|
||
</div>
|
||
|
||
<div className="bg-blue-50 rounded-lg p-4">
|
||
<h4 className="font-semibold text-blue-900 mb-2 text-left">同義詞</h4>
|
||
<div className="flex flex-wrap gap-2">
|
||
{word.synonyms.map((synonym: string, idx: number) => (
|
||
<span key={idx} className="bg-white text-blue-700 px-3 py-1 rounded-full text-sm border border-blue-200">
|
||
{synonym}
|
||
</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<button
|
||
onClick={onSave}
|
||
className="w-full bg-primary text-white py-3 rounded-lg font-medium hover:bg-primary-hover transition-colors flex items-center justify-center gap-2"
|
||
>
|
||
<span>💾</span>
|
||
<span>保存學習</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// 輔助函數
|
||
function getDesignFeatures(design: string): string[] {
|
||
const features = {
|
||
modern: [
|
||
'毛玻璃背景效果',
|
||
'大尺寸陰影和圓角',
|
||
'漸層按鈕設計',
|
||
'微互動動畫',
|
||
'現代配色方案'
|
||
],
|
||
classic: [
|
||
'藍色漸層標題欄',
|
||
'清晰的區塊分隔',
|
||
'傳統卡片佈局',
|
||
'顏色編碼標籤',
|
||
'穩重的設計風格'
|
||
],
|
||
minimal: [
|
||
'極簡配色方案',
|
||
'去除多餘裝飾',
|
||
'重點信息突出',
|
||
'輕量化設計',
|
||
'快速瀏覽體驗'
|
||
],
|
||
magazine: [
|
||
'雜誌式字體',
|
||
'專業排版設計',
|
||
'大標題小說明',
|
||
'黑白主色調',
|
||
'閱讀導向佈局'
|
||
],
|
||
mobile: [
|
||
'iOS/Android風格',
|
||
'圓角和圖標設計',
|
||
'列表式信息展示',
|
||
'觸控友好設計',
|
||
'移動端優化'
|
||
],
|
||
learning: [
|
||
'學習功能一致性',
|
||
'彩色區塊設計',
|
||
'教育導向佈局',
|
||
'清晰的信息分類',
|
||
'學習體驗優化'
|
||
]
|
||
}
|
||
return features[design as keyof typeof features] || []
|
||
}
|
||
|
||
function getDesignScenario(design: string): string {
|
||
const scenarios = {
|
||
modern: '適合追求現代感和科技感的用戶,特別是年輕用戶群體。設計前衛,視覺效果佳。',
|
||
classic: '適合喜歡傳統界面的用戶,信息展示清晰,功能分區明確,適合學術或商務場景。',
|
||
minimal: '適合追求效率的用戶,減少視覺干擾,快速獲取核心信息,適合頻繁使用的場景。',
|
||
magazine: '適合喜歡閱讀體驗的用戶,類似字典或雜誌的專業排版,適合深度學習。',
|
||
mobile: '適合手機用戶,觸控友好,符合移動端應用的使用習慣,適合隨時隨地學習。',
|
||
learning: '與現有學習功能保持一致,用戶體驗連貫,適合在學習流程中使用。'
|
||
}
|
||
return scenarios[design as keyof typeof scenarios] || ''
|
||
} |