feat(04-04-visual-distinction): Add custom vs program workout badges on WorkoutSelectPage
- Fetch custom workouts for authenticated user - Display 'Anpassad' (custom) or 'Program' badge on each workout card - Add badge component with orange accent for custom, muted color for program - Badge positioned bottom-right of workout icon - Responsive styling consistent with Gravl dark theme - All build checks pass
This commit is contained in:
@@ -17,11 +17,13 @@ const getWorkoutColor = (name) => {
|
||||
|
||||
function WorkoutSelectPage({ onBack, onSelectWorkout }) {
|
||||
const [program, setProgram] = useState(null)
|
||||
const [customWorkouts, setCustomWorkouts] = useState([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [selectedWorkout, setSelectedWorkout] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
fetchProgram()
|
||||
fetchCustomWorkouts()
|
||||
}, [])
|
||||
|
||||
const fetchProgram = async () => {
|
||||
@@ -36,6 +38,24 @@ function WorkoutSelectPage({ onBack, onSelectWorkout }) {
|
||||
}
|
||||
}
|
||||
|
||||
const fetchCustomWorkouts = async () => {
|
||||
try {
|
||||
const token = localStorage.getItem('token')
|
||||
if (!token) return
|
||||
const res = await fetch(`${API_URL}/custom-workouts`, {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
})
|
||||
const data = await res.json()
|
||||
setCustomWorkouts(data || [])
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch custom workouts:', err)
|
||||
}
|
||||
}
|
||||
|
||||
const isWorkoutCustom = (programDayId) => {
|
||||
return customWorkouts.some(cw => cw.source_program_day_id === programDayId)
|
||||
}
|
||||
|
||||
const handleSelect = (workout) => {
|
||||
setSelectedWorkout(workout)
|
||||
}
|
||||
@@ -76,6 +96,7 @@ function WorkoutSelectPage({ onBack, onSelectWorkout }) {
|
||||
const color = getWorkoutColor(workout.name)
|
||||
const isSelected = selectedWorkout?.id === workout.id
|
||||
const exerciseCount = workout.exercises?.filter(e => e.name).length || 0
|
||||
const isCustom = isWorkoutCustom(workout.id)
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -84,8 +105,13 @@ function WorkoutSelectPage({ onBack, onSelectWorkout }) {
|
||||
style={{ '--workout-color': color }}
|
||||
onClick={() => handleSelect(workout)}
|
||||
>
|
||||
<div className="workout-icon" style={{ background: color }}>
|
||||
<Icon name={iconName} size={28} />
|
||||
<div className="workout-badge-container">
|
||||
<div className="workout-icon" style={{ background: color }}>
|
||||
<Icon name={iconName} size={28} />
|
||||
</div>
|
||||
<span className={`workout-badge ${isCustom ? 'custom' : 'program'}`}>
|
||||
{isCustom ? 'Anpassad' : 'Program'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="workout-details">
|
||||
<h3>{workout.name}</h3>
|
||||
|
||||
Reference in New Issue
Block a user