80 lines
2.3 KiB
React
80 lines
2.3 KiB
React
import ExerciseCard from './ExerciseCard'
|
|
import './exerciseRecommendations.css'
|
|
|
|
const normalizeGroupLabel = (item) => {
|
|
return item.group || item.category || item.level || item.progression_level || 'Recommended'
|
|
}
|
|
|
|
const groupRecommendations = (items) => {
|
|
if (!Array.isArray(items)) return []
|
|
const groups = items.reduce((acc, item) => {
|
|
const label = normalizeGroupLabel(item)
|
|
if (!acc[label]) acc[label] = []
|
|
acc[label].push(item)
|
|
return acc
|
|
}, {})
|
|
|
|
return Object.entries(groups).map(([title, recommendations]) => ({
|
|
id: title,
|
|
title,
|
|
recommendations
|
|
}))
|
|
}
|
|
|
|
function RecommendationPanel({
|
|
title = 'Recommended Exercises',
|
|
subtitle,
|
|
recommendations = [],
|
|
groups,
|
|
layout = 'grid',
|
|
onSelect,
|
|
emptyMessage = 'No recommendations available yet.',
|
|
className = ''
|
|
}) {
|
|
const resolvedGroups = Array.isArray(groups) && groups.length > 0
|
|
? groups
|
|
: groupRecommendations(recommendations)
|
|
|
|
const hasContent = resolvedGroups.some(group => group.recommendations?.length)
|
|
|
|
return (
|
|
<section className={`recommendation-panel ${className}`}>
|
|
<div className="recommendation-panel-header">
|
|
<div>
|
|
<h2>{title}</h2>
|
|
{subtitle && <p>{subtitle}</p>}
|
|
</div>
|
|
</div>
|
|
|
|
{!hasContent && (
|
|
<div className="recommendation-empty">{emptyMessage}</div>
|
|
)}
|
|
|
|
{hasContent && (
|
|
<div className="recommendation-panel-body">
|
|
{resolvedGroups.map(group => (
|
|
<div key={group.id || group.title} className="recommendation-group">
|
|
<div className="recommendation-group-header">
|
|
<h3>{group.title}</h3>
|
|
{group.description && <span>{group.description}</span>}
|
|
</div>
|
|
<div className={`recommendation-list recommendation-list--${layout}`}>
|
|
{(group.recommendations || group.items || []).map(item => (
|
|
<ExerciseCard
|
|
key={item.id || `${group.title}-${item.name}`}
|
|
exercise={item}
|
|
onSelect={onSelect}
|
|
compact={layout === 'list'}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</section>
|
|
)
|
|
}
|
|
|
|
export default RecommendationPanel
|