diff --git a/frontend/app/learn/page.tsx b/frontend/app/learn/page.tsx index 98e28bb..b110d03 100644 --- a/frontend/app/learn/page.tsx +++ b/frontend/app/learn/page.tsx @@ -1,6 +1,6 @@ 'use client' -import { useState, useEffect } from 'react' +import { useState, useEffect, useRef, useLayoutEffect } from 'react' import { useRouter } from 'next/navigation' import { Navigation } from '@/components/Navigation' import AudioPlayer from '@/components/AudioPlayer' @@ -24,6 +24,12 @@ export default function LearnPage() { const [reportingCard, setReportingCard] = useState(null) const [showComplete, setShowComplete] = useState(false) const [quizOptions, setQuizOptions] = useState(['brought', 'determine', 'achieve', 'consider']) + const [cardHeight, setCardHeight] = useState(400) + + // Refs for measuring card content heights + const cardFrontRef = useRef(null) + const cardBackRef = useRef(null) + const cardContainerRef = useRef(null) // Mock data with real example images const cards = [ @@ -70,6 +76,37 @@ export default function LearnPage() { const currentCard = cards[currentCardIndex] + // Calculate optimal card height based on content (only when card changes) + const calculateCardHeight = () => { + if (!cardFrontRef.current || !cardBackRef.current) return 400; + + // Get the scroll heights to measure actual content + const frontHeight = cardFrontRef.current.scrollHeight; + const backHeight = cardBackRef.current.scrollHeight; + + console.log('Heights calculated:', { frontHeight, backHeight }); // Debug log + + // Use the maximum height with padding + const maxHeight = Math.max(frontHeight, backHeight); + const paddedHeight = maxHeight + 40; // Add padding for visual spacing + + // Ensure minimum height for visual consistency + return Math.max(paddedHeight, 450); + }; + + // Update card height only when card content changes (not on flip) + useLayoutEffect(() => { + if (mounted && cardFrontRef.current && cardBackRef.current) { + // Wait for DOM to be fully rendered + const timer = setTimeout(() => { + const newHeight = calculateCardHeight(); + setCardHeight(newHeight); + }, 50); + + return () => clearTimeout(timer); + } + }, [currentCardIndex, mounted]); + // Client-side mounting and quiz options generation useEffect(() => { setMounted(true) @@ -102,6 +139,7 @@ export default function LearnPage() { setShowResult(false) setFillAnswer('') setShowHint(false) + // Height will be recalculated in useLayoutEffect } else { setShowComplete(true) } @@ -115,6 +153,7 @@ export default function LearnPage() { setShowResult(false) setFillAnswer('') setShowHint(false) + // Height will be recalculated in useLayoutEffect } } @@ -305,95 +344,64 @@ export default function LearnPage() { -
+
{/* Front */}
-
-
- - {currentCard.difficulty} - -
-

+
+

{currentCard.word}

-

- {currentCard.partOfSpeech} {currentCard.pronunciation} -

- -

- 點擊查看翻譯 -

+
+ + {currentCard.pronunciation} + + +

{/* Back */}
-
-
- {/* Left Column - Text Content */} -
-
- - {currentCard.difficulty} - -
-

- {currentCard.word} -

-

- {currentCard.translation} -

-

- {currentCard.partOfSpeech} {currentCard.pronunciation} -

- -
- -
- -
-

定義

-

{currentCard.definition}

-
- -
-

例句

-

"{currentCard.example}"

-

"{currentCard.exampleTranslation}"

-
- -
-

同義詞

-
- {currentCard.synonyms.map((synonym, index) => ( - - {synonym} - - ))} -
-
+
+ {/* Content Sections */} +
+ {/* Definition */} +
+

定義

+

{currentCard.definition}

- {/* Right Column - Image */} -
-
- {`Example { - e.stopPropagation() - setModalImage(currentCard.exampleImage) - }} - /> -
- 點擊放大 -
+ {/* Example */} +
+

例句

+

"{currentCard.example}"

+

"{currentCard.exampleTranslation}"

+
+ + {/* Synonyms */} +
+

同義詞

+
+ {currentCard.synonyms.map((synonym, index) => ( + + {synonym} + + ))}
@@ -935,7 +943,9 @@ export default function LearnPage() {