import React, { memo, useCallback, useMemo } from 'react' import { useTestQueueStore } from '@/store/review/useTestQueueStore' /** * 智能導航控制器 * 根據PRD US-008要求實現: * - 答題前狀態:只顯示「跳過」按鈕 * - 答題後狀態:只顯示「繼續」按鈕 * - 答題提交與導航按鈕完全分離 */ export interface NavigationState { status: 'unanswered' | 'answered' | 'skipped' canSkip: boolean canContinue: boolean isLastTest: boolean hasAnswered: boolean } interface NavigationControllerProps { // 當前測驗狀態 hasAnswered: boolean isLastTest?: boolean // 導航動作 onSkip: () => void onContinue: () => void // 樣式配置 className?: string buttonClassName?: string // 禁用狀態 disabled?: boolean } export const NavigationController: React.FC = memo(({ hasAnswered, isLastTest = false, onSkip, onContinue, className = '', buttonClassName = '', disabled = false }) => { // 計算導航狀態 const navigationState: NavigationState = useMemo(() => ({ status: hasAnswered ? 'answered' : 'unanswered', canSkip: !hasAnswered && !disabled, canContinue: hasAnswered && !disabled, isLastTest, hasAnswered }), [hasAnswered, isLastTest, disabled]) // 處理跳過動作 const handleSkip = useCallback(() => { if (navigationState.canSkip) { onSkip() } }, [navigationState.canSkip, onSkip]) // 處理繼續動作 const handleContinue = useCallback(() => { if (navigationState.canContinue) { onContinue() } }, [navigationState.canContinue, onContinue]) // 獲取按鈕文字 const getButtonText = () => { if (navigationState.status === 'answered') { return isLastTest ? '完成學習' : '繼續' } return '跳過' } // 獲取按鈕樣式 const getButtonStyles = () => { const baseStyles = `px-6 py-3 rounded-lg font-medium transition-all ${buttonClassName}` if (navigationState.status === 'answered') { // 答題後 - 繼續按鈕(主要動作) return `${baseStyles} bg-blue-600 text-white hover:bg-blue-700 ${ disabled ? 'opacity-50 cursor-not-allowed' : 'shadow-lg hover:shadow-xl' }` } else { // 答題前 - 跳過按鈕(次要動作) return `${baseStyles} bg-gray-200 text-gray-700 hover:bg-gray-300 ${ disabled ? 'opacity-50 cursor-not-allowed' : '' }` } } // 獲取按鈕圖示 const getButtonIcon = () => { if (navigationState.status === 'answered') { return isLastTest ? '🎉' : '➡️' } return '⏭️' } return (
{/* 狀態驅動的單一按鈕 */}
{/* 狀態提示(開發模式可見) */} {process.env.NODE_ENV === 'development' && (
狀態: {navigationState.status} | 可跳過: {navigationState.canSkip ? '是' : '否'} | 可繼續: {navigationState.canContinue ? '是' : '否'}
)}
) }) NavigationController.displayName = 'NavigationController' /** * 整合測試隊列的高階導航控制器 * 自動處理隊列狀態更新和測驗導航 */ interface SmartNavigationControllerProps { hasAnswered: boolean className?: string buttonClassName?: string disabled?: boolean onSkipCallback?: () => void onContinueCallback?: () => void } export const SmartNavigationController: React.FC = memo(({ hasAnswered, className, buttonClassName, disabled, onSkipCallback, onContinueCallback }) => { const { currentTestIndex, testItems, skipCurrentTest, goToNextTest } = useTestQueueStore() // 判斷是否為最後一個測驗 const isLastTest = useMemo(() => { const remainingTests = testItems.filter(item => !item.isCompleted) return remainingTests.length <= 1 }, [testItems]) // 處理跳過 const handleSkip = useCallback(() => { skipCurrentTest() onSkipCallback?.() }, [skipCurrentTest, onSkipCallback]) // 處理繼續 const handleContinue = useCallback(() => { goToNextTest() onContinueCallback?.() }, [goToNextTest, onContinueCallback]) return ( ) }) SmartNavigationController.displayName = 'SmartNavigationController' /** * 導航狀態判斷工具函數 */ export const getNavigationState = ( hasAnswered: boolean, isSkipped: boolean = false, disabled: boolean = false ): NavigationState => { let status: NavigationState['status'] = 'unanswered' if (isSkipped) { status = 'skipped' } else if (hasAnswered) { status = 'answered' } return { status, canSkip: !hasAnswered && !isSkipped && !disabled, canContinue: hasAnswered && !disabled, isLastTest: false, hasAnswered } } /** * 導航控制器的設定選項 */ export interface NavigationConfig { showSkipButton: boolean showContinueButton: boolean skipButtonText: string continueButtonText: string completeButtonText: string skipButtonIcon: string continueButtonIcon: string completeButtonIcon: string } export const defaultNavigationConfig: NavigationConfig = { showSkipButton: true, showContinueButton: true, skipButtonText: '跳過', continueButtonText: '繼續', completeButtonText: '完成學習', skipButtonIcon: '⏭️', continueButtonIcon: '➡️', completeButtonIcon: '🎉' }