import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
Upload, Volume2, RefreshCcw, Image as ImageIcon, Lightbulb, Star, Trophy,
Heart, Clock, XCircle, CheckCircle, HelpCircle, Rocket, Type,
MousePointerClick, BookOpen, ArrowRight, ArrowLeft, Home, Shuffle,
Edit3, ImagePlus, Ear, CheckSquare, VolumeX
} from 'lucide-react';
/**
* ==========================================
* 圖片處理元件 (Triple-Fallback Safe Image)
* ==========================================
*/
const SafeImage = ({ src, word }) => {
const [imgStatus, setImgStatus] = useState('loading');
const [imgSrc, setImgSrc] = useState(src);
useEffect(() => {
setImgStatus('loading');
setImgSrc(src);
}, [src]);
return (
{imgStatus === 'loading' && (
)}
{imgSrc && (

setImgStatus('success')}
onError={() => {
const fallback = `https://api.dicebear.com/9.x/bottts/svg?seed=${encodeURIComponent(word)}`;
if (imgSrc !== fallback) setImgSrc(fallback);
}}
/>
)}
);
};
const App = () => {
// --- 狀態定義 ---
const [appState, setAppState] = useState('upload');
const [wordList, setWordList] = useState([]);
const [currentIndex, setCurrentIndex] = useState(0);
const [score, setScore] = useState(0);
const [lives, setLives] = useState(3);
const [isMuted, setIsMuted] = useState(false);
// --- 檔案處理 ---
const handleFileUpload = async (e) => {
const file = e.target.files[0];
if (!file) return;
// 動態載入 XLSX 庫確保 GitHub Pages 運行流暢
const script = document.createElement('script');
script.src = "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js";
script.onload = () => {
const reader = new FileReader();
reader.onload = (evt) => {
const wb = window.XLSX.read(evt.target.result, { type: 'array' });
const data = window.XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 });
const parsed = data.slice(1).map(row => ({
word: String(row[0] || '').trim().toLowerCase(),
translation: row[1] || '',
hasFetched: false
})).filter(i => i.word);
setWordList(parsed);
setAppState('selectMode');
};
reader.readAsArrayBuffer(file);
};
document.head.appendChild(script);
};
return (
{/* Header */}
Spelling Adventure
{wordList.length > 0 && (
)}
{appState === 'upload' && (
)}
{appState === 'selectMode' && (
)}
{/* 遊戲中與其它狀態... (邏輯同前) */}
{appState === 'playing' && wordList.length > 0 && (
{wordList[currentIndex].word}
{/* 拼字邏輯與 UI 按鈕 */}
)}
);
};
export default App;