Files
gravl/frontend/src/components/AlternativeModal.jsx
T
clawd 3b6b12d354 design: WorkoutPage Hevy-style redesign + AlternativeModal + backend API
- Add GET /api/exercises/:id/alternatives endpoint
- Add GET /api/exercises/:id/last-workout endpoint
- New AlternativeModal component for swapping exercises
- WorkoutPage: single-tap logging, +/- buttons, rest timer
- Updated Icons with new workout icons
- Polish: card shadows, borders, micro-interactions
- Tasks directory for project management
2026-02-28 21:25:23 +01:00

52 lines
1.7 KiB
React

import { Icon } from './Icons'
function AlternativeModal({ exercise, alternatives, loading, error, onSelect, onClose }) {
if (!exercise) return null
return (
<div className="alternative-modal-overlay" onClick={onClose}>
<div className="alternative-modal" onClick={(event) => event.stopPropagation()}>
<div className="alternative-modal-header">
<div>
<h3>Alternativa övningar</h3>
<p>För {exercise.name}</p>
</div>
<button className="alternative-modal-close" onClick={onClose} aria-label="Stäng">
<Icon name="chevronDown" size={18} />
</button>
</div>
{loading && (
<div className="alternative-modal-state">Laddar alternativ...</div>
)}
{!loading && error && (
<div className="alternative-modal-state error">{error}</div>
)}
{!loading && !error && alternatives.length === 0 && (
<div className="alternative-modal-state">Inga alternativ hittades.</div>
)}
{!loading && !error && alternatives.length > 0 && (
<div className="alternative-list">
{alternatives.map((alt) => (
<div key={alt.id} className="alternative-item">
<div className="alternative-info">
<strong>{alt.name}</strong>
<span>{alt.description || 'Ingen beskrivning tillgänglig.'}</span>
</div>
<button className="alternative-select-btn" onClick={() => onSelect(alt)}>
Välj
</button>
</div>
))}
</div>
)}
</div>
</div>
)
}
export default AlternativeModal