feat(exercise-detail): add embedded peek functionality for individual exercises
All checks were successful
Deploy Development / deploy (push) Successful in 40s
Test Suite / pytest-backend (push) Successful in 35s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / playwright-tests (push) Successful in 1m9s
Test Suite / pytest-backend (pull_request) Successful in 34s
Test Suite / lint-backend (pull_request) Successful in 0s
Test Suite / build-frontend (pull_request) Successful in 11s
Test Suite / playwright-tests (pull_request) Successful in 55s
All checks were successful
Deploy Development / deploy (push) Successful in 40s
Test Suite / pytest-backend (push) Successful in 35s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / playwright-tests (push) Successful in 1m9s
Test Suite / pytest-backend (pull_request) Successful in 34s
Test Suite / lint-backend (pull_request) Successful in 0s
Test Suite / build-frontend (pull_request) Successful in 11s
Test Suite / playwright-tests (pull_request) Successful in 55s
- Introduced `ExercisePeekModal` to allow users to view details of individual exercises without navigating away from the Exercise Detail Page. - Updated the UI to include a button interaction for peeking at exercises, enhancing user experience and accessibility. - Modified the description in the Exercise Detail section to clarify the new peek feature and its functionality. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
502dddd3b3
commit
85163ad440
|
|
@ -4,6 +4,7 @@ import api from '../utils/api'
|
|||
import ExerciseRichTextBlock from '../components/ExerciseRichTextBlock'
|
||||
import ExerciseAttachmentMediaStrip from '../components/ExerciseAttachmentMediaStrip'
|
||||
import CombinationPlanBracket from '../components/CombinationPlanBracket'
|
||||
import ExercisePeekModal from '../components/ExercisePeekModal'
|
||||
import { formatSkillLevelSlug } from '../constants/skillLevels'
|
||||
|
||||
function TagRow({ exercise }) {
|
||||
|
|
@ -58,6 +59,8 @@ function ExerciseDetailPage() {
|
|||
const [exercise, setExercise] = useState(null)
|
||||
const [error, setError] = useState(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
/** Schnellansicht für eingebettete Einzelübungen (Kombination) — ohne Route zu verlassen */
|
||||
const [embeddedPeekExerciseId, setEmbeddedPeekExerciseId] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
|
|
@ -121,6 +124,12 @@ function ExerciseDetailPage() {
|
|||
|
||||
return (
|
||||
<div className="exercise-detail-shell" style={{ padding: '12px 12px 24px' }}>
|
||||
<ExercisePeekModal
|
||||
key={embeddedPeekExerciseId != null ? String(embeddedPeekExerciseId) : 'exercise-detail-peek'}
|
||||
open={embeddedPeekExerciseId != null}
|
||||
exerciseId={embeddedPeekExerciseId}
|
||||
onClose={() => setEmbeddedPeekExerciseId(null)}
|
||||
/>
|
||||
<div style={{ marginBottom: '12px', display: 'flex', justifyContent: 'space-between', gap: '8px', flexWrap: 'wrap', alignItems: 'center' }}>
|
||||
<button type="button" className="btn btn-secondary" onClick={() => navigate('/exercises')}>
|
||||
← Übersicht
|
||||
|
|
@ -152,7 +161,9 @@ function ExerciseDetailPage() {
|
|||
<section className="card exercise-detail-section">
|
||||
<h2>Ablauf und Stationen</h2>
|
||||
<p style={{ marginTop: 0, fontSize: '0.88rem', color: 'var(--text2)', lineHeight: 1.45 }}>
|
||||
Katalog‑Ablauf mit Archetyp, Zeiten und Stationen — dieselbe Darstellung wie in der Planung und Vorschau.
|
||||
Katalog‑Ablauf mit Archetyp, Zeiten und Stationen. Station bzw. Einzelübung antippen öffnet eine
|
||||
Schnellansicht mit Kurztext und Ablauf, ohne diese Seite zu verlassen. Die vollständige Übungsseite
|
||||
liegt im Popup unten als Link.
|
||||
</p>
|
||||
<div className="training-run-combo-embed">
|
||||
<CombinationPlanBracket
|
||||
|
|
@ -160,7 +171,8 @@ function ExerciseDetailPage() {
|
|||
methodProfile={catalogMethodProfileForBracket}
|
||||
combinationSlots={exercise.combination_slots}
|
||||
planningAdjusted={false}
|
||||
candidateInteraction="link"
|
||||
candidateInteraction="button"
|
||||
onCandidatePeek={(exerciseId) => setEmbeddedPeekExerciseId(Number(exerciseId))}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user