diff --git a/frontend/src/index.css b/frontend/src/index.css index f3ac9ef..cb10b7a 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -230,20 +230,60 @@ body { position: fixed; inset: 0; z-index: 1000; - display: flex; - align-items: center; - justify-content: center; padding: 24px; background: rgba(15, 23, 42, 0.82); cursor: zoom-out; } +.image-lightbox-viewport { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + overflow: auto; + cursor: default; +} .image-lightbox img { - max-width: min(100%, 1100px); - max-height: 92vh; + display: block; border-radius: 10px; box-shadow: 0 24px 80px rgba(0, 0, 0, 0.35); cursor: default; } +.image-lightbox-controls { + position: fixed; + top: 16px; + left: 50%; + z-index: 1001; + display: flex; + align-items: center; + gap: 8px; + padding: 7px 9px; + border: 1px solid rgba(255, 255, 255, 0.28); + border-radius: 999px; + background: rgba(15, 23, 42, 0.82); + color: white; + transform: translateX(-50%); +} +.image-lightbox-controls button { + min-width: 34px; + height: 30px; + padding: 0 10px; + border: 1px solid rgba(255, 255, 255, 0.28); + border-radius: 999px; + background: rgba(255, 255, 255, 0.12); + color: white; + cursor: pointer; +} +.image-lightbox-controls button:disabled { + cursor: not-allowed; + opacity: 0.45; +} +.image-lightbox-controls span { + min-width: 48px; + text-align: center; + font-size: 0.86rem; + font-weight: 700; +} .image-lightbox-close { position: fixed; top: 16px; diff --git a/frontend/src/pages/QuizPage.jsx b/frontend/src/pages/QuizPage.jsx index 1a7531a..f5e3300 100644 --- a/frontend/src/pages/QuizPage.jsx +++ b/frontend/src/pages/QuizPage.jsx @@ -398,6 +398,7 @@ export default function QuizPage() { const [toast, setToast] = useState('') const [navOpen, setNavOpen] = useState(false) const [expandedImagePath, setExpandedImagePath] = useState('') + const [imageZoom, setImageZoom] = useState(1) const [startedAt, setStartedAt] = useState(null) const [favorites, setFavorites] = useState([]) const [activeReadSegment, setActiveReadSegment] = useState(null) @@ -1052,15 +1053,31 @@ const timerStarted = timeLeft !== null {current.question_type === 'mcq' ? 'Multiple Choice' : current.question_type === 'true_false' ? 'True / False' : 'Fill in the Blank'} {current.image_path && ( - )} {expandedImagePath && (
setExpandedImagePath('')}> +
e.stopPropagation()}> + + {Math.round(imageZoom * 100)}% + + +
- Expanded question illustration e.stopPropagation()} /> +
e.stopPropagation()}> + Expanded question illustration 1 ? `${imageZoom * 100}%` : undefined, + }} + /> +
)} {(current.question_type === 'mcq' || current.question_type === 'true_false') && current.options ? (